# chunks-ui — Full Documentation > React 19+ component library built on Base UI, Tailwind CSS v4, and Motion. --- # Getting Started ## Installation ```bash bun add chunks-ui motion ``` `motion` is an optional peer dependency. Components work without it, but animations require it. ## Setup Import the theme CSS in your app entry point (e.g. `app/layout.tsx`): ```tsx import "chunks-ui/theme.css"; ``` Then import components as needed: ```tsx import { Button, Input, Tabs } from "chunks-ui"; ``` The theme CSS exposes OKLCH color tokens as CSS variables. Your Tailwind CSS v4 config picks them up automatically -- no plugin needed. ## Architecture - **Headless layer:** `@base-ui/react` v1.2+ (includes Floating UI for positioning) - **Styling:** Tailwind CSS v4 + CVA + `clsx` + `tailwind-merge` - **Animation:** Motion v12+ (optional peer dependency) - **Build:** tsup (ESM + CJS + `.d.ts`) - **Compound pattern:** Components use ``, ``, `` patterns - **Composition:** Base UI `render` prop, not `asChild` --- # Theme Chunks UI uses a CSS variable-based design token system following the [shadcn/ui](https://ui.shadcn.com) naming convention. All colors are defined in the OKLCH color space for perceptual uniformity. ## Setup Import the theme CSS in your app entry point: ```tsx import "chunks-ui/theme.css"; ``` This single file provides all CSS variables for light mode, dark mode, and Tailwind v4 `@theme inline` tokens. ## Color System ### Semantic Colors (OKLCH) | Token | Light Value | Purpose | |---|---|---| | `--primary` | `oklch(60.48% 0.2165 257.21)` | Brand blue | | `--primary-foreground` | `oklch(0.985 0 0)` | Text on primary | | `--success` | `oklch(75.14% 0.1514 166.5)` | Positive actions | | `--success-foreground` | `oklch(0.985 0 0)` | Text on success | | `--warning` | `oklch(77.97% 0.1665 72.45)` | Caution states | | `--warning-foreground` | `oklch(0.145 0 0)` | Text on warning | | `--destructive` | `oklch(66.16% 0.2249 25.88)` | Errors, deletions | | `--destructive-foreground` | `oklch(0.985 0 0)` | Text on destructive | ### Surface Colors | Token | Light | Dark | |---|---|---| | `--background` | `oklch(1 0 0)` | `oklch(0.145 0 0)` | | `--foreground` | `oklch(0.145 0 0)` | `oklch(0.985 0 0)` | | `--card` | `oklch(1 0 0)` | `oklch(0.145 0 0)` | | `--card-foreground` | `oklch(0.145 0 0)` | `oklch(0.985 0 0)` | | `--popover` | `oklch(1 0 0)` | `oklch(0.145 0 0)` | | `--popover-foreground` | `oklch(0.145 0 0)` | `oklch(0.985 0 0)` | ### Neutral Palette | Token | Light | Dark | |---|---|---| | `--secondary` | `oklch(0.97 0 0)` | `oklch(0.269 0 0)` | | `--secondary-foreground` | `oklch(0.205 0 0)` | `oklch(0.985 0 0)` | | `--muted` | `oklch(0.97 0 0)` | `oklch(0.269 0 0)` | | `--muted-foreground` | `oklch(0.556 0 0)` | `oklch(0.708 0 0)` | | `--accent` | `oklch(0.97 0 0)` | `oklch(0.269 0 0)` | | `--accent-foreground` | `oklch(0.205 0 0)` | `oklch(0.985 0 0)` | ### Utility Tokens | Token | Light | Dark | |---|---|---| | `--border` | `oklch(0.922 0 0)` | `oklch(0.269 0 0)` | | `--input` | `oklch(0.922 0 0)` | `oklch(0.269 0 0)` | | `--ring` | `oklch(0.708 0 0)` | `oklch(0.556 0 0)` | | `--radius` | `0.625rem` | `0.625rem` | ## Tailwind Usage Variables are mapped to Tailwind utilities via `@theme inline`: ```css @theme inline { --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-success: var(--success); --color-destructive: var(--destructive); /* ... */ } ``` This means you can use them directly in Tailwind classes: ```tsx
``` ## Dark Mode Dark mode is toggled by adding the `.dark` class to the `` element (same convention as shadcn/ui). The same variable names are redefined with dark values: ```css .dark { --background: oklch(0.145 0 0); --foreground: oklch(0.985 0 0); --primary: oklch(60.48% 0.2165 257.21); /* ... */ } ``` Components automatically adapt -- no extra props needed. ## Typography | Token | Value | |---|---| | `--font-sans` | `"Manrope", sans-serif` | | `--font-mono` | `"Fira Code", monospace` | Use in Tailwind: `font-sans`, `font-mono`. ## Easing Curves | Token | Value | Use case | |---|---|---| | `--ease-fluid` | `cubic-bezier(0.3, 0, 0, 1)` | General transitions | | `--ease-snappy` | `cubic-bezier(0.2, 0, 0, 1)` | Quick, responsive motion | Use in Tailwind: `ease-fluid`, `ease-snappy`. ## Component Sizing | Token | Value | |---|---| | `--spacing-ui-height` | `35px` | | `--spacing-ui-icon-height` | `calc(var(--spacing-ui-height) * 0.5)` | ## Z-Index Layers The z-index system provides ordered layers to prevent stacking conflicts: | Token | Value | Use case | |---|---|---| | `--z-base` | `0` | Default content | | `--z-dropdowns` | `200` | Select popups, menus | | `--z-tooltips` | `400` | Tooltip overlays | | `--z-overlays` | `500` | General overlays | | `--z-drawers` | `600` | Side/bottom drawers | | `--z-modals` | `700` | Modal dialogs | | `--z-notifications` | `800` | Toast notifications | ## Border Radius | Token | Value | |---|---| | `--radius-sm` | `calc(var(--radius) - 4px)` | | `--radius-md` | `calc(var(--radius) - 2px)` | | `--radius-lg` | `var(--radius)` (0.625rem) | | `--radius-xl` | `calc(var(--radius) + 4px)` | ## Chart Colors Five chart colors are provided for data visualization, compatible with shadcn/ui charting: ```css --chart-1: oklch(0.646 0.222 41.116); --chart-2: oklch(0.6 0.118 184.704); --chart-3: oklch(0.398 0.07 227.392); --chart-4: oklch(0.828 0.189 84.429); --chart-5: oklch(0.769 0.188 70.08); ``` ## Customization To override tokens, redefine the CSS variables after importing the theme: ```css @import "chunks-ui/theme.css"; :root { --primary: oklch(70% 0.2 150); --radius: 0.5rem; } ``` All components will pick up the new values automatically. --- # Components --- # Accordion A vertically stacked set of collapsible sections built on Base UI's `Accordion` primitive. Each item has a trigger header that reveals its panel with an animated height transition. ## Import ```tsx import { Accordion } from "chunks-ui"; ``` ## Basic Usage ```tsx What is chunks-ui?
A personal React component library.
Is it accessible?
Yes — keyboard nav and ARIA handled by Base UI.
``` ## Multiple Open Items By default only one item can be open at a time. Set `multiple` to allow expanding several items simultaneously: ```tsx {/* items */} ``` ## Default Open Pass an array of item values to `defaultValue` to start with those items expanded: ```tsx {/* items */} ``` ## Controlled ```tsx function ControlledAccordion() { const [value, setValue] = useState([]); return ( Section
Content
); } ``` ## Disabled Item Set `disabled` on `Accordion.Item` to prevent it from being opened: ```tsx Unavailable
Unreachable content.
``` ## Animation The panel height animates using CSS transitions via Base UI's `--accordion-panel-height` CSS variable. No JavaScript animation library is required. To opt out, override the `transition` class on `Accordion.Panel`. Respects `prefers-reduced-motion` — the transition duration collapses to `0` when the user has reduced motion enabled. ## Compound Parts | Part | Description | |---|---| | `Accordion.Root` | State container. Manages which items are open. | | `Accordion.Item` | Wraps a single collapsible section. Requires a unique `value`. | | `Accordion.Header` | Semantic `

` wrapper around the trigger. | | `Accordion.Trigger` | Clickable button that toggles the panel. Includes the chevron icon. | | `Accordion.Panel` | The collapsible content area. Animates height on open/close. | ## Accordion.Root Props | Prop | Type | Default | Description | |---|---|---|---| | `value` | `string[]` | -- | Controlled open items | | `defaultValue` | `string[]` | `[]` | Initially open items (uncontrolled) | | `onValueChange` | `(value: string[]) => void` | -- | Called when open items change | | `multiple` | `boolean` | `false` | Allow multiple items open simultaneously | | `className` | `string` | -- | Additional CSS classes | ## Accordion.Item Props | Prop | Type | Default | Description | |---|---|---|---| | `value` | `string` | **required** | Unique identifier for this item | | `disabled` | `boolean` | `false` | Prevent this item from being opened | | `className` | `string` | -- | Additional CSS classes | ## Accordion.Trigger Props | Prop | Type | Default | Description | |---|---|---|---| | `children` | `ReactNode` | **required** | Trigger label content | | `className` | `string` | -- | Additional CSS classes | ## Accordion.Panel Props | Prop | Type | Default | Description | |---|---|---|---| | `children` | `ReactNode` | -- | Panel content | | `className` | `string` | -- | Additional CSS classes | --- # Avatar Displays a user avatar image with automatic fallback to initials. Supports numeric sizing and multiple shapes. ## Import ```tsx import { Avatar } from 'chunks-ui' ``` ## Basic Usage With an image: ```tsx ``` Without an image (shows initials derived from `alt`): ```tsx ``` This renders "JD" as fallback initials. ## Custom Fallback Override the auto-generated initials with the `fallback` prop: ```tsx ``` ## Sizes The `size` prop accepts a numeric value in pixels:
{[10, 20, 30, 40, 50, 60, 100].map(size => (

{size}px

))} ## Shapes ```tsx ``` ## Initials Generation When no `src` is provided and no `fallback` is set, initials are automatically generated from the `alt` text: - `"Jane Doe"` produces `"JD"` - `"Alice B. Charlie"` produces `"AB"` (first two initials) - Single word `"Admin"` produces `"A"` ## Props | Prop | Type | Default | Description | | ----------- | ----------------------------------- | ---------- | -------------------------------------------------------------- | | `src` | `string` | -- | Image URL. Shows image when provided, initials otherwise. | | `alt` | `string` | -- | Alt text for the image. Used to generate initials as fallback. | | `fallback` | `string` | -- | Explicit fallback text (overrides auto-generated initials). | | `size` | `number` | `40` | Avatar dimensions in pixels. | | `shape` | `"circle" \| "rounded" \| "square"` | `"circle"` | Avatar shape. | | `className` | `string` | -- | Additional CSS classes. | All other props are forwarded to the root `` element. --- # Button A styled button component built on Base UI's `Button` primitive. Supports multiple visual variants, semantic colors, loading state, and start/end icons. ## Import ```tsx import { Button } from 'chunks-ui' ``` ## Basic Usage ```tsx ``` ## Variants The `variant` prop controls the visual style: ```tsx ``` ## Colors The `color` prop sets the semantic color: ```tsx ``` Colors work with all variants: ```tsx ``` ## Loading State When `loading` is `true`, the button shows a `Loader` spinner in place of the `startIcon` and becomes disabled: ```tsx ``` The button remains focusable while loading (for accessibility) but click events are suppressed. ## Icons ```tsx ``` Icons are hidden during loading state. The `startIcon` slot is replaced by the `Loader`. ## Props | Prop | Type | Default | Description | | ----------- | --------------------------------------------------------------------- | ------------- | ------------------------------------ | | `variant` | `"contained" \| "outlined" \| "text"` | `"contained"` | Visual style | | `color` | `"primary" \| "destructive" \| "success" \| "warning" \| "secondary"` | `"primary"` | Semantic color | | `loading` | `boolean` | `false` | Show spinner and disable interaction | | `startIcon` | `ReactNode` | -- | Icon before children | | `endIcon` | `ReactNode` | -- | Icon after children | | `disabled` | `boolean` | `false` | Disable the button | | `className` | `string` | -- | Additional CSS classes | All other props are forwarded to the underlying Base UI `Button`. --- # Calendar A standalone date picker grid built without an external primitive. Supports controlled and uncontrolled selection, min/max bounds, and custom disabled-date predicates. ## Import ```tsx import { Calendar } from "chunks-ui"; ``` ## Basic Usage ```tsx ``` ## Controlled ```tsx function ControlledCalendar() { const [date, setDate] = useState(null); return ( ); } ``` ## Disabled Dates Use `min`/`max` to set a date range, or `isDateDisabled` to disable individual dates with a predicate: ```tsx const today = new Date(); const isWeekend = (date: Date) => date.getDay() === 0 || date.getDay() === 6; ``` ## Calendar Props | Prop | Type | Default | Description | |---|---|---|---| | `value` | `Date \| null` | -- | Controlled selected date | | `defaultValue` | `Date \| null` | `null` | Initial selected date (uncontrolled) | | `onValueChange` | `(date: Date \| null) => void` | -- | Called when the selected date changes | | `min` | `Date` | -- | Earliest selectable date (inclusive) | | `max` | `Date` | -- | Latest selectable date (inclusive) | | `isDateDisabled` | `(date: Date) => boolean` | -- | Predicate to disable individual dates | | `className` | `string` | -- | Additional CSS classes | --- # Card A compound layout component for displaying grouped content. Built with plain HTML elements (no Base UI dependency). Follows the compound pattern: `Card.Root`, `Card.Header`, `Card.Title`, `Card.Description`, `Card.Content`, `Card.Footer`. ## Import ```tsx import { Card } from "chunks-ui"; ``` ## Basic Usage ```tsx Project Alpha A brief description of the project.

Main content goes here.

``` ## Minimal Card You can use any subset of compound parts: ```tsx

Simple card with content only.

``` ## With Custom Content ```tsx Team Members Manage your team members and roles.

Alice Johnson

Admin

Bob Smith

Member

``` ## Compound Parts | Part | Description | |---|---| | `Card.Root` | Outer container. Rounded border, background, and shadow. | | `Card.Header` | Top section with vertical flex layout and padding (`p-6`). | | `Card.Title` | Heading rendered as `

`. Semibold, tight tracking. | | `Card.Description` | Subtext below the title. `text-muted-foreground`. | | `Card.Content` | Main body area. Padding `p-6 pt-0`. | | `Card.Footer` | Bottom section. Horizontal flex with `gap-2 p-6 pt-0`. | ## Props All compound parts accept standard HTML `div` props (or `h3`/`p` for Title/Description) plus `className` for additional styling. There are no component-specific variant props. --- # Checkbox A styled checkbox built on Base UI's `Checkbox` primitive. Supports checked, unchecked, and indeterminate states with a compound component pattern. ## Import ```tsx import { Checkbox } from "chunks-ui"; ``` ## Basic Usage ```tsx ``` ## With Label Use the `Field` component to associate a label: ```tsx
Accept terms and conditions
``` ## Controlled ```tsx function ControlledCheckbox() { const [checked, setChecked] = useState(false); return ( ); } ``` ## Indeterminate State The indeterminate state is used for "select all" patterns where some items are checked: ```tsx ``` ## Disabled ```tsx ``` ## Compound Parts | Part | Description | |---|---| | `Checkbox.Root` | The checkbox control. Handles checked state and keyboard interaction. | | `Checkbox.Indicator` | Renders the check/indeterminate icon inside the root. | ## Checkbox.Root Props | Prop | Type | Default | Description | |---|---|---|---| | `checked` | `boolean \| "indeterminate"` | -- | Controlled checked state | | `defaultChecked` | `boolean` | `false` | Initial checked state (uncontrolled) | | `onCheckedChange` | `(checked: boolean) => void` | -- | Called when checked state changes | | `disabled` | `boolean` | `false` | Disable the checkbox | | `className` | `string` | -- | Additional CSS classes | ## Checkbox.Indicator Props | Prop | Type | Default | Description | |---|---|---|---| | `className` | `string` | -- | Additional CSS classes | --- # Chip A small label/tag component with optional remove functionality. Uses the `ClearButton` component internally for the dismiss action. ## Import ```tsx import { Chip } from "chunks-ui"; ``` ## Basic Usage ```tsx Default ``` ## Colors ```tsx Primary Destructive Success Warning Secondary ``` Each color applies a light tinted background with matching text and border (e.g. `bg-primary/10 text-primary border-primary/30`). ## Removable Chip Pass an `onRemove` callback to show a close button: ```tsx function TagList() { const [tags, setTags] = useState(["React", "TypeScript", "Tailwind"]); return (
{tags.map((tag) => ( setTags((prev) => prev.filter((t) => t !== tag))} > {tag} ))}
); } ``` ## Props | Prop | Type | Default | Description | |---|---|---|---| | `color` | `"primary" \| "destructive" \| "success" \| "warning" \| "secondary"` | `"secondary"` | Semantic color variant | | `onRemove` | `() => void` | -- | Show remove button; called on click | | `className` | `string` | -- | Additional CSS classes | | `children` | `ReactNode` | -- | Chip label content | All other props are forwarded to the root `` element. --- # ClearButton A small circular icon button for clearing or dismissing values. Used internally by `Input` (via `onClear`) and `Chip` (via `onRemove`), but also exported for direct use. ## Import ```tsx import { ClearButton } from 'chunks-ui' ``` ## Basic Usage ```tsx console.log('Cleared')} /> ``` ## Custom Label Pass `aria-label` directly to override the default: ```tsx ``` Default label is `"Clear"`. ## Props | Prop | Type | Default | Description | | ----------- | ------------ | ------- | ---------------------- | | `className` | `string` | -- | Additional CSS classes | | `onClick` | `() => void` | -- | Click handler | | `disabled` | `boolean` | `false` | Disable the button | All HTML `

``` ## With Backdrop The `Dialog.Backdrop` renders a semi-transparent black overlay (`bg-black/50`) with a fade transition. It uses the `z-overlays` z-index layer: ```tsx Show Dialog with backdrop The backdrop dims the content behind the dialog. Close ``` ## Controlled ```tsx function ControlledDialog() { const [open, setOpen] = useState(false); return ( Open Controlled Dialog You can control the open state. Done ); } ``` ## Animation The popup enters with a scale-up + fade transition (`scale-95` to `scale-100`, `opacity-0` to `opacity-1`) over 200ms. The backdrop fades in/out independently. ## Compound Parts | Part | Description | |---|---| | `Dialog.Root` | State container. Manages open/close. | | `Dialog.Trigger` | Button that opens the dialog. | | `Dialog.Portal` | Renders children in a portal outside the DOM tree. | | `Dialog.Backdrop` | Semi-transparent overlay behind the dialog. `z-overlays` (500). | | `Dialog.Popup` | Centered content panel. `z-modals` (700). Max width `max-w-md`. | | `Dialog.Title` | Dialog heading. Rendered as a semibold `text-lg`. | | `Dialog.Description` | Supporting text below the title. Rendered in `text-muted-foreground`. | | `Dialog.Close` | Button that closes the dialog. | ## Dialog.Root Props | Prop | Type | Default | Description | |---|---|---|---| | `open` | `boolean` | -- | Controlled open state | | `defaultOpen` | `boolean` | `false` | Initial open state (uncontrolled) | | `onOpenChange` | `(open: boolean) => void` | -- | Called when open state changes | | `modal` | `boolean` | `true` | Whether the dialog is modal | --- # Drawer A side or bottom sheet overlay built on Base UI's `Dialog` primitive. Slides in from the left, right, or bottom edge with a snappy easing transition. ## Import ```tsx import { Drawer } from "chunks-ui"; ``` ## Basic Usage ```tsx Open Drawer Navigation Browse the app sections. Close ``` ## Side Variants The `side` prop on `Drawer.Popup` controls which edge the drawer slides from: ```tsx {/* Right side (default) */} ... {/* Left side */} ... {/* Bottom sheet */} ... ``` - `left` and `right` drawers have a fixed width of `w-80`. - `bottom` drawer spans the full width with automatic height and rounded top corners. ## Controlled ```tsx function ControlledDrawer() { const [open, setOpen] = useState(false); return ( Menu Menu Close ); } ``` ## Animation The drawer slides in from its designated edge using `translate-x` (left/right) or `translate-y` (bottom) with the `ease-snappy` easing curve over 200ms. The backdrop fades in independently. ## Compound Parts | Part | Description | |---|---| | `Drawer.Root` | State container. Manages open/close state. | | `Drawer.Trigger` | Button that opens the drawer. | | `Drawer.Portal` | Renders children in a portal. | | `Drawer.Backdrop` | Semi-transparent overlay. `z-drawers` (600). | | `Drawer.Popup` | The sliding panel. `z-drawers` (600). Accepts `side` prop. | | `Drawer.Title` | Drawer heading. | | `Drawer.Description` | Supporting description text. | | `Drawer.Close` | Button that closes the drawer. | ## Drawer.Root Props | Prop | Type | Default | Description | |---|---|---|---| | `open` | `boolean` | -- | Controlled open state | | `defaultOpen` | `boolean` | `false` | Initial open state (uncontrolled) | | `onOpenChange` | `(open: boolean) => void` | -- | Called when open state changes | ## Drawer.Popup Props | Prop | Type | Default | Description | |---|---|---|---| | `side` | `"left" \| "right" \| "bottom"` | `"right"` | Which edge the drawer slides from | | `className` | `string` | -- | Additional CSS classes | --- # Field A form field wrapper built on Base UI's `Field` primitive. Provides label, description, error message, and validation state management for form controls like `Input`, `Textarea`, `Checkbox`, etc. ## Import ```tsx import { Field } from "chunks-ui"; ``` ## Basic Usage ```tsx Email ``` ## With Description ```tsx Password Must be at least 8 characters. ``` ## Validation Error Set `invalid` on `Field.Root` to activate error styling. The `Field.Error` message appears and the input receives `data-[invalid]` for red border styling: ```tsx Email Please enter a valid email address. ``` ## With Textarea ```tsx Message Describe your issue in detail.