@reinvented/design 0.2.0 → 0.3.0
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.
- package/README.md +105 -0
- package/docs/components/alert-dialog.md +32 -0
- package/docs/components/avatar.md +14 -0
- package/docs/components/badge.md +24 -0
- package/docs/components/button.md +69 -0
- package/docs/components/card.md +49 -0
- package/docs/components/dialog.md +46 -0
- package/docs/components/dropdown-menu.md +32 -0
- package/docs/components/index.md +69 -50
- package/docs/components/input.md +34 -0
- package/docs/components/remaining-components.md +253 -0
- package/docs/components/scroll-area.md +17 -0
- package/docs/components/select.md +31 -0
- package/docs/components/separator.md +14 -0
- package/docs/components/sheet.md +32 -0
- package/docs/components/skeleton.md +20 -0
- package/docs/components/table.md +33 -0
- package/docs/components/tabs.md +23 -0
- package/docs/layouts/dashboard.md +70 -0
- package/docs/layouts/detail-page.md +83 -0
- package/docs/layouts/index.md +37 -24
- package/docs/layouts/list-page.md +107 -0
- package/docs/layouts/settings-page.md +79 -0
- package/docs/layouts/step-wizard.md +73 -0
- package/package.json +7 -3
- package/src/components/ui/accordion/Accordion.vue +13 -0
- package/src/components/ui/accordion/AccordionContent.vue +20 -0
- package/src/components/ui/accordion/AccordionItem.vue +15 -0
- package/src/components/ui/accordion/AccordionTrigger.vue +25 -0
- package/src/components/ui/accordion/index.ts +4 -0
- package/src/components/ui/alert/Alert.vue +38 -0
- package/src/components/ui/alert/AlertDescription.vue +12 -0
- package/src/components/ui/alert/AlertTitle.vue +12 -0
- package/src/components/ui/alert/index.ts +3 -0
- package/src/components/ui/alert-dialog/AlertDialog.vue +13 -0
- package/src/components/ui/alert-dialog/AlertDialogAction.vue +21 -0
- package/src/components/ui/alert-dialog/AlertDialogCancel.vue +21 -0
- package/src/components/ui/alert-dialog/AlertDialogContent.vue +39 -0
- package/src/components/ui/alert-dialog/AlertDialogDescription.vue +15 -0
- package/src/components/ui/alert-dialog/AlertDialogFooter.vue +12 -0
- package/src/components/ui/alert-dialog/AlertDialogHeader.vue +12 -0
- package/src/components/ui/alert-dialog/AlertDialogTitle.vue +15 -0
- package/src/components/ui/alert-dialog/AlertDialogTrigger.vue +11 -0
- package/src/components/ui/alert-dialog/index.ts +9 -0
- package/src/components/ui/breadcrumb/Breadcrumb.vue +6 -0
- package/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +12 -0
- package/src/components/ui/breadcrumb/BreadcrumbItem.vue +6 -0
- package/src/components/ui/breadcrumb/BreadcrumbLink.vue +20 -0
- package/src/components/ui/breadcrumb/BreadcrumbList.vue +6 -0
- package/src/components/ui/breadcrumb/BreadcrumbPage.vue +6 -0
- package/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +11 -0
- package/src/components/ui/breadcrumb/index.ts +7 -0
- package/src/components/ui/button/Button.vue +0 -1
- package/src/components/ui/checkbox/Checkbox.vue +25 -0
- package/src/components/ui/checkbox/index.ts +1 -0
- package/src/components/ui/collapsible/Collapsible.vue +13 -0
- package/src/components/ui/collapsible/index.ts +2 -0
- package/src/components/ui/command/Command.vue +16 -0
- package/src/components/ui/command/CommandEmpty.vue +5 -0
- package/src/components/ui/command/CommandGroup.vue +22 -0
- package/src/components/ui/command/CommandInput.vue +21 -0
- package/src/components/ui/command/CommandItem.vue +22 -0
- package/src/components/ui/command/CommandList.vue +17 -0
- package/src/components/ui/command/CommandSeparator.vue +5 -0
- package/src/components/ui/command/index.ts +7 -0
- package/src/components/ui/context-menu/ContextMenuContent.vue +24 -0
- package/src/components/ui/context-menu/ContextMenuItem.vue +16 -0
- package/src/components/ui/context-menu/ContextMenuLabel.vue +9 -0
- package/src/components/ui/context-menu/ContextMenuSeparator.vue +9 -0
- package/src/components/ui/context-menu/ContextMenuSubContent.vue +14 -0
- package/src/components/ui/context-menu/index.ts +9 -0
- package/src/components/ui/dialog/Dialog.vue +14 -0
- package/src/components/ui/dialog/DialogClose.vue +12 -0
- package/src/components/ui/dialog/DialogContent.vue +48 -0
- package/src/components/ui/dialog/DialogDescription.vue +23 -0
- package/src/components/ui/dialog/DialogFooter.vue +12 -0
- package/src/components/ui/dialog/DialogHeader.vue +12 -0
- package/src/components/ui/dialog/DialogScrollContent.vue +47 -0
- package/src/components/ui/dialog/DialogTitle.vue +23 -0
- package/src/components/ui/dialog/DialogTrigger.vue +12 -0
- package/src/components/ui/dialog/index.ts +9 -0
- package/src/components/ui/dropdown-menu/DropdownMenu.vue +13 -0
- package/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +28 -0
- package/src/components/ui/dropdown-menu/DropdownMenuContent.vue +33 -0
- package/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +11 -0
- package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +27 -0
- package/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +23 -0
- package/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +13 -0
- package/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +27 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +13 -0
- package/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +12 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSub.vue +13 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +27 -0
- package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +23 -0
- package/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +11 -0
- package/src/components/ui/dropdown-menu/index.ts +14 -0
- package/src/components/ui/form/FormControl.vue +3 -0
- package/src/components/ui/form/FormDescription.vue +6 -0
- package/src/components/ui/form/FormItem.vue +6 -0
- package/src/components/ui/form/FormLabel.vue +10 -0
- package/src/components/ui/form/FormMessage.vue +10 -0
- package/src/components/ui/form/index.ts +9 -0
- package/src/components/ui/hover-card/HoverCard.vue +13 -0
- package/src/components/ui/hover-card/HoverCardContent.vue +26 -0
- package/src/components/ui/hover-card/HoverCardTrigger.vue +11 -0
- package/src/components/ui/hover-card/index.ts +3 -0
- package/src/components/ui/label/Label.vue +18 -0
- package/src/components/ui/label/index.ts +1 -0
- package/src/components/ui/menubar/MenubarContent.vue +15 -0
- package/src/components/ui/menubar/MenubarItem.vue +13 -0
- package/src/components/ui/menubar/MenubarTrigger.vue +13 -0
- package/src/components/ui/menubar/index.ts +5 -0
- package/src/components/ui/navigation-menu/NavigationMenuContent.vue +14 -0
- package/src/components/ui/navigation-menu/NavigationMenuTrigger.vue +15 -0
- package/src/components/ui/navigation-menu/index.ts +4 -0
- package/src/components/ui/pagination/PaginationContent.vue +13 -0
- package/src/components/ui/pagination/PaginationEllipsis.vue +12 -0
- package/src/components/ui/pagination/PaginationNext.vue +14 -0
- package/src/components/ui/pagination/PaginationPrev.vue +14 -0
- package/src/components/ui/pagination/index.ts +6 -0
- package/src/components/ui/popover/Popover.vue +13 -0
- package/src/components/ui/popover/PopoverContent.vue +27 -0
- package/src/components/ui/popover/PopoverTrigger.vue +11 -0
- package/src/components/ui/popover/index.ts +3 -0
- package/src/components/ui/progress/Progress.vue +21 -0
- package/src/components/ui/progress/index.ts +1 -0
- package/src/components/ui/radio-group/RadioGroup.vue +16 -0
- package/src/components/ui/radio-group/RadioGroupItem.vue +24 -0
- package/src/components/ui/radio-group/index.ts +2 -0
- package/src/components/ui/select/Select.vue +13 -0
- package/src/components/ui/select/SelectContent.vue +40 -0
- package/src/components/ui/select/SelectGroup.vue +15 -0
- package/src/components/ui/select/SelectItem.vue +30 -0
- package/src/components/ui/select/SelectLabel.vue +15 -0
- package/src/components/ui/select/SelectSeparator.vue +13 -0
- package/src/components/ui/select/SelectTrigger.vue +23 -0
- package/src/components/ui/select/SelectValue.vue +11 -0
- package/src/components/ui/select/index.ts +8 -0
- package/src/components/ui/sheet/Sheet.vue +13 -0
- package/src/components/ui/sheet/SheetClose.vue +11 -0
- package/src/components/ui/sheet/SheetContent.vue +65 -0
- package/src/components/ui/sheet/SheetDescription.vue +15 -0
- package/src/components/ui/sheet/SheetFooter.vue +12 -0
- package/src/components/ui/sheet/SheetHeader.vue +12 -0
- package/src/components/ui/sheet/SheetTitle.vue +15 -0
- package/src/components/ui/sheet/SheetTrigger.vue +11 -0
- package/src/components/ui/sheet/index.ts +8 -0
- package/src/components/ui/slider/Slider.vue +26 -0
- package/src/components/ui/slider/index.ts +1 -0
- package/src/components/ui/switch/Switch.vue +24 -0
- package/src/components/ui/switch/index.ts +1 -0
- package/src/components/ui/table/Table.vue +13 -0
- package/src/components/ui/table/TableBody.vue +6 -0
- package/src/components/ui/table/TableCaption.vue +6 -0
- package/src/components/ui/table/TableCell.vue +6 -0
- package/src/components/ui/table/TableFooter.vue +6 -0
- package/src/components/ui/table/TableHead.vue +6 -0
- package/src/components/ui/table/TableHeader.vue +6 -0
- package/src/components/ui/table/TableRow.vue +6 -0
- package/src/components/ui/table/index.ts +8 -0
- package/src/components/ui/tabs/Tabs.vue +13 -0
- package/src/components/ui/tabs/TabsContent.vue +21 -0
- package/src/components/ui/tabs/TabsList.vue +21 -0
- package/src/components/ui/tabs/TabsTrigger.vue +21 -0
- package/src/components/ui/tabs/index.ts +4 -0
- package/src/components/ui/textarea/Textarea.vue +29 -0
- package/src/components/ui/textarea/index.ts +1 -0
- package/src/components/ui/toggle/Toggle.vue +40 -0
- package/src/components/ui/toggle/index.ts +1 -0
- package/src/components/ui/toggle-group/ToggleGroup.vue +16 -0
- package/src/components/ui/toggle-group/ToggleGroupItem.vue +21 -0
- package/src/components/ui/toggle-group/index.ts +2 -0
- package/src/components/ui/tooltip/Tooltip.vue +13 -0
- package/src/components/ui/tooltip/TooltipContent.vue +27 -0
- package/src/components/ui/tooltip/TooltipProvider.vue +12 -0
- package/src/components/ui/tooltip/TooltipTrigger.vue +11 -0
- package/src/components/ui/tooltip/index.ts +4 -0
- package/src/eslint/index.js +192 -0
- package/src/eslint/recommended.js +64 -0
- package/src/index.ts +46 -192
- package/src/patterns/DetailView.vue +2 -2
- package/src/patterns/EmptyState.vue +2 -2
- package/src/patterns/FormView.vue +2 -2
- package/src/patterns/ListView.vue +2 -2
- package/tsconfig.json +17 -3
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# Tooltip
|
|
2
|
+
## Skeleton Code
|
|
3
|
+
```vue
|
|
4
|
+
<script setup>
|
|
5
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Button } from '@reinvented/design'
|
|
6
|
+
</script>
|
|
7
|
+
<template>
|
|
8
|
+
<TooltipProvider>
|
|
9
|
+
<Tooltip>
|
|
10
|
+
<TooltipTrigger as-child>
|
|
11
|
+
<Button variant="ghost" size="icon"><Settings class="w-4 h-4" /></Button>
|
|
12
|
+
</TooltipTrigger>
|
|
13
|
+
<TooltipContent><p>Settings</p></TooltipContent>
|
|
14
|
+
</Tooltip>
|
|
15
|
+
</TooltipProvider>
|
|
16
|
+
</template>
|
|
17
|
+
```
|
|
18
|
+
## Gotchas
|
|
19
|
+
- Wrap the app root with `<TooltipProvider>` once
|
|
20
|
+
- Use for icon-only buttons to provide text labels
|
|
21
|
+
- Keep tooltip text to 1-2 words
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Popover
|
|
26
|
+
## Skeleton Code
|
|
27
|
+
```vue
|
|
28
|
+
<script setup>
|
|
29
|
+
import { Popover, PopoverContent, PopoverTrigger, Button } from '@reinvented/design'
|
|
30
|
+
</script>
|
|
31
|
+
<template>
|
|
32
|
+
<Popover>
|
|
33
|
+
<PopoverTrigger as-child>
|
|
34
|
+
<Button variant="outline">Open</Button>
|
|
35
|
+
</PopoverTrigger>
|
|
36
|
+
<PopoverContent class="w-80">
|
|
37
|
+
<div class="grid gap-4">
|
|
38
|
+
<h4 class="font-medium leading-none">Dimensions</h4>
|
|
39
|
+
<p class="text-sm text-muted-foreground">Set the dimensions for the layer.</p>
|
|
40
|
+
</div>
|
|
41
|
+
</PopoverContent>
|
|
42
|
+
</Popover>
|
|
43
|
+
</template>
|
|
44
|
+
```
|
|
45
|
+
## Gotchas
|
|
46
|
+
- Override width with class on `PopoverContent`
|
|
47
|
+
- Default alignment is `center` — use `align="start"` or `align="end"` as needed
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
# HoverCard
|
|
52
|
+
## Skeleton Code
|
|
53
|
+
```vue
|
|
54
|
+
<script setup>
|
|
55
|
+
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@reinvented/design'
|
|
56
|
+
</script>
|
|
57
|
+
<template>
|
|
58
|
+
<HoverCard>
|
|
59
|
+
<HoverCardTrigger as-child>
|
|
60
|
+
<a href="/user/janakan" class="underline">@janakan</a>
|
|
61
|
+
</HoverCardTrigger>
|
|
62
|
+
<HoverCardContent class="w-80">
|
|
63
|
+
<div class="flex justify-between gap-4">
|
|
64
|
+
<!-- User preview card content -->
|
|
65
|
+
</div>
|
|
66
|
+
</HoverCardContent>
|
|
67
|
+
</HoverCard>
|
|
68
|
+
</template>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
# Alert
|
|
74
|
+
## Variants
|
|
75
|
+
| Variant | Use for |
|
|
76
|
+
|---------|---------|
|
|
77
|
+
| `default` | Informational notices |
|
|
78
|
+
| `destructive` | Errors, critical warnings |
|
|
79
|
+
|
|
80
|
+
## Skeleton Code
|
|
81
|
+
```vue
|
|
82
|
+
<script setup>
|
|
83
|
+
import { Alert, AlertDescription, AlertTitle } from '@reinvented/design'
|
|
84
|
+
import { AlertCircle } from 'lucide-vue-next'
|
|
85
|
+
</script>
|
|
86
|
+
<template>
|
|
87
|
+
<Alert variant="destructive">
|
|
88
|
+
<AlertCircle class="h-4 w-4" />
|
|
89
|
+
<AlertTitle>Error</AlertTitle>
|
|
90
|
+
<AlertDescription>Something went wrong.</AlertDescription>
|
|
91
|
+
</Alert>
|
|
92
|
+
</template>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
# Form Components
|
|
98
|
+
|
|
99
|
+
## Label
|
|
100
|
+
```vue
|
|
101
|
+
<script setup>
|
|
102
|
+
import { Label } from '@reinvented/design'
|
|
103
|
+
</script>
|
|
104
|
+
<template><Label for="email">Email</Label></template>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Textarea
|
|
108
|
+
```vue
|
|
109
|
+
<script setup>
|
|
110
|
+
import { Textarea, Label } from '@reinvented/design'
|
|
111
|
+
</script>
|
|
112
|
+
<template>
|
|
113
|
+
<div class="space-y-2">
|
|
114
|
+
<Label for="bio">Bio</Label>
|
|
115
|
+
<Textarea id="bio" placeholder="Tell us about yourself" />
|
|
116
|
+
</div>
|
|
117
|
+
</template>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Switch
|
|
121
|
+
```vue
|
|
122
|
+
<script setup>
|
|
123
|
+
import { Switch, Label } from '@reinvented/design'
|
|
124
|
+
</script>
|
|
125
|
+
<template>
|
|
126
|
+
<div class="flex items-center gap-2">
|
|
127
|
+
<Switch id="dark-mode" />
|
|
128
|
+
<Label for="dark-mode">Dark mode</Label>
|
|
129
|
+
</div>
|
|
130
|
+
</template>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Checkbox
|
|
134
|
+
```vue
|
|
135
|
+
<script setup>
|
|
136
|
+
import { Checkbox, Label } from '@reinvented/design'
|
|
137
|
+
</script>
|
|
138
|
+
<template>
|
|
139
|
+
<div class="flex items-center gap-2">
|
|
140
|
+
<Checkbox id="terms" />
|
|
141
|
+
<Label for="terms">Accept terms and conditions</Label>
|
|
142
|
+
</div>
|
|
143
|
+
</template>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## RadioGroup
|
|
147
|
+
```vue
|
|
148
|
+
<script setup>
|
|
149
|
+
import { RadioGroup, RadioGroupItem, Label } from '@reinvented/design'
|
|
150
|
+
</script>
|
|
151
|
+
<template>
|
|
152
|
+
<RadioGroup default-value="comfortable">
|
|
153
|
+
<div class="flex items-center gap-2">
|
|
154
|
+
<RadioGroupItem value="default" id="r1" />
|
|
155
|
+
<Label for="r1">Default</Label>
|
|
156
|
+
</div>
|
|
157
|
+
<div class="flex items-center gap-2">
|
|
158
|
+
<RadioGroupItem value="comfortable" id="r2" />
|
|
159
|
+
<Label for="r2">Comfortable</Label>
|
|
160
|
+
</div>
|
|
161
|
+
</RadioGroup>
|
|
162
|
+
</template>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
# Accordion
|
|
168
|
+
## Skeleton Code
|
|
169
|
+
```vue
|
|
170
|
+
<script setup>
|
|
171
|
+
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@reinvented/design'
|
|
172
|
+
</script>
|
|
173
|
+
<template>
|
|
174
|
+
<Accordion type="single" collapsible>
|
|
175
|
+
<AccordionItem value="item-1">
|
|
176
|
+
<AccordionTrigger>Is it accessible?</AccordionTrigger>
|
|
177
|
+
<AccordionContent>Yes. It adheres to the WAI-ARIA design pattern.</AccordionContent>
|
|
178
|
+
</AccordionItem>
|
|
179
|
+
</Accordion>
|
|
180
|
+
</template>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
# Breadcrumb
|
|
186
|
+
## Skeleton Code
|
|
187
|
+
```vue
|
|
188
|
+
<script setup>
|
|
189
|
+
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@reinvented/design'
|
|
190
|
+
</script>
|
|
191
|
+
<template>
|
|
192
|
+
<Breadcrumb>
|
|
193
|
+
<BreadcrumbList>
|
|
194
|
+
<BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem>
|
|
195
|
+
<BreadcrumbSeparator />
|
|
196
|
+
<BreadcrumbItem><BreadcrumbLink href="/items">Items</BreadcrumbLink></BreadcrumbItem>
|
|
197
|
+
<BreadcrumbSeparator />
|
|
198
|
+
<BreadcrumbItem><BreadcrumbPage>Current</BreadcrumbPage></BreadcrumbItem>
|
|
199
|
+
</BreadcrumbList>
|
|
200
|
+
</Breadcrumb>
|
|
201
|
+
</template>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
# Progress
|
|
207
|
+
```vue
|
|
208
|
+
<script setup>
|
|
209
|
+
import { Progress } from '@reinvented/design'
|
|
210
|
+
</script>
|
|
211
|
+
<template><Progress :model-value="60" /></template>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
# Slider
|
|
215
|
+
```vue
|
|
216
|
+
<script setup>
|
|
217
|
+
import { Slider } from '@reinvented/design'
|
|
218
|
+
</script>
|
|
219
|
+
<template><Slider :model-value="[50]" :max="100" :step="1" /></template>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
# Toggle
|
|
223
|
+
```vue
|
|
224
|
+
<script setup>
|
|
225
|
+
import { Toggle } from '@reinvented/design'
|
|
226
|
+
import { Bold } from 'lucide-vue-next'
|
|
227
|
+
</script>
|
|
228
|
+
<template><Toggle variant="outline" aria-label="Toggle bold"><Bold class="h-4 w-4" /></Toggle></template>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
# Command
|
|
232
|
+
## When to Use
|
|
233
|
+
- Command palette (Ctrl+K)
|
|
234
|
+
- Searchable list selection
|
|
235
|
+
|
|
236
|
+
## Skeleton Code
|
|
237
|
+
```vue
|
|
238
|
+
<script setup>
|
|
239
|
+
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@reinvented/design'
|
|
240
|
+
</script>
|
|
241
|
+
<template>
|
|
242
|
+
<Command>
|
|
243
|
+
<CommandInput placeholder="Type to search..." />
|
|
244
|
+
<CommandList>
|
|
245
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
246
|
+
<CommandGroup heading="Actions">
|
|
247
|
+
<CommandItem value="create">Create new item</CommandItem>
|
|
248
|
+
<CommandItem value="search">Search items</CommandItem>
|
|
249
|
+
</CommandGroup>
|
|
250
|
+
</CommandList>
|
|
251
|
+
</Command>
|
|
252
|
+
</template>
|
|
253
|
+
```
|
|
@@ -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
|
package/docs/layouts/index.md
CHANGED
|
@@ -1,32 +1,45 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Layout Documentation
|
|
2
2
|
|
|
3
|
-
|
|
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) |
|
|
10
|
-
| [Detail Page](detail-page.md) |
|
|
11
|
-
| [Dashboard](dashboard.md) |
|
|
12
|
-
| [
|
|
13
|
-
| [
|
|
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
|
|
39
|
+
## General Layout Rules
|
|
27
40
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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+)
|