@reinvented/design 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/DESIGN_GUIDE.md +148 -0
  2. package/README.md +39 -162
  3. package/docs/components/alert-dialog.md +32 -0
  4. package/docs/components/avatar.md +14 -0
  5. package/docs/components/badge.md +24 -0
  6. package/docs/components/button.md +69 -0
  7. package/docs/components/card.md +49 -0
  8. package/docs/components/dialog.md +46 -0
  9. package/docs/components/dropdown-menu.md +32 -0
  10. package/docs/components/index.md +69 -0
  11. package/docs/components/input.md +34 -0
  12. package/docs/components/remaining-components.md +253 -0
  13. package/docs/components/scroll-area.md +17 -0
  14. package/docs/components/select.md +31 -0
  15. package/docs/components/separator.md +14 -0
  16. package/docs/components/sheet.md +32 -0
  17. package/docs/components/skeleton.md +20 -0
  18. package/docs/components/table.md +33 -0
  19. package/docs/components/tabs.md +23 -0
  20. package/docs/conventions.md +74 -0
  21. package/docs/layouts/dashboard.md +70 -0
  22. package/docs/layouts/detail-page.md +83 -0
  23. package/docs/layouts/index.md +45 -0
  24. package/docs/layouts/list-page.md +107 -0
  25. package/docs/layouts/settings-page.md +79 -0
  26. package/docs/layouts/step-wizard.md +73 -0
  27. package/docs/patterns/index.md +39 -0
  28. package/docs/rules.md +43 -0
  29. package/docs/visual-polish.md +141 -0
  30. package/package.json +40 -61
  31. package/src/components/ui/accordion/Accordion.vue +13 -0
  32. package/src/components/ui/accordion/AccordionContent.vue +20 -0
  33. package/src/components/ui/accordion/AccordionItem.vue +15 -0
  34. package/src/components/ui/accordion/AccordionTrigger.vue +25 -0
  35. package/src/components/ui/accordion/index.ts +4 -0
  36. package/src/components/ui/alert/Alert.vue +38 -0
  37. package/src/components/ui/alert/AlertDescription.vue +12 -0
  38. package/src/components/ui/alert/AlertTitle.vue +12 -0
  39. package/src/components/ui/alert/index.ts +3 -0
  40. package/src/components/ui/alert-dialog/AlertDialog.vue +13 -0
  41. package/src/components/ui/alert-dialog/AlertDialogAction.vue +21 -0
  42. package/src/components/ui/alert-dialog/AlertDialogCancel.vue +21 -0
  43. package/src/components/ui/alert-dialog/AlertDialogContent.vue +39 -0
  44. package/src/components/ui/alert-dialog/AlertDialogDescription.vue +15 -0
  45. package/src/components/ui/alert-dialog/AlertDialogFooter.vue +12 -0
  46. package/src/components/ui/alert-dialog/AlertDialogHeader.vue +12 -0
  47. package/src/components/ui/alert-dialog/AlertDialogTitle.vue +15 -0
  48. package/src/components/ui/alert-dialog/AlertDialogTrigger.vue +11 -0
  49. package/src/components/ui/alert-dialog/index.ts +9 -0
  50. package/src/components/ui/avatar/Avatar.vue +14 -0
  51. package/src/components/ui/avatar/index.ts +1 -0
  52. package/src/components/ui/badge/Badge.vue +27 -0
  53. package/src/components/ui/badge/index.ts +1 -0
  54. package/src/components/ui/breadcrumb/Breadcrumb.vue +6 -0
  55. package/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +12 -0
  56. package/src/components/ui/breadcrumb/BreadcrumbItem.vue +6 -0
  57. package/src/components/ui/breadcrumb/BreadcrumbLink.vue +20 -0
  58. package/src/components/ui/breadcrumb/BreadcrumbList.vue +6 -0
  59. package/src/components/ui/breadcrumb/BreadcrumbPage.vue +6 -0
  60. package/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +11 -0
  61. package/src/components/ui/breadcrumb/index.ts +7 -0
  62. package/src/components/ui/button/Button.vue +65 -0
  63. package/src/components/ui/button/index.ts +1 -0
  64. package/src/components/ui/card/Card.vue +13 -0
  65. package/src/components/ui/card/CardContent.vue +7 -0
  66. package/src/components/ui/card/CardDescription.vue +7 -0
  67. package/src/components/ui/card/CardFooter.vue +7 -0
  68. package/src/components/ui/card/CardHeader.vue +9 -0
  69. package/src/components/ui/card/CardTitle.vue +7 -0
  70. package/src/components/ui/card/index.ts +6 -0
  71. package/src/components/ui/checkbox/Checkbox.vue +25 -0
  72. package/src/components/ui/checkbox/index.ts +1 -0
  73. package/src/components/ui/collapsible/Collapsible.vue +13 -0
  74. package/src/components/ui/collapsible/index.ts +2 -0
  75. package/src/components/ui/command/Command.vue +16 -0
  76. package/src/components/ui/command/CommandEmpty.vue +5 -0
  77. package/src/components/ui/command/CommandGroup.vue +22 -0
  78. package/src/components/ui/command/CommandInput.vue +21 -0
  79. package/src/components/ui/command/CommandItem.vue +22 -0
  80. package/src/components/ui/command/CommandList.vue +17 -0
  81. package/src/components/ui/command/CommandSeparator.vue +5 -0
  82. package/src/components/ui/command/index.ts +7 -0
  83. package/src/components/ui/context-menu/ContextMenuContent.vue +24 -0
  84. package/src/components/ui/context-menu/ContextMenuItem.vue +16 -0
  85. package/src/components/ui/context-menu/ContextMenuLabel.vue +9 -0
  86. package/src/components/ui/context-menu/ContextMenuSeparator.vue +9 -0
  87. package/src/components/ui/context-menu/ContextMenuSubContent.vue +14 -0
  88. package/src/components/ui/context-menu/index.ts +9 -0
  89. package/src/components/ui/dialog/Dialog.vue +14 -0
  90. package/src/components/ui/dialog/DialogClose.vue +12 -0
  91. package/src/components/ui/dialog/DialogContent.vue +48 -0
  92. package/src/components/ui/dialog/DialogDescription.vue +23 -0
  93. package/src/components/ui/dialog/DialogFooter.vue +12 -0
  94. package/src/components/ui/dialog/DialogHeader.vue +12 -0
  95. package/src/components/ui/dialog/DialogScrollContent.vue +47 -0
  96. package/src/components/ui/dialog/DialogTitle.vue +23 -0
  97. package/src/components/ui/dialog/DialogTrigger.vue +12 -0
  98. package/src/components/ui/dialog/index.ts +9 -0
  99. package/src/components/ui/dropdown-menu/DropdownMenu.vue +13 -0
  100. package/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +28 -0
  101. package/src/components/ui/dropdown-menu/DropdownMenuContent.vue +33 -0
  102. package/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +11 -0
  103. package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +27 -0
  104. package/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +23 -0
  105. package/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +13 -0
  106. package/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +27 -0
  107. package/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +13 -0
  108. package/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +12 -0
  109. package/src/components/ui/dropdown-menu/DropdownMenuSub.vue +13 -0
  110. package/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +27 -0
  111. package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +23 -0
  112. package/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +11 -0
  113. package/src/components/ui/dropdown-menu/index.ts +14 -0
  114. package/src/components/ui/form/FormControl.vue +3 -0
  115. package/src/components/ui/form/FormDescription.vue +6 -0
  116. package/src/components/ui/form/FormItem.vue +6 -0
  117. package/src/components/ui/form/FormLabel.vue +10 -0
  118. package/src/components/ui/form/FormMessage.vue +10 -0
  119. package/src/components/ui/form/index.ts +9 -0
  120. package/src/components/ui/hover-card/HoverCard.vue +13 -0
  121. package/src/components/ui/hover-card/HoverCardContent.vue +26 -0
  122. package/src/components/ui/hover-card/HoverCardTrigger.vue +11 -0
  123. package/src/components/ui/hover-card/index.ts +3 -0
  124. package/src/components/ui/input/Input.vue +23 -0
  125. package/src/components/ui/input/index.ts +1 -0
  126. package/src/components/ui/label/Label.vue +18 -0
  127. package/src/components/ui/label/index.ts +1 -0
  128. package/src/components/ui/lib/utils.ts +2 -0
  129. package/src/components/ui/menubar/MenubarContent.vue +15 -0
  130. package/src/components/ui/menubar/MenubarItem.vue +13 -0
  131. package/src/components/ui/menubar/MenubarTrigger.vue +13 -0
  132. package/src/components/ui/menubar/index.ts +5 -0
  133. package/src/components/ui/navigation-menu/NavigationMenuContent.vue +14 -0
  134. package/src/components/ui/navigation-menu/NavigationMenuTrigger.vue +15 -0
  135. package/src/components/ui/navigation-menu/index.ts +4 -0
  136. package/src/components/ui/pagination/PaginationContent.vue +13 -0
  137. package/src/components/ui/pagination/PaginationEllipsis.vue +12 -0
  138. package/src/components/ui/pagination/PaginationNext.vue +14 -0
  139. package/src/components/ui/pagination/PaginationPrev.vue +14 -0
  140. package/src/components/ui/pagination/index.ts +6 -0
  141. package/src/components/ui/popover/Popover.vue +13 -0
  142. package/src/components/ui/popover/PopoverContent.vue +27 -0
  143. package/src/components/ui/popover/PopoverTrigger.vue +11 -0
  144. package/src/components/ui/popover/index.ts +3 -0
  145. package/src/components/ui/progress/Progress.vue +21 -0
  146. package/src/components/ui/progress/index.ts +1 -0
  147. package/src/components/ui/radio-group/RadioGroup.vue +16 -0
  148. package/src/components/ui/radio-group/RadioGroupItem.vue +24 -0
  149. package/src/components/ui/radio-group/index.ts +2 -0
  150. package/src/components/ui/scroll-area/ScrollArea.vue +13 -0
  151. package/src/components/ui/scroll-area/index.ts +1 -0
  152. package/src/components/ui/select/Select.vue +13 -0
  153. package/src/components/ui/select/SelectContent.vue +40 -0
  154. package/src/components/ui/select/SelectGroup.vue +15 -0
  155. package/src/components/ui/select/SelectItem.vue +30 -0
  156. package/src/components/ui/select/SelectLabel.vue +15 -0
  157. package/src/components/ui/select/SelectSeparator.vue +13 -0
  158. package/src/components/ui/select/SelectTrigger.vue +23 -0
  159. package/src/components/ui/select/SelectValue.vue +11 -0
  160. package/src/components/ui/select/index.ts +8 -0
  161. package/src/components/ui/separator/Separator.vue +16 -0
  162. package/src/components/ui/separator/index.ts +1 -0
  163. package/src/components/ui/sheet/Sheet.vue +13 -0
  164. package/src/components/ui/sheet/SheetClose.vue +11 -0
  165. package/src/components/ui/sheet/SheetContent.vue +65 -0
  166. package/src/components/ui/sheet/SheetDescription.vue +15 -0
  167. package/src/components/ui/sheet/SheetFooter.vue +12 -0
  168. package/src/components/ui/sheet/SheetHeader.vue +12 -0
  169. package/src/components/ui/sheet/SheetTitle.vue +15 -0
  170. package/src/components/ui/sheet/SheetTrigger.vue +11 -0
  171. package/src/components/ui/sheet/index.ts +8 -0
  172. package/src/components/ui/skeleton/Skeleton.vue +9 -0
  173. package/src/components/ui/skeleton/index.ts +1 -0
  174. package/src/components/ui/slider/Slider.vue +26 -0
  175. package/src/components/ui/slider/index.ts +1 -0
  176. package/src/components/ui/switch/Switch.vue +24 -0
  177. package/src/components/ui/switch/index.ts +1 -0
  178. package/src/components/ui/table/Table.vue +13 -0
  179. package/src/components/ui/table/TableBody.vue +6 -0
  180. package/src/components/ui/table/TableCaption.vue +6 -0
  181. package/src/components/ui/table/TableCell.vue +6 -0
  182. package/src/components/ui/table/TableFooter.vue +6 -0
  183. package/src/components/ui/table/TableHead.vue +6 -0
  184. package/src/components/ui/table/TableHeader.vue +6 -0
  185. package/src/components/ui/table/TableRow.vue +6 -0
  186. package/src/components/ui/table/index.ts +8 -0
  187. package/src/components/ui/tabs/Tabs.vue +13 -0
  188. package/src/components/ui/tabs/TabsContent.vue +21 -0
  189. package/src/components/ui/tabs/TabsList.vue +21 -0
  190. package/src/components/ui/tabs/TabsTrigger.vue +21 -0
  191. package/src/components/ui/tabs/index.ts +4 -0
  192. package/src/components/ui/textarea/Textarea.vue +29 -0
  193. package/src/components/ui/textarea/index.ts +1 -0
  194. package/src/components/ui/toggle/Toggle.vue +40 -0
  195. package/src/components/ui/toggle/index.ts +1 -0
  196. package/src/components/ui/toggle-group/ToggleGroup.vue +16 -0
  197. package/src/components/ui/toggle-group/ToggleGroupItem.vue +21 -0
  198. package/src/components/ui/toggle-group/index.ts +2 -0
  199. package/src/components/ui/tooltip/Tooltip.vue +13 -0
  200. package/src/components/ui/tooltip/TooltipContent.vue +27 -0
  201. package/src/components/ui/tooltip/TooltipProvider.vue +12 -0
  202. package/src/components/ui/tooltip/TooltipTrigger.vue +11 -0
  203. package/src/components/ui/tooltip/index.ts +4 -0
  204. package/src/env.d.ts +7 -0
  205. package/src/index.ts +63 -0
  206. package/src/lib/utils.ts +7 -0
  207. package/src/patterns/DetailView.vue +46 -0
  208. package/src/patterns/EmptyState.vue +27 -0
  209. package/src/patterns/FormView.vue +34 -0
  210. package/src/patterns/ListView.vue +45 -0
  211. package/src/styles/index.css +4 -0
  212. package/src/styles/tokens.css +144 -0
  213. package/tailwind.config.js +108 -0
  214. package/tsconfig.json +21 -0
  215. package/dist/index.css +0 -1890
  216. package/dist/index.d.ts +0 -406
  217. package/dist/index.js +0 -1721
  218. package/dist/index.js.map +0 -1
  219. package/tailwind.config.ts +0 -174
@@ -0,0 +1,148 @@
1
+ # Reinvented Design Guide
2
+
3
+ ## Overview
4
+ The Reinvented design system uses **Shadcn-vue** components with custom **Radix-vue** primitives,
5
+ **Tailwind CSS** for styling, and **Lucide** icons. All UI surfaces share this consistent foundation.
6
+
7
+ ---
8
+
9
+ ## Typography
10
+
11
+ | Token | Size | Weight | Use |
12
+ |---------------|--------|----------|------------------------|
13
+ | `text-xs` | 12px | 400 | Timestamps, captions |
14
+ | `text-sm` | 14px | 400–500 | Body text, labels |
15
+ | `text-base` | 16px | 400 | Default body |
16
+ | `text-lg` | 18px | 600 | Section headings |
17
+ | `text-xl` | 20px | 600 | Page subtitles |
18
+ | `text-2xl` | 24px | 700 | Page titles |
19
+ | `text-3xl` | 30px | 700 | Hero text |
20
+
21
+ **Font:** Inter (loaded via Google Fonts).
22
+ **Line height:** Use `leading-tight` (1.25) for headings, `leading-normal` (1.5) for body.
23
+
24
+ ---
25
+
26
+ ## Colors
27
+
28
+ Our brand color is **purple** (`hsl(252 100% 63%)`).
29
+
30
+ | Token | Light | Dark | Use |
31
+ |-----------------|-------------------|-------------------|------------------------|
32
+ | `primary` | Purple 63% | Purple 69% | Buttons, links, focus |
33
+ | `secondary` | Zinc 96% | Zinc 16% | Secondary actions |
34
+ | `muted` | Zinc 96% | Zinc 16% | Backgrounds, disabled |
35
+ | `destructive` | Red 60% | Red 31% | Delete, errors |
36
+ | `success` | Green 36% | Green 45% | Confirmations |
37
+ | `warning` | Amber 50% | Amber 55% | Alerts |
38
+ | `info` | Blue 60% | Blue 65% | Information |
39
+
40
+ **Usage rules:**
41
+ - Never hardcode colors — always use `hsl(var(--token))`
42
+ - Use `text-muted-foreground` for secondary text (not arbitrary gray)
43
+ - Apply `bg-card` for card surfaces, `bg-background` for page backgrounds
44
+
45
+ ---
46
+
47
+ ## Spacing
48
+
49
+ Based on **4px increments**. Use Tailwind utilities:
50
+
51
+ | Class | Value | Use |
52
+ |----------|-------|----------------------------|
53
+ | `gap-1` | 4px | Icon-to-text gap |
54
+ | `gap-2` | 8px | Between small elements |
55
+ | `gap-3` | 12px | Between form fields |
56
+ | `gap-4` | 16px | Section spacing |
57
+ | `gap-6` | 24px | Between major sections |
58
+ | `p-4` | 16px | Standard padding |
59
+ | `p-6` | 24px | Card padding |
60
+ | `px-4` | 16px | Page horizontal padding |
61
+
62
+ **Rules:**
63
+ - Always use spacing tokens, never arbitrary values
64
+ - Vertical rhythm: Use `gap-4` or `gap-6` for stacking sections
65
+ - Horizontal rhythm: Use `gap-2` or `gap-3` for inline elements
66
+
67
+ ---
68
+
69
+ ## Icons
70
+
71
+ - **Library:** Lucide Vue Next (`lucide-vue-next`)
72
+ - **NO emojis** anywhere in the UI
73
+ - Default icon size: `16px` (`w-4 h-4`)
74
+ - In buttons/nav: `w-4 h-4`
75
+ - In empty states: `w-12 h-12` with `text-muted-foreground`
76
+ - Always use `stroke-width="2"` (Lucide default)
77
+
78
+ ---
79
+
80
+ ## Shadows & Borders
81
+
82
+ | Token | CSS | Use |
83
+ |-------------|-------------------------------|----------------------------|
84
+ | `shadow-sm` | Subtle 1px shadow | Cards, buttons |
85
+ | `shadow-md` | Medium depth | Dropdowns, popovers |
86
+ | `shadow-lg` | Strong depth | Modals, dialogs |
87
+ | `rounded-md`| `calc(var(--radius) - 2px)` | Inputs, small elements |
88
+ | `rounded-lg`| `var(--radius)` (10px) | Cards, containers |
89
+
90
+ ---
91
+
92
+ ## Component Guidelines
93
+
94
+ ### When to use existing components
95
+ Always check `@reinvented/design` first:
96
+ ```ts
97
+ import { Button, Card, Input, Avatar, Badge } from '@reinvented/design'
98
+ ```
99
+
100
+ ### Using Radix primitives
101
+ For Dialog, DropdownMenu, Tabs, Tooltip, PopoverSelect, etc.:
102
+ ```ts
103
+ import { Dialog, DialogTrigger, DialogContent, DialogTitle } from '@reinvented/design'
104
+ ```
105
+ Style them using `cn()` and Tailwind:
106
+ ```vue
107
+ <DialogContent :class="cn('fixed inset-0 z-50 flex items-center justify-center')">
108
+ ```
109
+
110
+ ### Building new components
111
+ 1. Create in `packages/ds/src/components/ui/<name>/`
112
+ 2. Use `cn()` for class merging
113
+ 3. Accept `class` prop for customization
114
+ 4. Use design tokens (never hardcode colors)
115
+ 5. Export from barrel (`src/index.ts`)
116
+
117
+ ---
118
+
119
+ ## Page Patterns
120
+
121
+ Import from `@reinvented/design/patterns/*`:
122
+
123
+ | Pattern | Use |
124
+ |--------------|----------------------------------------------|
125
+ | `ListView` | Lists with search, filters, items |
126
+ | `DetailView` | Detail pages with hero, tabs, content |
127
+ | `FormView` | Forms with validation and submit |
128
+ | `EmptyState` | Centered empty state with icon and CTA |
129
+
130
+ ---
131
+
132
+ ## Dark Mode
133
+
134
+ - Controlled via `.dark` class on `<html>` or `<body>`
135
+ - All tokens automatically switch in dark mode
136
+ - Test both modes when building surfaces
137
+ - Use `dark:` prefix sparingly — prefer CSS variable-driven theming
138
+
139
+ ---
140
+
141
+ ## Do NOT
142
+
143
+ - Use `alert()`, `confirm()`, or `prompt()` — use Dialog/AlertDialog
144
+ - Use emojis — use Lucide icons
145
+ - Hardcode colors — use CSS variables
146
+ - Use arbitrary Tailwind values (e.g., `text-[#333]`) — use tokens
147
+ - Create split-screen layouts — use single-column responsive design
148
+ - Use `@apply` excessively — prefer utility classes in templates
package/README.md CHANGED
@@ -1,179 +1,56 @@
1
- # @reinvented/design
1
+ # Reinvented Design System
2
2
 
3
- Opinionated design system for the Reinvented platform. Built on **Shadcn/ui + Radix + Tailwind CSS** with a **Linear-inspired** dark-first premium aesthetic.
3
+ The opinionated visual foundation for all Reinvented apps. Components, patterns, layouts, conventions, rules, and documentation.
4
4
 
5
- ## Design Principles
6
-
7
- - **Dark-first** — Nearly-black backgrounds (`#0a0a0b`) with subtle surface elevation, not obvious cards
8
- - **Restrained palette** — Mostly grays with one accent color (violet-blue `#5b6af0`), used sparingly on interactive elements
9
- - **Muted borders** — No heavy shadows in dark mode; borders at 4–16% white opacity
10
- - **Tight typography** — Inter font, compact scale (11px–36px), 4 main text styles
11
- - **Smooth animations** — Subtle fade-in, slide-up, scale-in transitions (200ms default)
12
- - **Consistency-first** — Composition components with locked styling prevent visual drift
13
-
14
- ## Installation
5
+ ## Quick Start
15
6
 
16
7
  ```bash
17
- pnpm add @reinvented/design
8
+ npm install @reinvented/design
18
9
  ```
19
10
 
20
- Import CSS in your app entry:
21
-
22
- ```tsx
23
- import "@reinvented/design/css";
11
+ ```vue
12
+ <script setup>
13
+ import { Button, Card, Input, Badge, Dialog } from '@reinvented/design'
14
+ </script>
24
15
  ```
25
16
 
26
- ## Usage
17
+ ## Stack
27
18
 
28
- ### Primitives (flexible, accept className)
19
+ - **Components**: [Shadcn-vue](https://www.shadcn-vue.com/) (all components, styled with our tokens)
20
+ - **Primitives**: [Radix Vue](https://www.radix-vue.com/) (accessible headless components)
21
+ - **Styling**: [Tailwind CSS](https://tailwindcss.com/) with design tokens
22
+ - **Icons**: [Lucide Vue Next](https://lucide.dev/) (no emojis, ever)
23
+ - **Typography**: Inter (via Google Fonts)
29
24
 
30
- ```tsx
31
- import { Button, Input, Card, Badge, Dialog } from "@reinvented/design";
25
+ ## Structure
32
26
 
33
- <Button variant="primary" size="md">Save</Button>
34
- <Button variant="ghost" size="sm">Cancel</Button>
35
- <Input label="Email" placeholder="you@example.com" error="Required" />
36
- <Badge variant="success">Active</Badge>
37
27
  ```
38
-
39
- ### Composition Components (locked, no className)
40
-
41
- These are the **recommended API** — use them for guaranteed visual consistency:
42
-
43
- ```tsx
44
- import { ContentCard, PageHeader, ListItem, FormSection, ActionBar, EmptyState } from "@reinvented/design";
45
-
46
- <PageHeader title="Settings" description="Manage your account" actions={<Button>Save</Button>} />
47
-
48
- <ContentCard title="Profile" description="Your personal information">
49
- <Input label="Name" />
50
- </ContentCard>
51
-
52
- <ListItem
53
- leading={<UserIcon size={16} />}
54
- title="John Doe"
55
- description="john@example.com"
56
- trailing={<Badge>Admin</Badge>}
57
- onClick={() => navigate("/users/1")}
58
- />
59
-
60
- <EmptyState
61
- icon={<InboxIcon size={32} />}
62
- title="No items yet"
63
- description="Create your first item to get started"
64
- action={<Button>Create</Button>}
65
- />
28
+ src/
29
+ components/ui/ All styled components
30
+ patterns/ Reusable compositions (ListView, DetailView, etc.)
31
+ layouts/ Page-level layout components with slots
32
+ lib/ Utilities (cn, etc.)
33
+ styles/ Tokens, CSS variables
34
+ docs/
35
+ rules.md Hard design rules
36
+ conventions.md Opinionated UX decisions
37
+ visual-polish.md Animations, transitions, polish guidelines
38
+ components/ Per-component usage guides
39
+ patterns/ Per-pattern docs with skeleton code
40
+ layouts/ Per-layout docs with skeleton code
41
+ examples/ Full skeleton examples
66
42
  ```
67
43
 
68
- ### Layout
69
-
70
- ```tsx
71
- import { AppShell, TopBar, SideRail, SideRailItem, PageContainer } from "@reinvented/design";
44
+ ## Documentation
72
45
 
73
- <AppShell
74
- topBar={<TopBar brand={<Logo />} actions={<Avatar />} />}
75
- sideRail={
76
- <SideRail>
77
- <SideRailItem active tooltip="Home"><HomeIcon size={18} /></SideRailItem>
78
- <SideRailItem tooltip="Settings"><SettingsIcon size={18} /></SideRailItem>
79
- </SideRail>
80
- }
81
- >
82
- <PageContainer>
83
- {/* Page content */}
84
- </PageContainer>
85
- </AppShell>
86
- ```
87
-
88
- ### Icons
89
-
90
- ```tsx
91
- import { DynamicIcon, Settings, ChevronRight } from "@reinvented/design";
92
-
93
- // Static icon
94
- <Settings size={16} />
95
-
96
- // Dynamic icon by name string (for app manager)
97
- <DynamicIcon name="Settings" size={16} />
98
- ```
99
-
100
- ### Hooks
101
-
102
- ```tsx
103
- import { useTheme, useMediaQuery } from "@reinvented/design";
104
-
105
- const { theme, toggleTheme, isDark } = useTheme();
106
- const isMobile = useMediaQuery("(max-width: 768px)");
107
- ```
108
-
109
- ### Utilities
110
-
111
- ```tsx
112
- import { cn } from "@reinvented/design";
113
-
114
- <div className={cn("text-fg-primary", isActive && "text-accent")} />
115
- ```
116
-
117
- ### Command Palette
118
-
119
- ```tsx
120
- import { CommandPalette, CommandGroup, CommandItem, CommandEmpty } from "@reinvented/design";
121
-
122
- <CommandPalette placeholder="Search or jump to…">
123
- <CommandEmpty>No results found.</CommandEmpty>
124
- <CommandGroup heading="Actions">
125
- <CommandItem onSelect={() => navigate("/settings")}>Settings</CommandItem>
126
- </CommandGroup>
127
- </CommandPalette>
128
- // Opens with Cmd+K / Ctrl+K
129
- ```
130
-
131
- ## Token Reference
132
-
133
- | Token | Dark Value | Purpose |
134
- |-------|-----------|---------|
135
- | `--bg-base` | `#0a0a0b` | App background |
136
- | `--bg-surface` | `#111113` | Cards, panels |
137
- | `--bg-elevated` | `#191a1f` | Dropdowns, popovers |
138
- | `--fg-primary` | `#ededef` | Primary text |
139
- | `--fg-secondary` | `#a1a1a6` | Secondary text |
140
- | `--fg-muted` | `#6e6e76` | Placeholder, hints |
141
- | `--accent` | `#5b6af0` | Interactive elements |
142
- | `--border-default` | `rgba(255,255,255,0.08)` | Standard borders |
143
-
144
- ## Component Catalog
145
-
146
- ### Primitives
147
- Button, Input, Badge, Avatar, Card, Label, Dialog, DropdownMenu, Toast, Separator, ScrollArea, Select, Switch, Checkbox, Tabs, Tooltip, Skeleton, Sheet
148
-
149
- ### Composition (locked)
150
- ContentCard, PageHeader, ListItem, FormSection, ActionBar, EmptyState
151
-
152
- ### Layout
153
- AppShell, TopBar, SideRail, BottomBar, PageContainer
154
-
155
- ### Feedback & Overlays
156
- Spinner, ErrorBoundary, CommandPalette
157
-
158
- ## Tailwind Config
159
-
160
- Consuming apps should extend the design system's Tailwind config:
161
-
162
- ```ts
163
- // tailwind.config.ts in your app
164
- import designConfig from "@reinvented/design/tailwind";
165
-
166
- export default {
167
- presets: [designConfig],
168
- content: [
169
- "./src/**/*.{ts,tsx}",
170
- "../../packages/design/src/**/*.{ts,tsx}",
171
- ],
172
- };
173
- ```
46
+ - **[Rules](docs/rules.md)** — Non-negotiable design constraints
47
+ - **[Conventions](docs/conventions.md)** Opinionated UX decisions
48
+ - **[Visual Polish](docs/visual-polish.md)** — Animation and polish guide
49
+ - **[Components](docs/components/index.md)** — Component usage guides
50
+ - **[Patterns](docs/patterns/index.md)** Reusable UI patterns
51
+ - **[Layouts](docs/layouts/index.md)** Page layout recipes
52
+ - **[Design Guide](DESIGN_GUIDE.md)** — Tokens, typography, colors, spacing
174
53
 
175
- ## Adding New Components
54
+ ## Contributing
176
55
 
177
- 1. Create the component in `src/components/`
178
- 2. Export it from `src/index.ts`
179
- 3. Run `pnpm build` to verify
56
+ Agents and humans can propose changes via PRs. See [conventions](docs/conventions.md) for design principles.
@@ -0,0 +1,32 @@
1
+ # AlertDialog
2
+ ## When to Use
3
+ - Destructive action confirmation (delete, remove, irreversible changes)
4
+
5
+ ## Skeleton Code
6
+ ```vue
7
+ <script setup>
8
+ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, Button } from '@reinvented/design'
9
+ </script>
10
+
11
+ <template>
12
+ <AlertDialog>
13
+ <AlertDialogTrigger as-child>
14
+ <Button variant="destructive">Delete</Button>
15
+ </AlertDialogTrigger>
16
+ <AlertDialogContent>
17
+ <AlertDialogHeader>
18
+ <AlertDialogTitle>Are you sure?</AlertDialogTitle>
19
+ <AlertDialogDescription>This action cannot be undone.</AlertDialogDescription>
20
+ </AlertDialogHeader>
21
+ <AlertDialogFooter>
22
+ <AlertDialogCancel>Cancel</AlertDialogCancel>
23
+ <AlertDialogAction>Delete Item</AlertDialogAction>
24
+ </AlertDialogFooter>
25
+ </AlertDialogContent>
26
+ </AlertDialog>
27
+ </template>
28
+ ```
29
+
30
+ ## Gotchas
31
+ - Action button text must describe what it does ("Delete Task", not "OK")
32
+ - Cancel is always the default focused element
@@ -0,0 +1,14 @@
1
+ # Avatar
2
+ ## Skeleton Code
3
+ ```vue
4
+ <script setup>
5
+ import { Avatar } from '@reinvented/design'
6
+ </script>
7
+ <template>
8
+ <Avatar src="/user.jpg" alt="User name" />
9
+ <Avatar>JD</Avatar> <!-- Fallback initials -->
10
+ </template>
11
+ ```
12
+ ## Gotchas
13
+ - Always provide `alt` text for accessibility
14
+ - Fallback shows slot content when `src` fails to load
@@ -0,0 +1,24 @@
1
+ # Badge
2
+ ## Variants
3
+ | Variant | Use for |
4
+ |---------|---------|
5
+ | `default` | Neutral status |
6
+ | `secondary` | Subtle labels |
7
+ | `destructive` | Error/danger status |
8
+ | `outline` | Bordered labels |
9
+
10
+ ## Skeleton Code
11
+ ```vue
12
+ <script setup>
13
+ import { Badge } from '@reinvented/design'
14
+ </script>
15
+ <template>
16
+ <Badge>Active</Badge>
17
+ <Badge variant="destructive">Error</Badge>
18
+ <Badge variant="secondary">Draft</Badge>
19
+ <Badge variant="outline">v1.2</Badge>
20
+ </template>
21
+ ```
22
+ ## Gotchas
23
+ - Use for status indicators, never for interactive actions (use Button for that)
24
+ - Keep text short (1-2 words)
@@ -0,0 +1,69 @@
1
+ # Button
2
+
3
+ ## Variants
4
+ | Variant | Use for |
5
+ |---------|---------|
6
+ | `default` | Primary actions |
7
+ | `secondary` | Secondary actions |
8
+ | `destructive` | Delete, remove, cancel |
9
+ | `outline` | Tertiary actions |
10
+ | `ghost` | Toolbar actions, icon-only buttons |
11
+ | `link` | Inline text actions |
12
+ | `success` | Positive confirmation actions |
13
+
14
+ ## Sizes
15
+ | Size | Use for |
16
+ |------|---------|
17
+ | `default` | Standard buttons |
18
+ | `xs` | Compact UI, inline actions |
19
+ | `sm` | Compact UI, table rows |
20
+ | `lg` | Hero CTAs, empty state actions |
21
+ | `xl` | Landing page CTAs |
22
+ | `icon` | Icon-only square buttons |
23
+
24
+ ## Skeleton Code
25
+
26
+ ```vue
27
+ <script setup>
28
+ import { Button } from '@reinvented/design'
29
+ </script>
30
+
31
+ <template>
32
+ <Button>Default</Button>
33
+ <Button variant="secondary">Secondary</Button>
34
+ <Button variant="destructive">Delete</Button>
35
+ <Button variant="outline">Outline</Button>
36
+ <Button variant="ghost">Ghost</Button>
37
+ <Button size="sm">Small</Button>
38
+ <Button size="icon"><Trash2 class="w-4 h-4" /></Button>
39
+ </template>
40
+ ```
41
+
42
+ ## With Loading State
43
+
44
+ ```vue
45
+ <script setup>
46
+ import { ref } from 'vue'
47
+ import { Button } from '@reinvented/design'
48
+ import { Loader2 } from 'lucide-vue-next'
49
+
50
+ const saving = ref(false)
51
+ async function handleSave() {
52
+ saving.value = true
53
+ try { await saveMutation() }
54
+ finally { saving.value = false }
55
+ }
56
+ </script>
57
+
58
+ <template>
59
+ <Button :disabled="saving" @click="handleSave">
60
+ <Loader2 v-if="saving" class="w-4 h-4 mr-2 animate-spin" />
61
+ {{ saving ? 'Saving...' : 'Save' }}
62
+ </Button>
63
+ </template>
64
+ ```
65
+
66
+ ## Gotchas
67
+ - Always provide `aria-label` for icon-only buttons
68
+ - Use `type="button"` to prevent form submission unless intended
69
+ - Use `as="a"` prop to render as a link element with button styling
@@ -0,0 +1,49 @@
1
+ # Card
2
+
3
+ ## Sub-components
4
+ | Component | Use for |
5
+ |-----------|---------|
6
+ | `Card` | Container wrapper |
7
+ | `CardHeader` | Title + description area |
8
+ | `CardTitle` | Main heading |
9
+ | `CardDescription` | Subtitle or description |
10
+ | `CardContent` | Main content area |
11
+ | `CardFooter` | Actions area |
12
+
13
+ ## Skeleton Code
14
+
15
+ ```vue
16
+ <script setup>
17
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, Button } from '@reinvented/design'
18
+ </script>
19
+
20
+ <template>
21
+ <Card>
22
+ <CardHeader>
23
+ <CardTitle>Card Title</CardTitle>
24
+ <CardDescription>Card description text</CardDescription>
25
+ </CardHeader>
26
+ <CardContent>
27
+ <p>Card content goes here</p>
28
+ </CardContent>
29
+ <CardFooter>
30
+ <Button>Action</Button>
31
+ </CardFooter>
32
+ </Card>
33
+ </template>
34
+ ```
35
+
36
+ ## Clickable Card
37
+
38
+ ```vue
39
+ <template>
40
+ <Card class="transition-shadow duration-150 hover:shadow-md cursor-pointer" @click="navigate">
41
+ <!-- content -->
42
+ </Card>
43
+ </template>
44
+ ```
45
+
46
+ ## Gotchas
47
+ - Don't nest cards inside cards
48
+ - Use `CardFooter` for actions, not `CardContent`
49
+ - Apply hover styles via `class` prop, not custom CSS
@@ -0,0 +1,46 @@
1
+ # Dialog
2
+ ## When to Use
3
+ - Simple create/edit forms (≤ 5 fields)
4
+ - Confirmations
5
+ - Quick actions that keep page context
6
+
7
+ When NOT to use: Forms with 8+ fields (use full page), rich content editing (use full page).
8
+
9
+ ## Sub-components
10
+ `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogFooter`, `DialogTitle`, `DialogDescription`, `DialogClose`, `DialogScrollContent`
11
+
12
+ ## Skeleton Code
13
+ ```vue
14
+ <script setup>
15
+ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Button, Input, Label } from '@reinvented/design'
16
+ </script>
17
+
18
+ <template>
19
+ <Dialog>
20
+ <DialogTrigger as-child>
21
+ <Button>Create Item</Button>
22
+ </DialogTrigger>
23
+ <DialogContent>
24
+ <DialogHeader>
25
+ <DialogTitle>Create New Item</DialogTitle>
26
+ <DialogDescription>Fill in the details below.</DialogDescription>
27
+ </DialogHeader>
28
+ <div class="grid gap-4 py-4">
29
+ <div class="space-y-2">
30
+ <Label for="name">Name</Label>
31
+ <Input id="name" placeholder="Item name" />
32
+ </div>
33
+ </div>
34
+ <DialogFooter>
35
+ <Button variant="outline">Cancel</Button>
36
+ <Button>Save</Button>
37
+ </DialogFooter>
38
+ </DialogContent>
39
+ </Dialog>
40
+ </template>
41
+ ```
42
+
43
+ ## Gotchas
44
+ - Use `as-child` on `DialogTrigger` to avoid nested buttons
45
+ - For long content, use `DialogScrollContent` instead of `DialogContent`
46
+ - Always include `DialogTitle` for accessibility (even if visually hidden)
@@ -0,0 +1,32 @@
1
+ # DropdownMenu
2
+ ## When to Use
3
+ - Action menus on items (edit, delete, share)
4
+ - User profile menus
5
+ - More options (...) buttons
6
+
7
+ ## Skeleton Code
8
+ ```vue
9
+ <script setup>
10
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Button } from '@reinvented/design'
11
+ import { MoreHorizontal, Pencil, Trash2 } from 'lucide-vue-next'
12
+ </script>
13
+
14
+ <template>
15
+ <DropdownMenu>
16
+ <DropdownMenuTrigger as-child>
17
+ <Button variant="ghost" size="icon"><MoreHorizontal class="w-4 h-4" /></Button>
18
+ </DropdownMenuTrigger>
19
+ <DropdownMenuContent align="end">
20
+ <DropdownMenuLabel>Actions</DropdownMenuLabel>
21
+ <DropdownMenuSeparator />
22
+ <DropdownMenuItem><Pencil class="mr-2 h-4 w-4" /> Edit</DropdownMenuItem>
23
+ <DropdownMenuItem class="text-destructive"><Trash2 class="mr-2 h-4 w-4" /> Delete</DropdownMenuItem>
24
+ </DropdownMenuContent>
25
+ </DropdownMenu>
26
+ </template>
27
+ ```
28
+
29
+ ## Gotchas
30
+ - Use `align="end"` for right-aligned menus
31
+ - Use `as-child` on trigger to compose with existing buttons
32
+ - Destructive items should use `class="text-destructive"`