@skunkworksai/ui-kit 0.1.18

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 (274) hide show
  1. package/AGENTS.md +250 -0
  2. package/README.md +429 -0
  3. package/dist/assets/Service-applets-apps/audience-measurement.png +0 -0
  4. package/dist/assets/Service-applets-apps/coatro-app.png +0 -0
  5. package/dist/assets/Service-applets-apps/content-effectiveness.png +0 -0
  6. package/dist/assets/Service-applets-apps/hop-tracking.png +0 -0
  7. package/dist/assets/Service-applets-apps/index.ts +13 -0
  8. package/dist/assets/Service-applets-apps/journeys-app.png +0 -0
  9. package/dist/assets/Service-applets-apps/people-counting.png +0 -0
  10. package/dist/assets/Service-applets-apps/petra.png +0 -0
  11. package/dist/assets/Service-applets-apps/sam-generic.png +0 -0
  12. package/dist/assets/Service-applets-apps/sami-for-environment.png +0 -0
  13. package/dist/assets/Service-applets-apps/shelf-engagement.png +0 -0
  14. package/dist/assets/Service-applets-apps/traffic-management.png +0 -0
  15. package/dist/assets/Service-applets-apps/viana.png +0 -0
  16. package/dist/assets/Service-applets-apps/zone-engagement.png +0 -0
  17. package/dist/assets/icons/Dashboard-active.svg +29 -0
  18. package/dist/assets/icons/Dashboard.svg +25 -0
  19. package/dist/assets/icons/DashboardActiveIcon.tsx +35 -0
  20. package/dist/assets/icons/DashboardIcon.tsx +31 -0
  21. package/dist/assets/icons/Devices-active.svg +27 -0
  22. package/dist/assets/icons/Devices.svg +20 -0
  23. package/dist/assets/icons/DevicesActiveIcon.tsx +33 -0
  24. package/dist/assets/icons/DevicesIcon.tsx +26 -0
  25. package/dist/assets/icons/Installer-active.svg +29 -0
  26. package/dist/assets/icons/Installer.svg +17 -0
  27. package/dist/assets/icons/InstallerActiveIcon.tsx +35 -0
  28. package/dist/assets/icons/InstallerIcon.tsx +23 -0
  29. package/dist/assets/icons/Manifest-active.svg +49 -0
  30. package/dist/assets/icons/Manifest.svg +49 -0
  31. package/dist/assets/icons/ManifestActiveIcon.tsx +55 -0
  32. package/dist/assets/icons/ManifestIcon.tsx +55 -0
  33. package/dist/assets/icons/Sensor-active.svg +15 -0
  34. package/dist/assets/icons/Sensor.svg +11 -0
  35. package/dist/assets/icons/SensorActiveIcon.tsx +21 -0
  36. package/dist/assets/icons/SensorIcon.tsx +17 -0
  37. package/dist/assets/icons/Site-active.svg +14 -0
  38. package/dist/assets/icons/Site.svg +10 -0
  39. package/dist/assets/icons/SiteActiveIcon.tsx +20 -0
  40. package/dist/assets/icons/SiteIcon.tsx +16 -0
  41. package/dist/assets/icons/X-ray-active.svg +199 -0
  42. package/dist/assets/icons/X-ray.svg +47 -0
  43. package/dist/assets/icons/XrayActiveIcon.tsx +205 -0
  44. package/dist/assets/icons/XrayIcon.tsx +53 -0
  45. package/dist/assets/icons/index.ts +14 -0
  46. package/dist/assets/logos/DarkLogo.tsx +28 -0
  47. package/dist/assets/logos/DarkSymbol.tsx +9 -0
  48. package/dist/assets/logos/PrimaryLogo.tsx +28 -0
  49. package/dist/assets/logos/PrimarySymbol.tsx +9 -0
  50. package/dist/assets/logos/WhiteLogo.tsx +28 -0
  51. package/dist/assets/logos/WhiteSymbol.tsx +9 -0
  52. package/dist/assets/logos/dark_logo.svg +22 -0
  53. package/dist/assets/logos/dark_symbol.svg +3 -0
  54. package/dist/assets/logos/index.ts +6 -0
  55. package/dist/assets/logos/primary-logo.svg +22 -0
  56. package/dist/assets/logos/primary_logo.svg +22 -0
  57. package/dist/assets/logos/primary_symbol.svg +3 -0
  58. package/dist/assets/logos/white_symbol.svg +3 -0
  59. package/dist/index.cjs +160 -0
  60. package/dist/index.cjs.map +1 -0
  61. package/dist/index.js +45276 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/tokens-source.css +121 -0
  64. package/dist/types/assets/Service-applets-apps/index.d.ts +13 -0
  65. package/dist/types/assets/icons/DashboardActiveIcon.d.ts +2 -0
  66. package/dist/types/assets/icons/DashboardIcon.d.ts +2 -0
  67. package/dist/types/assets/icons/DevicesActiveIcon.d.ts +2 -0
  68. package/dist/types/assets/icons/DevicesIcon.d.ts +2 -0
  69. package/dist/types/assets/icons/InstallerActiveIcon.d.ts +2 -0
  70. package/dist/types/assets/icons/InstallerIcon.d.ts +2 -0
  71. package/dist/types/assets/icons/ManifestActiveIcon.d.ts +2 -0
  72. package/dist/types/assets/icons/ManifestIcon.d.ts +2 -0
  73. package/dist/types/assets/icons/SensorActiveIcon.d.ts +2 -0
  74. package/dist/types/assets/icons/SensorIcon.d.ts +2 -0
  75. package/dist/types/assets/icons/SiteActiveIcon.d.ts +2 -0
  76. package/dist/types/assets/icons/SiteIcon.d.ts +2 -0
  77. package/dist/types/assets/icons/XrayActiveIcon.d.ts +2 -0
  78. package/dist/types/assets/icons/XrayIcon.d.ts +2 -0
  79. package/dist/types/assets/icons/index.d.ts +14 -0
  80. package/dist/types/assets/logos/DarkLogo.d.ts +2 -0
  81. package/dist/types/assets/logos/DarkSymbol.d.ts +2 -0
  82. package/dist/types/assets/logos/PrimaryLogo.d.ts +2 -0
  83. package/dist/types/assets/logos/PrimarySymbol.d.ts +2 -0
  84. package/dist/types/assets/logos/WhiteLogo.d.ts +2 -0
  85. package/dist/types/assets/logos/WhiteSymbol.d.ts +2 -0
  86. package/dist/types/assets/logos/index.d.ts +6 -0
  87. package/dist/types/components/blocks/AppBentoMenu.d.ts +31 -0
  88. package/dist/types/components/blocks/AppDashboard.d.ts +121 -0
  89. package/dist/types/components/blocks/AppHeader.d.ts +198 -0
  90. package/dist/types/components/blocks/AppLocationTreeFilter.d.ts +44 -0
  91. package/dist/types/components/blocks/AppNotificationsMenu.d.ts +50 -0
  92. package/dist/types/components/blocks/AppPageTitle.d.ts +86 -0
  93. package/dist/types/components/blocks/AppProfile.d.ts +53 -0
  94. package/dist/types/components/blocks/TableManager.d.ts +194 -0
  95. package/dist/types/components/blocks/backgrounds/AppDashboardBackgroundDots.d.ts +14 -0
  96. package/dist/types/components/blocks/backgrounds/AppDashboardBackgroundWave.d.ts +14 -0
  97. package/dist/types/components/blocks/backgrounds/index.d.ts +3 -0
  98. package/dist/types/components/blocks/backgrounds/types.d.ts +13 -0
  99. package/dist/types/components/blocks/index.d.ts +9 -0
  100. package/dist/types/components/primitives/AppAccordion.d.ts +22 -0
  101. package/dist/types/components/primitives/AppAlert.d.ts +33 -0
  102. package/dist/types/components/primitives/AppAlertDialog.d.ts +79 -0
  103. package/dist/types/components/primitives/AppAspectRatio.d.ts +7 -0
  104. package/dist/types/components/primitives/AppAvatar.d.ts +17 -0
  105. package/dist/types/components/primitives/AppBadge.d.ts +9 -0
  106. package/dist/types/components/primitives/AppBreadcrumb.d.ts +45 -0
  107. package/dist/types/components/primitives/AppButton.d.ts +24 -0
  108. package/dist/types/components/primitives/AppButtonGroup.d.ts +10 -0
  109. package/dist/types/components/primitives/AppCalendar.d.ts +51 -0
  110. package/dist/types/components/primitives/AppCard.d.ts +41 -0
  111. package/dist/types/components/primitives/AppCarousel.d.ts +26 -0
  112. package/dist/types/components/primitives/AppChart.d.ts +27 -0
  113. package/dist/types/components/primitives/AppCheckbox.d.ts +9 -0
  114. package/dist/types/components/primitives/AppCollapsible.d.ts +20 -0
  115. package/dist/types/components/primitives/AppCombobox.d.ts +37 -0
  116. package/dist/types/components/primitives/AppCommand.d.ts +47 -0
  117. package/dist/types/components/primitives/AppContextMenu.d.ts +82 -0
  118. package/dist/types/components/primitives/AppDataTable.d.ts +23 -0
  119. package/dist/types/components/primitives/AppDatePicker.d.ts +26 -0
  120. package/dist/types/components/primitives/AppDialog.d.ts +40 -0
  121. package/dist/types/components/primitives/AppDrawer.d.ts +58 -0
  122. package/dist/types/components/primitives/AppDropdownMenu.d.ts +85 -0
  123. package/dist/types/components/primitives/AppEmpty.d.ts +35 -0
  124. package/dist/types/components/primitives/AppField.d.ts +65 -0
  125. package/dist/types/components/primitives/AppForm.d.ts +58 -0
  126. package/dist/types/components/primitives/AppHoverCard.d.ts +19 -0
  127. package/dist/types/components/primitives/AppInput.d.ts +21 -0
  128. package/dist/types/components/primitives/AppKbd.d.ts +18 -0
  129. package/dist/types/components/primitives/AppLabel.d.ts +8 -0
  130. package/dist/types/components/primitives/AppMenubar.d.ts +83 -0
  131. package/dist/types/components/primitives/AppNavigationMenu.d.ts +51 -0
  132. package/dist/types/components/primitives/AppPagination.d.ts +46 -0
  133. package/dist/types/components/primitives/AppPopover.d.ts +20 -0
  134. package/dist/types/components/primitives/AppProgress.d.ts +9 -0
  135. package/dist/types/components/primitives/AppRadioGroup.d.ts +15 -0
  136. package/dist/types/components/primitives/AppScrollArea.d.ts +12 -0
  137. package/dist/types/components/primitives/AppScrollText.d.ts +7 -0
  138. package/dist/types/components/primitives/AppSelect.d.ts +46 -0
  139. package/dist/types/components/primitives/AppSeparator.d.ts +8 -0
  140. package/dist/types/components/primitives/AppSheet.d.ts +32 -0
  141. package/dist/types/components/primitives/AppSidebar.d.ts +59 -0
  142. package/dist/types/components/primitives/AppSkeleton.d.ts +6 -0
  143. package/dist/types/components/primitives/AppSpinner.d.ts +13 -0
  144. package/dist/types/components/primitives/AppSwitch.d.ts +8 -0
  145. package/dist/types/components/primitives/AppTable.d.ts +53 -0
  146. package/dist/types/components/primitives/AppTabs.d.ts +10 -0
  147. package/dist/types/components/primitives/AppTextarea.d.ts +9 -0
  148. package/dist/types/components/primitives/AppThemeProvider.d.ts +46 -0
  149. package/dist/types/components/primitives/AppToaster.d.ts +7 -0
  150. package/dist/types/components/primitives/AppToggle.d.ts +9 -0
  151. package/dist/types/components/primitives/AppToggleGroup.d.ts +18 -0
  152. package/dist/types/components/primitives/AppTooltip.d.ts +26 -0
  153. package/dist/types/components/primitives/AppTypography.d.ts +80 -0
  154. package/dist/types/components/primitives/index.d.ts +57 -0
  155. package/dist/types/components/ui/accordion.d.ts +7 -0
  156. package/dist/types/components/ui/alert-dialog.d.ts +20 -0
  157. package/dist/types/components/ui/alert.d.ts +8 -0
  158. package/dist/types/components/ui/aspect-ratio.d.ts +4 -0
  159. package/dist/types/components/ui/avatar.d.ts +6 -0
  160. package/dist/types/components/ui/badge.d.ts +9 -0
  161. package/dist/types/components/ui/breadcrumb.d.ts +19 -0
  162. package/dist/types/components/ui/button.d.ts +13 -0
  163. package/dist/types/components/ui/calendar.d.ts +8 -0
  164. package/dist/types/components/ui/card.d.ts +11 -0
  165. package/dist/types/components/ui/carousel.d.ts +28 -0
  166. package/dist/types/components/ui/chart.d.ts +48 -0
  167. package/dist/types/components/ui/checkbox.d.ts +4 -0
  168. package/dist/types/components/ui/collapsible.d.ts +6 -0
  169. package/dist/types/components/ui/combobox.d.ts +83 -0
  170. package/dist/types/components/ui/command.d.ts +82 -0
  171. package/dist/types/components/ui/context-menu.d.ts +27 -0
  172. package/dist/types/components/ui/dialog.d.ts +19 -0
  173. package/dist/types/components/ui/drawer.d.ts +23 -0
  174. package/dist/types/components/ui/dropdown-menu.d.ts +27 -0
  175. package/dist/types/components/ui/empty.d.ts +14 -0
  176. package/dist/types/components/ui/field.d.ts +40 -0
  177. package/dist/types/components/ui/form.d.ts +22 -0
  178. package/dist/types/components/ui/hover-card.d.ts +6 -0
  179. package/dist/types/components/ui/input.d.ts +3 -0
  180. package/dist/types/components/ui/kbd.d.ts +4 -0
  181. package/dist/types/components/ui/label.d.ts +4 -0
  182. package/dist/types/components/ui/menubar.d.ts +30 -0
  183. package/dist/types/components/ui/navigation-menu.d.ts +12 -0
  184. package/dist/types/components/ui/pagination.d.ts +28 -0
  185. package/dist/types/components/ui/popover.d.ts +6 -0
  186. package/dist/types/components/ui/progress.d.ts +4 -0
  187. package/dist/types/components/ui/radio-group.d.ts +5 -0
  188. package/dist/types/components/ui/scroll-area.d.ts +5 -0
  189. package/dist/types/components/ui/scroll-text.d.ts +6 -0
  190. package/dist/types/components/ui/select.d.ts +13 -0
  191. package/dist/types/components/ui/separator.d.ts +4 -0
  192. package/dist/types/components/ui/sheet.d.ts +25 -0
  193. package/dist/types/components/ui/sidebar.d.ts +69 -0
  194. package/dist/types/components/ui/skeleton.d.ts +2 -0
  195. package/dist/types/components/ui/sonner.d.ts +2 -0
  196. package/dist/types/components/ui/switch.d.ts +4 -0
  197. package/dist/types/components/ui/table.d.ts +10 -0
  198. package/dist/types/components/ui/tabs.d.ts +19 -0
  199. package/dist/types/components/ui/textarea.d.ts +5 -0
  200. package/dist/types/components/ui/toggle-group.d.ts +15 -0
  201. package/dist/types/components/ui/toggle.d.ts +12 -0
  202. package/dist/types/components/ui/tooltip.d.ts +7 -0
  203. package/dist/types/hooks/use-mobile.d.ts +13 -0
  204. package/dist/types/hooks/use-page-title.d.ts +23 -0
  205. package/dist/types/index.d.ts +2 -0
  206. package/dist/types/lib/utils.d.ts +2 -0
  207. package/dist/ui-kit.css +1 -0
  208. package/package.json +117 -0
  209. package/rules/accordion.md +60 -0
  210. package/rules/alert-dialog.md +62 -0
  211. package/rules/alert.md +61 -0
  212. package/rules/aspect-ratio.md +47 -0
  213. package/rules/avatar.md +52 -0
  214. package/rules/badge.md +55 -0
  215. package/rules/bento-menu.md +86 -0
  216. package/rules/breadcrumb.md +80 -0
  217. package/rules/button-group.md +58 -0
  218. package/rules/button.md +66 -0
  219. package/rules/calendar.md +97 -0
  220. package/rules/card.md +84 -0
  221. package/rules/carousel.md +113 -0
  222. package/rules/chart.md +125 -0
  223. package/rules/checkbox.md +49 -0
  224. package/rules/collapsible.md +57 -0
  225. package/rules/combobox.md +133 -0
  226. package/rules/command.md +73 -0
  227. package/rules/context-menu.md +65 -0
  228. package/rules/dashboard.md +368 -0
  229. package/rules/data-table.md +91 -0
  230. package/rules/date-picker.md +65 -0
  231. package/rules/dialog.md +60 -0
  232. package/rules/drawer.md +65 -0
  233. package/rules/dropdown-menu.md +72 -0
  234. package/rules/empty.md +110 -0
  235. package/rules/field.md +149 -0
  236. package/rules/form.md +60 -0
  237. package/rules/header.md +245 -0
  238. package/rules/hover-card.md +53 -0
  239. package/rules/icons.md +141 -0
  240. package/rules/input.md +66 -0
  241. package/rules/kbd.md +58 -0
  242. package/rules/label.md +30 -0
  243. package/rules/location-tree-filter.md +165 -0
  244. package/rules/logo.md +58 -0
  245. package/rules/menubar.md +75 -0
  246. package/rules/navigation-menu.md +68 -0
  247. package/rules/notifications-menu.md +137 -0
  248. package/rules/pagetitle.md +160 -0
  249. package/rules/pagination.md +71 -0
  250. package/rules/popover.md +48 -0
  251. package/rules/profile.md +125 -0
  252. package/rules/progress.md +41 -0
  253. package/rules/radio-group.md +44 -0
  254. package/rules/scroll-area.md +32 -0
  255. package/rules/scroll-text.md +40 -0
  256. package/rules/select.md +86 -0
  257. package/rules/separator.md +43 -0
  258. package/rules/sheet.md +76 -0
  259. package/rules/sidebar.md +442 -0
  260. package/rules/skeleton.md +46 -0
  261. package/rules/spinner.md +43 -0
  262. package/rules/switch.md +46 -0
  263. package/rules/table-manager.md +306 -0
  264. package/rules/table.md +177 -0
  265. package/rules/tabs.md +82 -0
  266. package/rules/text.md +3 -0
  267. package/rules/textarea.md +38 -0
  268. package/rules/toaster.md +58 -0
  269. package/rules/toggle-group.md +50 -0
  270. package/rules/toggle.md +40 -0
  271. package/rules/tokens.md +88 -0
  272. package/rules/tooltip.md +78 -0
  273. package/rules/typography.md +81 -0
  274. package/scripts/scaffold.mjs +28 -0
@@ -0,0 +1,97 @@
1
+ # AppCalendar
2
+
3
+ > Docs: https://ui-kit.vercel.app/docs/components/calendar
4
+
5
+ ```tsx
6
+ import { AppCalendar } from "@/components/primitives/AppCalendar"
7
+ ```
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ |------|------|---------|-------------|
13
+ | `mode` | `"single" \| "range"` | `"single"` | Selection mode |
14
+ | `value` | `Date \| DateRange` | — | Controlled selected date(s) |
15
+ | `onChange` | `(date) => void` | — | Change handler |
16
+ | `popover` | `boolean` | `false` | Render as a popover trigger instead of inline |
17
+ | `presets` | `{ label: string; days: number }[]` | `[]` | Quick-select preset buttons (popover only) |
18
+ | `placeholder` | `string` | — | Trigger button label when no date selected (popover only) |
19
+ | `numberOfMonths` | `number` | `1` | Months to display side by side |
20
+ | `showWeekNumber` | `boolean` | `false` | Show ISO week numbers |
21
+ | `disabled` | `boolean` | `false` | Disable the trigger button (popover only) |
22
+ | `disabledDates` | `Matcher \| Matcher[]` | — | Disable specific dates in the calendar |
23
+
24
+ ## Usage
25
+
26
+ ### Inline (basic)
27
+ ```tsx
28
+ <AppCalendar
29
+ mode="single"
30
+ value={date}
31
+ onChange={setDate}
32
+ />
33
+ ```
34
+
35
+ ### Inline range
36
+ ```tsx
37
+ <AppCalendar
38
+ mode="range"
39
+ value={range}
40
+ onChange={setRange}
41
+ numberOfMonths={2}
42
+ />
43
+ ```
44
+
45
+ ### Popover date picker (built-in)
46
+ ```tsx
47
+ <AppCalendar
48
+ mode="single"
49
+ popover
50
+ value={date}
51
+ onChange={setDate}
52
+ placeholder="Pick a date"
53
+ className="w-64"
54
+ />
55
+ ```
56
+
57
+ ### Popover with presets
58
+ ```tsx
59
+ <AppCalendar
60
+ mode="single"
61
+ popover
62
+ value={date}
63
+ onChange={setDate}
64
+ presets={[
65
+ { label: "Today", days: 0 },
66
+ { label: "Tomorrow", days: 1 },
67
+ { label: "In a week", days: 7 },
68
+ ]}
69
+ className="w-64"
70
+ />
71
+ ```
72
+
73
+ ### Popover range picker
74
+ ```tsx
75
+ <AppCalendar
76
+ mode="range"
77
+ popover
78
+ value={range}
79
+ onChange={setRange}
80
+ numberOfMonths={2}
81
+ className="w-64"
82
+ />
83
+ ```
84
+
85
+ ## Rules
86
+ - ✅ Always use `mode` to specify the selection behavior
87
+ - ✅ Use `popover` prop for a built-in dropdown date picker — no need to manually wrap in `AppPopover`
88
+ - ✅ Use `presets` for quick-select shortcuts (popover mode only)
89
+ - ✅ Use `numberOfMonths={2}` for range selection to improve usability
90
+ - ✅ Set trigger width via `className` when using `popover` (e.g. `className="w-64"`) — no default width
91
+ - ❌ Do not wrap `AppCalendar` in `AppPopover` manually — use the `popover` prop instead
92
+ - ❌ Do not use `AppCalendar` for simple month/year selection — it is optimized for date selection
93
+ - ❌ If a prop you need is missing, stop and inform the design team
94
+
95
+ ## Responsive
96
+
97
+ On mobile (<768px) `numberOfMonths` is forced to `1` regardless of the prop value; on desktop the prop value is used (default `2` for range mode). Pass `numberOfMonths={1}` explicitly to opt out of the 2-month default on desktop without affecting mobile behavior.
package/rules/card.md ADDED
@@ -0,0 +1,84 @@
1
+ # AppCard
2
+
3
+ > Docs: https://ui-kit.vercel.app/docs/components/card
4
+
5
+ ```tsx
6
+ import {
7
+ AppCard,
8
+ AppCardHeader,
9
+ AppCardTitle,
10
+ AppCardDescription,
11
+ AppCardAction,
12
+ AppCardContent,
13
+ AppCardFooter,
14
+ } from "@/components/primitives/AppCard"
15
+ ```
16
+
17
+ ## AppCard
18
+
19
+ | Prop | Type | Default | Description |
20
+ |------|------|---------|-------------|
21
+ | `size` | `"default" \| "sm"` | `"default"` | Padding and spacing size (shadcn base prop) |
22
+ | `padding` | `"default" \| "none" \| "sm" \| "md" \| "lg"` | `"default"` | Override internal padding for dense/media layouts |
23
+
24
+ ## Usage
25
+
26
+ ### Basic
27
+ ```tsx
28
+ <AppCard>
29
+ <AppCardHeader>
30
+ <AppCardTitle>Project Update</AppCardTitle>
31
+ <AppCardDescription>Deploying to production tomorrow.</AppCardDescription>
32
+ </AppCardHeader>
33
+ <AppCardContent>
34
+ <p>Everything is looking good. All tests passed.</p>
35
+ </AppCardContent>
36
+ <AppCardFooter>
37
+ <AppButton>Dismiss</AppButton>
38
+ </AppCardFooter>
39
+ </AppCard>
40
+ ```
41
+
42
+ ### With Action
43
+ ```tsx
44
+ <AppCardHeader>
45
+ <AppCardTitle>Settings</AppCardTitle>
46
+ <AppCardDescription>Manage your account settings.</AppCardDescription>
47
+ <AppCardAction>
48
+ <AppButton variant="outline" size="sm">Edit</AppButton>
49
+ </AppCardAction>
50
+ </AppCardHeader>
51
+ ```
52
+
53
+ ### Small Size
54
+ ```tsx
55
+ <AppCard size="sm">
56
+ <AppCardHeader>
57
+ <AppCardTitle>Summary</AppCardTitle>
58
+ </AppCardHeader>
59
+ <AppCardContent>
60
+ <p>Compact card content.</p>
61
+ </AppCardContent>
62
+ </AppCard>
63
+ ```
64
+
65
+ ### Dense / media layout
66
+ ```tsx
67
+ <AppCard padding="none">
68
+ <img src="/feed.jpg" alt="Camera feed" className="h-40 w-full object-cover" />
69
+ <AppCardHeader>
70
+ <AppCardTitle>Camera 01</AppCardTitle>
71
+ </AppCardHeader>
72
+ </AppCard>
73
+ ```
74
+
75
+ `padding` values: `"default"` (24px), `"none"` (0), `"sm"` (12px), `"md"` (16px), `"lg"` (32px).
76
+
77
+ ## Rules
78
+ - ✅ Use `AppCardAction` for actions that should live in the header (aligned top-right)
79
+ - ✅ Use `AppCardHeader` to group Title, Description, and Action together
80
+ - ✅ Use `AppCard` as the standard container for grouped information
81
+ - ✅ Use `padding="none"` for flush media cards (camera feeds, image-first layouts)
82
+ - ❌ Do not nest multiple `AppCard` components unless visually distinct
83
+ - ❌ Do not use `!important` overrides on Card children — use the `padding` prop instead
84
+ - ❌ If a prop you need is missing, stop and inform the design team
@@ -0,0 +1,113 @@
1
+ # AppCarousel
2
+
3
+ > Docs: https://ui-kit.vercel.app/docs/components/carousel
4
+
5
+ ```tsx
6
+ import {
7
+ AppCarousel,
8
+ AppCarouselContent,
9
+ AppCarouselItem,
10
+ AppCarouselPrevious,
11
+ AppCarouselNext,
12
+ type AppCarouselApi,
13
+ useAppCarousel,
14
+ } from "@skunkworksai/ui-kit"
15
+ ```
16
+
17
+ ## AppCarousel
18
+
19
+ | Prop | Type | Default | Description |
20
+ |------|------|---------|-------------|
21
+ | `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Scroll axis. |
22
+ | `opts` | `EmblaOptionsType` | — | Embla configuration object (align, loop, etc.). |
23
+ | `setApi` | `(api: AppCarouselApi) => void` | — | Callback to receive the Embla API instance for programmatic control. |
24
+ | `plugins` | `EmblaPluginType[]` | — | Embla plugins (e.g. autoplay). |
25
+
26
+ ## AppCarouselContent
27
+
28
+ Accepts all `div` props. The scrollable slide container — wrap `AppCarouselItem` children inside.
29
+
30
+ ## AppCarouselItem
31
+
32
+ Accepts all `div` props. Use `className="basis-1/2"` (or `basis-1/3`, etc.) to show multiple slides at once.
33
+
34
+ ## AppCarouselPrevious / AppCarouselNext
35
+
36
+ Accepts all `button` props. Positioned absolutely — ensure the parent (`AppCarousel`) has enough horizontal padding (e.g. `px-14`) so buttons don't overlap slide content.
37
+
38
+ ## Usage
39
+
40
+ ### Basic
41
+ ```tsx
42
+ <div className="px-14 max-w-sm">
43
+ <AppCarousel>
44
+ <AppCarouselContent>
45
+ {items.map((item, i) => (
46
+ <AppCarouselItem key={i}>
47
+ <AppCard>
48
+ <AppCardContent className="flex aspect-square items-center justify-center p-6">
49
+ {item}
50
+ </AppCardContent>
51
+ </AppCard>
52
+ </AppCarouselItem>
53
+ ))}
54
+ </AppCarouselContent>
55
+ <AppCarouselPrevious />
56
+ <AppCarouselNext />
57
+ </AppCarousel>
58
+ </div>
59
+ ```
60
+
61
+ ### Multiple slides visible
62
+ ```tsx
63
+ <AppCarousel opts={{ align: "start" }}>
64
+ <AppCarouselContent>
65
+ {items.map((item, i) => (
66
+ <AppCarouselItem key={i} className="basis-1/3">
67
+ ...
68
+ </AppCarouselItem>
69
+ ))}
70
+ </AppCarouselContent>
71
+ <AppCarouselPrevious />
72
+ <AppCarouselNext />
73
+ </AppCarousel>
74
+ ```
75
+
76
+ ### Vertical orientation
77
+ ```tsx
78
+ <AppCarousel orientation="vertical" className="max-h-64">
79
+ <AppCarouselContent className="-mt-1 h-64">
80
+ {items.map((item, i) => (
81
+ <AppCarouselItem key={i} className="pt-1 basis-1/3">
82
+ ...
83
+ </AppCarouselItem>
84
+ ))}
85
+ </AppCarouselContent>
86
+ <AppCarouselPrevious />
87
+ <AppCarouselNext />
88
+ </AppCarousel>
89
+ ```
90
+
91
+ ### Programmatic API access
92
+ ```tsx
93
+ const [api, setApi] = React.useState<AppCarouselApi>()
94
+ const [current, setCurrent] = React.useState(0)
95
+
96
+ React.useEffect(() => {
97
+ if (!api) return
98
+ setCurrent(api.selectedScrollSnap() + 1)
99
+ api.on("select", () => setCurrent(api.selectedScrollSnap() + 1))
100
+ }, [api])
101
+
102
+ <AppCarousel setApi={setApi}>...</AppCarousel>
103
+ <p>Slide {current} of {api?.scrollSnapList().length}</p>
104
+ ```
105
+
106
+ ## Rules
107
+ - ✅ Always wrap `AppCarouselPrevious` / `AppCarouselNext` inside `AppCarousel` — they use carousel context
108
+ - ✅ Add horizontal padding (e.g. `px-14`) to the container when using nav buttons in horizontal mode
109
+ - ✅ Add vertical padding (e.g. `py-14`) when using nav buttons in vertical mode
110
+ - ✅ Use `opts={{ loop: true }}` for infinite looping
111
+ - ✅ Use `setApi` to get the Embla instance for programmatic scroll, event listeners, or slide counters
112
+ - ❌ Do not use `AppCarouselPrevious` / `AppCarouselNext` outside an `AppCarousel` — they require its context
113
+ - ❌ If a prop you need is missing, stop and inform the design team
package/rules/chart.md ADDED
@@ -0,0 +1,125 @@
1
+ # AppChart
2
+
3
+ > Docs: https://ui-kit.vercel.app/docs/components/chart
4
+
5
+ ```tsx
6
+ import {
7
+ AppChartContainer,
8
+ AppChartTooltip,
9
+ AppChartTooltipContent,
10
+ AppChartLegend,
11
+ AppChartLegendContent,
12
+ AppChartStyle,
13
+ type AppChartConfig,
14
+ // Recharts chart + shape components re-exported:
15
+ BarChart, Bar, LineChart, Line, AreaChart, Area,
16
+ PieChart, Pie, Cell, CartesianGrid, XAxis, YAxis,
17
+ } from "@skunkworksai/ui-kit"
18
+ ```
19
+
20
+ ## AppChartContainer
21
+
22
+ | Prop | Type | Default | Description |
23
+ |------|------|---------|-------------|
24
+ | `config` | `AppChartConfig` | required | Color and label mappings for each data key. |
25
+ | `className` | `string` | — | Must include a height constraint (`min-h-*` or `aspect-*`). |
26
+ | `children` | `ReactElement` | required | A single Recharts chart component (BarChart, LineChart, etc.). |
27
+
28
+ ## AppChartTooltipContent
29
+
30
+ | Prop | Type | Default | Description |
31
+ |------|------|---------|-------------|
32
+ | `indicator` | `"dot" \| "line" \| "dashed"` | `"dot"` | Color swatch shape. |
33
+ | `nameKey` | `string` | — | Config key to look up labels. Set when `dataKey` ≠ config key (e.g. Pie charts). |
34
+ | `hideLabel` | `boolean` | `false` | Hides the series label row. |
35
+
36
+ ## AppChartLegendContent
37
+
38
+ | Prop | Type | Default | Description |
39
+ |------|------|---------|-------------|
40
+ | `nameKey` | `string` | — | Config key for label lookup. Set when `dataKey` ≠ config key (e.g. Pie charts). |
41
+
42
+ ## AppChartConfig
43
+
44
+ ```ts
45
+ type AppChartConfig = {
46
+ [key: string]: {
47
+ label: string
48
+ color?: string // CSS variable: "var(--chart-1)"
49
+ theme?: { // or per-theme colors
50
+ light: string
51
+ dark: string
52
+ }
53
+ icon?: React.ComponentType
54
+ }
55
+ }
56
+ ```
57
+
58
+ Inside Recharts, reference colors as `var(--color-{key})` — e.g. `var(--color-desktop)`.
59
+
60
+ ## Usage
61
+
62
+ ### Bar chart
63
+ ```tsx
64
+ const chartConfig = {
65
+ desktop: { label: "Desktop", color: "var(--chart-1)" },
66
+ mobile: { label: "Mobile", color: "var(--chart-2)" },
67
+ } satisfies AppChartConfig
68
+
69
+ <AppChartContainer config={chartConfig} className="min-h-[250px] w-full">
70
+ <BarChart data={data} accessibilityLayer>
71
+ <CartesianGrid vertical={false} />
72
+ <XAxis dataKey="month" tickLine={false} axisLine={false} tickMargin={8} />
73
+ <AppChartTooltip content={<AppChartTooltipContent />} />
74
+ <AppChartLegend content={<AppChartLegendContent />} />
75
+ <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
76
+ <Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
77
+ </BarChart>
78
+ </AppChartContainer>
79
+ ```
80
+
81
+ ### Line chart
82
+ ```tsx
83
+ <AppChartContainer config={chartConfig} className="min-h-[250px] w-full">
84
+ <LineChart data={data} accessibilityLayer>
85
+ <CartesianGrid vertical={false} />
86
+ <XAxis dataKey="month" tickLine={false} axisLine={false} tickMargin={8} />
87
+ <YAxis tickLine={false} axisLine={false} tickMargin={8} />
88
+ <AppChartTooltip content={<AppChartTooltipContent />} />
89
+ <AppChartLegend content={<AppChartLegendContent />} />
90
+ <Line dataKey="desktop" stroke="var(--color-desktop)" strokeWidth={2} dot={false} />
91
+ <Line dataKey="mobile" stroke="var(--color-mobile)" strokeWidth={2} dot={false} />
92
+ </LineChart>
93
+ </AppChartContainer>
94
+ ```
95
+
96
+ ### Pie chart
97
+ ```tsx
98
+ const pieConfig = {
99
+ Chrome: { label: "Chrome", color: "var(--chart-1)" },
100
+ Firefox: { label: "Firefox", color: "var(--chart-2)" },
101
+ } satisfies AppChartConfig
102
+
103
+ <AppChartContainer config={pieConfig} className="min-h-[250px] w-full">
104
+ <PieChart accessibilityLayer>
105
+ <AppChartTooltip content={<AppChartTooltipContent nameKey="name" />} />
106
+ <AppChartLegend content={<AppChartLegendContent nameKey="name" />} />
107
+ <Pie data={pieData} dataKey="value" nameKey="name" outerRadius={80}>
108
+ {pieData.map((entry) => (
109
+ <Cell key={entry.name} fill={pieConfig[entry.name as keyof typeof pieConfig]?.color} />
110
+ ))}
111
+ </Pie>
112
+ </PieChart>
113
+ </AppChartContainer>
114
+ ```
115
+
116
+ ## Rules
117
+ - ✅ Always set a height constraint on `AppChartContainer` (`min-h-[250px]`, `aspect-video`, etc.)
118
+ - ✅ Add `accessibilityLayer` to every Recharts chart component
119
+ - ✅ Use `var(--chart-1)` through `var(--chart-5)` as color values in config — never hardcode colors
120
+ - ✅ Reference colors inside the chart as `var(--color-{key})` (e.g. `var(--color-desktop)`)
121
+ - ✅ For Pie charts, set `nameKey` on both `AppChartTooltipContent` and `AppChartLegendContent` so labels resolve correctly
122
+ - ✅ Use `satisfies AppChartConfig` on your config object for type safety
123
+ - ❌ Do not import from `recharts` directly — import Recharts components from `@skunkworksai/ui-kit`
124
+ - ❌ Do not hardcode color values in `fill` or `stroke` — always use `var(--color-{key})`
125
+ - ❌ If a prop you need is missing, stop and inform the design team
@@ -0,0 +1,49 @@
1
+ # AppCheckbox
2
+
3
+ > Docs: https://ui-kit.vercel.app/docs/components/checkbox
4
+
5
+ ```tsx
6
+ import { AppCheckbox } from "@/components/primitives/AppCheckbox"
7
+ ```
8
+
9
+ ## AppCheckbox
10
+
11
+ | Prop | Type | Default | Description |
12
+ | :--- | :--- | :--- | :--- |
13
+ | `checked` | `boolean \| "indeterminate"` | - | The controlled checked state of the checkbox. |
14
+ | `defaultChecked` | `boolean` | - | The checked state of the checkbox when it is initially rendered. |
15
+ | `onCheckedChange` | `(checked: boolean \| "indeterminate") => void` | - | Event handler called when the checked state of the checkbox changes. |
16
+ | `disabled` | `boolean` | - | When true, prevents the user from interacting with the checkbox. |
17
+ | `required` | `boolean` | - | When true, indicates that the user must check the checkbox before the owning form can be submitted. |
18
+ | `name` | `string` | - | The name of the checkbox. Submitted with its owning form as part of a name/value pair. |
19
+ | `value` | `string` | `"on"` | The value given as data to the checkbox when submitted in a form. |
20
+
21
+ ## Usage
22
+
23
+ ### Default Checkbox
24
+ ```tsx
25
+ <div className="flex items-center gap-2">
26
+ <AppCheckbox id="terms" />
27
+ <label htmlFor="terms" className="text-sm font-medium">
28
+ Accept terms and conditions
29
+ </label>
30
+ </div>
31
+ ```
32
+
33
+ ### Disabled State
34
+ ```tsx
35
+ <div className="flex items-center gap-2">
36
+ <AppCheckbox id="disabled-terms" disabled />
37
+ <label htmlFor="disabled-terms" className="text-sm font-medium opacity-50">
38
+ Disabled checkbox
39
+ </label>
40
+ </div>
41
+ ```
42
+
43
+ ## Rules
44
+
45
+ - **Do** use `AppCheckbox` for all checkbox needs.
46
+ - **Do** always provide a corresponding label for accessibility.
47
+ - **Don't** use the raw HTML `<input type="checkbox">`.
48
+ - **Don't** manually style the checkbox unless absolutely necessary.
49
+ - If a prop you need is missing, stop and inform the design team.
@@ -0,0 +1,57 @@
1
+ # AppCollapsible
2
+
3
+ > Docs: https://ui-kit.vercel.app/docs/components/collapsible
4
+
5
+ ```tsx
6
+ import {
7
+ AppCollapsible,
8
+ AppCollapsibleTrigger,
9
+ AppCollapsibleContent
10
+ } from "@/components/primitives/AppCollapsible"
11
+ ```
12
+
13
+ ## AppCollapsible
14
+
15
+ | Prop | Type | Default | Description |
16
+ | :--- | :--- | :--- | :--- |
17
+ | `open` | `boolean` | - | The controlled open state of the collapsible. |
18
+ | `defaultOpen` | `boolean` | - | The open state of the collapsible when it is initially rendered. |
19
+ | `onOpenChange` | `(open: boolean) => void` | - | Event handler called when the open state of the collapsible changes. |
20
+ | `disabled` | `boolean` | - | When true, prevents the user from interacting with the collapsible. |
21
+
22
+ ## AppCollapsibleTrigger
23
+
24
+ | Prop | Type | Default | Description |
25
+ | :--- | :--- | :--- | :--- |
26
+ | `asChild` | `boolean` | `false` | Change the default rendered element for the one passed as a child, merging their props and behavior. |
27
+
28
+ ## AppCollapsibleContent
29
+
30
+ | Prop | Type | Default | Description |
31
+ | :--- | :--- | :--- | :--- |
32
+ | `forceMount` | `boolean` | - | Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries. |
33
+
34
+ ## Usage
35
+
36
+ ### Simple Collapsible
37
+ ```tsx
38
+ const [isOpen, setIsOpen] = React.useState(false)
39
+
40
+ <AppCollapsible open={isOpen} onOpenChange={setIsOpen}>
41
+ <AppCollapsibleTrigger asChild>
42
+ <AppButton variant="ghost">Toggle Content</AppButton>
43
+ </AppCollapsibleTrigger>
44
+ <AppCollapsibleContent>
45
+ <div className="p-4 border rounded-md">
46
+ Hidden information revealed!
47
+ </div>
48
+ </AppCollapsibleContent>
49
+ </AppCollapsible>
50
+ ```
51
+
52
+ ## Rules
53
+
54
+ - **Do** use `AppCollapsible` for showing/hiding additional content.
55
+ - **Do** use `asChild` on the trigger if you want to use a custom component like `AppButton`.
56
+ - **Don't** use `AppCollapsible` for complex menus; use `AppAccordion` or `AppNavigationMenu` instead.
57
+ - If a prop you need is missing, stop and inform the design team.
@@ -0,0 +1,133 @@
1
+ # AppCombobox
2
+
3
+ > Docs: https://ui-kit.vercel.app/docs/components/combobox
4
+
5
+ ```tsx
6
+ import {
7
+ AppCombobox,
8
+ AppComboboxInput,
9
+ AppComboboxContent,
10
+ AppComboboxList,
11
+ AppComboboxItem,
12
+ AppComboboxEmpty,
13
+ AppComboboxSeparator,
14
+ } from "@skunkworksai/ui-kit"
15
+ ```
16
+
17
+ ## AppCombobox
18
+
19
+ Root provider. Manages open state, search state, selection, and filtering.
20
+
21
+ | Prop | Type | Default | Description |
22
+ |------|------|---------|-------------|
23
+ | `items` | `readonly string[]` | — | **Required.** Flat list of option values. |
24
+ | `value` | `string` \| `string[]` | — | Controlled selected value(s). |
25
+ | `onValueChange` | `(value: string) => void` \| `(value: string[]) => void` | — | Selection change handler. |
26
+ | `multiple` | `boolean` | `false` | Enables multi-select. `value` becomes `string[]`. |
27
+ | `filter` | `(item: string, search: string) => boolean` | case-insensitive substring | Custom filter function. |
28
+ | `getDisplayValue` | `(value: string \| string[]) => string \| null` | — | Maps selected value(s) to display text in the trigger. |
29
+ | `disabled` | `boolean` | `false` | Disables the entire combobox. |
30
+
31
+ ## AppComboboxInput
32
+
33
+ Trigger button. Shows current selection or placeholder.
34
+
35
+ | Prop | Type | Default | Description |
36
+ |------|------|---------|-------------|
37
+ | `placeholder` | `string` | `"Select..."` | Shown when nothing is selected. |
38
+ | `className` | `string` | — | Additional Tailwind classes. |
39
+
40
+ ## AppComboboxContent
41
+
42
+ Popover panel. Contains search input and item list.
43
+
44
+ | Prop | Type | Default | Description |
45
+ |------|------|---------|-------------|
46
+ | `searchPlaceholder` | `string` | `"Search..."` | Placeholder inside the search input. |
47
+ | `align` | `"start"` \| `"center"` \| `"end"` | `"start"` | Popover alignment relative to trigger. |
48
+ | `sideOffset` | `number` | `4` | Vertical gap between trigger and popover (px). |
49
+
50
+ ## AppComboboxList
51
+
52
+ Renders filtered items via a render-prop function.
53
+
54
+ | Prop | Type | Default | Description |
55
+ |------|------|---------|-------------|
56
+ | `children` | `(item: string) => ReactNode` | — | **Required.** Render function per item value. |
57
+
58
+ ## AppComboboxItem
59
+
60
+ Single selectable option. Shows a checkmark when selected.
61
+
62
+ | Prop | Type | Default | Description |
63
+ |------|------|---------|-------------|
64
+ | `value` | `string` | — | **Required.** Must match a value in `items`. |
65
+
66
+ ## AppComboboxEmpty
67
+
68
+ Shown when no items match the current search.
69
+
70
+ | Prop | Type | Default | Description |
71
+ |------|------|---------|-------------|
72
+ | `children` | `ReactNode` | `"No results found."` | Empty-state message. |
73
+
74
+ ## AppComboboxSeparator
75
+
76
+ Visual divider between groups of items.
77
+
78
+ ## Usage
79
+
80
+ ### Single select with label mapping
81
+ ```tsx
82
+ const options = [
83
+ { value: "next", label: "Next.js" },
84
+ { value: "remix", label: "Remix" },
85
+ ]
86
+ const values = options.map((o) => o.value)
87
+ const labelOf = (v: string) => options.find((o) => o.value === v)?.label ?? v
88
+
89
+ <AppCombobox
90
+ items={values}
91
+ value={selected}
92
+ onValueChange={setSelected}
93
+ getDisplayValue={(v) => (v ? labelOf(v as string) : null)}
94
+ filter={(item, search) => labelOf(item).toLowerCase().includes(search.toLowerCase())}
95
+ >
96
+ <AppComboboxInput placeholder="Select framework..." />
97
+ <AppComboboxContent searchPlaceholder="Search...">
98
+ <AppComboboxEmpty>No framework found.</AppComboboxEmpty>
99
+ <AppComboboxList>
100
+ {(item) => <AppComboboxItem value={item}>{labelOf(item)}</AppComboboxItem>}
101
+ </AppComboboxList>
102
+ </AppComboboxContent>
103
+ </AppCombobox>
104
+ ```
105
+
106
+ ### Multi-select
107
+ ```tsx
108
+ <AppCombobox
109
+ multiple
110
+ items={values}
111
+ value={selected}
112
+ onValueChange={setSelected}
113
+ getDisplayValue={(v) => {
114
+ const arr = (v as string[]) ?? []
115
+ return arr.length ? arr.map(labelOf).join(", ") : null
116
+ }}
117
+ >
118
+ <AppComboboxInput placeholder="Select frameworks..." />
119
+ <AppComboboxContent>
120
+ <AppComboboxEmpty>No results.</AppComboboxEmpty>
121
+ <AppComboboxList>
122
+ {(item) => <AppComboboxItem value={item}>{labelOf(item)}</AppComboboxItem>}
123
+ </AppComboboxList>
124
+ </AppComboboxContent>
125
+ </AppCombobox>
126
+ ```
127
+
128
+ ## Rules
129
+ - ✅ Always pass `items` as `string[]` — use `getDisplayValue` + `filter` for label mapping
130
+ - ✅ Always render `AppComboboxEmpty` inside `AppComboboxContent`
131
+ - ✅ Always use `AppComboboxList` render-prop to map items to `AppComboboxItem`
132
+ - ❌ Never use a raw `<select>` or custom dropdown — use `AppCombobox`
133
+ - ❌ If a prop you need is missing, stop and inform the design team