@reinvented/design 1.0.0 → 1.2.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.
Files changed (203) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +214 -0
  3. package/package.json +4 -3
  4. package/skills/apps/analytics.md +103 -0
  5. package/skills/apps/booking-scheduling.md +97 -0
  6. package/skills/apps/content-management.md +52 -0
  7. package/skills/apps/crm.md +80 -0
  8. package/skills/apps/e-commerce.md +109 -0
  9. package/skills/apps/education.md +79 -0
  10. package/skills/apps/finance.md +68 -0
  11. package/skills/apps/health-fitness.md +72 -0
  12. package/skills/apps/marketplace.md +99 -0
  13. package/skills/apps/messaging.md +84 -0
  14. package/skills/apps/portfolio-personal.md +90 -0
  15. package/skills/apps/project-management.md +95 -0
  16. package/skills/apps/saas-dashboard.md +104 -0
  17. package/skills/apps/social-platform.md +50 -0
  18. package/skills/blocks/auth.md +106 -0
  19. package/skills/blocks/communication.md +98 -0
  20. package/skills/blocks/content.md +107 -0
  21. package/skills/blocks/data-management.md +109 -0
  22. package/skills/blocks/data-viz.md +92 -0
  23. package/skills/blocks/ecommerce.md +126 -0
  24. package/skills/blocks/feedback.md +97 -0
  25. package/skills/blocks/filtering.md +127 -0
  26. package/skills/blocks/marketing.md +136 -0
  27. package/skills/blocks/media.md +102 -0
  28. package/skills/blocks/navigation.md +136 -0
  29. package/skills/blocks/onboarding.md +75 -0
  30. package/skills/blocks/profiles.md +131 -0
  31. package/skills/blocks/scheduling.md +117 -0
  32. package/skills/blocks/settings.md +102 -0
  33. package/skills/components/advanced-components.md +142 -0
  34. package/skills/components/avatar.md +92 -0
  35. package/skills/components/badge.md +105 -0
  36. package/skills/components/button.md +87 -0
  37. package/skills/components/card.md +144 -0
  38. package/skills/components/chart.md +88 -0
  39. package/skills/components/dialog.md +109 -0
  40. package/skills/components/dropdown-menu.md +117 -0
  41. package/skills/components/extended-components.md +187 -0
  42. package/skills/components/feedback.md +165 -0
  43. package/skills/components/form.md +112 -0
  44. package/skills/components/input.md +107 -0
  45. package/skills/components/map.md +53 -0
  46. package/skills/components/navigation.md +73 -0
  47. package/skills/components/overlay.md +77 -0
  48. package/skills/components/page-header.md +51 -0
  49. package/skills/components/select.md +175 -0
  50. package/skills/components/table.md +102 -0
  51. package/skills/components/tabs.md +105 -0
  52. package/skills/components/utilities.md +138 -0
  53. package/skills/devices/desktop.md +43 -0
  54. package/skills/devices/mobile.md +77 -0
  55. package/skills/foundation/design-principles.md +77 -0
  56. package/skills/foundation/design-tokens.md +121 -0
  57. package/skills/foundation/mockup-generation.md +118 -0
  58. package/skills/foundation/rules.md +54 -0
  59. package/skills/foundation/tailwind-usage.md +204 -0
  60. package/skills/layouts/dashboard.md +71 -0
  61. package/skills/layouts/full-page-form.md +75 -0
  62. package/skills/layouts/list-detail.md +70 -0
  63. package/skills/layouts/marketing.md +70 -0
  64. package/skills/layouts/responsive.md +67 -0
  65. package/skills/layouts/settings-page.md +106 -0
  66. package/skills/layouts/sidebar.md +73 -0
  67. package/skills/layouts/topbar.md +68 -0
  68. package/skills/patterns/auth.md +131 -0
  69. package/skills/patterns/content-display.md +164 -0
  70. package/skills/patterns/dashboards.md +104 -0
  71. package/skills/patterns/data-tables.md +113 -0
  72. package/skills/patterns/empty-states.md +71 -0
  73. package/skills/patterns/error-states.md +73 -0
  74. package/skills/patterns/forms.md +136 -0
  75. package/skills/patterns/loading-states.md +92 -0
  76. package/skills/patterns/navigation.md +113 -0
  77. package/skills/patterns/notifications.md +91 -0
  78. package/skills/patterns/onboarding.md +42 -0
  79. package/skills/patterns/search.md +55 -0
  80. package/skills/patterns/settings.md +132 -0
  81. package/skills/patterns/user-profiles.md +67 -0
  82. package/skills/personas/business-operator.md +114 -0
  83. package/skills/personas/consumer-casual.md +60 -0
  84. package/skills/personas/consumer-power-user.md +109 -0
  85. package/skills/personas/creative-professional.md +109 -0
  86. package/skills/personas/enterprise-admin.md +134 -0
  87. package/skills/visual/color-usage.md +62 -0
  88. package/skills/visual/dark-mode.md +50 -0
  89. package/skills/visual/polish-techniques.md +101 -0
  90. package/skills/visual/spacing-composition.md +69 -0
  91. package/skills/visual/transitions-animations.md +66 -0
  92. package/skills/visual/typography-hierarchy.md +66 -0
  93. package/src/components/blocks/auth/auth-card/AuthCard.tsx +2 -2
  94. package/src/components/blocks/auth/social-login/SocialLoginGroup.tsx +2 -2
  95. package/src/components/blocks/auth/two-factor/TwoFactorForm.tsx +4 -4
  96. package/src/components/blocks/communication/activity-item/ActivityItem.tsx +1 -1
  97. package/src/components/blocks/communication/activity-item/ActivityItemAvatar.tsx +2 -2
  98. package/src/components/blocks/communication/activity-item/ActivityItemContent.tsx +1 -1
  99. package/src/components/blocks/communication/chat-bubble/ChatBubble.tsx +1 -1
  100. package/src/components/blocks/communication/chat-bubble/ChatBubbleAvatar.tsx +2 -2
  101. package/src/components/blocks/communication/chat-bubble/ChatBubbleMessage.tsx +1 -1
  102. package/src/components/blocks/communication/chat-bubble/ChatBubbleTimestamp.tsx +1 -1
  103. package/src/components/blocks/content/article-header/ArticleHeader.tsx +3 -3
  104. package/src/components/blocks/content/author-card/AuthorCard.tsx +4 -4
  105. package/src/components/blocks/content/rich-text/RichTextContent.tsx +1 -1
  106. package/src/components/blocks/data-management/kanban/KanbanBoard.tsx +1 -1
  107. package/src/components/blocks/data-management/kanban/KanbanCard.tsx +4 -4
  108. package/src/components/blocks/data-management/kanban/KanbanColumn.tsx +3 -3
  109. package/src/components/blocks/data-management/tree-view/TreeItem.tsx +2 -2
  110. package/src/components/blocks/data-management/tree-view/TreeView.tsx +1 -1
  111. package/src/components/blocks/data-viz/financial-ticker/FinancialTicker.tsx +1 -1
  112. package/src/components/blocks/data-viz/kpi-card/KpiCard.tsx +2 -2
  113. package/src/components/blocks/data-viz/stat-grid/StatGrid.tsx +1 -1
  114. package/src/components/blocks/ecommerce/pricing-tier/PricingFeatureList.tsx +2 -2
  115. package/src/components/blocks/ecommerce/pricing-tier/PricingHeader.tsx +2 -2
  116. package/src/components/blocks/ecommerce/pricing-tier/PricingTier.tsx +2 -2
  117. package/src/components/blocks/ecommerce/product-card/ProductCard.tsx +2 -2
  118. package/src/components/blocks/ecommerce/product-card/ProductCardContent.tsx +2 -2
  119. package/src/components/blocks/ecommerce/product-card/ProductCardImage.tsx +1 -1
  120. package/src/components/blocks/ecommerce/product-card/ProductCardPrice.tsx +1 -1
  121. package/src/components/blocks/ecommerce/rating-summary/RatingStars.tsx +1 -1
  122. package/src/components/blocks/feedback/empty-state/EmptyState.tsx +2 -2
  123. package/src/components/blocks/feedback/error-state/ErrorState.tsx +2 -2
  124. package/src/components/blocks/feedback/not-found/NotFoundState.tsx +2 -2
  125. package/src/components/blocks/filtering/faceted-sidebar/FacetedGroup.tsx +2 -2
  126. package/src/components/blocks/filtering/faceted-sidebar/FacetedSidebar.tsx +2 -2
  127. package/src/components/blocks/filtering/filter-bar/FilterBar.tsx +4 -4
  128. package/src/components/blocks/filtering/search-result/SearchResultItem.tsx +2 -2
  129. package/src/components/blocks/marketing/cta-block/CtaBlock.tsx +2 -2
  130. package/src/components/blocks/marketing/feature-grid/FeatureGrid.tsx +1 -1
  131. package/src/components/blocks/marketing/hero-section/HeroSection.tsx +3 -3
  132. package/src/components/blocks/marketing/testimonial-card/TestimonialCard.tsx +3 -3
  133. package/src/components/blocks/media/call-controls/CallControlButton.tsx +3 -3
  134. package/src/components/blocks/media/call-controls/CallControls.tsx +1 -1
  135. package/src/components/blocks/media/media-player/MediaPlayer.tsx +1 -1
  136. package/src/components/blocks/media/media-player/MediaPlayerControls.tsx +1 -1
  137. package/src/components/blocks/media/media-player/MediaPlayerScrubber.tsx +1 -1
  138. package/src/components/blocks/media/media-player/MediaPlayerVideo.tsx +1 -1
  139. package/src/components/blocks/navigation/app-sidebar/AppSidebar.tsx +2 -2
  140. package/src/components/blocks/navigation/app-sidebar/NavItem.tsx +1 -1
  141. package/src/components/blocks/navigation/context-switcher/ContextSwitcher.tsx +3 -3
  142. package/src/components/blocks/navigation/top-navbar/TopNavbar.tsx +2 -2
  143. package/src/components/blocks/onboarding/onboarding-welcome/OnboardingWelcome.tsx +3 -3
  144. package/src/components/blocks/onboarding/step-wizard/StepWizard.tsx +1 -1
  145. package/src/components/blocks/profiles/connection-list/ConnectionItem.tsx +3 -3
  146. package/src/components/blocks/profiles/connection-list/ConnectionList.tsx +1 -1
  147. package/src/components/blocks/profiles/profile-header/ProfileHeader.tsx +3 -3
  148. package/src/components/blocks/profiles/profile-stats/ProfileStats.tsx +1 -1
  149. package/src/components/blocks/scheduling/booking-slot/BookingSlot.tsx +1 -1
  150. package/src/components/blocks/scheduling/event-card/EventCard.tsx +3 -3
  151. package/src/components/blocks/scheduling/timeline-row/TimelineRow.tsx +2 -2
  152. package/src/components/blocks/settings/billing-usage/BillingUsage.tsx +3 -3
  153. package/src/components/blocks/settings/integration-card/IntegrationCard.tsx +5 -5
  154. package/src/components/blocks/settings/settings-section/SettingsSection.tsx +1 -1
  155. package/src/components/ui/accordion.tsx +1 -1
  156. package/src/components/ui/alert-dialog.tsx +2 -2
  157. package/src/components/ui/alert.tsx +1 -1
  158. package/src/components/ui/avatar.tsx +1 -1
  159. package/src/components/ui/badge.tsx +7 -1
  160. package/src/components/ui/breadcrumb.tsx +1 -1
  161. package/src/components/ui/button.tsx +8 -1
  162. package/src/components/ui/calendar.tsx +2 -2
  163. package/src/components/ui/card.tsx +1 -1
  164. package/src/components/ui/carousel.tsx +2 -2
  165. package/src/components/ui/chart.tsx +1 -1
  166. package/src/components/ui/checkbox.tsx +1 -1
  167. package/src/components/ui/command.tsx +2 -2
  168. package/src/components/ui/component-placeholder.tsx +1 -1
  169. package/src/components/ui/context-menu.tsx +1 -1
  170. package/src/components/ui/dialog.tsx +1 -1
  171. package/src/components/ui/drawer.tsx +1 -1
  172. package/src/components/ui/dropdown-menu.tsx +1 -1
  173. package/src/components/ui/form.tsx +2 -2
  174. package/src/components/ui/hover-card.tsx +1 -1
  175. package/src/components/ui/input-otp.tsx +1 -1
  176. package/src/components/ui/input.tsx +1 -1
  177. package/src/components/ui/label.tsx +1 -1
  178. package/src/components/ui/menubar.tsx +1 -1
  179. package/src/components/ui/navigation-menu.tsx +1 -1
  180. package/src/components/ui/pagination.tsx +2 -2
  181. package/src/components/ui/popover.tsx +1 -1
  182. package/src/components/ui/progress.tsx +1 -1
  183. package/src/components/ui/radio-group.tsx +1 -1
  184. package/src/components/ui/resizable.tsx +1 -1
  185. package/src/components/ui/scroll-area.tsx +1 -1
  186. package/src/components/ui/select.tsx +1 -1
  187. package/src/components/ui/separator.tsx +1 -1
  188. package/src/components/ui/sheet.tsx +1 -1
  189. package/src/components/ui/skeleton.tsx +1 -1
  190. package/src/components/ui/slider.tsx +1 -1
  191. package/src/components/ui/sonner.tsx +13 -6
  192. package/src/components/ui/switch.tsx +1 -1
  193. package/src/components/ui/table.tsx +1 -1
  194. package/src/components/ui/tabs.tsx +1 -1
  195. package/src/components/ui/textarea.tsx +1 -1
  196. package/src/components/ui/toast.tsx +1 -1
  197. package/src/components/ui/toaster.tsx +1 -1
  198. package/src/components/ui/toggle-group.tsx +2 -2
  199. package/src/components/ui/toggle.tsx +1 -1
  200. package/src/components/ui/tooltip.tsx +1 -1
  201. package/src/hooks/use-toast.ts +1 -1
  202. package/src/styles/tokens.css +1 -1
  203. package/DESIGN_GUIDE.md +0 -148
@@ -0,0 +1,107 @@
1
+ # Input, Textarea, Label
2
+
3
+ Text entry components. Never use raw `<input>` or `<textarea>`.
4
+
5
+ ```ts
6
+ import { Input, Textarea, Label } from '@reinvented/design'
7
+ ```
8
+
9
+ ## Input
10
+
11
+ Standard single-line text field with built-in styling for focus, disabled, and placeholder states.
12
+
13
+ ```tsx
14
+ <div className="space-y-2">
15
+ <Label for="email">Email</Label>
16
+ <Input id="email" type="email" placeholder="sarah@example.com" defaultValue="email" />
17
+ </div>
18
+ ```
19
+
20
+ ### Input with Icon
21
+
22
+ ```tsx
23
+ <div className="relative">
24
+ <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
25
+ <Input className="pl-9" placeholder="Search..." defaultValue="query" />
26
+ </div>
27
+ ```
28
+
29
+ Key: Use `pl-9` (36px) to make room for the icon. Icon is positioned with `absolute left-3 top-1/2 -translate-y-1/2`.
30
+
31
+ ### Input Sizes
32
+
33
+ The default Input height matches `h-9` (36px). For different contexts:
34
+ - Standard: default (no size prop needed)
35
+ - Custom height: apply via class `className="h-8"` for compact, `className="h-10"` for larger
36
+
37
+ ### Disabled Input
38
+
39
+ ```tsx
40
+ <Input disabled :value="user.email" />
41
+ ```
42
+
43
+ ### Form Field Pattern (Label + Input + Description + Error)
44
+
45
+ ```tsx
46
+ <div className="space-y-2">
47
+ <Label for="name">Display Name</Label>
48
+ <Input id="name" defaultValue="name" placeholder="Your display name" />
49
+ <p className="text-xs text-muted-foreground">This is how others will see you.</p>
50
+ </div>
51
+ ```
52
+
53
+ For error state:
54
+ ```tsx
55
+ <div className="space-y-2">
56
+ <Label for="name">Display Name</Label>
57
+ <Input id="name" defaultValue="name" className="border-destructive" />
58
+ <p className="text-xs text-destructive">Name is required.</p>
59
+ </div>
60
+ ```
61
+
62
+ ## Textarea
63
+
64
+ Multi-line text input.
65
+
66
+ ```tsx
67
+ <div className="space-y-2">
68
+ <Label for="bio">Bio</Label>
69
+ <Textarea id="bio" defaultValue="bio" placeholder="Tell us about yourself..." rows="4" />
70
+ </div>
71
+ ```
72
+
73
+ Use `rows` to control initial height. Default is 3 rows.
74
+
75
+ ## Label
76
+
77
+ Always pair with an input using matching `for`/`id` attributes.
78
+
79
+ ```tsx
80
+ <Label for="username" className="text-sm font-medium">Username</Label>
81
+ ```
82
+
83
+ Label is `text-sm font-medium` by default. Never use `text-base` or larger for form labels.
84
+
85
+ ## Anti-Patterns
86
+
87
+ ```tsx
88
+ <!-- ❌ No label -->
89
+ <Input placeholder="Enter name" />
90
+
91
+ <!-- ✅ Always pair with Label -->
92
+ <div className="space-y-2">
93
+ <Label for="name">Name</Label>
94
+ <Input id="name" placeholder="Enter name" />
95
+ </div>
96
+ ```
97
+
98
+ ```tsx
99
+ <!-- ❌ Using icon inside Input via slot (doesn't exist) -->
100
+ <Input><SearchIcon /></Input>
101
+
102
+ <!-- ✅ Use the absolute-positioned icon pattern -->
103
+ <div className="relative">
104
+ <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
105
+ <Input className="pl-9" placeholder="Search..." />
106
+ </div>
107
+ ```
@@ -0,0 +1,53 @@
1
+ # Interactive Map
2
+
3
+ Data-focused map visualization wrapper around Google Maps.
4
+
5
+ ```ts
6
+ import { InteractiveMap } from '@reinvented/design'
7
+ ```
8
+
9
+ ## Basic Structure
10
+
11
+ The `InteractiveMap` component renders a fluid, styled Google Map meant for spatial data visualization like finding locations, tracking fleets, or plotting regional data.
12
+
13
+ ```tsx
14
+ <InteractiveMap
15
+ :markers="[
16
+ { id: 1, lat: 40.7128, lng: -74.0060, label: 'NYC Hub' },
17
+ { id: 2, lat: 34.0522, lng: -118.2437, label: 'LA Port' }
18
+ ]"
19
+ className="h-[400px]"
20
+ />
21
+ ```
22
+
23
+ When `markers` are provided, the map will **automatically fit its bounds** to ensure all markers are visible. You do not need to provide a `center` or `zoom` when providing `markers`.
24
+
25
+ ## Usage Without Markers
26
+
27
+ If you want to render a map without markers, explicitly provide `center` and `zoom`:
28
+
29
+ ```tsx
30
+ <InteractiveMap
31
+ :center="{ lat: 51.5072, lng: -0.1276 }"
32
+ :zoom="12"
33
+ className="h-[400px]"
34
+ />
35
+ ```
36
+
37
+ ## Mock Mode (Mockups Only)
38
+
39
+ When generating pure mockups without real data or needing a strict wireframe, use the `mock` prop to bypass the heavyweight map engine and display a beautiful placeholder.
40
+
41
+ ```tsx
42
+ <InteractiveMap
43
+ mock
44
+ :markers="mockLocations"
45
+ className="h-[400px]"
46
+ />
47
+ ```
48
+
49
+ ## Component Rules
50
+
51
+ - **Always set height**: The wrapper `<div className="relative w-full h-full">` inherits dimensions. Give the component an explicit absolute height (e.g., `className="h-96"`, `className="h-[400px]"`) or place it in a container that has explicit height.
52
+ - **Data formats**: `lat` and `lng` must be **numbers**, not strings.
53
+ - **Do not use `ComponentPlaceholder` for Maps**: Now that the design system formally provides `<InteractiveMap>`, never use a `ComponentPlaceholder` for maps in your layouts. Use this native component.
@@ -0,0 +1,73 @@
1
+ # Navigation Components
2
+
3
+ Breadcrumbs, pagination, and navigation menus.
4
+
5
+ ```ts
6
+ import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from '@reinvented/design'
7
+ import { Pagination, PaginationContent, PaginationEllipsis, PaginationFirst, PaginationLast, PaginationNext, PaginationPrev } from '@reinvented/design'
8
+ import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger } from '@reinvented/design'
9
+ ```
10
+
11
+ ## Breadcrumb
12
+
13
+ Path navigation for hierarchies of 3+ levels. Shows the user where they are.
14
+
15
+ ```tsx
16
+ <Breadcrumb>
17
+ <BreadcrumbList>
18
+ <BreadcrumbItem>
19
+ <BreadcrumbLink href="/">Home</BreadcrumbLink>
20
+ </BreadcrumbItem>
21
+ <BreadcrumbSeparator />
22
+ <BreadcrumbItem>
23
+ <BreadcrumbLink href="/projects">Projects</BreadcrumbLink>
24
+ </BreadcrumbItem>
25
+ <BreadcrumbSeparator />
26
+ <BreadcrumbItem>
27
+ <BreadcrumbPage>Project Alpha</BreadcrumbPage>
28
+ </BreadcrumbItem>
29
+ </BreadcrumbList>
30
+ </Breadcrumb>
31
+ ```
32
+
33
+ - The last item uses `BreadcrumbPage` (non-clickable, current location)
34
+ - All intermediate items use `BreadcrumbLink` (clickable)
35
+ - Only use breadcrumbs for 3+ level hierarchies. For simpler navigation, use a Back button.
36
+
37
+ ## Pagination
38
+
39
+ Page-based navigation for large datasets.
40
+
41
+ ```tsx
42
+ <div className="flex items-center justify-between">
43
+ <p className="text-sm text-muted-foreground">Showing 1–10 of 97 results</p>
44
+ <Pagination :total="97" :sibling-count="1" show-edges :default-page="1">
45
+ <PaginationContent>
46
+ <PaginationFirst />
47
+ <PaginationPrev />
48
+ <!-- Page buttons are auto-generated -->
49
+ <PaginationNext />
50
+ <PaginationLast />
51
+ </PaginationContent>
52
+ </Pagination>
53
+ </div>
54
+ ```
55
+
56
+ Place pagination at the bottom of data tables or list views, with a results count on the left.
57
+
58
+ ## Back Button
59
+
60
+ For detail views, use a ghost button instead of breadcrumbs:
61
+
62
+ ```tsx
63
+ <Button variant="ghost" size="sm" className="gap-1">
64
+ <ArrowLeft className="w-4 h-4" />
65
+ Back
66
+ </Button>
67
+ ```
68
+
69
+ ## Rules
70
+ - **Breadcrumbs**: Only for 3+ level hierarchies
71
+ - **Back button**: Always present on detail/drill-down views
72
+ - **Tabs**: For related content within a single view (not for navigation between views)
73
+ - **Pagination**: Always show results count alongside page controls
@@ -0,0 +1,77 @@
1
+ # Sheet, ScrollArea
2
+
3
+ Overlay and scroll components.
4
+
5
+ ```ts
6
+ import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetFooter, SheetTrigger, SheetClose } from '@reinvented/design'
7
+ import { ScrollArea } from '@reinvented/design'
8
+ ```
9
+
10
+ ## Sheet
11
+
12
+ Slide-out panel from the edge of the screen. Use for secondary forms, filters, or detail previews that don't warrant a full page.
13
+
14
+ ```tsx
15
+ <Sheet>
16
+ <SheetTrigger as-child>
17
+ <Button variant="outline">View Details</Button>
18
+ </SheetTrigger>
19
+ <SheetContent side="right" className="w-full max-w-md sm:max-w-lg">
20
+ <SheetHeader>
21
+ <SheetTitle>Task Details</SheetTitle>
22
+ <SheetDescription>View and edit task information.</SheetDescription>
23
+ </SheetHeader>
24
+ <div className="space-y-6 py-6">
25
+ <!-- Content -->
26
+ </div>
27
+ <SheetFooter>
28
+ <SheetClose as-child>
29
+ <Button variant="outline">Cancel</Button>
30
+ </SheetClose>
31
+ <Button>Save Changes</Button>
32
+ </SheetFooter>
33
+ </SheetContent>
34
+ </Sheet>
35
+ ```
36
+
37
+ ### Sheet Sides
38
+ | Side | When to Use |
39
+ |------|-------------|
40
+ | `right` | Default. Detail panels, edit forms, filters. |
41
+ | `left` | Mobile navigation drawer. |
42
+ | `bottom` | Mobile action sheets, bottom drawers. |
43
+ | `top` | Rarely used. Notification panels. |
44
+
45
+ ### Sheet vs Dialog
46
+ | Use Case | Component |
47
+ |----------|-----------|
48
+ | Quick form (≤5 fields) | Dialog |
49
+ | Detail panel / preview | Sheet (right) |
50
+ | Complex edit form | Sheet (right, wider) |
51
+ | Mobile navigation | Sheet (left) |
52
+ | Destructive confirmation | AlertDialog |
53
+
54
+ ## ScrollArea
55
+
56
+ Styled scrollbar container. Use when content might overflow.
57
+
58
+ ```tsx
59
+ <ScrollArea className="h-72">
60
+ <div className="space-y-4 pr-4">
61
+ <!-- Scrollable content -->
62
+ </div>
63
+ </ScrollArea>
64
+ ```
65
+
66
+ ### Common Uses
67
+ - Long lists inside fixed-height containers
68
+ - Sidebar navigation that exceeds viewport
69
+ - Modal content that might overflow
70
+ - Code preview areas
71
+
72
+ ### Rules
73
+ - Add `pr-4` to content inside ScrollArea to prevent scrollbar overlapping text
74
+ - **In Normal Containers**: Set an explicit height (`h-72`, `max-h-96`, or use a named size).
75
+ - **In Flex/Grid Containers**: If placed inside a flex column or grid cell that stretches, DO NOT use a fixed height. Instead, ensure the parent has `flex-1 min-h-0` (or `min-w-0`) and make the `ScrollArea` `h-full` to fill the available space dynamically.
76
+ - **Avoid Nested Scrolling**: Never put a vertical `<ScrollArea>` inside a page that also scrolls vertically ("scrolling within scrolling"). If you require an inner scrollable area (like a kanban column), ensure the root wrapper of the view is bounded and cannot scroll (e.g., `h-[100dvh] overflow-hidden`).
77
+ - Use `<ScrollArea>` instead of `overflow-y-auto` for consistent scrollbar styling
@@ -0,0 +1,51 @@
1
+ # Component: PageHeader
2
+
3
+ A structured set of components for building consistent, responsive page headers across the application. These prevent common layout errors when switching from desktop (horizontal) to mobile (vertical).
4
+
5
+ ## Components
6
+
7
+ - `PageHeader`: The outer container. Handles responsive flex flow.
8
+ - `PageHeaderHeading`: Groups the title and description vertically.
9
+ - `PageHeaderTitle`: The main `<h1>`. Handles font scaling from mobile (`text-xl`) to desktop (`text-2xl`).
10
+ - `PageHeaderDescription`: Secondary text below the title.
11
+ - `PageHeaderActions`: The container for buttons. On mobile, elements stack to full width.
12
+
13
+ ## Usage
14
+
15
+ ```tsx
16
+ // React Component
17
+ import {
18
+ PageHeader,
19
+ PageHeaderHeading,
20
+ PageHeaderTitle,
21
+ PageHeaderDescription,
22
+ PageHeaderActions,
23
+ Button
24
+ } from '@reinvented/design'
25
+ // ...
26
+
27
+
28
+ export default function Component() {
29
+ return (
30
+ <>
31
+ <PageHeader>
32
+ <PageHeaderHeading>
33
+ <PageHeaderTitle>Settings</PageHeaderTitle>
34
+ <PageHeaderDescription>Manage your account preferences and defaults.</PageHeaderDescription>
35
+ </PageHeaderHeading>
36
+
37
+ <PageHeaderActions>
38
+ <Button variant="outline">Cancel</Button>
39
+ <Button>Save Changes</Button>
40
+ </PageHeaderActions>
41
+ </PageHeader>
42
+ </>
43
+ )
44
+ }
45
+ ```
46
+
47
+ ## Rules
48
+
49
+ - **Always use these components** instead of raw `<h1>` or `<div>` trees for primary page headers.
50
+ - **Do not manually add sizing classes** to `<PageHeaderTitle>`: it inherently handles the `text-xl sm:text-2xl` scaling.
51
+ - **Do not manually add width classes** to buttons inside `<PageHeaderActions>`: the container handles stretching them on mobile (`w-full`) and sizing them to content on desktop (`sm:w-auto`).
@@ -0,0 +1,175 @@
1
+ # Select, Checkbox, Switch, RadioGroup, Slider
2
+
3
+ Form controls for choosing values.
4
+
5
+ ```ts
6
+ import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@reinvented/design'
7
+ import { Checkbox } from '@reinvented/design'
8
+ import { Switch } from '@reinvented/design'
9
+ import { RadioGroup, RadioGroupItem } from '@reinvented/design'
10
+ import { Slider } from '@reinvented/design'
11
+ ```
12
+
13
+ ## Select
14
+
15
+ Dropdown for choosing one value from a list. Use when there are 4+ options.
16
+
17
+ ```tsx
18
+ <div className="space-y-2">
19
+ <Label>Status</Label>
20
+ <Select defaultValue="status">
21
+ <SelectTrigger className="w-48">
22
+ <SelectValue placeholder="Select status" />
23
+ </SelectTrigger>
24
+ <SelectContent>
25
+ <SelectGroup>
26
+ <SelectLabel>Status</SelectLabel>
27
+ <SelectItem value="active">Active</SelectItem>
28
+ <SelectItem value="inactive">Inactive</SelectItem>
29
+ <SelectItem value="pending">Pending</SelectItem>
30
+ </SelectGroup>
31
+ </SelectContent>
32
+ </Select>
33
+ </div>
34
+ ```
35
+
36
+ ### Select Width
37
+ - **Filter select** (in toolbar): `w-36` or `w-48`
38
+ - **Form select** (in form): `w-full` (takes full width of form column)
39
+
40
+ ### Grouped Select
41
+ ```tsx
42
+ <SelectContent>
43
+ <SelectGroup>
44
+ <SelectLabel>Roles</SelectLabel>
45
+ <SelectItem value="admin">Admin</SelectItem>
46
+ <SelectItem value="editor">Editor</SelectItem>
47
+ </SelectGroup>
48
+ <SelectGroup>
49
+ <SelectLabel>Access</SelectLabel>
50
+ <SelectItem value="viewer">Viewer</SelectItem>
51
+ <SelectItem value="none">No Access</SelectItem>
52
+ </SelectGroup>
53
+ </SelectContent>
54
+ ```
55
+
56
+ ## Checkbox
57
+
58
+ Boolean toggle with checkmark. Use for multi-select from a set of options.
59
+
60
+ ```tsx
61
+ <div className="flex items-start gap-3">
62
+ <Checkbox id="terms" v-model:checked="agreed" className="mt-0.5" />
63
+ <div>
64
+ <Label for="terms" className="text-sm font-medium">Accept terms</Label>
65
+ <p className="text-xs text-muted-foreground">You agree to our Terms of Service and Privacy Policy.</p>
66
+ </div>
67
+ </div>
68
+ ```
69
+
70
+ ### Checkbox Group
71
+ ```tsx
72
+ <div className="space-y-3">
73
+ <Label className="text-sm font-medium">Notifications</Label>
74
+ <div v-for="opt in options" :key="opt.id" className="flex items-center gap-3">
75
+ <Checkbox :id="opt.id" v-model:checked="opt.enabled" />
76
+ <Label :for="opt.id" className="text-sm">{{ opt.label }}</Label>
77
+ </div>
78
+ </div>
79
+ ```
80
+
81
+ ## Switch
82
+
83
+ On/off toggle. Use for boolean settings where the effect is immediate.
84
+
85
+ ```tsx
86
+ <div className="flex items-center justify-between">
87
+ <div>
88
+ <p className="text-sm font-medium">Email Notifications</p>
89
+ <p className="text-xs text-muted-foreground">Receive emails about account activity.</p>
90
+ </div>
91
+ <Switch v-model:checked="emailEnabled" />
92
+ </div>
93
+ ```
94
+
95
+ The standard pattern: label/description on the left, Switch on the right, separated by `justify-between`.
96
+
97
+ ## RadioGroup
98
+
99
+ Single choice from a small set (2–5 options). Use when all options should be visible.
100
+
101
+ ```tsx
102
+ <div className="space-y-3">
103
+ <Label className="text-sm font-medium">Plan</Label>
104
+ <RadioGroup defaultValue="plan" className="space-y-2">
105
+ <div className="flex items-center gap-3">
106
+ <RadioGroupItem value="free" id="free" />
107
+ <Label for="free" className="text-sm">Free — $0/month</Label>
108
+ </div>
109
+ <div className="flex items-center gap-3">
110
+ <RadioGroupItem value="pro" id="pro" />
111
+ <Label for="pro" className="text-sm">Pro — $19/month</Label>
112
+ </div>
113
+ <div className="flex items-center gap-3">
114
+ <RadioGroupItem value="team" id="team" />
115
+ <Label for="team" className="text-sm">Team — $49/month</Label>
116
+ </div>
117
+ </RadioGroup>
118
+ </div>
119
+ ```
120
+
121
+ ### Color Swatch Selector (RadioGroup Variant)
122
+
123
+ For e-commerce or customizable settings, use `RadioGroup` and style the items as color swatches to preserve visual aesthetics and keyboard accessibility.
124
+
125
+ ```tsx
126
+ <div className="space-y-3">
127
+ <Label className="text-xs font-bold text-muted-foreground uppercase tracking-widest">Theme Color</Label>
128
+ <RadioGroup defaultValue="activeColor" className="flex items-center gap-3">
129
+ <RadioGroupItem
130
+ v-for="color in colors"
131
+ :key="color.id"
132
+ :value="color.id"
133
+ :id="color.id"
134
+ className="w-8 h-8 rounded-full border border-black/10 dark:border-white/10 shadow-sm transition-all duration-200"
135
+ className={[
136
+ color.bgClass, // e.g., 'bg-amber-400'
137
+ activeColor === color.id ? 'ring-2 ring-offset-2 ring-foreground scale-110 border-transparent' : 'opacity-90 hover:opacity-100 hover:scale-105'
138
+ ]}
139
+ />
140
+ </RadioGroup>
141
+ </div>
142
+ ```
143
+
144
+ > **Warning:** When applying `ring` and `scale` transforms to active elements within collapsible panels, verify the parent container has enough bottom margin/padding (e.g. `pb-2`). Otherwise, strict `overflow-hidden` transitions will clip the focus ring.
145
+
146
+ ## Slider
147
+
148
+ Numeric range input.
149
+
150
+ ```tsx
151
+ <div className="space-y-3">
152
+ <div className="flex items-center justify-between">
153
+ <Label className="text-sm font-medium">Volume</Label>
154
+ <span className="text-sm text-muted-foreground">{{ volume }}%</span>
155
+ </div>
156
+ <Slider defaultValue="volume" :max="100" :step="1" className="w-full" />
157
+ </div>
158
+ ```
159
+
160
+ ## Decision Tree
161
+
162
+ ```
163
+ How many options?
164
+ ├─ 2 (on/off, yes/no)
165
+ │ ├─ Setting that takes effect immediately? → Switch
166
+ │ └─ Checkbox in a form submission? → Checkbox
167
+ ├─ 2–5 (all visible at once)
168
+ │ └─ → RadioGroup
169
+ ├─ 4+ (too many for radio buttons)
170
+ │ └─ → Select dropdown
171
+ ├─ Multi-select from options
172
+ │ └─ → Checkbox group
173
+ ├─ Numeric range
174
+ │ └─ → Slider
175
+ ```
@@ -0,0 +1,102 @@
1
+ # Table
2
+
3
+ Data tables for structured, tabular content. Never use raw `<table>`.
4
+
5
+ ```ts
6
+ import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from '@reinvented/design'
7
+ ```
8
+
9
+ ## Basic Table
10
+
11
+ ```tsx
12
+ <Table>
13
+ <TableHeader>
14
+ <TableRow>
15
+ <TableHead>Name</TableHead>
16
+ <TableHead>Email</TableHead>
17
+ <TableHead>Role</TableHead>
18
+ <TableHead>Status</TableHead>
19
+ <TableHead className="text-right">Amount</TableHead>
20
+ <TableHead className="w-10"></TableHead>
21
+ </TableRow>
22
+ </TableHeader>
23
+ <TableBody>
24
+ <TableRow v-for="user in users" :key="user.id">
25
+ <TableCell>
26
+ <div className="flex items-center gap-3">
27
+ <div className="w-8 h-8 rounded-full shrink-0 flex items-center justify-center text-xs font-medium bg-muted text-muted-foreground">
28
+ {{ user.name.split(' ').map(n => n[0]).join('') }}
29
+ </div>
30
+ <div className="min-w-0">
31
+ <p className="text-sm font-medium truncate">{{ user.name }}</p>
32
+ <p className="text-xs text-muted-foreground truncate">{{ user.email }}</p>
33
+ </div>
34
+ </div>
35
+ </TableCell>
36
+ <TableCell className="text-muted-foreground">{{ user.email }}</TableCell>
37
+ <TableCell>{{ user.role }}</TableCell>
38
+ <TableCell>
39
+ <Badge :variant="user.status === 'active' ? 'default' : 'secondary'">{{ user.status }}</Badge>
40
+ </TableCell>
41
+ <TableCell className="text-right font-medium">${{ user.amount.toLocaleString() }}</TableCell>
42
+ <TableCell>
43
+ <DropdownMenu>
44
+ <DropdownMenuTrigger as-child>
45
+ <Button variant="ghost" size="icon" className="h-8 w-8">
46
+ <MoreHorizontal className="w-4 h-4" />
47
+ </Button>
48
+ </DropdownMenuTrigger>
49
+ <DropdownMenuContent align="end">
50
+ <DropdownMenuItem><Pencil className="w-4 h-4" /> Edit</DropdownMenuItem>
51
+ <DropdownMenuSeparator />
52
+ <DropdownMenuItem className="text-destructive"><Trash2 className="w-4 h-4" /> Delete</DropdownMenuItem>
53
+ </DropdownMenuContent>
54
+ </DropdownMenu>
55
+ </TableCell>
56
+ </TableRow>
57
+ </TableBody>
58
+ </Table>
59
+ ```
60
+
61
+ ## Column Formatting Rules
62
+
63
+ | Content Type | Alignment | Class |
64
+ |-------------|-----------|-------|
65
+ | Text (names, descriptions) | Left (default) | — |
66
+ | Numbers, currency, amounts | Right | `className="text-right"` |
67
+ | Status badges | Left | — |
68
+ | Dates | Left | `className="text-muted-foreground"` |
69
+ | Actions (menu) | Right | `className="w-10"` on the head |
70
+ | Primary identifier (name) | Left | `className="font-medium"` |
71
+
72
+ ## Empty Table
73
+
74
+ ```tsx
75
+ <TableBody>
76
+ <TableRow v-if="items.length === 0">
77
+ <TableCell :colspan="columns.length" className="h-32 text-center text-muted-foreground">
78
+ No results found.
79
+ </TableCell>
80
+ </TableRow>
81
+ </TableBody>
82
+ ```
83
+
84
+ ## Table with Selection
85
+
86
+ ```tsx
87
+ <TableHead className="w-10">
88
+ <Checkbox :checked="allSelected" @update:checked="toggleAll" />
89
+ </TableHead>
90
+ <!-- ... -->
91
+ <TableCell>
92
+ <Checkbox :checked="selectedIds.includes(user.id)" @update:checked="toggleUser(user.id)" />
93
+ </TableCell>
94
+ ```
95
+
96
+ ## Rules
97
+ - **Primary identifier column**: Use `font-medium` on the main entity name
98
+ - **Right-align numbers**: All currency, amounts, counts use `text-right`
99
+ - **Actions column**: Always last. Use `w-10` on `TableHead` and a three-dot `DropdownMenu`
100
+ - **Row count**: Show 5–8 rows for realistic density. Not 2, not 20.
101
+ - **Wrap in Card**: Data tables should typically be inside a `Card` for containment. When wrapping in a Card, note that the `CardHeader` has 24px horizontal padding, but `Table` cells default to 16px. To visually align the table headers and values with the card title, always add `className="pl-6"` to the first `TableHead` and `TableCell`, and `className="pr-6"` to the last `TableHead` and `TableCell`.
102
+ - **Always include a `TableHeader`**: Even if columns seem obvious.