@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,73 @@
1
+ # AppCommand
2
+
3
+ > Docs: https://ui-kit.vercel.app/docs/components/command
4
+
5
+ ```tsx
6
+ import {
7
+ AppCommand,
8
+ AppCommandDialog,
9
+ AppCommandInput,
10
+ AppCommandList,
11
+ AppCommandEmpty,
12
+ AppCommandGroup,
13
+ AppCommandItem,
14
+ AppCommandShortcut,
15
+ AppCommandSeparator,
16
+ } from "@/components/primitives/AppCommand"
17
+ ```
18
+
19
+ ## AppCommand
20
+
21
+ | Prop | Type | Default | Description |
22
+ | :--- | :--- | :--- | :--- |
23
+ | `label` | `string` | - | Accessible label for the command menu. |
24
+ | `shouldFilter` | `boolean` | `true` | Whether to filter items based on the search input. |
25
+
26
+ ## AppCommandInput
27
+
28
+ | Prop | Type | Default | Description |
29
+ | :--- | :--- | :--- | :--- |
30
+ | `placeholder` | `string` | - | Placeholder text for the search input. |
31
+
32
+ ## AppCommandItem
33
+
34
+ | Prop | Type | Default | Description |
35
+ | :--- | :--- | :--- | :--- |
36
+ | `onSelect` | `(value: string) => void` | - | Event handler called when the item is selected. |
37
+ | `disabled` | `boolean` | - | Whether the item is disabled. |
38
+ | `value` | `string` | - | Optional value for the item. Defaults to text content. |
39
+
40
+ ## Usage
41
+
42
+ ### Default Command Menu
43
+ ```tsx
44
+ <AppCommand className="rounded-lg border shadow-md">
45
+ <AppCommandInput placeholder="Type a command or search..." />
46
+ <AppCommandList>
47
+ <AppCommandEmpty>No results found.</AppCommandEmpty>
48
+ <AppCommandGroup heading="Suggestions">
49
+ <AppCommandItem>Calendar</AppCommandItem>
50
+ <AppCommandItem>Search Emoji</AppCommandItem>
51
+ <AppCommandItem>Calculator</AppCommandItem>
52
+ </AppCommandGroup>
53
+ <AppCommandSeparator />
54
+ <AppCommandGroup heading="Settings">
55
+ <AppCommandItem>
56
+ <span>Profile</span>
57
+ <AppCommandShortcut>⌘P</AppCommandShortcut>
58
+ </AppCommandItem>
59
+ <AppCommandItem>
60
+ <span>Settings</span>
61
+ <AppCommandShortcut>⌘S</AppCommandShortcut>
62
+ </AppCommandItem>
63
+ </AppCommandGroup>
64
+ </AppCommandList>
65
+ </AppCommand>
66
+ ```
67
+
68
+ ## Rules
69
+
70
+ - **Do** use `AppCommand` for searchable lists and command palettes.
71
+ - **Do** use `AppCommandDialog` for full-screen or modal command interfaces.
72
+ - **Don't** forget to handle `onSelect` for interactive items.
73
+ - If a prop you need is missing, stop and inform the design team.
@@ -0,0 +1,65 @@
1
+ # AppContextMenu
2
+
3
+ > Docs: https://ui-kit.vercel.app/docs/components/context-menu
4
+
5
+ ```tsx
6
+ import {
7
+ AppContextMenu,
8
+ AppContextMenuTrigger,
9
+ AppContextMenuContent,
10
+ AppContextMenuItem,
11
+ AppContextMenuCheckboxItem,
12
+ AppContextMenuRadioItem,
13
+ AppContextMenuLabel,
14
+ AppContextMenuSeparator,
15
+ AppContextMenuShortcut,
16
+ AppContextMenuGroup,
17
+ AppContextMenuSub,
18
+ AppContextMenuSubContent,
19
+ AppContextMenuSubTrigger,
20
+ AppContextMenuRadioGroup,
21
+ } from "@/components/primitives/AppContextMenu"
22
+ ```
23
+
24
+ ## AppContextMenuContent
25
+
26
+ | Prop | Type | Default | Description |
27
+ | :--- | :--- | :--- | :--- |
28
+ | `loop` | `boolean` | `false` | Whether keyboard navigation should loop from last to first item. |
29
+
30
+ ## AppContextMenuItem
31
+
32
+ | Prop | Type | Default | Description |
33
+ | :--- | :--- | :--- | :--- |
34
+ | `onSelect` | `(event: Event) => void` | - | Event handler called when the item is selected. |
35
+ | `disabled` | `boolean` | - | Whether the item is disabled. |
36
+
37
+ ## Usage
38
+
39
+ ### Basic Context Menu
40
+ ```tsx
41
+ <AppContextMenu>
42
+ <AppContextMenuTrigger className="flex h-32 w-64 items-center justify-center border border-dashed">
43
+ Right click here
44
+ </AppContextMenuTrigger>
45
+ <AppContextMenuContent className="w-56">
46
+ <AppContextMenuItem>
47
+ <span>Copy</span>
48
+ <AppContextMenuShortcut>⌘C</AppContextMenuShortcut>
49
+ </AppContextMenuItem>
50
+ <AppContextMenuItem>
51
+ <span>Paste</span>
52
+ <AppContextMenuShortcut>⌘V</AppContextMenuShortcut>
53
+ </AppContextMenuItem>
54
+ <AppContextMenuSeparator />
55
+ <AppContextMenuItem>Settings</AppContextMenuItem>
56
+ </AppContextMenuContent>
57
+ </AppContextMenu>
58
+ ```
59
+
60
+ ## Rules
61
+
62
+ - **Do** use `AppContextMenu` for secondary actions associated with a specific UI element.
63
+ - **Do** include shortcuts using `AppContextMenuShortcut` where appropriate.
64
+ - **Don't** overpopulate the context menu; keep it concise.
65
+ - If a prop you need is missing, stop and inform the design team.
@@ -0,0 +1,368 @@
1
+ # AppDashboard
2
+
3
+ > **Single entry point** — Use this for every page. Do not compose the scaffold manually.
4
+
5
+ ## Import
6
+
7
+ ```tsx
8
+ import { AppDashboard } from '@skunkworksai/ui-kit'
9
+ ```
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Default | Description |
14
+ |------|------|---------|-------------|
15
+ | `nav` | `AppDashboardNavSection[]` | built-in default nav | Sidebar navigation sections. Omit to use the built-in UI Kit default. |
16
+ | `header` | `Omit<AppHeaderProps, "className">` | `{}` | Props forwarded to `AppHeader`. Use to customize searchbar, actions, avatar, etc. |
17
+ | `sidebarWidth` | `string` | `"14rem"` | Overrides the `--sidebar-width` CSS variable. |
18
+ | `headerHeight` | `string` | `"3.5rem"` | Overrides the `--header-height` CSS variable. |
19
+ | `mainClassName` | `string` | `"p-6"` | Extra classes on the main content area. |
20
+ | `backgroundTheme` | `"dark" \| "light"` | `"dark"` | Locks sidebar, header, and background to a fixed mode regardless of page theme toggle. |
21
+ | `animated` | `"auto" \| "on" \| "off"` | `"auto"` | Controls the canvas animation. `"auto"` honors `prefers-reduced-motion`; `"off"` renders gradient only — use for perf-constrained consumers. |
22
+ | `background` | `ReactNode` | `<AppDashboardBackgroundWave />` | Background preset or custom component. Must render gradient. See Background presets section. |
23
+ | `pageTitle` | `AppPageTitleProps \| false` | omitted | Page title bar below the header. Pass `false` to hide entirely. |
24
+ | `brand` | `Omit<AppSidebarBrandProps, "className">` | `WhiteLogo` / `WhiteSymbol` | Props forwarded to `AppSidebarBrand`. Use to set a custom logo for expanded and collapsed sidebar states. |
25
+ | `children` | `ReactNode` | required | Page content. |
26
+
27
+ ## Customising the header
28
+
29
+ `AppDashboard` renders `AppHeader` internally. Pass the `header` prop to forward any `AppHeaderProps` to it:
30
+
31
+ ```tsx
32
+ // Remove searchbar
33
+ <AppDashboard header={{ searchbar: null }}>...</AppDashboard>
34
+
35
+ // Remove avatar
36
+ <AppDashboard header={{ avatar: null }}>...</AppDashboard>
37
+
38
+ // Remove network select
39
+ <AppDashboard header={{ networkSelect: null }}>...</AppDashboard>
40
+
41
+ // No theme toggle or bento
42
+ <AppDashboard header={{ showThemeToggle: false, showBento: false }}>...</AppDashboard>
43
+
44
+ // Custom right-side actions (replaces entire actions slot)
45
+ <AppDashboard header={{ actions: <AppButton>Save</AppButton> }}>...</AppDashboard>
46
+
47
+ // Custom searchbar
48
+ <AppDashboard header={{ searchbar: <AppInput placeholder="Find sites..." /> }}>...</AppDashboard>
49
+ ```
50
+
51
+ See `rules/header.md` for the full `AppHeaderProps` reference.
52
+
53
+ ## Customising the brand
54
+
55
+ `AppDashboard` renders `AppSidebarBrand` internally. Pass the `brand` prop to forward any `AppSidebarBrandProps` to it:
56
+
57
+ ```tsx
58
+ // Custom SVG logo components (import from your own src/assets/logos)
59
+ import { MyLogo, MySymbol } from './assets/logos'
60
+
61
+ <AppDashboard
62
+ brand={{
63
+ logo: <MyLogo width={90} height={28} />,
64
+ collapsedLogo: <MySymbol width={24} height={24} />,
65
+ }}
66
+ >
67
+ ...
68
+ </AppDashboard>
69
+
70
+ // With a brand switcher dropdown
71
+ <AppDashboard
72
+ brand={{
73
+ logo: <MyLogo />,
74
+ collapsedLogo: <MySymbol />,
75
+ dropdown: [
76
+ { label: "Workspace A", onClick: () => switchWorkspace("a") },
77
+ { label: "Workspace B", onClick: () => switchWorkspace("b") },
78
+ { separator: true },
79
+ { label: "Create new", onClick: openCreateDialog },
80
+ ],
81
+ }}
82
+ >
83
+ ...
84
+ </AppDashboard>
85
+
86
+ // Hide the dropdown chevron
87
+ <AppDashboard brand={{ logo: <MyLogo />, showChevron: false }}>...</AppDashboard>
88
+ ```
89
+
90
+ Logo rules:
91
+ - Import logos from `./assets/logos` — never from the package root
92
+ - Use `WhiteLogo` / `WhiteSymbol` variants on dark backgrounds (default `backgroundTheme="dark"`)
93
+ - Use `PrimaryLogo` / `PrimarySymbol` on light backgrounds (`backgroundTheme="light"`)
94
+ - Pass SVG React components — not `<img>` tags or PNG paths
95
+
96
+ ## Background theme
97
+
98
+ The `backgroundTheme` prop locks sidebar, header, and background to a fixed mode. The main content area still responds to the page theme toggle independently.
99
+
100
+ ```tsx
101
+ // Dark background (default)
102
+ <AppDashboard backgroundTheme="dark">
103
+ <PageContent />
104
+ </AppDashboard>
105
+
106
+ // Light background
107
+ <AppDashboard backgroundTheme="light">
108
+ <PageContent />
109
+ </AppDashboard>
110
+ ```
111
+
112
+ Set once in the root layout — do not change per page.
113
+
114
+ ## Background presets
115
+
116
+ `AppDashboard` accepts a `background` prop for swapping the background visual. Omit it for the default Wave.
117
+
118
+ ```tsx
119
+ import { AppDashboardBackgroundWave, AppDashboardBackgroundDots } from '@skunkworksai/ui-kit'
120
+
121
+ // Default — same as omitting the prop
122
+ <AppDashboard background={<AppDashboardBackgroundWave />}>...</AppDashboard>
123
+
124
+ // Dot grid
125
+ <AppDashboard background={<AppDashboardBackgroundDots />}>...</AppDashboard>
126
+
127
+ // Custom — must render the gradient (sidebar/header have no background of their own)
128
+ <AppDashboard background={<MyCustomBackground />}>...</AppDashboard>
129
+ ```
130
+
131
+ | Preset | Description |
132
+ |--------|-------------|
133
+ | `AppDashboardBackgroundWave` | Perlin noise wave grid + mouse-follow glow. Default. |
134
+ | `AppDashboardBackgroundDots` | Uniform dot grid. Dots fade near cursor (closer = lower opacity). |
135
+
136
+ ### Custom background contract
137
+
138
+ Custom backgrounds receive `animated`, `interactive`, and `themeClass` from `AppDashboardBackgroundContext`:
139
+
140
+ ```tsx
141
+ import { useAppDashboardBackgroundContext } from '@skunkworksai/ui-kit'
142
+
143
+ function MyBackground() {
144
+ const { animated, interactive, themeClass } = useAppDashboardBackgroundContext()
145
+ return (
146
+ // gradient required — sidebar and header depend on it
147
+ <div className={`absolute inset-0 bg-gradient-to-br from-sidebar to-sidebar-accent ${themeClass}`}>
148
+ {animated && <canvas ... />}
149
+ </div>
150
+ )
151
+ }
152
+ ```
153
+
154
+ Rules:
155
+ - **Must** render as `absolute inset-0`.
156
+ - **Must** include `bg-gradient-to-br from-sidebar to-sidebar-accent` — sidebar and header have no own background.
157
+ - **Must** apply `themeClass` from context so CSS tokens resolve correctly.
158
+ - **Must** gate canvas/animation behind the `animated` flag from context.
159
+ - **Never** hardcode colors — use CSS variables from `src/tokens/tokens-source.css`.
160
+
161
+ ## Background animation
162
+
163
+ The canvas animation runs by default. Use `animated` to control it:
164
+
165
+ ```tsx
166
+ // Default — animation on, respects OS reduced-motion setting
167
+ <AppDashboard animated="auto">
168
+ <PageContent />
169
+ </AppDashboard>
170
+
171
+ // Force animation off — static gradient only (best for perf-constrained apps)
172
+ <AppDashboard animated="off">
173
+ <PageContent />
174
+ </AppDashboard>
175
+
176
+ // Force animation on regardless of prefers-reduced-motion
177
+ <AppDashboard animated="on">
178
+ <PageContent />
179
+ </AppDashboard>
180
+ ```
181
+
182
+ **When `animated="off"`:** no canvas element, no `requestAnimationFrame` loop, no glow — only the `bg-gradient-to-br from-sidebar to-sidebar-accent` base layer. Removes all CPU/GPU cost from the background.
183
+
184
+ **When `animated="auto"` (default):** animation runs normally unless the user's OS has `prefers-reduced-motion: reduce` set, in which case the canvas is skipped automatically. No consumer code needed for accessibility compliance.
185
+
186
+ ## AppThemeProvider requirement
187
+
188
+ The default header includes a theme toggle that requires `AppThemeProvider` in the tree:
189
+
190
+ ```tsx
191
+ import { AppThemeProvider } from '@skunkworksai/ui-kit'
192
+
193
+ export default function RootLayout({ children }) {
194
+ return (
195
+ <html lang="en" suppressHydrationWarning>
196
+ <body>
197
+ <AppThemeProvider>{children}</AppThemeProvider>
198
+ </body>
199
+ </html>
200
+ )
201
+ }
202
+ ```
203
+
204
+ Without it, the toggle renders but does nothing.
205
+
206
+ ## Nav types
207
+
208
+ ```ts
209
+ type AppDashboardNavSection = {
210
+ label?: string
211
+ items: AppDashboardNavItem[]
212
+ }
213
+
214
+ type AppDashboardNavItem = {
215
+ title: string // label and tooltip text
216
+ icon: React.ElementType // lucide-react icon component (not JSX, the component itself)
217
+ isActive?: boolean // marks the current route
218
+ onClick?: (e: React.MouseEvent<HTMLElement>) => void // click handler on the menu button / anchor
219
+ url?: string // when set, renders button as <a href>
220
+ }
221
+ ```
222
+
223
+ ## Router integration
224
+
225
+ Use `url` + `onClick` together for router-driven navigation. `onClick` fires first — call `e.preventDefault()` to suppress the native anchor navigation, then call your router's navigate function.
226
+
227
+ ### react-router-dom
228
+
229
+ ```tsx
230
+ import { useNavigate } from "react-router-dom"
231
+
232
+ function Shell() {
233
+ const navigate = useNavigate()
234
+
235
+ const nav = [
236
+ {
237
+ items: [
238
+ {
239
+ title: "Dashboard",
240
+ icon: LayoutDashboard,
241
+ isActive: location.pathname === "/",
242
+ url: "/",
243
+ onClick: (e) => { e.preventDefault(); navigate("/") },
244
+ },
245
+ {
246
+ title: "Sites",
247
+ icon: MapPin,
248
+ isActive: location.pathname === "/sites",
249
+ url: "/sites",
250
+ onClick: (e) => { e.preventDefault(); navigate("/sites") },
251
+ },
252
+ ],
253
+ },
254
+ ]
255
+
256
+ return <AppDashboard nav={nav}>...</AppDashboard>
257
+ }
258
+ ```
259
+
260
+ If both `url` and `onClick` are set and `onClick` does **not** call `e.preventDefault()`, the anchor's native navigation runs after the handler.
261
+
262
+ If only `onClick` is needed (no anchor href), omit `url` — the button renders as a `<button>` element.
263
+
264
+ ## usePageTitle hook
265
+
266
+ Pages declare their own title from within the page component — no shell wiring required.
267
+
268
+ ```tsx
269
+ import { usePageTitle } from "@skunkworksai/ui-kit"
270
+
271
+ function IncidentsPage() {
272
+ usePageTitle({
273
+ title: "Incidents",
274
+ subtitle: "Active alerts across all sites.",
275
+ breadcrumbs: [{ label: "Dashboard", href: "/" }, { label: "Incidents" }],
276
+ actions: <AppButton>+ New Alert</AppButton>,
277
+ })
278
+
279
+ return <div>...</div>
280
+ }
281
+
282
+ // In the shell — no pageTitle prop needed on AppDashboard
283
+ <AppDashboard nav={nav}>
284
+ <IncidentsPage />
285
+ </AppDashboard>
286
+ ```
287
+
288
+ **Rules:**
289
+ - Must be called inside a component rendered within `AppDashboard` — throws outside that tree.
290
+ - Clears automatically on unmount.
291
+ - `pageTitle` prop on `AppDashboard` is the fallback — `usePageTitle` takes priority when both are set.
292
+ - Pass a stable object (top-level const or `useMemo`) to avoid unnecessary re-renders.
293
+
294
+ ## Usage examples
295
+
296
+ ### Minimal (default everything)
297
+
298
+ ```tsx
299
+ <AppDashboard>
300
+ <p>Page content here.</p>
301
+ </AppDashboard>
302
+ ```
303
+
304
+ ### Custom nav
305
+
306
+ ```tsx
307
+ const nav = [
308
+ { items: [{ title: "Home", icon: Home, isActive: true }] },
309
+ { label: "Manage", items: [{ title: "Sites", icon: MapPin }] },
310
+ ]
311
+
312
+ <AppDashboard nav={nav}>
313
+ <PageContent />
314
+ </AppDashboard>
315
+ ```
316
+
317
+ ### No searchbar, no avatar
318
+
319
+ ```tsx
320
+ <AppDashboard header={{ searchbar: null, avatar: null }}>
321
+ <PageContent />
322
+ </AppDashboard>
323
+ ```
324
+
325
+ ### Full-bleed content area
326
+
327
+ ```tsx
328
+ <AppDashboard mainClassName="p-0">
329
+ <FullBleedContent />
330
+ </AppDashboard>
331
+ ```
332
+
333
+ ### With page title
334
+
335
+ ```tsx
336
+ <AppDashboard
337
+ pageTitle={{
338
+ title: "Sites",
339
+ subtitle: "Manage and monitor all sites.",
340
+ breadcrumbs: [{ label: "Dashboard", href: "/" }, { label: "Sites" }],
341
+ actions: <AppButton>+ Add Site</AppButton>,
342
+ }}
343
+ >
344
+ <PageContent />
345
+ </AppDashboard>
346
+ ```
347
+
348
+ ## Rules
349
+
350
+ - **Do** use `AppDashboard` as the layout for every page — do not compose the scaffold manually.
351
+ - **Do** omit `nav` when the UI Kit default nav is sufficient.
352
+ - **Do** set `isActive` on exactly one nav item per page when using custom `nav`.
353
+ - **Do** pass icons as `React.ElementType` (the component, not `<Icon />`).
354
+ - **Do** use `url` + `onClick` on nav items for router integration — never wire up sidebar DOM queries.
355
+ - **Do** use `usePageTitle()` in page components to declare titles — avoids growing switch/map in the shell.
356
+ - **Do** customize the header via the `header` prop — never rebuild `AppHeader` yourself inside `AppDashboard`.
357
+ - **Don't** add `bg-*`, `dark`, or `border-*` to anything wrapping `AppDashboard`. Use `backgroundTheme` instead.
358
+ - **Do** set `animated="off"` in perf-constrained consumer apps (older hardware, low-end mobile-web, slow networks).
359
+ - **Don't** conditionally toggle `animated` at runtime — it triggers a component remount. Set it once at the root layout level.
360
+ - **Don't** import `AppDashboardContent`, `AppDashboardMain`, `AppSidebarProvider`, `AppHeader`, etc. to rebuild the scaffold yourself.
361
+ - **Don't** use DOM queries (`data-sidebar="menu-button"`) to bridge sidebar clicks to a router — use the `onClick` prop on nav items.
362
+ - **Don't** hardcode color values — all colors come from CSS variables.
363
+
364
+ If a prop you need is missing, stop and inform the design team.
365
+
366
+ ## Responsive
367
+
368
+ On mobile (<768px) the sidebar collapses to a Sheet drawer toggled via the header trigger; `AppDashboardMain` has no top-left rounding and uses `p-4` padding. On desktop (≥768px) rounding restores to `rounded-tl-3xl`, padding increases to `p-6`, and the Perlin canvas background re-enables mouse interaction. No consumer changes are needed — layout adapts automatically based on viewport width.
@@ -0,0 +1,91 @@
1
+ # AppDataTable
2
+
3
+ > Docs: https://ui-kit.vercel.app/docs/components/data-table
4
+
5
+ ```tsx
6
+ import { AppDataTable, type AppDataTableProps } from "@skunkworksai/ui-kit"
7
+ import type { ColumnDef } from "@tanstack/react-table"
8
+ ```
9
+
10
+ ## AppDataTable
11
+
12
+ | Prop | Type | Default | Description |
13
+ |------|------|---------|-------------|
14
+ | `data` | `TData[]` | required | Row data array. |
15
+ | `columns` | `ColumnDef<TData, TValue>[]` | required | Column definitions (from `@tanstack/react-table`). |
16
+ | `filterColumn` | `string` | first column's `accessorKey` | Column key to filter on. |
17
+ | `filterPlaceholder` | `string` | `"Filter..."` | Filter input placeholder text. |
18
+ | `pageSize` | `number` | `10` | Rows per page. |
19
+ | `enableSorting` | `boolean` | `true` | Click-to-sort on column headers. |
20
+ | `enableFiltering` | `boolean` | `true` | Show filter text input. |
21
+ | `enablePagination` | `boolean` | `true` | Show pagination controls. |
22
+ | `enableColumnVisibility` | `boolean` | `true` | Show columns toggle dropdown. |
23
+ | `className` | `string` | — | Additional classes on the outer wrapper. |
24
+
25
+ ## Usage
26
+
27
+ ### Basic with all features
28
+ ```tsx
29
+ type Payment = { id: string; amount: number; status: string; email: string }
30
+
31
+ const columns: ColumnDef<Payment>[] = [
32
+ { accessorKey: "email", header: "Email" },
33
+ { accessorKey: "status", header: "Status" },
34
+ { accessorKey: "amount", header: "Amount" },
35
+ ]
36
+
37
+ <AppDataTable
38
+ data={payments}
39
+ columns={columns}
40
+ filterColumn="email"
41
+ filterPlaceholder="Filter by email..."
42
+ />
43
+ ```
44
+
45
+ ### With custom cell renderers
46
+ ```tsx
47
+ const columns: ColumnDef<Payment>[] = [
48
+ { accessorKey: "email", header: "Email" },
49
+ {
50
+ accessorKey: "status",
51
+ header: "Status",
52
+ cell: ({ row }) => (
53
+ <AppBadge variant={statusVariantMap[row.getValue("status")]}>
54
+ {row.getValue("status")}
55
+ </AppBadge>
56
+ ),
57
+ },
58
+ {
59
+ accessorKey: "amount",
60
+ header: "Amount",
61
+ cell: ({ row }) =>
62
+ new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(
63
+ row.getValue("amount")
64
+ ),
65
+ },
66
+ ]
67
+ ```
68
+
69
+ ### Plain table (no controls)
70
+ ```tsx
71
+ <AppDataTable
72
+ data={rows}
73
+ columns={columns}
74
+ enableSorting={false}
75
+ enableFiltering={false}
76
+ enablePagination={false}
77
+ enableColumnVisibility={false}
78
+ />
79
+ ```
80
+
81
+ ## Rules
82
+ - ✅ Import `ColumnDef` from `@tanstack/react-table` — it is re-exported from `@skunkworksai/ui-kit` for convenience but the type comes from TanStack
83
+ - ✅ All features enabled by default — explicitly disable what you don't need
84
+ - ✅ Set `filterColumn` when you want a specific column to be filterable; defaults to first column's `accessorKey`
85
+ - ✅ Use `cell` renderers in column defs to format values or render `App*` components
86
+ - ❌ Do not add custom sorting/filtering/pagination logic outside of column defs — pass props to control all behavior
87
+ - ❌ If a prop you need is missing, stop and inform the design team
88
+
89
+ ## Responsive
90
+
91
+ The toolbar (filter input + columns toggle) wraps with `flex-wrap` on small screens, and the pagination footer also wraps on small screens. The underlying `Table` already scrolls horizontally via shadcn's `overflow-auto` wrapper — no consumer changes needed.
@@ -0,0 +1,65 @@
1
+ # AppDatePicker
2
+
3
+ > Docs: https://ui-kit.vercel.app/docs/components/date-picker
4
+
5
+ ```tsx
6
+ import { AppDatePicker, type AppDatePickerProps } from "@skunkworksai/ui-kit"
7
+ ```
8
+
9
+ ## AppDatePicker
10
+
11
+ | Prop | Type | Default | Description |
12
+ |------|------|---------|-------------|
13
+ | `mode` | `"single" \| "range"` | `"single"` | Selection mode. Determines the shape of `value` and `onChange`. |
14
+ | `value` | `Date \| undefined` (single) or `DateRange \| undefined` (range) | — | Controlled selected value. |
15
+ | `onChange` | `(date: Date \| undefined) => void` (single) or `(range: DateRange \| undefined) => void` (range) | — | Callback when selection changes. |
16
+ | `placeholder` | `string` | `"Pick a date"` / `"Pick a date range"` | Trigger button text when no date selected. |
17
+ | `disabled` | `boolean` | `false` | Disables the trigger button. |
18
+ | `className` | `string` | — | Additional classes on the trigger button. |
19
+
20
+ ## Usage
21
+
22
+ ### Single date (controlled)
23
+ ```tsx
24
+ const [date, setDate] = React.useState<Date | undefined>()
25
+
26
+ <AppDatePicker value={date} onChange={setDate} />
27
+ ```
28
+
29
+ ### Date range (controlled)
30
+ ```tsx
31
+ import type { DateRange } from "react-day-picker"
32
+
33
+ const [range, setRange] = React.useState<DateRange | undefined>()
34
+
35
+ <AppDatePicker mode="range" value={range} onChange={setRange} />
36
+ ```
37
+
38
+ ### With initial value
39
+ ```tsx
40
+ const [date, setDate] = React.useState<Date | undefined>(new Date())
41
+
42
+ <AppDatePicker value={date} onChange={setDate} />
43
+ ```
44
+
45
+ ### Disabled
46
+ ```tsx
47
+ <AppDatePicker value={undefined} onChange={() => {}} disabled />
48
+ ```
49
+
50
+ ### Custom placeholder
51
+ ```tsx
52
+ <AppDatePicker
53
+ value={date}
54
+ onChange={setDate}
55
+ placeholder="Select invoice date"
56
+ />
57
+ ```
58
+
59
+ ## Rules
60
+ - ✅ Always control via `value` + `onChange` — this component is controlled only
61
+ - ✅ When using `mode="range"`, the `value` type is `DateRange` from `react-day-picker` and `onChange` receives `DateRange | undefined`
62
+ - ✅ Set trigger button width explicitly via `className` (e.g. `className="w-64"` or `className="w-full"`) — no default width
63
+ - ✅ The range mode shows 2 months side by side — ensure there's enough horizontal space
64
+ - ❌ Do not use without `onChange` — the component is always controlled
65
+ - ❌ If a prop you need is missing, stop and inform the design team