# @cherrystudio/ui Cherry Studio UI component library for React applications. ## โœจ Features - ๐ŸŽจ **Design System**: Full Cherry Studio design tokens with 17 color families, 11 shades, and semantic theme mappings - ๐ŸŒ“ **Dark Mode**: Built-in light and dark theme support - ๐Ÿš€ **Tailwind v4**: Built on top of the latest Tailwind CSS v4 - ๐Ÿ“ฆ **Flexible Imports**: Two style integration modes for different adoption paths - ๐Ÿ”ท **TypeScript**: Complete type definitions and editor support - ๐ŸŽฏ **Low Collision**: CSS variable isolation without taking over app runtime state by default --- ## ๐Ÿš€ Quick Start ### Install ```bash npm install @cherrystudio/ui # peer dependencies npm install motion react react-dom tailwindcss ``` > The recommended integration style in this repository is to use the package export entry points: > `@cherrystudio/ui` > `@cherrystudio/ui/components` > `@cherrystudio/ui/icons` > `@cherrystudio/ui/utils` > `@cherrystudio/ui/styles/*` > ### Two Integration Modes #### Mode 1: Full Theme Contract โœจ Use the full Cherry Studio design system so Tailwind theme tokens resolve to Cherry Studio values. ```css /* app.css */ @import '@cherrystudio/ui/styles/theme.css'; ``` **Characteristics:** - โœ… Use standard Tailwind utility names directly (`bg-primary`, `bg-red-500`, `p-md`, `rounded-lg`) - โœ… Colors resolve to Cherry Studio design values - โœ… Includes the extended spacing scale (`p-5xs` through `p-8xl`, 16 semantic sizes) - โœ… Includes the extended radius scale (`rounded-4xs` through `rounded-3xl`, plus `rounded-round`) - โš ๏ธ Overrides the default Tailwind theme contract for the imported app bundle **Example:** ```tsx {/* Extended utility classes */}
Tiny spacing (0.5rem)
Extra small spacing (1rem)
Small spacing (1.5rem)
Medium spacing (2.5rem)
Large spacing (3.5rem)
Extra large spacing (5rem)
Maximum spacing (15rem)
Tiny radius (0.03125rem)
Small radius (0.125rem)
Medium radius (0.5rem)
Large radius (0.875rem)
Full radius (999px)
``` #### Mode 2: Selective Token Consumption ๐ŸŽฏ Import only the design tokens and decide which theme mappings your app wants to expose. ```css /* app.css */ @import 'tailwindcss'; @import '@cherrystudio/ui/styles/tokens.css'; /* Re-export only the parts you need */ @theme { --color-primary: var(--cs-primary); /* Use the Cherry Studio primary color */ --color-red-500: oklch(...); /* Keep your own red scale */ --spacing-md: var(--cs-size-md); /* Reuse Cherry Studio spacing */ --radius-lg: 1rem; /* Keep your own radius */ } ``` **Characteristics:** - โœ… Does not override the full Tailwind theme - โœ… Gives access to all Cherry Studio design tokens through CSS variables (`var(--cs-primary)`, `var(--cs-red-500)`) - โœ… Lets you choose what to adopt and what to keep - โœ… Works well when you already have a design system and only want selected Cherry Studio tokens **Example:** ```tsx {/* Use Cherry Studio tokens directly via CSS variables */} {/* Keep your original Tailwind theme untouched */}
Use the default Tailwind red
{/* Available CSS variables */}
``` ### CSS Variable Rules To avoid mixing tokens, theme mappings, and runtime overrides, use the following rules: 1. `--cs-*` is the design token namespace, sourced from `tokens/*` 2. `--color-*`, `--radius-*`, and `--font-*` are public theme contracts and should be the default choice for components and external consumers 3. `--cs-theme-*` is a runtime override input and should only be used for controlled runtime overrides 4. `--primary` is a compatibility alias kept for shadcn / Tailwind ecosystem compatibility and should not be preferred in new code Default consumption rules: 1. Regular application packages should depend on `@cherrystudio/ui/styles/theme.css` by default 2. Regular application packages should prefer public contracts such as `--color-*` and should not bind directly to primitive tokens like `--cs-brand-500` 3. Only design-system-adjacent packages that explicitly need token-level access should depend on `@cherrystudio/ui/styles/tokens.css` 4. Runtime theme logic should only write to controlled entry variables such as `--cs-theme-*`, not directly to derived `--color-*` variables ## Usage ### Basic Components ```tsx import { Button, Input } from '@cherrystudio/ui' function App() { return (
console.log(value)} />
) } ``` ### Modular Imports ```tsx // Components only import { Button } from '@cherrystudio/ui/components' // Utilities only import { cn, formatFileSize } from '@cherrystudio/ui/utils' ``` ## Development ```bash # Install dependencies pnpm install # Development mode pnpm dev # Build pnpm build # Type check pnpm type-check # Run tests pnpm test ``` ## Package Surface The `packages/ui` workspace contains both runtime code and development-only assets. - Runtime surface: - `src/` - `dist/` build output - package export entry points declared in `package.json` - Development assets: - `stories/` and `.storybook/` - `scripts/` used for icon and theme generation - `icons/` source assets used by the generation pipeline - `docs/` for migration and reference material Only the runtime surface should be treated as consumable package API. ## Directory Structure ```text docs/ # Migration plans and reference docs src/ โ”œโ”€โ”€ components/ โ”‚ โ”œโ”€โ”€ primitives/ # Primitive components โ”‚ โ”œโ”€โ”€ composites/ # Composite components โ”‚ โ”œโ”€โ”€ icons/ # Icon runtime exports and catalogs โ”‚ โ””โ”€โ”€ index.ts โ”œโ”€โ”€ hooks/ # React Hooks โ”œโ”€โ”€ lib/ # Internal utilities โ”œโ”€โ”€ styles/ # Tokens and theme entry files โ”œโ”€โ”€ utils/ # Utility functions โ””โ”€โ”€ index.ts # Main runtime entry point scripts/ # Theme and icon generation tooling stories/ # Storybook stories and sandbox usage icons/ # Raw icon assets for code generation ``` ## Naming Conventions All file and directory names under `packages/ui/` follow **kebab-case** (per shadcn CLI convention and project-wide rule ยง4.5 in [`../../docs/references/naming-conventions.md`](../../docs/references/naming-conventions.md)). This covers `primitives/`, `composites/`, `icons/`, `hooks/`, and `stories/` alike. Exported identifiers inside files remain `PascalCase` for components and `camelCase` for utilities and hooks. Examples: - `button.tsx` exports `Button` - `data-table.tsx` exports `DataTable` - `error-boundary/index.tsx` exports `ErrorBoundary` - `use-dnd-reorder.ts` exports `useDndReorder` ## Components ### Button A button component with multiple variants and sizes. **Props:** - `variant`: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' - `size`: 'sm' | 'md' | 'lg' - `loading`: boolean - `fullWidth`: boolean - `leftIcon` / `rightIcon`: React.ReactNode ### Input An input component with error handling and password visibility support. **Props:** - `type`: 'text' | 'password' | 'email' | 'number' - `error`: boolean - `errorMessage`: string - `onChange`: (value: string) => void ## Hooks ### useDebounce Debounces state updates or callback execution. ### useLocalStorage React hook wrapper for local storage. ### useClickOutside Detects clicks outside an element. ### useCopyToClipboard Copies text to the clipboard. ## Utilities ### cn(...inputs) Class name merge helper built on top of `clsx`. ### formatFileSize(bytes) Formats byte sizes into readable strings. ### debounce(func, delay) Debounce helper. ### throttle(func, delay) Throttle helper. ## License MIT