@reinvented/design 0.2.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 (182) hide show
  1. package/docs/components/alert-dialog.md +32 -0
  2. package/docs/components/avatar.md +14 -0
  3. package/docs/components/badge.md +24 -0
  4. package/docs/components/button.md +69 -0
  5. package/docs/components/card.md +49 -0
  6. package/docs/components/dialog.md +46 -0
  7. package/docs/components/dropdown-menu.md +32 -0
  8. package/docs/components/index.md +69 -50
  9. package/docs/components/input.md +34 -0
  10. package/docs/components/remaining-components.md +253 -0
  11. package/docs/components/scroll-area.md +17 -0
  12. package/docs/components/select.md +31 -0
  13. package/docs/components/separator.md +14 -0
  14. package/docs/components/sheet.md +32 -0
  15. package/docs/components/skeleton.md +20 -0
  16. package/docs/components/table.md +33 -0
  17. package/docs/components/tabs.md +23 -0
  18. package/docs/layouts/dashboard.md +70 -0
  19. package/docs/layouts/detail-page.md +83 -0
  20. package/docs/layouts/index.md +37 -24
  21. package/docs/layouts/list-page.md +107 -0
  22. package/docs/layouts/settings-page.md +79 -0
  23. package/docs/layouts/step-wizard.md +73 -0
  24. package/package.json +1 -1
  25. package/src/components/ui/accordion/Accordion.vue +13 -0
  26. package/src/components/ui/accordion/AccordionContent.vue +20 -0
  27. package/src/components/ui/accordion/AccordionItem.vue +15 -0
  28. package/src/components/ui/accordion/AccordionTrigger.vue +25 -0
  29. package/src/components/ui/accordion/index.ts +4 -0
  30. package/src/components/ui/alert/Alert.vue +38 -0
  31. package/src/components/ui/alert/AlertDescription.vue +12 -0
  32. package/src/components/ui/alert/AlertTitle.vue +12 -0
  33. package/src/components/ui/alert/index.ts +3 -0
  34. package/src/components/ui/alert-dialog/AlertDialog.vue +13 -0
  35. package/src/components/ui/alert-dialog/AlertDialogAction.vue +21 -0
  36. package/src/components/ui/alert-dialog/AlertDialogCancel.vue +21 -0
  37. package/src/components/ui/alert-dialog/AlertDialogContent.vue +39 -0
  38. package/src/components/ui/alert-dialog/AlertDialogDescription.vue +15 -0
  39. package/src/components/ui/alert-dialog/AlertDialogFooter.vue +12 -0
  40. package/src/components/ui/alert-dialog/AlertDialogHeader.vue +12 -0
  41. package/src/components/ui/alert-dialog/AlertDialogTitle.vue +15 -0
  42. package/src/components/ui/alert-dialog/AlertDialogTrigger.vue +11 -0
  43. package/src/components/ui/alert-dialog/index.ts +9 -0
  44. package/src/components/ui/breadcrumb/Breadcrumb.vue +6 -0
  45. package/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +12 -0
  46. package/src/components/ui/breadcrumb/BreadcrumbItem.vue +6 -0
  47. package/src/components/ui/breadcrumb/BreadcrumbLink.vue +20 -0
  48. package/src/components/ui/breadcrumb/BreadcrumbList.vue +6 -0
  49. package/src/components/ui/breadcrumb/BreadcrumbPage.vue +6 -0
  50. package/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +11 -0
  51. package/src/components/ui/breadcrumb/index.ts +7 -0
  52. package/src/components/ui/button/Button.vue +0 -1
  53. package/src/components/ui/checkbox/Checkbox.vue +25 -0
  54. package/src/components/ui/checkbox/index.ts +1 -0
  55. package/src/components/ui/collapsible/Collapsible.vue +13 -0
  56. package/src/components/ui/collapsible/index.ts +2 -0
  57. package/src/components/ui/command/Command.vue +16 -0
  58. package/src/components/ui/command/CommandEmpty.vue +5 -0
  59. package/src/components/ui/command/CommandGroup.vue +22 -0
  60. package/src/components/ui/command/CommandInput.vue +21 -0
  61. package/src/components/ui/command/CommandItem.vue +22 -0
  62. package/src/components/ui/command/CommandList.vue +17 -0
  63. package/src/components/ui/command/CommandSeparator.vue +5 -0
  64. package/src/components/ui/command/index.ts +7 -0
  65. package/src/components/ui/context-menu/ContextMenuContent.vue +24 -0
  66. package/src/components/ui/context-menu/ContextMenuItem.vue +16 -0
  67. package/src/components/ui/context-menu/ContextMenuLabel.vue +9 -0
  68. package/src/components/ui/context-menu/ContextMenuSeparator.vue +9 -0
  69. package/src/components/ui/context-menu/ContextMenuSubContent.vue +14 -0
  70. package/src/components/ui/context-menu/index.ts +9 -0
  71. package/src/components/ui/dialog/Dialog.vue +14 -0
  72. package/src/components/ui/dialog/DialogClose.vue +12 -0
  73. package/src/components/ui/dialog/DialogContent.vue +48 -0
  74. package/src/components/ui/dialog/DialogDescription.vue +23 -0
  75. package/src/components/ui/dialog/DialogFooter.vue +12 -0
  76. package/src/components/ui/dialog/DialogHeader.vue +12 -0
  77. package/src/components/ui/dialog/DialogScrollContent.vue +47 -0
  78. package/src/components/ui/dialog/DialogTitle.vue +23 -0
  79. package/src/components/ui/dialog/DialogTrigger.vue +12 -0
  80. package/src/components/ui/dialog/index.ts +9 -0
  81. package/src/components/ui/dropdown-menu/DropdownMenu.vue +13 -0
  82. package/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +28 -0
  83. package/src/components/ui/dropdown-menu/DropdownMenuContent.vue +33 -0
  84. package/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +11 -0
  85. package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +27 -0
  86. package/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +23 -0
  87. package/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +13 -0
  88. package/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +27 -0
  89. package/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +13 -0
  90. package/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +12 -0
  91. package/src/components/ui/dropdown-menu/DropdownMenuSub.vue +13 -0
  92. package/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +27 -0
  93. package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +23 -0
  94. package/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +11 -0
  95. package/src/components/ui/dropdown-menu/index.ts +14 -0
  96. package/src/components/ui/form/FormControl.vue +3 -0
  97. package/src/components/ui/form/FormDescription.vue +6 -0
  98. package/src/components/ui/form/FormItem.vue +6 -0
  99. package/src/components/ui/form/FormLabel.vue +10 -0
  100. package/src/components/ui/form/FormMessage.vue +10 -0
  101. package/src/components/ui/form/index.ts +9 -0
  102. package/src/components/ui/hover-card/HoverCard.vue +13 -0
  103. package/src/components/ui/hover-card/HoverCardContent.vue +26 -0
  104. package/src/components/ui/hover-card/HoverCardTrigger.vue +11 -0
  105. package/src/components/ui/hover-card/index.ts +3 -0
  106. package/src/components/ui/label/Label.vue +18 -0
  107. package/src/components/ui/label/index.ts +1 -0
  108. package/src/components/ui/menubar/MenubarContent.vue +15 -0
  109. package/src/components/ui/menubar/MenubarItem.vue +13 -0
  110. package/src/components/ui/menubar/MenubarTrigger.vue +13 -0
  111. package/src/components/ui/menubar/index.ts +5 -0
  112. package/src/components/ui/navigation-menu/NavigationMenuContent.vue +14 -0
  113. package/src/components/ui/navigation-menu/NavigationMenuTrigger.vue +15 -0
  114. package/src/components/ui/navigation-menu/index.ts +4 -0
  115. package/src/components/ui/pagination/PaginationContent.vue +13 -0
  116. package/src/components/ui/pagination/PaginationEllipsis.vue +12 -0
  117. package/src/components/ui/pagination/PaginationNext.vue +14 -0
  118. package/src/components/ui/pagination/PaginationPrev.vue +14 -0
  119. package/src/components/ui/pagination/index.ts +6 -0
  120. package/src/components/ui/popover/Popover.vue +13 -0
  121. package/src/components/ui/popover/PopoverContent.vue +27 -0
  122. package/src/components/ui/popover/PopoverTrigger.vue +11 -0
  123. package/src/components/ui/popover/index.ts +3 -0
  124. package/src/components/ui/progress/Progress.vue +21 -0
  125. package/src/components/ui/progress/index.ts +1 -0
  126. package/src/components/ui/radio-group/RadioGroup.vue +16 -0
  127. package/src/components/ui/radio-group/RadioGroupItem.vue +24 -0
  128. package/src/components/ui/radio-group/index.ts +2 -0
  129. package/src/components/ui/select/Select.vue +13 -0
  130. package/src/components/ui/select/SelectContent.vue +40 -0
  131. package/src/components/ui/select/SelectGroup.vue +15 -0
  132. package/src/components/ui/select/SelectItem.vue +30 -0
  133. package/src/components/ui/select/SelectLabel.vue +15 -0
  134. package/src/components/ui/select/SelectSeparator.vue +13 -0
  135. package/src/components/ui/select/SelectTrigger.vue +23 -0
  136. package/src/components/ui/select/SelectValue.vue +11 -0
  137. package/src/components/ui/select/index.ts +8 -0
  138. package/src/components/ui/sheet/Sheet.vue +13 -0
  139. package/src/components/ui/sheet/SheetClose.vue +11 -0
  140. package/src/components/ui/sheet/SheetContent.vue +65 -0
  141. package/src/components/ui/sheet/SheetDescription.vue +15 -0
  142. package/src/components/ui/sheet/SheetFooter.vue +12 -0
  143. package/src/components/ui/sheet/SheetHeader.vue +12 -0
  144. package/src/components/ui/sheet/SheetTitle.vue +15 -0
  145. package/src/components/ui/sheet/SheetTrigger.vue +11 -0
  146. package/src/components/ui/sheet/index.ts +8 -0
  147. package/src/components/ui/slider/Slider.vue +26 -0
  148. package/src/components/ui/slider/index.ts +1 -0
  149. package/src/components/ui/switch/Switch.vue +24 -0
  150. package/src/components/ui/switch/index.ts +1 -0
  151. package/src/components/ui/table/Table.vue +13 -0
  152. package/src/components/ui/table/TableBody.vue +6 -0
  153. package/src/components/ui/table/TableCaption.vue +6 -0
  154. package/src/components/ui/table/TableCell.vue +6 -0
  155. package/src/components/ui/table/TableFooter.vue +6 -0
  156. package/src/components/ui/table/TableHead.vue +6 -0
  157. package/src/components/ui/table/TableHeader.vue +6 -0
  158. package/src/components/ui/table/TableRow.vue +6 -0
  159. package/src/components/ui/table/index.ts +8 -0
  160. package/src/components/ui/tabs/Tabs.vue +13 -0
  161. package/src/components/ui/tabs/TabsContent.vue +21 -0
  162. package/src/components/ui/tabs/TabsList.vue +21 -0
  163. package/src/components/ui/tabs/TabsTrigger.vue +21 -0
  164. package/src/components/ui/tabs/index.ts +4 -0
  165. package/src/components/ui/textarea/Textarea.vue +29 -0
  166. package/src/components/ui/textarea/index.ts +1 -0
  167. package/src/components/ui/toggle/Toggle.vue +40 -0
  168. package/src/components/ui/toggle/index.ts +1 -0
  169. package/src/components/ui/toggle-group/ToggleGroup.vue +16 -0
  170. package/src/components/ui/toggle-group/ToggleGroupItem.vue +21 -0
  171. package/src/components/ui/toggle-group/index.ts +2 -0
  172. package/src/components/ui/tooltip/Tooltip.vue +13 -0
  173. package/src/components/ui/tooltip/TooltipContent.vue +27 -0
  174. package/src/components/ui/tooltip/TooltipProvider.vue +12 -0
  175. package/src/components/ui/tooltip/TooltipTrigger.vue +11 -0
  176. package/src/components/ui/tooltip/index.ts +4 -0
  177. package/src/index.ts +46 -192
  178. package/src/patterns/DetailView.vue +2 -2
  179. package/src/patterns/EmptyState.vue +2 -2
  180. package/src/patterns/FormView.vue +2 -2
  181. package/src/patterns/ListView.vue +2 -2
  182. package/tsconfig.json +17 -3
@@ -0,0 +1,17 @@
1
+ # ScrollArea
2
+ ## Skeleton Code
3
+ ```vue
4
+ <script setup>
5
+ import { ScrollArea } from '@reinvented/design'
6
+ </script>
7
+ <template>
8
+ <ScrollArea class="h-72 w-48 rounded-md border">
9
+ <div class="p-4">
10
+ <!-- Scrollable content -->
11
+ </div>
12
+ </ScrollArea>
13
+ </template>
14
+ ```
15
+ ## Gotchas
16
+ - Must have explicit height set via class
17
+ - Use instead of native scrollbars per DS rules
@@ -0,0 +1,31 @@
1
+ # Select
2
+ ## When to Use
3
+ - Single-value selection from a list of options
4
+ - When NOT to use: multi-select (use Checkbox group), binary toggle (use Switch)
5
+
6
+ ## Skeleton Code
7
+ ```vue
8
+ <script setup>
9
+ import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@reinvented/design'
10
+ </script>
11
+
12
+ <template>
13
+ <Select>
14
+ <SelectTrigger class="w-[180px]">
15
+ <SelectValue placeholder="Select a fruit" />
16
+ </SelectTrigger>
17
+ <SelectContent>
18
+ <SelectGroup>
19
+ <SelectLabel>Fruits</SelectLabel>
20
+ <SelectItem value="apple">Apple</SelectItem>
21
+ <SelectItem value="banana">Banana</SelectItem>
22
+ <SelectItem value="orange">Orange</SelectItem>
23
+ </SelectGroup>
24
+ </SelectContent>
25
+ </Select>
26
+ </template>
27
+ ```
28
+
29
+ ## Gotchas
30
+ - Use `placeholder` on `SelectValue` for the empty state text
31
+ - Supports `v-model` via `modelValue` prop on `Select`
@@ -0,0 +1,14 @@
1
+ # Separator
2
+ ## Skeleton Code
3
+ ```vue
4
+ <script setup>
5
+ import { Separator } from '@reinvented/design'
6
+ </script>
7
+ <template>
8
+ <Separator /> <!-- Horizontal -->
9
+ <Separator orientation="vertical" /> <!-- Vertical -->
10
+ </template>
11
+ ```
12
+ ## Gotchas
13
+ - Use between logical sections, not decoratively
14
+ - Vertical separators need a container with `flex` and explicit height
@@ -0,0 +1,32 @@
1
+ # Sheet
2
+ ## When to Use
3
+ - Side panels for details or filters
4
+ - Mobile navigation drawers
5
+ - Quick edit forms that need more space than a dialog
6
+
7
+ ## Skeleton Code
8
+ ```vue
9
+ <script setup>
10
+ import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger, Button } from '@reinvented/design'
11
+ </script>
12
+ <template>
13
+ <Sheet>
14
+ <SheetTrigger as-child>
15
+ <Button variant="outline">Open</Button>
16
+ </SheetTrigger>
17
+ <SheetContent>
18
+ <SheetHeader>
19
+ <SheetTitle>Edit Profile</SheetTitle>
20
+ <SheetDescription>Make changes to your profile here.</SheetDescription>
21
+ </SheetHeader>
22
+ <!-- Content here -->
23
+ </SheetContent>
24
+ </Sheet>
25
+ </template>
26
+ ```
27
+ ## Side Variants
28
+ Use `side` prop on `SheetContent`: `"top"`, `"bottom"`, `"left"`, `"right"` (default: `"right"`).
29
+
30
+ ## Gotchas
31
+ - Default width is `sm:max-w-sm` — override with class if wider content needed
32
+ - Mobile: use `side="bottom"` for bottom sheets
@@ -0,0 +1,20 @@
1
+ # Skeleton
2
+ ## Skeleton Code
3
+ ```vue
4
+ <script setup>
5
+ import { Skeleton } from '@reinvented/design'
6
+ </script>
7
+ <template>
8
+ <!-- Match shape of real content -->
9
+ <div class="flex items-center gap-3">
10
+ <Skeleton class="w-10 h-10 rounded-full" />
11
+ <div class="flex-1 space-y-2">
12
+ <Skeleton class="h-4 w-3/4" />
13
+ <Skeleton class="h-3 w-1/2" />
14
+ </div>
15
+ </div>
16
+ </template>
17
+ ```
18
+ ## Gotchas
19
+ - Must match the shape of actual content layout
20
+ - Never show bare spinner — always show skeletons matching the data shape
@@ -0,0 +1,33 @@
1
+ # Table
2
+ ## Sub-components
3
+ `Table`, `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell`, `TableCaption`
4
+
5
+ ## Skeleton Code
6
+ ```vue
7
+ <script setup>
8
+ import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from '@reinvented/design'
9
+ </script>
10
+ <template>
11
+ <Table>
12
+ <TableCaption>A list of your recent invoices.</TableCaption>
13
+ <TableHeader>
14
+ <TableRow>
15
+ <TableHead>Invoice</TableHead>
16
+ <TableHead>Status</TableHead>
17
+ <TableHead class="text-right">Amount</TableHead>
18
+ </TableRow>
19
+ </TableHeader>
20
+ <TableBody>
21
+ <TableRow v-for="item in items" :key="item.id">
22
+ <TableCell class="font-medium">{{ item.invoice }}</TableCell>
23
+ <TableCell>{{ item.status }}</TableCell>
24
+ <TableCell class="text-right">{{ item.amount }}</TableCell>
25
+ </TableRow>
26
+ </TableBody>
27
+ </Table>
28
+ </template>
29
+ ```
30
+ ## Gotchas
31
+ - Use `text-right` for numeric columns
32
+ - Use `font-medium` for the primary identifier column
33
+ - For empty state, show a full-width row with empty state message
@@ -0,0 +1,23 @@
1
+ # Tabs
2
+ ## Skeleton Code
3
+ ```vue
4
+ <script setup>
5
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@reinvented/design'
6
+ </script>
7
+ <template>
8
+ <Tabs default-value="overview">
9
+ <TabsList>
10
+ <TabsTrigger value="overview">Overview</TabsTrigger>
11
+ <TabsTrigger value="analytics">Analytics</TabsTrigger>
12
+ <TabsTrigger value="settings">Settings</TabsTrigger>
13
+ </TabsList>
14
+ <TabsContent value="overview">Overview content</TabsContent>
15
+ <TabsContent value="analytics">Analytics content</TabsContent>
16
+ <TabsContent value="settings">Settings content</TabsContent>
17
+ </Tabs>
18
+ </template>
19
+ ```
20
+ ## Gotchas
21
+ - Use `default-value` for uncontrolled, `v-model` for controlled
22
+ - Tab values must be unique strings
23
+ - Keep tab labels short (1-2 words)
@@ -0,0 +1,70 @@
1
+ # Dashboard Layout
2
+
3
+ ## When to Use
4
+ - App home/overview pages
5
+ - Stats summaries with key metrics
6
+ - Quick-access to recent items
7
+
8
+ ## Skeleton Code
9
+
10
+ ```vue
11
+ <script setup>
12
+ import {
13
+ Card, CardContent, CardDescription, CardHeader, CardTitle, Skeleton,
14
+ } from '@reinvented/design'
15
+ import { Activity, Users, CreditCard, DollarSign } from 'lucide-vue-next'
16
+ </script>
17
+
18
+ <template>
19
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 space-y-6">
20
+
21
+ <!-- Page Header -->
22
+ <div>
23
+ <h1 class="text-2xl font-bold tracking-tight">Dashboard</h1>
24
+ <p class="text-muted-foreground">Overview of your workspace.</p>
25
+ </div>
26
+
27
+ <!-- Stats Grid -->
28
+ <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
29
+ <Card>
30
+ <CardHeader class="flex flex-row items-center justify-between pb-2">
31
+ <CardTitle class="text-sm font-medium">Total Revenue</CardTitle>
32
+ <DollarSign class="h-4 w-4 text-muted-foreground" />
33
+ </CardHeader>
34
+ <CardContent>
35
+ <p class="text-2xl font-bold">$45,231</p>
36
+ <p class="text-xs text-muted-foreground">+20.1% from last month</p>
37
+ </CardContent>
38
+ </Card>
39
+ <!-- Repeat for other stats -->
40
+ </div>
41
+
42
+ <!-- Content Grid -->
43
+ <div class="grid gap-6 md:grid-cols-2 lg:grid-cols-7">
44
+ <Card class="col-span-4">
45
+ <CardHeader>
46
+ <CardTitle>Overview</CardTitle>
47
+ </CardHeader>
48
+ <CardContent>
49
+ <!-- Chart or main content -->
50
+ </CardContent>
51
+ </Card>
52
+ <Card class="col-span-3">
53
+ <CardHeader>
54
+ <CardTitle>Recent Activity</CardTitle>
55
+ <CardDescription>Latest actions in your workspace.</CardDescription>
56
+ </CardHeader>
57
+ <CardContent>
58
+ <!-- Activity list -->
59
+ </CardContent>
60
+ </Card>
61
+ </div>
62
+ </div>
63
+ </template>
64
+ ```
65
+
66
+ ## Key Patterns
67
+ - **Stats row**: 4-column grid of metric cards
68
+ - **Content grid**: Asymmetric grid (4/7 + 3/7) for main content + sidebar
69
+ - **Card headers**: Icon + title aligned horizontally
70
+ - **Responsive**: Stack to 2-col then 1-col on smaller screens
@@ -0,0 +1,83 @@
1
+ # Detail Page Layout
2
+
3
+ ## When to Use
4
+ - Viewing a single item's complete information
5
+ - Item detail with related data sections
6
+ - Edit-in-place forms
7
+
8
+ ## Skeleton Code
9
+
10
+ ```vue
11
+ <script setup>
12
+ import {
13
+ Button, Badge, Separator, Tabs, TabsContent, TabsList, TabsTrigger,
14
+ Card, CardContent, CardHeader, CardTitle, Skeleton,
15
+ Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator,
16
+ } from '@reinvented/design'
17
+ import { ArrowLeft, Pencil, Trash2 } from 'lucide-vue-next'
18
+
19
+ const item = ref(null)
20
+ const loading = ref(true)
21
+ </script>
22
+
23
+ <template>
24
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 space-y-6">
25
+
26
+ <!-- Breadcrumb -->
27
+ <Breadcrumb>
28
+ <BreadcrumbList>
29
+ <BreadcrumbItem><BreadcrumbLink href="/items">Items</BreadcrumbLink></BreadcrumbItem>
30
+ <BreadcrumbSeparator />
31
+ <BreadcrumbItem><BreadcrumbPage>{{ item?.name }}</BreadcrumbPage></BreadcrumbItem>
32
+ </BreadcrumbList>
33
+ </Breadcrumb>
34
+
35
+ <!-- Page Header -->
36
+ <div class="flex items-center justify-between">
37
+ <div class="flex items-center gap-3">
38
+ <h1 class="text-2xl font-bold tracking-tight">{{ item?.name }}</h1>
39
+ <Badge>{{ item?.status }}</Badge>
40
+ </div>
41
+ <div class="flex items-center gap-2">
42
+ <Button variant="outline"><Pencil class="mr-2 h-4 w-4" /> Edit</Button>
43
+ <Button variant="destructive"><Trash2 class="mr-2 h-4 w-4" /> Delete</Button>
44
+ </div>
45
+ </div>
46
+
47
+ <Separator />
48
+
49
+ <!-- Tabbed Content -->
50
+ <Tabs default-value="overview">
51
+ <TabsList>
52
+ <TabsTrigger value="overview">Overview</TabsTrigger>
53
+ <TabsTrigger value="activity">Activity</TabsTrigger>
54
+ <TabsTrigger value="settings">Settings</TabsTrigger>
55
+ </TabsList>
56
+
57
+ <TabsContent value="overview" class="space-y-6">
58
+ <!-- Detail Cards -->
59
+ <div class="grid gap-6 md:grid-cols-2">
60
+ <Card>
61
+ <CardHeader><CardTitle>Details</CardTitle></CardHeader>
62
+ <CardContent>
63
+ <dl class="space-y-3">
64
+ <div>
65
+ <dt class="text-sm text-muted-foreground">Created</dt>
66
+ <dd class="text-sm font-medium">{{ item?.createdAt }}</dd>
67
+ </div>
68
+ </dl>
69
+ </CardContent>
70
+ </Card>
71
+ </div>
72
+ </TabsContent>
73
+ </Tabs>
74
+ </div>
75
+ </template>
76
+ ```
77
+
78
+ ## Key Patterns
79
+ - **Breadcrumb** at the top for back navigation
80
+ - **Header**: Title + badge + action buttons
81
+ - **Tabbed sections** for detailed content
82
+ - **Detail cards** in a 2-column grid for metadata
83
+ - **Separator** between header and tabbed content
@@ -1,32 +1,45 @@
1
- # Layouts Index
1
+ # Layout Documentation
2
2
 
3
- Page-level layout components with slots. Each layout is a Vue component in `src/layouts/` AND documented here with skeleton code and usage guidance.
3
+ ## Decision Tree
4
+
5
+ Use this tree to choose the right layout for each view:
6
+
7
+ ```
8
+ Is this a list of items?
9
+ ├─ Yes → List Page (list-page.md)
10
+ ├─ No
11
+ │ ├─ Is this showing a single item's details?
12
+ │ │ ├─ Yes → Detail Page (detail-page.md)
13
+ │ │ ├─ No
14
+ │ │ │ ├─ Is this a dashboard/overview?
15
+ │ │ │ │ ├─ Yes → Dashboard (dashboard.md)
16
+ │ │ │ │ ├─ No
17
+ │ │ │ │ │ ├─ Is this a settings/configuration page?
18
+ │ │ │ │ │ │ ├─ Yes → Settings Page (settings-page.md)
19
+ │ │ │ │ │ │ ├─ No
20
+ │ │ │ │ │ │ │ ├─ Is this a multi-step process?
21
+ │ │ │ │ │ │ │ │ ├─ Yes → Step Wizard (step-wizard.md)
22
+ │ │ │ │ │ │ │ │ ├─ No
23
+ │ │ │ │ │ │ │ │ │ ├─ Is this a simple form?
24
+ │ │ │ │ │ │ │ │ │ │ ├─ ≤5 fields → Modal Form (use Dialog)
25
+ │ │ │ │ │ │ │ │ │ │ ├─ >5 fields → Full Page Form (detail-page.md variant)
26
+ ```
4
27
 
5
28
  ## Available Layouts
6
29
 
7
30
  | Layout | File | Use for |
8
31
  |--------|------|---------|
9
- | [List Page](list-page.md) | `list-page.md` | Browsing collections (tasks, members, notifications) |
10
- | [Detail Page](detail-page.md) | `detail-page.md` | Viewing a single item with full context |
11
- | [Dashboard](dashboard.md) | `dashboard.md` | Overview with stats, charts, recent activity |
12
- | [Modal Form](modal-form.md) | `modal-form.md` | Create/edit dialogs with form fields |
13
- | [Settings Page](settings-page.md) | `settings-page.md` | Configuration with sectioned form |
14
-
15
- ## Choosing a Layout
16
-
17
- ```
18
- What is the user doing?
19
- ├── Browsing a list of things → List Page
20
- ├── Looking at one specific thing → Detail Page
21
- ├── Getting an overview / summary → Dashboard
22
- ├── Creating or editing something → Modal Form (default) or Settings Page (complex)
23
- └── Configuring settings → Settings Page
24
- ```
32
+ | [List Page](list-page.md) | | Filterable, searchable lists of items |
33
+ | [Detail Page](detail-page.md) | | Single item view with actions |
34
+ | [Dashboard](dashboard.md) | | Overview grids with stats and summaries |
35
+ | [Settings Page](settings-page.md) | | Configuration with sidebar nav |
36
+ | [Step Wizard](step-wizard.md) | | Multi-step guided processes |
37
+ | Modal Form | — | Use Dialog component (≤5 fields) |
25
38
 
26
- ## Layout Component Structure
39
+ ## General Layout Rules
27
40
 
28
- All layout components follow the same convention:
29
- - Accept a `class` prop for customization
30
- - Use named slots for content areas (header, content, footer, etc.)
31
- - Handle responsive breakpoints internally
32
- - Use DS tokens for spacing and typography
41
+ 1. **Max content width**: `max-w-7xl mx-auto` for main content
42
+ 2. **Page padding**: `px-4 sm:px-6 lg:px-8`
43
+ 3. **Section spacing**: `space-y-6` between major sections
44
+ 4. **Page header pattern**: Title + description + primary action
45
+ 5. **Responsive**: All layouts must work at mobile (320px+), tablet (768px+), desktop (1024px+)
@@ -0,0 +1,107 @@
1
+ # List Page Layout
2
+
3
+ ## When to Use
4
+ - Browse a collection of items (tasks, users, apps)
5
+ - Filterable, searchable, sortable data
6
+ - Paginated or infinite-scroll lists
7
+
8
+ ## Skeleton Code
9
+
10
+ ```vue
11
+ <script setup>
12
+ import { ref } from 'vue'
13
+ import {
14
+ Button, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
15
+ Card, CardContent, Badge, Skeleton,
16
+ DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger,
17
+ } from '@reinvented/design'
18
+ import { Plus, Search, MoreHorizontal } from 'lucide-vue-next'
19
+
20
+ const search = ref('')
21
+ const filter = ref('all')
22
+ const items = ref([]) // from GraphQL query
23
+ const loading = ref(true)
24
+ </script>
25
+
26
+ <template>
27
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 space-y-6">
28
+
29
+ <!-- Page Header -->
30
+ <div class="flex items-center justify-between">
31
+ <div>
32
+ <h1 class="text-2xl font-bold tracking-tight">Items</h1>
33
+ <p class="text-muted-foreground">Manage your items.</p>
34
+ </div>
35
+ <Button><Plus class="mr-2 h-4 w-4" /> New Item</Button>
36
+ </div>
37
+
38
+ <!-- Filters Bar -->
39
+ <div class="flex items-center gap-4">
40
+ <div class="relative flex-1 max-w-sm">
41
+ <Search class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
42
+ <Input v-model="search" class="pl-9" placeholder="Search items..." />
43
+ </div>
44
+ <Select v-model="filter">
45
+ <SelectTrigger class="w-[150px]">
46
+ <SelectValue placeholder="Filter" />
47
+ </SelectTrigger>
48
+ <SelectContent>
49
+ <SelectItem value="all">All</SelectItem>
50
+ <SelectItem value="active">Active</SelectItem>
51
+ <SelectItem value="archived">Archived</SelectItem>
52
+ </SelectContent>
53
+ </Select>
54
+ </div>
55
+
56
+ <!-- Loading State -->
57
+ <div v-if="loading" class="space-y-3">
58
+ <Skeleton v-for="i in 5" :key="i" class="h-16 w-full rounded-lg" />
59
+ </div>
60
+
61
+ <!-- Empty State -->
62
+ <div v-else-if="items.length === 0" class="flex flex-col items-center justify-center py-12 text-center">
63
+ <div class="rounded-full bg-muted p-4 mb-4">
64
+ <Search class="h-8 w-8 text-muted-foreground" />
65
+ </div>
66
+ <h3 class="text-lg font-semibold">No items found</h3>
67
+ <p class="text-muted-foreground mt-1">Get started by creating your first item.</p>
68
+ <Button class="mt-4"><Plus class="mr-2 h-4 w-4" /> Create Item</Button>
69
+ </div>
70
+
71
+ <!-- Data State -->
72
+ <div v-else class="space-y-3">
73
+ <Card v-for="item in items" :key="item.id" class="hover:shadow-sm transition-shadow">
74
+ <CardContent class="flex items-center justify-between p-4">
75
+ <div class="flex items-center gap-3">
76
+ <div>
77
+ <p class="font-medium">{{ item.name }}</p>
78
+ <p class="text-sm text-muted-foreground">{{ item.description }}</p>
79
+ </div>
80
+ </div>
81
+ <div class="flex items-center gap-2">
82
+ <Badge>{{ item.status }}</Badge>
83
+ <DropdownMenu>
84
+ <DropdownMenuTrigger as-child>
85
+ <Button variant="ghost" size="icon">
86
+ <MoreHorizontal class="h-4 w-4" />
87
+ </Button>
88
+ </DropdownMenuTrigger>
89
+ <DropdownMenuContent align="end">
90
+ <DropdownMenuItem>Edit</DropdownMenuItem>
91
+ <DropdownMenuItem class="text-destructive">Delete</DropdownMenuItem>
92
+ </DropdownMenuContent>
93
+ </DropdownMenu>
94
+ </div>
95
+ </CardContent>
96
+ </Card>
97
+ </div>
98
+ </div>
99
+ </template>
100
+ ```
101
+
102
+ ## Key Patterns
103
+ - **Header**: Title + description + primary CTA
104
+ - **Filters**: Search + dropdown filters in a row
105
+ - **Three states**: Loading (skeletons), empty, data
106
+ - **Item cards**: Name + description + badge + action menu
107
+ - **Empty state**: Icon + message + CTA
@@ -0,0 +1,79 @@
1
+ # Settings Page Layout
2
+
3
+ ## When to Use
4
+ - User preferences
5
+ - App configuration
6
+ - Account management
7
+
8
+ ## Skeleton Code
9
+
10
+ ```vue
11
+ <script setup>
12
+ import {
13
+ Button, Input, Label, Separator, Switch, Textarea,
14
+ Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle,
15
+ } from '@reinvented/design'
16
+ </script>
17
+
18
+ <template>
19
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
20
+ <div class="flex flex-col md:flex-row gap-8">
21
+
22
+ <!-- Sidebar Nav -->
23
+ <nav class="w-full md:w-48 space-y-1">
24
+ <a v-for="section in sections" :key="section.id"
25
+ :href="`#${section.id}`"
26
+ class="block rounded-md px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-muted hover:text-foreground"
27
+ :class="{ 'bg-muted text-foreground': activeSection === section.id }">
28
+ {{ section.label }}
29
+ </a>
30
+ </nav>
31
+
32
+ <!-- Settings Content -->
33
+ <div class="flex-1 space-y-6 max-w-2xl">
34
+ <Card id="profile">
35
+ <CardHeader>
36
+ <CardTitle>Profile</CardTitle>
37
+ <CardDescription>Update your personal information.</CardDescription>
38
+ </CardHeader>
39
+ <CardContent class="space-y-4">
40
+ <div class="space-y-2">
41
+ <Label for="name">Name</Label>
42
+ <Input id="name" placeholder="Your name" />
43
+ </div>
44
+ <div class="space-y-2">
45
+ <Label for="bio">Bio</Label>
46
+ <Textarea id="bio" placeholder="About you" />
47
+ </div>
48
+ </CardContent>
49
+ <CardFooter>
50
+ <Button>Save Changes</Button>
51
+ </CardFooter>
52
+ </Card>
53
+
54
+ <Card id="notifications">
55
+ <CardHeader>
56
+ <CardTitle>Notifications</CardTitle>
57
+ <CardDescription>Choose what notifications you receive.</CardDescription>
58
+ </CardHeader>
59
+ <CardContent class="space-y-4">
60
+ <div class="flex items-center justify-between">
61
+ <div>
62
+ <p class="text-sm font-medium">Email notifications</p>
63
+ <p class="text-sm text-muted-foreground">Receive updates via email.</p>
64
+ </div>
65
+ <Switch />
66
+ </div>
67
+ </CardContent>
68
+ </Card>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </template>
73
+ ```
74
+
75
+ ## Key Patterns
76
+ - **Sidebar nav** on left, content on right
77
+ - **Each section** is a Card with header + form fields + save button
78
+ - **Switch rows**: Label + description on left, Switch on right
79
+ - **Mobile**: sidebar stacks above content
@@ -0,0 +1,73 @@
1
+ # Step Wizard Layout
2
+
3
+ ## When to Use
4
+ - Multi-step processes (onboarding, app creation, checkout)
5
+ - 3–7 steps where each depends on the previous
6
+
7
+ ## Skeleton Code
8
+
9
+ ```vue
10
+ <script setup>
11
+ import { ref, computed } from 'vue'
12
+ import { Button, Card, CardContent, CardFooter, CardHeader, CardTitle, Progress } from '@reinvented/design'
13
+ import { Check } from 'lucide-vue-next'
14
+
15
+ const currentStep = ref(0)
16
+ const steps = [
17
+ { title: 'Details', component: 'StepDetails' },
18
+ { title: 'Configuration', component: 'StepConfig' },
19
+ { title: 'Review', component: 'StepReview' },
20
+ ]
21
+ const progress = computed(() => ((currentStep.value + 1) / steps.length) * 100)
22
+ </script>
23
+
24
+ <template>
25
+ <div class="max-w-2xl mx-auto px-4 py-8 space-y-8">
26
+
27
+ <!-- Step Indicator -->
28
+ <div class="space-y-4">
29
+ <Progress :model-value="progress" />
30
+ <div class="flex justify-between">
31
+ <div v-for="(step, i) in steps" :key="i" class="flex items-center gap-2 text-sm">
32
+ <div
33
+ class="flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium"
34
+ :class="i <= currentStep ? 'bg-primary text-primary-foreground' : 'bg-muted text-muted-foreground'"
35
+ >
36
+ <Check v-if="i < currentStep" class="h-3 w-3" />
37
+ <span v-else>{{ i + 1 }}</span>
38
+ </div>
39
+ <span :class="i <= currentStep ? 'text-foreground' : 'text-muted-foreground'">{{ step.title }}</span>
40
+ </div>
41
+ </div>
42
+ </div>
43
+
44
+ <!-- Step Content -->
45
+ <Card>
46
+ <CardHeader>
47
+ <CardTitle>{{ steps[currentStep].title }}</CardTitle>
48
+ </CardHeader>
49
+ <CardContent>
50
+ <component :is="steps[currentStep].component" />
51
+ </CardContent>
52
+ <CardFooter class="flex justify-between">
53
+ <Button variant="outline" :disabled="currentStep === 0" @click="currentStep--">
54
+ Previous
55
+ </Button>
56
+ <Button v-if="currentStep < steps.length - 1" @click="currentStep++">
57
+ Next
58
+ </Button>
59
+ <Button v-else @click="submit">
60
+ Complete
61
+ </Button>
62
+ </CardFooter>
63
+ </Card>
64
+ </div>
65
+ </template>
66
+ ```
67
+
68
+ ## Key Patterns
69
+ - **Progress bar** + step circles at top
70
+ - **Single card** with dynamic content
71
+ - **Previous/Next** buttons in card footer
72
+ - **Narrower max-width** than other layouts (`max-w-2xl`)
73
+ - Completed steps show ✓, current step highlighted
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reinvented/design",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "exports": {