npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ccatto/ui

v1.1.0

Published

Catto UI Component Library - React components with Tailwind CSS

Downloads

185

Readme

@ccatto/ui

Catto (noun) — Pronounced like it rhymes with "tomato" or "potato" 🍅🥔

"Is it cat-oh or cah-toe?" — Yes.

A production-ready React component library built with Tailwind CSS v4, designed for modern web and mobile applications.

The Story

I started building these components in 2022 while working on RLeaguez.com, a sports league management platform. After years of copying the same Button, Card, and Modal components between projects, I decided to package them up properly.

Now I'm sharing them with the community. Take them, use them, build something cool. If they save you time, that's all the thanks I need.

Chris Catto

Who Is This For?

@ccatto/ui is built for you if:

  • You're building a Next.js 14+ app with the App Router
  • You use Tailwind CSS (v3 or v4) for styling
  • You want dark mode without the headache
  • You need components that work on web and mobile (Capacitor/iOS/Android)
  • You're tired of building the same Button, Modal, and Table for every project
  • You value TypeScript, accessibility, and consistent APIs

Perfect for:

  • SaaS dashboards
  • E-commerce sites
  • Sports/league management apps
  • Admin panels
  • Mobile-first web apps

Not the best fit if:

  • You need unstyled/headless primitives (check out Radix UI or DaisyUI)
  • You're not using React
  • You prefer CSS-in-JS over Tailwind

Overview

@ccatto/ui provides a comprehensive set of accessible, themeable UI components that work seamlessly with Next.js 14+ and React 18+. Built with a "dark-first" design philosophy, every component looks great in both light and dark modes out of the box.

Why choose @ccatto/ui?

  • Production-Tested — Battle-tested in the RLeaguez sports platform serving real users
  • Accessibility First — ARIA labels, keyboard navigation, and screen reader support built-in
  • Performance Optimized — React.memo on high-frequency components, forwardRef support for form integration
  • i18n Ready — Ships with 7 languages (EN, ES, PT, ZH, FR, DE, HI) + easy custom translations
  • Mobile Native — Optional Capacitor haptics integration for iOS/Android apps
  • Consistent API — Predictable props patterns across all components (variant, size, className)
  • Zero Config Theming — CSS custom properties for runtime theme switching without rebuilds

Whether you're building a dashboard, e-commerce site, or mobile app, @ccatto/ui gives you the building blocks to ship faster without sacrificing quality.

Features

  • 71 UI Components - Buttons, Cards, Inputs, Modals, Tables, Forms, Calendars, and more
  • 4 Custom Hooks - Table state management, haptic feedback, drag-and-drop
  • 7 Languages - English, Spanish, Portuguese, Chinese, French, German, Hindi
  • Tailwind CSS v4 - Modern utility-first styling
  • Dark Mode Support - All components support light/dark themes
  • TypeScript - Full type definitions included
  • Next.js Compatible - Works with App Router and use client directive
  • Mobile Ready - Optional Capacitor haptics support for iOS/Android
  • 2 Themes - RLeaguez (orange/navy) and Neon Pulse themes included
  • 1,208 Unit Tests - Comprehensive test coverage with Vitest
  • Storybook - Visual component documentation with 50+ stories

Installation

# Using yarn (recommended for RLeaguez monorepo)
yarn add @ccatto/ui

# Using npm
npm install @ccatto/ui

Peer Dependencies

{
  "react": ">=18.0.0",
  "react-dom": ">=18.0.0",
  "next": ">=13.0.0"
}

Optional Peer Dependencies

{
  "@capacitor/core": ">=5.0.0", // For mobile haptics
  "@capacitor/haptics": ">=5.0.0", // For mobile haptics
  "@tanstack/react-table": ">=8.0.0", // For table utilities
  "libphonenumber-js": ">=1.10.0", // For phone input formatting
  "react-hook-form": ">=7.0.0", // For FormCatto
  "zod": ">=3.0.0", // For FormCatto validation
  "@hookform/resolvers": ">=3.0.0", // For FormCatto zod integration
  "next-themes": ">=0.2.0" // For ThemeToggleCatto
}

Quick Start

import { ButtonCatto, CardCatto, InputCatto } from '@ccatto/ui';

function MyComponent() {
  return (
    <CardCatto title="Welcome" width="lg">
      <InputCatto placeholder="Enter your name" />
      <ButtonCatto variant="primary" onClick={() => alert('Hello!')}>
        Say Hello
      </ButtonCatto>
    </CardCatto>
  );
}

Tailwind CSS Configuration

Add the package to your Tailwind CSS content sources:

/* In your global.css (Tailwind v4) */
@import 'tailwindcss';
@source "../../node_modules/@ccatto/ui/dist";

Or in tailwind.config.js (Tailwind v3):

module.exports = {
  content: [
    // ... your other paths
    './node_modules/@ccatto/ui/dist/**/*.{js,cjs}',
  ],
};

Theme Setup

Import the theme CSS files in your app:

// In your layout or global styles
import '@ccatto/ui/themes/tokens.css';
import '@ccatto/ui/themes/rleaguez.css';

// Or for the alternative theme:
// import '@ccatto/ui/themes/neon-pulse.css';

Components (70)

Core Components

| Component | Description | | ----------------------- | ----------------------------------------------------------------------- | | ButtonCatto | Versatile button with 13 variants, loading states, haptic feedback | | CardCatto | Content container with collapsible sections, multiple widths/elevations | | InputCatto | Text input with validation, icons, multiple variants | | SelectCatto | Dropdown select with search, custom rendering, keyboard navigation | | SearchableSelectCatto | Searchable dropdown with create-new option | | LinkCatto | Styled links with 8 variants, icons, button-style options | | CheckboxCatto | Checkbox input with 4 sizes, custom styling |

Form Components

| Component | Description | | ----------------- | -------------------------------------------------- | | FormCatto | Form wrapper with react-hook-form + Zod validation | | OtpInputCatto | Multi-digit OTP/verification code input | | DatePickerCatto | Date input with calendar popup | | CalendarCatto | Calendar for date selection with 5 themes |

Feedback Components

| Component | Description | | ------------------ | --------------------------------------------------------------- | | ToastCatto | Notifications with 6 variants, animations, placements | | MellowModalCatto | Modal dialog with themes, sizes, positions, auto-close | | TooltipCatto | Hover tooltips with 5 variants, 4 positions | | EmptyStateCatto | Empty/no-data states with icons, actions, variants | | BadgeCatto | Status badges with 8 variants, icons, dot mode, pulse animation |

Navigation Components

| Component | Description | | ------------------------ | --------------------------------------------------------- | | TabsCatto | Tabbed navigation with 4 variants, icons, disabled states | | DrawerCatto | Slide-out drawer/sidebar | | BottomNavCatto | Mobile bottom navigation with hide-on-scroll | | AnimatedHamburgerCatto | Animated hamburger menu icon | | NavLinkGroupCatto | Grouped navigation links with section headers | | HideOnScrollWrapper | Wrapper that hides content on scroll |

Data Display

| Component | Description | | -------------------- | ----------------------------------------------------------- | | AvatarCatto | User avatar with image, initials fallback, status indicator | | SkeletonBaseCatto | Base skeleton with shimmer animation | | CardSkeletonCatto | Card-shaped loading skeleton | | TableSkeletonCatto | Table loading skeleton | | CarouselCatto | Image carousel with auto-advance and manual navigation |

Table Components (14)

| Component | Description | | ----------------------------------------- | -------------------------------------------- | | TableCatto | Full-featured data table with TanStack Table | | TableCoreCatto | Core table rendering component | | TableControlsCatto | Table filter, search, and column visibility | | SortableHeaderCatto | Sortable column header | | Table, TableHeader, TableBody, etc. | Primitive table elements |

E-commerce Components

| Component | Description | | ----------------------- | -------------------------------------------------------- | | ProductCardCatto | Product display card with image, price, rating, wishlist | | PricingCardCatto | Pricing tier card for subscription displays | | CartItemCatto | Cart line item with quantity selector, remove action | | QuantitySelectorCatto | Quantity +/- buttons with min/max limits | | RatingStarsCatto | Star rating display/input with partial stars |

Phone Components

| Component | Description | | ------------------- | --------------------------------------------------- | | PhoneInputCatto | Phone number input with auto-formatting, validation | | PhoneDisplayCatto | Formatted phone number display |

Loading Components

| Component | Description | | ------------------------------- | ------------------------------------------------ | | PageLoadingCatto | Full-page loading spinner with RLeaguez branding | | InlineLoadingCatto | Inline loading spinner for containers | | LoadingCircleOrangeFancyCatto | Animated orange loading circle | | LoadingMessageAndCircleCatto | Loading with message |

Stepper Components

| Component | Description | | ---------------------- | ---------------------------------------------- | | ProgressStepperCatto | Visual progress indicator for multi-step flows | | DetailedStepperCatto | Stepper with titles and descriptions |

HR (Divider) Components (12)

| Component | Description | | --------------------- | ------------------------------------ | | HRDividerCatto | Basic dashed divider | | HRCircleCatto | Divider with circle decoration | | HRTriangleCatto | Divider with triangle decoration | | HRAnimatedLineCatto | Animated line divider | | HRSquareCatto | Divider with square decoration | | HRSquaresCatto | Divider with multiple squares | | HRPartyPulseCatto | Colorful pulsing divider | | HRPulseDividerCatto | Subtle pulsing divider | | HRSubtleCatto | Minimal subtle divider | | HRWideCatto | Wide decorative divider | | HRHypnoCatto | Hypnotic animated divider | | SectionTitleCatto | Section title with optional subtitle |

Utility Components

| Component | Description | | ----------------------------------- | --------------------------------------- | | ThemeSwitcherCatto | Theme selection component | | ThemeToggleCatto | Dark/light mode toggle (next-themes) | | ButtonTogglePillCatto | Pill-shaped toggle button | | LanguageSwitcherCatto | Language/locale switcher | | MobileScrollIndicatorWrapperCatto | Scroll indicator for mobile | | AddToCalendarCatto | Calendar export dropdown (ICS + Google) |


Component Examples

ButtonCatto

import { ButtonCatto } from '@ccatto/ui';
import { Mail } from 'lucide-react';

<ButtonCatto variant="primary" size="medium" onClick={handleClick}>
  Click Me
</ButtonCatto>

<ButtonCatto variant="danger" leftIcon={<Trash2 className="h-4 w-4" />}>
  Delete
</ButtonCatto>

<ButtonCatto variant="primary" isLoading>
  Saving...
</ButtonCatto>

Variants: primary, secondary, tertiary, danger, catto, ghost, outline, goGreen, pill, pillOutline, funOrange, outlineRoundedXL, blueGradientXL

CardCatto

import { CardCatto } from '@ccatto/ui';

<CardCatto
  title="Section Title"
  width="lg"
  collapsible
  defaultCollapsed={false}
>
  <p>Card content goes here</p>
</CardCatto>;

BadgeCatto

import { BadgeCatto } from '@ccatto/ui';

<BadgeCatto variant="success">Active</BadgeCatto>
<BadgeCatto variant="error" pulse>Live</BadgeCatto>
<BadgeCatto variant="primary" dot>New</BadgeCatto>

Variants: default, primary, secondary, success, warning, error, info, outline

ProductCardCatto

import { ProductCardCatto } from '@ccatto/ui';

<ProductCardCatto
  name="Premium Widget"
  price={29.99}
  originalPrice={39.99}
  image="/product.jpg"
  rating={4.5}
  reviewCount={128}
  onAddToCart={() => {}}
  onToggleWishlist={() => {}}
/>;

MellowModalCatto

import { MellowModalCatto } from '@ccatto/ui';

<MellowModalCatto
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
  title="Confirm Action"
  theme="danger"
  size="md"
>
  <p>Are you sure you want to proceed?</p>
</MellowModalCatto>;

Hooks (4)

useHaptics

Provides haptic feedback on mobile devices (requires Capacitor).

import { useHaptics } from '@ccatto/ui';

function MyComponent() {
  const { triggerHaptic, isAvailable } = useHaptics();

  const handlePress = () => {
    triggerHaptic('medium'); // 'light' | 'medium' | 'heavy'
  };

  return <button onClick={handlePress}>Tap me</button>;
}

useTableStateCatto

Manages TanStack Table state (sorting, filtering, visibility, selection).

import { useTableStateCatto } from '@ccatto/ui';

function MyTable() {
  const {
    sorting,
    setSorting,
    columnFilters,
    setColumnFilters,
    columnVisibility,
    setColumnVisibility,
    rowSelection,
    setRowSelection,
  } = useTableStateCatto();

  // Use with useReactTable...
}

useTableInstanceCatto

Creates a TanStack Table instance with common configuration.

import { useTableInstanceCatto } from '@ccatto/ui';

function MyTable({ data, columns }) {
  const table = useTableInstanceCatto(data, columns);
  // Render table...
}

useDragDropList

Drag and drop list functionality.

import { useDragDropList } from '@ccatto/ui';

function MyList({ items, onReorder }) {
  const { dragHandleProps, isDragging } = useDragDropList({
    items,
    onReorder,
  });
  // Render draggable list...
}

Utilities

cn

Class name merge utility (combines clsx + tailwind-merge).

import { cn } from '@ccatto/ui';

<div className={cn('base-class', isActive && 'active-class', className)} />;

Phone Utilities

import {
  formatPhoneNumber,
  isValidPhoneNumber,
  parsePhoneNumber,
} from '@ccatto/ui';

formatPhoneNumber('+15551234567'); // "(555) 123-4567"
isValidPhoneNumber('5551234567'); // true

Keyboard Utilities

import { handleKeyboardSelect, isEnterOrSpace } from '@ccatto/ui';

<div role="button" tabIndex={0} onKeyDown={handleKeyboardSelect(onClick)}>
  Accessible button
</div>;

Internationalization (i18n)

All components accept a labels prop for easy internationalization. We also ship pre-made translations for popular languages.

Available Locales

| Language | Import | Locale Code | | ---------------------- | ----------------------------------------- | ------------ | | English | defaultLabels | en (default) | | Spanish | spanishLabels or esLabels | es | | Portuguese (Brazilian) | portugueseLabels or ptLabels | pt-BR | | Chinese (Simplified) | chineseSimplifiedLabels or zhCNLabels | zh-CN | | French | frenchLabels or frLabels | fr | | German | germanLabels or deLabels | de | | Hindi | hindiLabels or hiLabels | hi |

Using Pre-made Translations

import { portugueseLabels, SelectCatto, spanishLabels } from '@ccatto/ui';

// Use with a specific component
<SelectCatto labels={spanishLabels.select} options={options} />;

// Or use the full labels object based on locale
const labels =
  locale === 'es'
    ? spanishLabels
    : locale === 'pt'
      ? portugueseLabels
      : defaultLabels;

<SelectCatto labels={labels.select} options={options} />;

Custom Translations

You can also provide your own translations:

import { defaultLabels, SelectCatto } from '@ccatto/ui';

const frenchLabels = {
  ...defaultLabels,
  select: {
    placeholder: 'Sélectionnez une option',
    noOptions: 'Aucune option trouvée',
    clearButton: 'Effacer la sélection',
  },
};

<SelectCatto labels={frenchLabels.select} options={options} />;

Types

import type {
  FontSizeType,
  FontWeightType,
  HapticFeedback,
  SelectOption,
  StyleAnimations,
  StyleWidth,
  ThemeType,
} from '@ccatto/ui';

Storybook

Run Storybook to explore all components visually:

yarn workspace @ccatto/ui storybook
# Opens at http://localhost:6006

Build static Storybook:

yarn workspace @ccatto/ui build-storybook

Development

Building the Package

cd packages/ui
yarn build

Watch Mode

yarn dev

Testing

yarn test        # Watch mode
yarn test:run    # Single run (1,208 tests)
yarn test:coverage

Type Checking

yarn typecheck

Package Info

  • Version: 1.0.0
  • Bundle Size: ~255KB (ESM)
  • License: MIT
  • Author: Chris Catto

Links