# @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