# Cowork UI Kit — Cross-Reference Mapping

> Mapping 40 Cowork component → shadcn/ui + Radix UI + HeroUI equivalent. Dùng khi:
> - AI khác (Cursor/Grok/v0) cần gen code mà chỉ biết shadcn → tìm Cowork equivalent
> - Migrate project từ shadcn sang Cowork hoặc ngược lại
> - Đối chiếu API khác biệt
>
> **Cowork version:** v0.4 (40 components, 0 hex, HSL math + 7 brand presets)
> **shadcn/ui:** latest (Radix + Tailwind, copy-paste)
> **Radix UI:** primitives 1.x (headless)
> **HeroUI:** v3 BETA (React Aria, compound, Tailwind v4)
>
> Convention chung: Cowork dùng **enum prop** (`variant="primary"`), shadcn dùng **cva class variants**, Radix dùng **headless primitives** (BYO styles), HeroUI v3 dùng **compound** (`Card.Header`).

---

## Atoms

| Cowork | shadcn/ui | Radix UI | HeroUI v3 | API diff notes |
|---|---|---|---|---|
| `<Avatar>` | `<Avatar>` (composed `AvatarImage` + `AvatarFallback`) | `@radix-ui/react-avatar` | `<Avatar>` | Cowork single-prop (`src`+`name`+`size`+`status` dot). shadcn/Radix require composition. Cowork built-in `name`→initials auto + status indicator. |
| `<Badge>` | `<Badge>` | — | `<Badge>` / `<Chip>` | Cowork `variant` enum (neutral/info/success/warning/danger/brand) + `tone` soft/solid. shadcn cva variants. HeroUI tách Badge (notification dot) vs Chip (label pill) — Cowork gộp 1. |
| `<Button>` | `<Button>` | — | `<Button>` | Cowork enum `variant` (primary/secondary/ghost/outline/danger) + `size` sm/md/lg + `loading` + `leftIcon`/`rightIcon`. shadcn cva. HeroUI tương tự + `color`/`radius` props. |
| `<Checkbox>` | `<Checkbox>` | `@radix-ui/react-checkbox` | `<Checkbox>` | Cowork = native `<input type=checkbox>` styled (uncontrolled friendly). Radix/shadcn dùng custom div + ARIA (indeterminate built-in). HeroUI Aria. |
| `<Combobox>` | `<Combobox>` (Popover+Command) | — (compose Popover+Command primitives) | `<ComboBox>` / `<Autocomplete>` | Cowork single component flat `options[{value,label}]` + filter built-in. shadcn require manual composition Popover+cmdk. HeroUI Aria built-in keyboard. |
| `<Divider>` | `<Separator>` | `@radix-ui/react-separator` | `<Separator>` | Cowork `orientation` h/v + `dashed`. Radix decorative role. Name khác (Divider vs Separator) — direct alias. |
| `<Helper>` | (none — use `<FormDescription>` / `<FormMessage>`) | — | `<Description>` / `<ErrorMessage>` | Cowork `variant` default/error/success — 1 component cho cả helper text + error. shadcn tách 2 component. |
| `<Icon>` | (none — use lucide-react direct) | — | (none — bring your own) | Cowork wrapper SVG với `size` enum + `label` (a11y). Reset stroke defaults. shadcn assume lucide direct. Tiện cho design system consistency. |
| `<Input>` | `<Input>` | — (form primitives only) | `<Input>` / `<TextField>` | Cowork classic `<input>` styled. shadcn similar. HeroUI v3 tách `Input` (low-level) vs `TextField` (label+helper+error compound). |
| `<Kbd>` | (none) | — | `<Kbd>` | Cowork `size` sm/md, mono font, `bg-surface` + border. HeroUI tương tự. shadcn không có chính chủ — phải tự css. |
| `<Label>` | `<Label>` | `@radix-ui/react-label` | `<Label>` | Direct alias, all forward `htmlFor` ref. |
| `<Popover>` | `<Popover>` (compound Trigger+Content) | `@radix-ui/react-popover` | `<Popover>` | Cowork đơn giản hơn — render-prop / controlled `open`. shadcn/Radix compound `Trigger`/`Content` + Portal. Cowork không Portal (inline). |
| `<Progress>` | `<Progress>` | `@radix-ui/react-progress` | `<ProgressBar>` / `<ProgressCircle>` | Cowork bar only, `value` 0-100 + `variant` color. HeroUI tách bar vs circle. |
| `<Radio>` | `<RadioGroup>` (compound `RadioGroupItem`) | `@radix-ui/react-radio-group` | `<RadioGroup>` (`.Item`) | Cowork single `<Radio>` + parent dùng name attr. shadcn/Radix/HeroUI force group wrapper với context. |
| `<Select>` | `<Select>` (compound Trigger+Content+Item) | `@radix-ui/react-select` | `<Select>` | Cowork = native `<select>` styled (simplest, no portal, mobile native UX). shadcn/Radix custom div + ARIA (full control over option rendering). |
| `<Skeleton>` | `<Skeleton>` | — | `<Skeleton>` | Direct alias, all just animated `bg` placeholder. Cowork dùng `bg-surface-2 animate-pulse`. |
| `<Spinner>` | (none — use lucide Loader2) | — | `<Spinner>` | Cowork dedicated component `size` enum. shadcn convention dùng icon + `animate-spin`. |
| `<Switch>` | `<Switch>` | `@radix-ui/react-switch` | `<Switch>` | Direct alias. Cowork controlled `checked`+`onCheckedChange`. |
| `<Textarea>` | `<Textarea>` | — | `<TextArea>` | Direct alias, native `<textarea>` styled. |
| `<Tooltip>` | `<Tooltip>` (compound Trigger+Content + `<TooltipProvider>`) | `@radix-ui/react-tooltip` | `<Tooltip>` | Cowork single component, `content` prop + wraps `children`. shadcn/Radix yêu cầu `<TooltipProvider>` root + compound (delay shared). Cowork simpler nhưng không share delay. |

---

## Molecules

| Cowork | shadcn/ui | Radix UI | HeroUI v3 | API diff notes |
|---|---|---|---|---|
| `<Accordion>` | `<Accordion>` (compound Item+Trigger+Content) | `@radix-ui/react-accordion` | `<Accordion>` / `<Disclosure>` | Cowork flat `items[{question, answer}]` array prop. shadcn/Radix require compound JSX cho mỗi item. HeroUI tách Disclosure (1 item) vs Accordion (group). |
| `<Banner>` | `<Alert>` (compound Title+Description) | — | `<Alert>` | Cowork enum `variant` info/success/warning/danger + `title`/`description`/`icon`/`cta`/`onClose` flat props. shadcn compound `AlertTitle`+`AlertDescription`. Name khác (Banner vs Alert). |
| `<Breadcrumb>` | `<Breadcrumb>` (compound List+Item+Separator) | — | `<Breadcrumbs>` (`.Item`) | Cowork flat `items[{label, href}]`. shadcn compound JSX. Plural khác (Breadcrumb vs Breadcrumbs). |
| `<Card>` | `<Card>` (compound Header+Title+Description+Content+Footer) | — | `<Card>` (`.Header`, `.Body`, `.Footer`) | Cowork compound (`Card.Header`, `Card.Body`, `Card.Footer`) + `variant` enum basic/elevated/outlined/ghost. shadcn fixed structure. HeroUI dùng `.Body` thay vì `.Content`. |
| `<Dropdown>` | `<DropdownMenu>` (compound) | `@radix-ui/react-dropdown-menu` | `<Dropdown>` (compound `.Trigger`, `.Content`, `.Item`) | Cowork compound (`Dropdown.Trigger`, `.Content`, `.Item`) controlled `open`/`onOpenChange`. shadcn/Radix tương tự nhưng full keyboard nav + Portal. Cowork không Portal. |
| `<FormGroup>` | `<FormField>` + `<FormItem>` + `<FormLabel>` + `<FormControl>` + `<FormDescription>` + `<FormMessage>` (react-hook-form integration) | — | `<Fieldset>` + `<Label>` + `<Description>` + `<ErrorMessage>` | Cowork all-in-one `label`+`helper`+`error`+`required`+`htmlFor` (1 wrapper, không tie tới form lib). shadcn tightly couple `react-hook-form`. HeroUI tách primitives. |
| `<Pagination>` | `<Pagination>` (compound Content+Item+Previous+Next+Ellipsis) | — | `<Pagination>` | Cowork flat `total`/`page`/`onPageChange` props. shadcn compound JSX. HeroUI flat props. |
| `<SearchBar>` | (none — compose `<Input>` + lucide Search icon) | — | `<SearchField>` | Cowork dedicated component với `onClear` X button. HeroUI có `SearchField` (Aria escape-to-clear). shadcn convention compose manual. |
| `<Tabs>` | `<Tabs>` (compound List+Trigger+Content) | `@radix-ui/react-tabs` | `<Tabs>` (`.List`, `.Tab`, `.Panel`) | Cowork compound + value/onChange. shadcn/Radix tương tự, `data-state` for styling. HeroUI v3 dùng `.Tab` thay `.Trigger`. |
| `<Toast>` | `<Toast>` (Sonner now recommended) | `@radix-ui/react-toast` | `<Toast>` | Cowork render 1 toast direct (consumer manage stack). shadcn deprecated `<Toast>` for Sonner (imperative `toast.success()`). HeroUI declarative + provider. |

---

## Organisms

| Cowork | shadcn/ui | Radix UI | HeroUI v3 | API diff notes |
|---|---|---|---|---|
| `<CmdPalette>` | `<Command>` + `<CommandDialog>` (cmdk lib) | — | (none chính chủ — compose Modal + ComboBox) | Cowork flat `commands[{label, group, kbd, onSelect}]` + `open`/`onClose`. shadcn `cmdk` lib + manual modal wrap. Cowork built-in keyboard nav + grouping + kbd hint. |
| `<DataTable>` | `<Table>` primitive + tanstack-table example | — | `<Table>` (compound `.Header`, `.Body`, `.Row`, `.Cell`) | Cowork high-level `columns[]`+`data[]`+sortable+pageSize+selection — works out-of-box. shadcn `<Table>` chỉ là markup, anh phải tự bring `@tanstack/react-table`. HeroUI compound primitive low-level. |
| `<Drawer>` | `<Sheet>` (drawer pattern) / `<Drawer>` (vaul lib) | `@radix-ui/react-dialog` (side) | `<Drawer>` | Cowork `side` left/right/top/bottom + flat `open`/`onClose`. shadcn `Sheet` (side panel) khác `Drawer` (mobile pull-up vaul). HeroUI dùng tên `Drawer` đúng. |
| `<FAQ>` | (none — compose Accordion + section) | — | (none) | Cowork section-level (`title`+`subtitle`+`items[]`+layout). shadcn dừng ở Accordion atomic. Cowork-specific landing page block. |
| `<Hero>` | (none — bring your own layout) | — | (none) | Cowork landing-page section `eyebrow`+`title`+`subtitle`+`primaryCta`+`secondaryCta`+`visual`+`align`. Cowork-specific marketing block, không có ở shadcn. |
| `<KPICard>` | (none) | — | (none) | Cowork dashboard block `label`+`value`+`delta{value, direction, positive}`+`sparkline`+`icon`. Cowork-specific dashboard organism. |
| `<Modal>` | `<Dialog>` (compound Trigger+Content+Header+Title+Description+Footer) | `@radix-ui/react-dialog` | `<Modal>` / `<AlertDialog>` | Cowork flat `open`/`onClose`/`title`/`description`/`footer` props. shadcn/Radix compound + Portal + ESC/overlay built-in. HeroUI tách Modal (regular) vs AlertDialog (destructive). |
| `<Navbar>` | (none — compose primitives) | — | (none) | Cowork landing/app nav `brand`+`links[]`+`actions` + mobile hamburger built-in. shadcn không cung cấp — compose Button + Sheet + custom. Cowork-specific. |
| `<Pricing>` | (none) | — | (none) | Cowork pricing section `tiers[{name, price, features[], cta, featured, badge}]`. Cowork-specific landing block. |
| `<Sidebar>` | `<Sidebar>` (v0+ blocks) (compound Header+Content+Footer+Group+Item) | — | (none chính chủ — compose) | Cowork flat `items[]` (nested supported) + `collapsible`+`brand` + state internal. shadcn `<Sidebar>` mới ra với `<SidebarProvider>` context + nhiều compound — phong phú hơn nhưng nặng setup. |

---

## Component gap analysis

### Có trong shadcn nhưng KHÔNG có Cowork (gap)
- `<Alert>` — Cowork dùng `<Banner>` (semantically tương tự, rename)
- `<AlertDialog>` — Cowork chưa tách destructive khỏi `<Modal>`
- `<AspectRatio>` — Cowork chưa có
- `<Calendar>` / `<DatePicker>` — Cowork chưa có (HeroUI có 5 variants: Calendar, DateField, DatePicker, DateRangePicker, TimeField)
- `<Carousel>` — Cowork chưa có
- `<Collapsible>` — Cowork dùng `<Accordion>` cho 1 item
- `<ContextMenu>` — Cowork chỉ có `<Dropdown>` (click trigger)
- `<Form>` — Cowork không tie react-hook-form, dùng `<FormGroup>` thuần wrapper
- `<HoverCard>` — Cowork dùng `<Popover>` (click trigger only, không hover)
- `<MenuBar>` — Cowork chưa có (desktop app nav)
- `<NavigationMenu>` — Cowork dùng `<Navbar>` (đơn giản hơn)
- `<ScrollArea>` — Cowork chưa có (HeroUI có `ScrollShadow`)
- `<Sheet>` — Cowork dùng `<Drawer>` (đồng nghĩa)
- `<Slider>` — Cowork chưa có (HeroUI có)
- `<Sonner>` (toast) — Cowork dùng `<Toast>` declarative, không imperative `toast()`
- `<Toggle>` / `<ToggleGroup>` — Cowork chưa có (HeroUI có `ToggleButton`, `ToggleButtonGroup`)
- `<InputOTP>` — Cowork chưa có (HeroUI có)
- `<NumberField>` / `<Slider>` / `<Meter>` — Cowork chưa có

### Có Cowork nhưng KHÔNG có shadcn standard (counter-gap, Cowork-specific)
- `<KPICard>` — dashboard metric block (Cowork landing/dashboard)
- `<Hero>` — landing page hero section
- `<Pricing>` — pricing section organism
- `<FAQ>` — FAQ landing section (shadcn dừng ở Accordion atomic)
- `<Navbar>` — full nav organism với mobile menu built-in
- `<CmdPalette>` — shadcn có `<Command>` primitive nhưng KHÔNG có palette wrapper hoàn chỉnh
- `<DataTable>` — shadcn chỉ có `<Table>` markup, không có high-level columns+data+sort+page bundled
- `<Banner>` — không trùng `<Alert>`: có `cta` slot + `onClose` X built-in
- `<Helper>` — 1 component 3 variant (default/error/success), shadcn tách `FormDescription`+`FormMessage`
- `<Icon>` — wrapper SVG có a11y + size enum (shadcn assume lucide direct)

---

## API patterns khác biệt

| Pattern | Cowork | shadcn | Radix | HeroUI v3 |
|---|---|---|---|---|
| Variant API | Enum prop `variant="primary"` | cva class variants | — (BYO) | Enum prop `variant`/`color` |
| Composition | Flat props (preferred), compound khi cần (Card/Dropdown/Tabs) | Compound aggressive (Card.Header/.Title/.Description/.Content/.Footer) | Compound primitives (full headless) | Compound (Card.Header/.Body/.Footer) — 3 level thay 5 |
| Theme switch | `aesthetic-warm`/`aesthetic-dark` class on `<body>` + HSL CSS var | `dark:` Tailwind prefix + `next-themes` toggle | BYO | `@source` Tailwind v4 + provider-less v3 |
| Multi-brand | 7 brand presets via `--brand-h/s/l` CSS var (HSL math) — swap brand bằng 1 class | Không built-in (1 theme/project) | — | Theme tokens nhưng không multi-brand |
| Portal | KHÔNG (inline render) | CÓ (Radix Portal default) | CÓ | CÓ (React Aria portal) |
| Form library | Không tie (FormGroup thuần) | Tightly couple `react-hook-form` | — | Aria `Form` primitive |
| State pattern | Controlled (consumer manage `open`/`value`) | Controlled + uncontrolled (`defaultOpen`) | Controlled + uncontrolled | Controlled + uncontrolled (Aria) |
| Toast API | Declarative JSX (`<Toast variant="success" title="..."/>`) | Imperative Sonner (`toast.success('...')`) | Declarative | Declarative + provider |
| Icons | `<Icon>` wrapper SVG, size enum | lucide-react direct | — | Built-in icons + slot |

---

## Brand swap parity

- **shadcn**: KHÔNG có multi-brand built-in. 1 project = 1 theme. Override `--primary` CSS var thủ công.
- **Radix**: Headless, brand là responsibility của consumer.
- **HeroUI v3**: Theme tokens nhưng KHÔNG có brand swap pattern — phải tự `data-theme` + override tokens.
- **Cowork**: 7 brand preset (`khi`/`annhien`/`betterbuy`/`xanh`/`hgg-jungle`/`hgg-lucky`/`hgg-mrhao`) qua HSL math. Swap 1 brand = đổi 1 class trên `<body>` hoặc include file `brands/<brand>.brand.css`. Derived tokens (`--primary`, `--primary-hover`, `--primary-soft`) auto-compute từ `--brand-h/s/l`.

**Migrate shadcn → Cowork:**
1. Replace `--primary` raw hex → Cowork HSL pipeline (`--brand-h`, `--brand-s`, `--brand-l`)
2. Replace cva variants → enum `variant` prop
3. Replace compound (`<Card.Title>`) → flat props khi available, giữ compound khi Cowork cũng compound
4. Replace `react-hook-form` Form coupling → bare `<FormGroup>` (anh tự handle state)
5. Remove `<TooltipProvider>` wrapper (Cowork không cần)

**Migrate Cowork → shadcn:**
1. Replace enum `variant` → cva pattern
2. Replace flat `items[]` props (Accordion/Tabs/Breadcrumb/Pagination) → compound JSX
3. Wrap app với `<TooltipProvider>`, integrate `react-hook-form` cho forms
4. Replace `<Banner>` → `<Alert>` + manual close button
5. Hand-roll `<KPICard>`, `<Hero>`, `<Pricing>`, `<FAQ>` (shadcn không có)

---

## When to use which

| Use case | Recommendation | Lý do |
|---|---|---|
| Production app cần multi-brand | **Cowork** | Chỉ Cowork có brand swap qua HSL CSS var (7 brand preset built-in) |
| Need most components out-of-box | **shadcn** | 50+ components copy-paste, ecosystem lớn nhất, Sonner/cmdk/vaul integrated |
| Headless full control over styling | **Radix** | Pure primitives, BYO styles, không opinionated |
| React Aria a11y first | **HeroUI v3** | React Aria base, keyboard/screen-reader complete |
| Vietnamese-first project (KHI/An Nhien/BetterBuy) | **Cowork** | Vietnamese microcopy patterns + brand context built-in |
| Landing page nhanh (Hero/Pricing/FAQ/Navbar) | **Cowork** | Có sẵn 4 organism landing, shadcn không có |
| Dashboard với KPI + DataTable | **Cowork** | KPICard + DataTable bundled, shadcn phải lắp tanstack-table |
| App có dark/light toggle, 1 brand | **shadcn** | `next-themes` + `dark:` prefix là chuẩn, Cowork overkill |
| Need DatePicker/Calendar/Slider | **HeroUI v3** hoặc shadcn | Cowork chưa có (gap) |
| AI gen code mass (v0/Cursor/Grok) | **shadcn** | AI training data nhiều nhất, sau migrate sang Cowork qua bảng này |

---

## Footer

- **Source Cowork:** 📁 [react/src/](file:///C:/Users/DANG/AI-Cowork/00-templates/ui-kit/react/src/) — 40 TSX components
- **Tokens:** 📁 [tokens/](file:///C:/Users/DANG/AI-Cowork/00-templates/ui-kit/tokens/) — `foundation.css` + `semantic.css` + 7 brand presets
- **Live gallery:** 🌐 https://ui.dang.pm/
- **shadcn doc:** 🌐 https://ui.shadcn.com/docs/components
- **Radix doc:** 🌐 https://www.radix-ui.com/primitives/docs/components
- **HeroUI v3 doc:** 🌐 https://v3.heroui.com/docs/components (71 components v3 BETA)

**Last updated:** 2026-05-20
