@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
package/README.md
CHANGED
|
@@ -21,6 +21,110 @@ import { Button, Card, Input, Badge, Dialog } from '@reinvented/design'
|
|
|
21
21
|
- **Styling**: [Tailwind CSS](https://tailwindcss.com/) with design tokens
|
|
22
22
|
- **Icons**: [Lucide Vue Next](https://lucide.dev/) (no emojis, ever)
|
|
23
23
|
- **Typography**: Inter (via Google Fonts)
|
|
24
|
+
- **Linting**: Built-in ESLint plugin enforcing design rules
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Consumer Setup
|
|
29
|
+
|
|
30
|
+
### 1. Install dependencies
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# The design system (includes all component + ESLint deps)
|
|
34
|
+
npm install @reinvented/design
|
|
35
|
+
|
|
36
|
+
# Required dev dependencies for Tailwind CSS processing
|
|
37
|
+
npm install -D tailwindcss@^3.4 postcss@^8.4 autoprefixer@^10.4 tailwindcss-animate@^1.0
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Tailwind CSS config
|
|
41
|
+
|
|
42
|
+
Create `tailwind.config.js` in your app root. **Extend** the DS config — this gives you all design tokens, theme colors, animations, and font family:
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
import baseConfig from '@reinvented/design/tailwind.config.js'
|
|
46
|
+
|
|
47
|
+
export default {
|
|
48
|
+
...baseConfig,
|
|
49
|
+
content: [
|
|
50
|
+
'./index.html',
|
|
51
|
+
'./src/**/*.{vue,js,ts,jsx,tsx}',
|
|
52
|
+
// Include DS source so Tailwind picks up classes used inside components
|
|
53
|
+
'./node_modules/@reinvented/design/src/**/*.{vue,ts}',
|
|
54
|
+
],
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 3. PostCSS config
|
|
59
|
+
|
|
60
|
+
Create `postcss.config.js`:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
export default {
|
|
64
|
+
plugins: {
|
|
65
|
+
tailwindcss: {},
|
|
66
|
+
autoprefixer: {},
|
|
67
|
+
},
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 4. CSS entry point
|
|
72
|
+
|
|
73
|
+
Create `src/assets/main.css` (or similar) and import the DS styles. This loads the design tokens (CSS variables) and Tailwind directives:
|
|
74
|
+
|
|
75
|
+
```css
|
|
76
|
+
@import '@reinvented/design/styles';
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Then import it in your app entry (`main.js` or `main.ts`):
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
import './assets/main.css'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 5. Dark mode
|
|
86
|
+
|
|
87
|
+
The DS uses the `class` strategy for dark mode. Add `class="dark"` to `<html>` for dark theme:
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<html lang="en" class="dark">
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
All color tokens automatically switch between light and dark values.
|
|
94
|
+
|
|
95
|
+
### 6. ESLint (recommended)
|
|
96
|
+
|
|
97
|
+
The DS ships an ESLint plugin that enforces design system rules. Create `eslint.config.js`:
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
import recommended from '@reinvented/design/eslint/recommended'
|
|
101
|
+
|
|
102
|
+
export default [
|
|
103
|
+
...recommended,
|
|
104
|
+
// Your custom overrides (optional)
|
|
105
|
+
]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This enables:
|
|
109
|
+
|
|
110
|
+
| Rule | Severity | What it catches |
|
|
111
|
+
|------|----------|-----------------|
|
|
112
|
+
| `no-raw-button` | error | Raw `<button>` → use `<Button>` |
|
|
113
|
+
| `no-raw-input` | error | Raw `<input>` → use `<Input>` |
|
|
114
|
+
| `no-raw-select` | error | Raw `<select>` → use `<Select>` |
|
|
115
|
+
| `no-raw-textarea` | error | Raw `<textarea>` → use `<Textarea>` |
|
|
116
|
+
| `no-browser-dialogs` | error | `alert()`, `confirm()`, `prompt()` → use Dialog/Toast |
|
|
117
|
+
| `no-emoji` | error | Emoji characters → use Lucide icons |
|
|
118
|
+
| `no-hardcoded-colors` | warn | Inline hex/rgb colors → use token variables |
|
|
119
|
+
| `no-arbitrary-tailwind` | warn | `text-[#333]` → use token classes |
|
|
120
|
+
|
|
121
|
+
Install ESLint if not already present:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npm install -D eslint
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
24
128
|
|
|
25
129
|
## Structure
|
|
26
130
|
|
|
@@ -31,6 +135,7 @@ src/
|
|
|
31
135
|
layouts/ Page-level layout components with slots
|
|
32
136
|
lib/ Utilities (cn, etc.)
|
|
33
137
|
styles/ Tokens, CSS variables
|
|
138
|
+
eslint/ ESLint plugin + recommended config
|
|
34
139
|
docs/
|
|
35
140
|
rules.md Hard design rules
|
|
36
141
|
conventions.md Opinionated UX decisions
|
|
@@ -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"`
|
package/docs/components/index.md
CHANGED
|
@@ -1,50 +1,69 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
| [
|
|
10
|
-
| [
|
|
11
|
-
| [
|
|
12
|
-
| [
|
|
13
|
-
| [
|
|
14
|
-
| [
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
|
23
|
-
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
|
31
|
-
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
|
41
|
-
|
|
42
|
-
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
|
47
|
-
|
|
48
|
-
|
|
|
49
|
-
|
|
50
|
-
|
|
1
|
+
# Component Index
|
|
2
|
+
|
|
3
|
+
All DS components available from `@reinvented/design`. Each component links to its documentation.
|
|
4
|
+
|
|
5
|
+
## Core Display
|
|
6
|
+
| Component | Doc | Description |
|
|
7
|
+
|-----------|-----|-------------|
|
|
8
|
+
| [Button](button.md) | ✅ | Actions with 7 variants + 6 sizes |
|
|
9
|
+
| [Card](card.md) | ✅ | Content containers with header/footer |
|
|
10
|
+
| [Badge](badge.md) | ✅ | Status labels and tags |
|
|
11
|
+
| [Avatar](avatar.md) | ✅ | User/entity images with fallback |
|
|
12
|
+
| [Separator](separator.md) | ✅ | Visual dividers |
|
|
13
|
+
| [Skeleton](skeleton.md) | ✅ | Loading placeholders |
|
|
14
|
+
| [ScrollArea](scroll-area.md) | ✅ | Custom-scrollbar containers |
|
|
15
|
+
|
|
16
|
+
## Data Input
|
|
17
|
+
| Component | Doc | Description |
|
|
18
|
+
|-----------|-----|-------------|
|
|
19
|
+
| [Input](input.md) | ✅ | Text input fields |
|
|
20
|
+
| [Textarea](remaining-components.md#textarea) | ✅ | Multi-line text |
|
|
21
|
+
| [Select](select.md) | ✅ | Single-value dropdown selection |
|
|
22
|
+
| [Checkbox](remaining-components.md#checkbox) | ✅ | Boolean toggle (checkmark) |
|
|
23
|
+
| [Switch](remaining-components.md#switch) | ✅ | Boolean toggle (slider) |
|
|
24
|
+
| [RadioGroup](remaining-components.md#radiogroup) | ✅ | Single-value from small set |
|
|
25
|
+
| [Slider](remaining-components.md#slider) | ✅ | Numeric range input |
|
|
26
|
+
| [Label](remaining-components.md#label) | ✅ | Form field labels |
|
|
27
|
+
| [Form](remaining-components.md) | ✅ | vee-validate form integration |
|
|
28
|
+
|
|
29
|
+
## Overlays
|
|
30
|
+
| Component | Doc | Description |
|
|
31
|
+
|-----------|-----|-------------|
|
|
32
|
+
| [Dialog](dialog.md) | ✅ | Modal dialogs for forms/actions |
|
|
33
|
+
| [AlertDialog](alert-dialog.md) | ✅ | Confirmation dialogs for destructive actions |
|
|
34
|
+
| [Sheet](sheet.md) | ✅ | Side panels (left/right/top/bottom) |
|
|
35
|
+
| [Popover](remaining-components.md#popover) | ✅ | Floating content panels |
|
|
36
|
+
| [Tooltip](remaining-components.md#tooltip) | ✅ | Hover hints |
|
|
37
|
+
| [HoverCard](remaining-components.md#hovercard) | ✅ | Rich hover previews |
|
|
38
|
+
|
|
39
|
+
## Navigation & Menus
|
|
40
|
+
| Component | Doc | Description |
|
|
41
|
+
|-----------|-----|-------------|
|
|
42
|
+
| [DropdownMenu](dropdown-menu.md) | ✅ | Action menus |
|
|
43
|
+
| [ContextMenu](remaining-components.md) | ✅ | Right-click menus |
|
|
44
|
+
| [Menubar](remaining-components.md) | ✅ | App menu bars |
|
|
45
|
+
| [NavigationMenu](remaining-components.md) | ✅ | Site navigation |
|
|
46
|
+
| [Tabs](tabs.md) | ✅ | Tab navigation |
|
|
47
|
+
| [Breadcrumb](remaining-components.md#breadcrumb) | ✅ | Path navigation |
|
|
48
|
+
| [Pagination](remaining-components.md) | ✅ | Page navigation |
|
|
49
|
+
|
|
50
|
+
## Data Display
|
|
51
|
+
| Component | Doc | Description |
|
|
52
|
+
|-----------|-----|-------------|
|
|
53
|
+
| [Table](table.md) | ✅ | Tabular data |
|
|
54
|
+
| [Accordion](remaining-components.md#accordion) | ✅ | Collapsible sections |
|
|
55
|
+
| [Collapsible](remaining-components.md) | ✅ | Show/hide content |
|
|
56
|
+
| [Progress](remaining-components.md#progress) | ✅ | Progress bars |
|
|
57
|
+
|
|
58
|
+
## Actions
|
|
59
|
+
| Component | Doc | Description |
|
|
60
|
+
|-----------|-----|-------------|
|
|
61
|
+
| [Toggle](remaining-components.md#toggle) | ✅ | State toggle buttons |
|
|
62
|
+
| [ToggleGroup](remaining-components.md) | ✅ | Grouped toggles |
|
|
63
|
+
| [Command](remaining-components.md#command) | ✅ | Command palette / searchable list |
|
|
64
|
+
|
|
65
|
+
## Feedback
|
|
66
|
+
| Component | Doc | Description |
|
|
67
|
+
|-----------|-----|-------------|
|
|
68
|
+
| [Alert](remaining-components.md#alert) | ✅ | Inline notifications |
|
|
69
|
+
| Toast (`vue-sonner`) | — | Ephemeral notifications |
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Input
|
|
2
|
+
|
|
3
|
+
## Skeleton Code
|
|
4
|
+
|
|
5
|
+
```vue
|
|
6
|
+
<script setup>
|
|
7
|
+
import { Input, Label } from '@reinvented/design'
|
|
8
|
+
import { ref } from 'vue'
|
|
9
|
+
const value = ref('')
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<div class="space-y-2">
|
|
14
|
+
<Label for="email">Email</Label>
|
|
15
|
+
<Input id="email" v-model="value" type="email" placeholder="name@example.com" />
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## With Icon
|
|
21
|
+
|
|
22
|
+
```vue
|
|
23
|
+
<template>
|
|
24
|
+
<div class="relative">
|
|
25
|
+
<Search class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
|
26
|
+
<Input class="pl-9" placeholder="Search..." />
|
|
27
|
+
</div>
|
|
28
|
+
</template>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Gotchas
|
|
32
|
+
- Always pair with `<Label>` for accessibility
|
|
33
|
+
- Use `placeholder` for format hints, not labels
|
|
34
|
+
- Supports `v-model` for two-way binding
|