@reinvented/design 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/DESIGN_GUIDE.md +148 -0
  2. package/README.md +39 -162
  3. package/docs/components/alert-dialog.md +32 -0
  4. package/docs/components/avatar.md +14 -0
  5. package/docs/components/badge.md +24 -0
  6. package/docs/components/button.md +69 -0
  7. package/docs/components/card.md +49 -0
  8. package/docs/components/dialog.md +46 -0
  9. package/docs/components/dropdown-menu.md +32 -0
  10. package/docs/components/index.md +69 -0
  11. package/docs/components/input.md +34 -0
  12. package/docs/components/remaining-components.md +253 -0
  13. package/docs/components/scroll-area.md +17 -0
  14. package/docs/components/select.md +31 -0
  15. package/docs/components/separator.md +14 -0
  16. package/docs/components/sheet.md +32 -0
  17. package/docs/components/skeleton.md +20 -0
  18. package/docs/components/table.md +33 -0
  19. package/docs/components/tabs.md +23 -0
  20. package/docs/conventions.md +74 -0
  21. package/docs/layouts/dashboard.md +70 -0
  22. package/docs/layouts/detail-page.md +83 -0
  23. package/docs/layouts/index.md +45 -0
  24. package/docs/layouts/list-page.md +107 -0
  25. package/docs/layouts/settings-page.md +79 -0
  26. package/docs/layouts/step-wizard.md +73 -0
  27. package/docs/patterns/index.md +39 -0
  28. package/docs/rules.md +43 -0
  29. package/docs/visual-polish.md +141 -0
  30. package/package.json +40 -61
  31. package/src/components/ui/accordion/Accordion.vue +13 -0
  32. package/src/components/ui/accordion/AccordionContent.vue +20 -0
  33. package/src/components/ui/accordion/AccordionItem.vue +15 -0
  34. package/src/components/ui/accordion/AccordionTrigger.vue +25 -0
  35. package/src/components/ui/accordion/index.ts +4 -0
  36. package/src/components/ui/alert/Alert.vue +38 -0
  37. package/src/components/ui/alert/AlertDescription.vue +12 -0
  38. package/src/components/ui/alert/AlertTitle.vue +12 -0
  39. package/src/components/ui/alert/index.ts +3 -0
  40. package/src/components/ui/alert-dialog/AlertDialog.vue +13 -0
  41. package/src/components/ui/alert-dialog/AlertDialogAction.vue +21 -0
  42. package/src/components/ui/alert-dialog/AlertDialogCancel.vue +21 -0
  43. package/src/components/ui/alert-dialog/AlertDialogContent.vue +39 -0
  44. package/src/components/ui/alert-dialog/AlertDialogDescription.vue +15 -0
  45. package/src/components/ui/alert-dialog/AlertDialogFooter.vue +12 -0
  46. package/src/components/ui/alert-dialog/AlertDialogHeader.vue +12 -0
  47. package/src/components/ui/alert-dialog/AlertDialogTitle.vue +15 -0
  48. package/src/components/ui/alert-dialog/AlertDialogTrigger.vue +11 -0
  49. package/src/components/ui/alert-dialog/index.ts +9 -0
  50. package/src/components/ui/avatar/Avatar.vue +14 -0
  51. package/src/components/ui/avatar/index.ts +1 -0
  52. package/src/components/ui/badge/Badge.vue +27 -0
  53. package/src/components/ui/badge/index.ts +1 -0
  54. package/src/components/ui/breadcrumb/Breadcrumb.vue +6 -0
  55. package/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +12 -0
  56. package/src/components/ui/breadcrumb/BreadcrumbItem.vue +6 -0
  57. package/src/components/ui/breadcrumb/BreadcrumbLink.vue +20 -0
  58. package/src/components/ui/breadcrumb/BreadcrumbList.vue +6 -0
  59. package/src/components/ui/breadcrumb/BreadcrumbPage.vue +6 -0
  60. package/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +11 -0
  61. package/src/components/ui/breadcrumb/index.ts +7 -0
  62. package/src/components/ui/button/Button.vue +65 -0
  63. package/src/components/ui/button/index.ts +1 -0
  64. package/src/components/ui/card/Card.vue +13 -0
  65. package/src/components/ui/card/CardContent.vue +7 -0
  66. package/src/components/ui/card/CardDescription.vue +7 -0
  67. package/src/components/ui/card/CardFooter.vue +7 -0
  68. package/src/components/ui/card/CardHeader.vue +9 -0
  69. package/src/components/ui/card/CardTitle.vue +7 -0
  70. package/src/components/ui/card/index.ts +6 -0
  71. package/src/components/ui/checkbox/Checkbox.vue +25 -0
  72. package/src/components/ui/checkbox/index.ts +1 -0
  73. package/src/components/ui/collapsible/Collapsible.vue +13 -0
  74. package/src/components/ui/collapsible/index.ts +2 -0
  75. package/src/components/ui/command/Command.vue +16 -0
  76. package/src/components/ui/command/CommandEmpty.vue +5 -0
  77. package/src/components/ui/command/CommandGroup.vue +22 -0
  78. package/src/components/ui/command/CommandInput.vue +21 -0
  79. package/src/components/ui/command/CommandItem.vue +22 -0
  80. package/src/components/ui/command/CommandList.vue +17 -0
  81. package/src/components/ui/command/CommandSeparator.vue +5 -0
  82. package/src/components/ui/command/index.ts +7 -0
  83. package/src/components/ui/context-menu/ContextMenuContent.vue +24 -0
  84. package/src/components/ui/context-menu/ContextMenuItem.vue +16 -0
  85. package/src/components/ui/context-menu/ContextMenuLabel.vue +9 -0
  86. package/src/components/ui/context-menu/ContextMenuSeparator.vue +9 -0
  87. package/src/components/ui/context-menu/ContextMenuSubContent.vue +14 -0
  88. package/src/components/ui/context-menu/index.ts +9 -0
  89. package/src/components/ui/dialog/Dialog.vue +14 -0
  90. package/src/components/ui/dialog/DialogClose.vue +12 -0
  91. package/src/components/ui/dialog/DialogContent.vue +48 -0
  92. package/src/components/ui/dialog/DialogDescription.vue +23 -0
  93. package/src/components/ui/dialog/DialogFooter.vue +12 -0
  94. package/src/components/ui/dialog/DialogHeader.vue +12 -0
  95. package/src/components/ui/dialog/DialogScrollContent.vue +47 -0
  96. package/src/components/ui/dialog/DialogTitle.vue +23 -0
  97. package/src/components/ui/dialog/DialogTrigger.vue +12 -0
  98. package/src/components/ui/dialog/index.ts +9 -0
  99. package/src/components/ui/dropdown-menu/DropdownMenu.vue +13 -0
  100. package/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +28 -0
  101. package/src/components/ui/dropdown-menu/DropdownMenuContent.vue +33 -0
  102. package/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +11 -0
  103. package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +27 -0
  104. package/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +23 -0
  105. package/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +13 -0
  106. package/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +27 -0
  107. package/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +13 -0
  108. package/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +12 -0
  109. package/src/components/ui/dropdown-menu/DropdownMenuSub.vue +13 -0
  110. package/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +27 -0
  111. package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +23 -0
  112. package/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +11 -0
  113. package/src/components/ui/dropdown-menu/index.ts +14 -0
  114. package/src/components/ui/form/FormControl.vue +3 -0
  115. package/src/components/ui/form/FormDescription.vue +6 -0
  116. package/src/components/ui/form/FormItem.vue +6 -0
  117. package/src/components/ui/form/FormLabel.vue +10 -0
  118. package/src/components/ui/form/FormMessage.vue +10 -0
  119. package/src/components/ui/form/index.ts +9 -0
  120. package/src/components/ui/hover-card/HoverCard.vue +13 -0
  121. package/src/components/ui/hover-card/HoverCardContent.vue +26 -0
  122. package/src/components/ui/hover-card/HoverCardTrigger.vue +11 -0
  123. package/src/components/ui/hover-card/index.ts +3 -0
  124. package/src/components/ui/input/Input.vue +23 -0
  125. package/src/components/ui/input/index.ts +1 -0
  126. package/src/components/ui/label/Label.vue +18 -0
  127. package/src/components/ui/label/index.ts +1 -0
  128. package/src/components/ui/lib/utils.ts +2 -0
  129. package/src/components/ui/menubar/MenubarContent.vue +15 -0
  130. package/src/components/ui/menubar/MenubarItem.vue +13 -0
  131. package/src/components/ui/menubar/MenubarTrigger.vue +13 -0
  132. package/src/components/ui/menubar/index.ts +5 -0
  133. package/src/components/ui/navigation-menu/NavigationMenuContent.vue +14 -0
  134. package/src/components/ui/navigation-menu/NavigationMenuTrigger.vue +15 -0
  135. package/src/components/ui/navigation-menu/index.ts +4 -0
  136. package/src/components/ui/pagination/PaginationContent.vue +13 -0
  137. package/src/components/ui/pagination/PaginationEllipsis.vue +12 -0
  138. package/src/components/ui/pagination/PaginationNext.vue +14 -0
  139. package/src/components/ui/pagination/PaginationPrev.vue +14 -0
  140. package/src/components/ui/pagination/index.ts +6 -0
  141. package/src/components/ui/popover/Popover.vue +13 -0
  142. package/src/components/ui/popover/PopoverContent.vue +27 -0
  143. package/src/components/ui/popover/PopoverTrigger.vue +11 -0
  144. package/src/components/ui/popover/index.ts +3 -0
  145. package/src/components/ui/progress/Progress.vue +21 -0
  146. package/src/components/ui/progress/index.ts +1 -0
  147. package/src/components/ui/radio-group/RadioGroup.vue +16 -0
  148. package/src/components/ui/radio-group/RadioGroupItem.vue +24 -0
  149. package/src/components/ui/radio-group/index.ts +2 -0
  150. package/src/components/ui/scroll-area/ScrollArea.vue +13 -0
  151. package/src/components/ui/scroll-area/index.ts +1 -0
  152. package/src/components/ui/select/Select.vue +13 -0
  153. package/src/components/ui/select/SelectContent.vue +40 -0
  154. package/src/components/ui/select/SelectGroup.vue +15 -0
  155. package/src/components/ui/select/SelectItem.vue +30 -0
  156. package/src/components/ui/select/SelectLabel.vue +15 -0
  157. package/src/components/ui/select/SelectSeparator.vue +13 -0
  158. package/src/components/ui/select/SelectTrigger.vue +23 -0
  159. package/src/components/ui/select/SelectValue.vue +11 -0
  160. package/src/components/ui/select/index.ts +8 -0
  161. package/src/components/ui/separator/Separator.vue +16 -0
  162. package/src/components/ui/separator/index.ts +1 -0
  163. package/src/components/ui/sheet/Sheet.vue +13 -0
  164. package/src/components/ui/sheet/SheetClose.vue +11 -0
  165. package/src/components/ui/sheet/SheetContent.vue +65 -0
  166. package/src/components/ui/sheet/SheetDescription.vue +15 -0
  167. package/src/components/ui/sheet/SheetFooter.vue +12 -0
  168. package/src/components/ui/sheet/SheetHeader.vue +12 -0
  169. package/src/components/ui/sheet/SheetTitle.vue +15 -0
  170. package/src/components/ui/sheet/SheetTrigger.vue +11 -0
  171. package/src/components/ui/sheet/index.ts +8 -0
  172. package/src/components/ui/skeleton/Skeleton.vue +9 -0
  173. package/src/components/ui/skeleton/index.ts +1 -0
  174. package/src/components/ui/slider/Slider.vue +26 -0
  175. package/src/components/ui/slider/index.ts +1 -0
  176. package/src/components/ui/switch/Switch.vue +24 -0
  177. package/src/components/ui/switch/index.ts +1 -0
  178. package/src/components/ui/table/Table.vue +13 -0
  179. package/src/components/ui/table/TableBody.vue +6 -0
  180. package/src/components/ui/table/TableCaption.vue +6 -0
  181. package/src/components/ui/table/TableCell.vue +6 -0
  182. package/src/components/ui/table/TableFooter.vue +6 -0
  183. package/src/components/ui/table/TableHead.vue +6 -0
  184. package/src/components/ui/table/TableHeader.vue +6 -0
  185. package/src/components/ui/table/TableRow.vue +6 -0
  186. package/src/components/ui/table/index.ts +8 -0
  187. package/src/components/ui/tabs/Tabs.vue +13 -0
  188. package/src/components/ui/tabs/TabsContent.vue +21 -0
  189. package/src/components/ui/tabs/TabsList.vue +21 -0
  190. package/src/components/ui/tabs/TabsTrigger.vue +21 -0
  191. package/src/components/ui/tabs/index.ts +4 -0
  192. package/src/components/ui/textarea/Textarea.vue +29 -0
  193. package/src/components/ui/textarea/index.ts +1 -0
  194. package/src/components/ui/toggle/Toggle.vue +40 -0
  195. package/src/components/ui/toggle/index.ts +1 -0
  196. package/src/components/ui/toggle-group/ToggleGroup.vue +16 -0
  197. package/src/components/ui/toggle-group/ToggleGroupItem.vue +21 -0
  198. package/src/components/ui/toggle-group/index.ts +2 -0
  199. package/src/components/ui/tooltip/Tooltip.vue +13 -0
  200. package/src/components/ui/tooltip/TooltipContent.vue +27 -0
  201. package/src/components/ui/tooltip/TooltipProvider.vue +12 -0
  202. package/src/components/ui/tooltip/TooltipTrigger.vue +11 -0
  203. package/src/components/ui/tooltip/index.ts +4 -0
  204. package/src/env.d.ts +7 -0
  205. package/src/index.ts +63 -0
  206. package/src/lib/utils.ts +7 -0
  207. package/src/patterns/DetailView.vue +46 -0
  208. package/src/patterns/EmptyState.vue +27 -0
  209. package/src/patterns/FormView.vue +34 -0
  210. package/src/patterns/ListView.vue +45 -0
  211. package/src/styles/index.css +4 -0
  212. package/src/styles/tokens.css +144 -0
  213. package/tailwind.config.js +108 -0
  214. package/tsconfig.json +21 -0
  215. package/dist/index.css +0 -1890
  216. package/dist/index.d.ts +0 -406
  217. package/dist/index.js +0 -1721
  218. package/dist/index.js.map +0 -1
  219. package/tailwind.config.ts +0 -174
@@ -0,0 +1,6 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from 'vue'
3
+ import { cn } from '../lib/utils'
4
+ const props = defineProps<{ class?: HTMLAttributes['class'] }>()
5
+ </script>
6
+ <template><td :class="cn('p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-0.5', props.class)"><slot /></td></template>
@@ -0,0 +1,6 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from 'vue'
3
+ import { cn } from '../lib/utils'
4
+ const props = defineProps<{ class?: HTMLAttributes['class'] }>()
5
+ </script>
6
+ <template><tfoot :class="cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', props.class)"><slot /></tfoot></template>
@@ -0,0 +1,6 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from 'vue'
3
+ import { cn } from '../lib/utils'
4
+ const props = defineProps<{ class?: HTMLAttributes['class'] }>()
5
+ </script>
6
+ <template><th :class="cn('h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-0.5', props.class)"><slot /></th></template>
@@ -0,0 +1,6 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from 'vue'
3
+ import { cn } from '../lib/utils'
4
+ const props = defineProps<{ class?: HTMLAttributes['class'] }>()
5
+ </script>
6
+ <template><thead :class="cn('[&_tr]:border-b', props.class)"><slot /></thead></template>
@@ -0,0 +1,6 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from 'vue'
3
+ import { cn } from '../lib/utils'
4
+ const props = defineProps<{ class?: HTMLAttributes['class'] }>()
5
+ </script>
6
+ <template><tr :class="cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', props.class)"><slot /></tr></template>
@@ -0,0 +1,8 @@
1
+ export { default as Table } from './Table.vue'
2
+ export { default as TableBody } from './TableBody.vue'
3
+ export { default as TableCaption } from './TableCaption.vue'
4
+ export { default as TableCell } from './TableCell.vue'
5
+ export { default as TableFooter } from './TableFooter.vue'
6
+ export { default as TableHead } from './TableHead.vue'
7
+ export { default as TableHeader } from './TableHeader.vue'
8
+ export { default as TableRow } from './TableRow.vue'
@@ -0,0 +1,13 @@
1
+ <script setup lang="ts">
2
+ import { TabsRoot, type TabsRootEmits, type TabsRootProps, useForwardPropsEmits } from 'radix-vue'
3
+
4
+ const props = defineProps<TabsRootProps>()
5
+ const emits = defineEmits<TabsRootEmits>()
6
+ const forwarded = useForwardPropsEmits(props, emits)
7
+ </script>
8
+
9
+ <template>
10
+ <TabsRoot v-bind="forwarded">
11
+ <slot />
12
+ </TabsRoot>
13
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import { type HTMLAttributes, computed } from 'vue'
3
+ import { TabsContent, type TabsContentProps, useForwardProps } from 'radix-vue'
4
+ import { cn } from '../lib/utils'
5
+
6
+ const props = defineProps<TabsContentProps & { class?: HTMLAttributes['class'] }>()
7
+ const delegatedProps = computed(() => { const { class: _, ...d } = props; return d })
8
+ const forwardedProps = useForwardProps(delegatedProps)
9
+ </script>
10
+
11
+ <template>
12
+ <TabsContent
13
+ v-bind="forwardedProps"
14
+ :class="cn(
15
+ 'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
16
+ props.class,
17
+ )"
18
+ >
19
+ <slot />
20
+ </TabsContent>
21
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import { type HTMLAttributes, computed } from 'vue'
3
+ import { TabsList, type TabsListProps, useForwardProps } from 'radix-vue'
4
+ import { cn } from '../lib/utils'
5
+
6
+ const props = defineProps<TabsListProps & { class?: HTMLAttributes['class'] }>()
7
+ const delegatedProps = computed(() => { const { class: _, ...d } = props; return d })
8
+ const forwardedProps = useForwardProps(delegatedProps)
9
+ </script>
10
+
11
+ <template>
12
+ <TabsList
13
+ v-bind="forwardedProps"
14
+ :class="cn(
15
+ 'inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',
16
+ props.class,
17
+ )"
18
+ >
19
+ <slot />
20
+ </TabsList>
21
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import { type HTMLAttributes, computed } from 'vue'
3
+ import { TabsTrigger, type TabsTriggerProps, useForwardProps } from 'radix-vue'
4
+ import { cn } from '../lib/utils'
5
+
6
+ const props = defineProps<TabsTriggerProps & { class?: HTMLAttributes['class'] }>()
7
+ const delegatedProps = computed(() => { const { class: _, ...d } = props; return d })
8
+ const forwardedProps = useForwardProps(delegatedProps)
9
+ </script>
10
+
11
+ <template>
12
+ <TabsTrigger
13
+ v-bind="forwardedProps"
14
+ :class="cn(
15
+ 'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow',
16
+ props.class,
17
+ )"
18
+ >
19
+ <slot />
20
+ </TabsTrigger>
21
+ </template>
@@ -0,0 +1,4 @@
1
+ export { default as Tabs } from './Tabs.vue'
2
+ export { default as TabsContent } from './TabsContent.vue'
3
+ export { default as TabsList } from './TabsList.vue'
4
+ export { default as TabsTrigger } from './TabsTrigger.vue'
@@ -0,0 +1,29 @@
1
+ <script setup lang="ts">
2
+ import { type HTMLAttributes, computed } from 'vue'
3
+ import { cn } from '../lib/utils'
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes['class']
7
+ defaultValue?: string
8
+ modelValue?: string
9
+ }>()
10
+
11
+ const emits = defineEmits<{
12
+ 'update:modelValue': [value: string]
13
+ }>()
14
+
15
+ const modelValue = computed({
16
+ get: () => props.modelValue,
17
+ set: (val) => emits('update:modelValue', val ?? ''),
18
+ })
19
+ </script>
20
+
21
+ <template>
22
+ <textarea
23
+ v-model="modelValue"
24
+ :class="cn(
25
+ 'flex min-h-20 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
26
+ props.class,
27
+ )"
28
+ />
29
+ </template>
@@ -0,0 +1 @@
1
+ export { default as Textarea } from './Textarea.vue'
@@ -0,0 +1,40 @@
1
+ <script setup lang="ts">
2
+ import { type HTMLAttributes, computed } from 'vue'
3
+ import { Toggle as ToggleRoot, type ToggleEmits, type ToggleProps, useForwardPropsEmits } from 'radix-vue'
4
+ import { cva, type VariantProps } from 'class-variance-authority'
5
+ import { cn } from '../lib/utils'
6
+
7
+ const toggleVariants = cva(
8
+ 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground',
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: 'bg-transparent',
13
+ outline: 'border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground',
14
+ },
15
+ size: {
16
+ default: 'h-9 px-3',
17
+ sm: 'h-8 px-2',
18
+ lg: 'h-10 px-3',
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ variant: 'default',
23
+ size: 'default',
24
+ },
25
+ },
26
+ )
27
+
28
+ type ToggleVariants = VariantProps<typeof toggleVariants>
29
+
30
+ const props = defineProps<ToggleProps & { class?: HTMLAttributes['class']; variant?: ToggleVariants['variant']; size?: ToggleVariants['size'] }>()
31
+ const emits = defineEmits<ToggleEmits>()
32
+ const delegatedProps = computed(() => { const { class: _, variant: _v, size: _s, ...d } = props; return d })
33
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
34
+ </script>
35
+
36
+ <template>
37
+ <ToggleRoot v-bind="forwarded" :class="cn(toggleVariants({ variant, size }), props.class)">
38
+ <slot />
39
+ </ToggleRoot>
40
+ </template>
@@ -0,0 +1 @@
1
+ export { default as Toggle } from './Toggle.vue'
@@ -0,0 +1,16 @@
1
+ <script setup lang="ts">
2
+ import { type HTMLAttributes, computed } from 'vue'
3
+ import { ToggleGroupRoot, type ToggleGroupRootEmits, type ToggleGroupRootProps, useForwardPropsEmits } from 'radix-vue'
4
+ import { cn } from '../lib/utils'
5
+
6
+ const props = defineProps<ToggleGroupRootProps & { class?: HTMLAttributes['class'] }>()
7
+ const emits = defineEmits<ToggleGroupRootEmits>()
8
+ const delegatedProps = computed(() => { const { class: _, ...d } = props; return d })
9
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
10
+ </script>
11
+
12
+ <template>
13
+ <ToggleGroupRoot v-bind="forwarded" :class="cn('flex items-center justify-center gap-1', props.class)">
14
+ <slot />
15
+ </ToggleGroupRoot>
16
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import { type HTMLAttributes, computed } from 'vue'
3
+ import { ToggleGroupItem, type ToggleGroupItemProps, useForwardProps } from 'radix-vue'
4
+ import { cn } from '../lib/utils'
5
+
6
+ const props = defineProps<ToggleGroupItemProps & { class?: HTMLAttributes['class'] }>()
7
+ const delegatedProps = computed(() => { const { class: _, ...d } = props; return d })
8
+ const forwardedProps = useForwardProps(delegatedProps)
9
+ </script>
10
+
11
+ <template>
12
+ <ToggleGroupItem
13
+ v-bind="forwardedProps"
14
+ :class="cn(
15
+ 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground bg-transparent h-9 px-3',
16
+ props.class,
17
+ )"
18
+ >
19
+ <slot />
20
+ </ToggleGroupItem>
21
+ </template>
@@ -0,0 +1,2 @@
1
+ export { default as ToggleGroup } from './ToggleGroup.vue'
2
+ export { default as ToggleGroupItem } from './ToggleGroupItem.vue'
@@ -0,0 +1,13 @@
1
+ <script setup lang="ts">
2
+ import { TooltipRoot, type TooltipRootEmits, type TooltipRootProps, useForwardPropsEmits } from 'radix-vue'
3
+
4
+ const props = defineProps<TooltipRootProps>()
5
+ const emits = defineEmits<TooltipRootEmits>()
6
+ const forwarded = useForwardPropsEmits(props, emits)
7
+ </script>
8
+
9
+ <template>
10
+ <TooltipRoot v-bind="forwarded">
11
+ <slot />
12
+ </TooltipRoot>
13
+ </template>
@@ -0,0 +1,27 @@
1
+ <script setup lang="ts">
2
+ import { type HTMLAttributes, computed } from 'vue'
3
+ import { TooltipContent, type TooltipContentEmits, type TooltipContentProps, TooltipPortal, useForwardPropsEmits } from 'radix-vue'
4
+ import { cn } from '../lib/utils'
5
+
6
+ const props = withDefaults(
7
+ defineProps<TooltipContentProps & { class?: HTMLAttributes['class'] }>(),
8
+ { sideOffset: 4 },
9
+ )
10
+ const emits = defineEmits<TooltipContentEmits>()
11
+ const delegatedProps = computed(() => { const { class: _, ...d } = props; return d })
12
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
13
+ </script>
14
+
15
+ <template>
16
+ <TooltipPortal>
17
+ <TooltipContent
18
+ v-bind="forwarded"
19
+ :class="cn(
20
+ 'z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
21
+ props.class,
22
+ )"
23
+ >
24
+ <slot />
25
+ </TooltipContent>
26
+ </TooltipPortal>
27
+ </template>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ import { TooltipProvider, type TooltipProviderProps, useForwardProps } from 'radix-vue'
3
+
4
+ const props = withDefaults(defineProps<TooltipProviderProps>(), { delayDuration: 200 })
5
+ const forwardedProps = useForwardProps(props)
6
+ </script>
7
+
8
+ <template>
9
+ <TooltipProvider v-bind="forwardedProps">
10
+ <slot />
11
+ </TooltipProvider>
12
+ </template>
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ import { TooltipTrigger, type TooltipTriggerProps } from 'radix-vue'
3
+
4
+ const props = defineProps<TooltipTriggerProps>()
5
+ </script>
6
+
7
+ <template>
8
+ <TooltipTrigger v-bind="props">
9
+ <slot />
10
+ </TooltipTrigger>
11
+ </template>
@@ -0,0 +1,4 @@
1
+ export { default as Tooltip } from './Tooltip.vue'
2
+ export { default as TooltipContent } from './TooltipContent.vue'
3
+ export { default as TooltipProvider } from './TooltipProvider.vue'
4
+ export { default as TooltipTrigger } from './TooltipTrigger.vue'
package/src/env.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ declare module '*.vue' {
4
+ import type { DefineComponent } from 'vue'
5
+ const component: DefineComponent<{}, {}, any>
6
+ export default component
7
+ }
package/src/index.ts ADDED
@@ -0,0 +1,63 @@
1
+ // ── @reinvented/design — Design System Barrel Export ──────────────
2
+ // Re-exports all styled UI components, utils, and types
3
+
4
+ // Utilities
5
+ export { cn } from './lib/utils'
6
+
7
+ // ── Styled UI Components ──────────────────────────────────────────
8
+
9
+ // Core
10
+ export { Button } from './components/ui/button'
11
+ export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from './components/ui/card'
12
+ export { Input } from './components/ui/input'
13
+ export { Badge } from './components/ui/badge'
14
+ export { Avatar } from './components/ui/avatar'
15
+ export { Separator } from './components/ui/separator'
16
+ export { Skeleton } from './components/ui/skeleton'
17
+ export { ScrollArea } from './components/ui/scroll-area'
18
+
19
+ // Overlays
20
+ export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogScrollContent, DialogTitle, DialogTrigger } from './components/ui/dialog'
21
+ export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from './components/ui/alert-dialog'
22
+ export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from './components/ui/sheet'
23
+
24
+ // Data Input
25
+ export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue } from './components/ui/select'
26
+ export { Label } from './components/ui/label'
27
+ export { Textarea } from './components/ui/textarea'
28
+ export { Switch } from './components/ui/switch'
29
+ export { Checkbox } from './components/ui/checkbox'
30
+ export { RadioGroup, RadioGroupItem } from './components/ui/radio-group'
31
+ export { Slider } from './components/ui/slider'
32
+
33
+ // Navigation & Menus
34
+ export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from './components/ui/dropdown-menu'
35
+ export { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuSubContent } from './components/ui/context-menu'
36
+ export { Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarTrigger } from './components/ui/menubar'
37
+ export { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport } from './components/ui/navigation-menu'
38
+ export { Tabs, TabsContent, TabsList, TabsTrigger } from './components/ui/tabs'
39
+ export { Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from './components/ui/breadcrumb'
40
+ export { Pagination, PaginationContent, PaginationEllipsis, PaginationFirst, PaginationLast, PaginationNext, PaginationPrev } from './components/ui/pagination'
41
+
42
+ // Feedback
43
+ export { Alert, AlertDescription, AlertTitle } from './components/ui/alert'
44
+ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './components/ui/tooltip'
45
+ export { Popover, PopoverContent, PopoverTrigger } from './components/ui/popover'
46
+ export { HoverCard, HoverCardContent, HoverCardTrigger } from './components/ui/hover-card'
47
+ export { Progress } from './components/ui/progress'
48
+
49
+ // Data Display
50
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from './components/ui/table'
51
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from './components/ui/accordion'
52
+ export { Collapsible, CollapsibleContent, CollapsibleTrigger } from './components/ui/collapsible'
53
+
54
+ // Actions
55
+ export { Toggle } from './components/ui/toggle'
56
+ export { ToggleGroup, ToggleGroupItem } from './components/ui/toggle-group'
57
+ export { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from './components/ui/command'
58
+
59
+ // Form
60
+ export { Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage } from './components/ui/form'
61
+
62
+ // External library re-exports
63
+ export { Toaster, toast } from 'vue-sonner'
@@ -0,0 +1,7 @@
1
+ import type { ClassValue } from 'clsx'
2
+ import { clsx } from 'clsx'
3
+ import { twMerge } from 'tailwind-merge'
4
+
5
+ export function cn(...inputs: ClassValue[]) {
6
+ return twMerge(clsx(inputs))
7
+ }
@@ -0,0 +1,46 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * DetailView Pattern
4
+ * A detail page with hero/header + content sections.
5
+ * Use for: Circle detail, Event detail, Profile, App detail.
6
+ */
7
+ import { type HTMLAttributes } from 'vue'
8
+ import { cn } from '../lib/utils'
9
+
10
+ interface Props {
11
+ title?: string
12
+ subtitle?: string
13
+ class?: HTMLAttributes['class']
14
+ }
15
+ const props = defineProps<Props>()
16
+ </script>
17
+
18
+ <template>
19
+ <div :class="cn('flex flex-col h-full', props.class)">
20
+ <!-- Back navigation -->
21
+ <div class="flex items-center gap-2 px-4 py-2 border-b">
22
+ <slot name="back-button" />
23
+ <slot name="breadcrumb" />
24
+ <div class="flex-1" />
25
+ <slot name="header-actions" />
26
+ </div>
27
+
28
+ <!-- Hero / Header section -->
29
+ <div class="px-4 py-6 border-b">
30
+ <slot name="hero">
31
+ <h1 v-if="title" class="text-2xl font-bold">{{ title }}</h1>
32
+ <p v-if="subtitle" class="text-muted-foreground mt-1">{{ subtitle }}</p>
33
+ </slot>
34
+ </div>
35
+
36
+ <!-- Tabs / navigation -->
37
+ <div v-if="$slots['tabs']" class="px-4 border-b">
38
+ <slot name="tabs" />
39
+ </div>
40
+
41
+ <!-- Main content -->
42
+ <div class="flex-1 overflow-auto px-4 py-4">
43
+ <slot />
44
+ </div>
45
+ </div>
46
+ </template>
@@ -0,0 +1,27 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * EmptyState Pattern
4
+ * A centered, friendly empty state with icon, title, description, and CTA.
5
+ * Use when a list/section has no data.
6
+ */
7
+ import { type HTMLAttributes } from 'vue'
8
+ import { cn } from '../lib/utils'
9
+
10
+ interface Props {
11
+ title: string
12
+ description?: string
13
+ class?: HTMLAttributes['class']
14
+ }
15
+ const props = defineProps<Props>()
16
+ </script>
17
+
18
+ <template>
19
+ <div :class="cn('flex flex-col items-center justify-center text-center py-12 px-4', props.class)">
20
+ <div v-if="$slots['icon']" class="mb-4 text-muted-foreground">
21
+ <slot name="icon" />
22
+ </div>
23
+ <h3 class="text-lg font-semibold mb-1">{{ title }}</h3>
24
+ <p v-if="description" class="text-sm text-muted-foreground max-w-sm mb-4">{{ description }}</p>
25
+ <slot name="action" />
26
+ </div>
27
+ </template>
@@ -0,0 +1,34 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * FormView Pattern
4
+ * A form page/dialog with sections, validation, and submit.
5
+ * Use for: Settings, Profile edit, Create event, etc.
6
+ */
7
+ import { type HTMLAttributes } from 'vue'
8
+ import { cn } from '../lib/utils'
9
+
10
+ interface Props {
11
+ title?: string
12
+ description?: string
13
+ class?: HTMLAttributes['class']
14
+ }
15
+ const props = defineProps<Props>()
16
+ const emit = defineEmits<{ submit: [] }>()
17
+ </script>
18
+
19
+ <template>
20
+ <form :class="cn('flex flex-col gap-6', props.class)" @submit.prevent="emit('submit')">
21
+ <div v-if="title" class="space-y-1">
22
+ <h2 class="text-xl font-semibold">{{ title }}</h2>
23
+ <p v-if="description" class="text-sm text-muted-foreground">{{ description }}</p>
24
+ </div>
25
+
26
+ <!-- Form sections -->
27
+ <slot />
28
+
29
+ <!-- Actions -->
30
+ <div v-if="$slots['actions']" class="flex items-center justify-end gap-2 pt-4 border-t">
31
+ <slot name="actions" />
32
+ </div>
33
+ </form>
34
+ </template>
@@ -0,0 +1,45 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * ListView Pattern
4
+ * A standard list page with search, filters, and items.
5
+ * Use for: Circles list, Friends list, Notifications, App Store browse.
6
+ */
7
+ import { type HTMLAttributes } from 'vue'
8
+ import { cn } from '../lib/utils'
9
+
10
+ interface Props {
11
+ title?: string
12
+ class?: HTMLAttributes['class']
13
+ }
14
+ const props = defineProps<Props>()
15
+ </script>
16
+
17
+ <template>
18
+ <div :class="cn('flex flex-col h-full', props.class)">
19
+ <!-- Header with title and actions -->
20
+ <div class="flex items-center justify-between px-4 py-3 border-b">
21
+ <h1 v-if="title" class="text-xl font-semibold">{{ title }}</h1>
22
+ <slot name="header-actions" />
23
+ </div>
24
+
25
+ <!-- Search / Filter Bar -->
26
+ <div v-if="$slots['search']" class="px-4 py-2 border-b bg-muted/30">
27
+ <slot name="search" />
28
+ </div>
29
+
30
+ <!-- Filter Tabs -->
31
+ <div v-if="$slots['filters']" class="px-4 py-2 border-b">
32
+ <slot name="filters" />
33
+ </div>
34
+
35
+ <!-- List content -->
36
+ <div class="flex-1 overflow-auto">
37
+ <slot />
38
+ </div>
39
+
40
+ <!-- Empty state -->
41
+ <div v-if="$slots['empty']" class="flex-1 flex items-center justify-center p-8">
42
+ <slot name="empty" />
43
+ </div>
44
+ </div>
45
+ </template>
@@ -0,0 +1,4 @@
1
+ @import './tokens.css';
2
+ @tailwind base;
3
+ @tailwind components;
4
+ @tailwind utilities;