@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.
- package/AGENTS.md +250 -0
- package/README.md +429 -0
- package/dist/assets/Service-applets-apps/audience-measurement.png +0 -0
- package/dist/assets/Service-applets-apps/coatro-app.png +0 -0
- package/dist/assets/Service-applets-apps/content-effectiveness.png +0 -0
- package/dist/assets/Service-applets-apps/hop-tracking.png +0 -0
- package/dist/assets/Service-applets-apps/index.ts +13 -0
- package/dist/assets/Service-applets-apps/journeys-app.png +0 -0
- package/dist/assets/Service-applets-apps/people-counting.png +0 -0
- package/dist/assets/Service-applets-apps/petra.png +0 -0
- package/dist/assets/Service-applets-apps/sam-generic.png +0 -0
- package/dist/assets/Service-applets-apps/sami-for-environment.png +0 -0
- package/dist/assets/Service-applets-apps/shelf-engagement.png +0 -0
- package/dist/assets/Service-applets-apps/traffic-management.png +0 -0
- package/dist/assets/Service-applets-apps/viana.png +0 -0
- package/dist/assets/Service-applets-apps/zone-engagement.png +0 -0
- package/dist/assets/icons/Dashboard-active.svg +29 -0
- package/dist/assets/icons/Dashboard.svg +25 -0
- package/dist/assets/icons/DashboardActiveIcon.tsx +35 -0
- package/dist/assets/icons/DashboardIcon.tsx +31 -0
- package/dist/assets/icons/Devices-active.svg +27 -0
- package/dist/assets/icons/Devices.svg +20 -0
- package/dist/assets/icons/DevicesActiveIcon.tsx +33 -0
- package/dist/assets/icons/DevicesIcon.tsx +26 -0
- package/dist/assets/icons/Installer-active.svg +29 -0
- package/dist/assets/icons/Installer.svg +17 -0
- package/dist/assets/icons/InstallerActiveIcon.tsx +35 -0
- package/dist/assets/icons/InstallerIcon.tsx +23 -0
- package/dist/assets/icons/Manifest-active.svg +49 -0
- package/dist/assets/icons/Manifest.svg +49 -0
- package/dist/assets/icons/ManifestActiveIcon.tsx +55 -0
- package/dist/assets/icons/ManifestIcon.tsx +55 -0
- package/dist/assets/icons/Sensor-active.svg +15 -0
- package/dist/assets/icons/Sensor.svg +11 -0
- package/dist/assets/icons/SensorActiveIcon.tsx +21 -0
- package/dist/assets/icons/SensorIcon.tsx +17 -0
- package/dist/assets/icons/Site-active.svg +14 -0
- package/dist/assets/icons/Site.svg +10 -0
- package/dist/assets/icons/SiteActiveIcon.tsx +20 -0
- package/dist/assets/icons/SiteIcon.tsx +16 -0
- package/dist/assets/icons/X-ray-active.svg +199 -0
- package/dist/assets/icons/X-ray.svg +47 -0
- package/dist/assets/icons/XrayActiveIcon.tsx +205 -0
- package/dist/assets/icons/XrayIcon.tsx +53 -0
- package/dist/assets/icons/index.ts +14 -0
- package/dist/assets/logos/DarkLogo.tsx +28 -0
- package/dist/assets/logos/DarkSymbol.tsx +9 -0
- package/dist/assets/logos/PrimaryLogo.tsx +28 -0
- package/dist/assets/logos/PrimarySymbol.tsx +9 -0
- package/dist/assets/logos/WhiteLogo.tsx +28 -0
- package/dist/assets/logos/WhiteSymbol.tsx +9 -0
- package/dist/assets/logos/dark_logo.svg +22 -0
- package/dist/assets/logos/dark_symbol.svg +3 -0
- package/dist/assets/logos/index.ts +6 -0
- package/dist/assets/logos/primary-logo.svg +22 -0
- package/dist/assets/logos/primary_logo.svg +22 -0
- package/dist/assets/logos/primary_symbol.svg +3 -0
- package/dist/assets/logos/white_symbol.svg +3 -0
- package/dist/index.cjs +160 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +45276 -0
- package/dist/index.js.map +1 -0
- package/dist/tokens-source.css +121 -0
- package/dist/types/assets/Service-applets-apps/index.d.ts +13 -0
- package/dist/types/assets/icons/DashboardActiveIcon.d.ts +2 -0
- package/dist/types/assets/icons/DashboardIcon.d.ts +2 -0
- package/dist/types/assets/icons/DevicesActiveIcon.d.ts +2 -0
- package/dist/types/assets/icons/DevicesIcon.d.ts +2 -0
- package/dist/types/assets/icons/InstallerActiveIcon.d.ts +2 -0
- package/dist/types/assets/icons/InstallerIcon.d.ts +2 -0
- package/dist/types/assets/icons/ManifestActiveIcon.d.ts +2 -0
- package/dist/types/assets/icons/ManifestIcon.d.ts +2 -0
- package/dist/types/assets/icons/SensorActiveIcon.d.ts +2 -0
- package/dist/types/assets/icons/SensorIcon.d.ts +2 -0
- package/dist/types/assets/icons/SiteActiveIcon.d.ts +2 -0
- package/dist/types/assets/icons/SiteIcon.d.ts +2 -0
- package/dist/types/assets/icons/XrayActiveIcon.d.ts +2 -0
- package/dist/types/assets/icons/XrayIcon.d.ts +2 -0
- package/dist/types/assets/icons/index.d.ts +14 -0
- package/dist/types/assets/logos/DarkLogo.d.ts +2 -0
- package/dist/types/assets/logos/DarkSymbol.d.ts +2 -0
- package/dist/types/assets/logos/PrimaryLogo.d.ts +2 -0
- package/dist/types/assets/logos/PrimarySymbol.d.ts +2 -0
- package/dist/types/assets/logos/WhiteLogo.d.ts +2 -0
- package/dist/types/assets/logos/WhiteSymbol.d.ts +2 -0
- package/dist/types/assets/logos/index.d.ts +6 -0
- package/dist/types/components/blocks/AppBentoMenu.d.ts +31 -0
- package/dist/types/components/blocks/AppDashboard.d.ts +121 -0
- package/dist/types/components/blocks/AppHeader.d.ts +198 -0
- package/dist/types/components/blocks/AppLocationTreeFilter.d.ts +44 -0
- package/dist/types/components/blocks/AppNotificationsMenu.d.ts +50 -0
- package/dist/types/components/blocks/AppPageTitle.d.ts +86 -0
- package/dist/types/components/blocks/AppProfile.d.ts +53 -0
- package/dist/types/components/blocks/TableManager.d.ts +194 -0
- package/dist/types/components/blocks/backgrounds/AppDashboardBackgroundDots.d.ts +14 -0
- package/dist/types/components/blocks/backgrounds/AppDashboardBackgroundWave.d.ts +14 -0
- package/dist/types/components/blocks/backgrounds/index.d.ts +3 -0
- package/dist/types/components/blocks/backgrounds/types.d.ts +13 -0
- package/dist/types/components/blocks/index.d.ts +9 -0
- package/dist/types/components/primitives/AppAccordion.d.ts +22 -0
- package/dist/types/components/primitives/AppAlert.d.ts +33 -0
- package/dist/types/components/primitives/AppAlertDialog.d.ts +79 -0
- package/dist/types/components/primitives/AppAspectRatio.d.ts +7 -0
- package/dist/types/components/primitives/AppAvatar.d.ts +17 -0
- package/dist/types/components/primitives/AppBadge.d.ts +9 -0
- package/dist/types/components/primitives/AppBreadcrumb.d.ts +45 -0
- package/dist/types/components/primitives/AppButton.d.ts +24 -0
- package/dist/types/components/primitives/AppButtonGroup.d.ts +10 -0
- package/dist/types/components/primitives/AppCalendar.d.ts +51 -0
- package/dist/types/components/primitives/AppCard.d.ts +41 -0
- package/dist/types/components/primitives/AppCarousel.d.ts +26 -0
- package/dist/types/components/primitives/AppChart.d.ts +27 -0
- package/dist/types/components/primitives/AppCheckbox.d.ts +9 -0
- package/dist/types/components/primitives/AppCollapsible.d.ts +20 -0
- package/dist/types/components/primitives/AppCombobox.d.ts +37 -0
- package/dist/types/components/primitives/AppCommand.d.ts +47 -0
- package/dist/types/components/primitives/AppContextMenu.d.ts +82 -0
- package/dist/types/components/primitives/AppDataTable.d.ts +23 -0
- package/dist/types/components/primitives/AppDatePicker.d.ts +26 -0
- package/dist/types/components/primitives/AppDialog.d.ts +40 -0
- package/dist/types/components/primitives/AppDrawer.d.ts +58 -0
- package/dist/types/components/primitives/AppDropdownMenu.d.ts +85 -0
- package/dist/types/components/primitives/AppEmpty.d.ts +35 -0
- package/dist/types/components/primitives/AppField.d.ts +65 -0
- package/dist/types/components/primitives/AppForm.d.ts +58 -0
- package/dist/types/components/primitives/AppHoverCard.d.ts +19 -0
- package/dist/types/components/primitives/AppInput.d.ts +21 -0
- package/dist/types/components/primitives/AppKbd.d.ts +18 -0
- package/dist/types/components/primitives/AppLabel.d.ts +8 -0
- package/dist/types/components/primitives/AppMenubar.d.ts +83 -0
- package/dist/types/components/primitives/AppNavigationMenu.d.ts +51 -0
- package/dist/types/components/primitives/AppPagination.d.ts +46 -0
- package/dist/types/components/primitives/AppPopover.d.ts +20 -0
- package/dist/types/components/primitives/AppProgress.d.ts +9 -0
- package/dist/types/components/primitives/AppRadioGroup.d.ts +15 -0
- package/dist/types/components/primitives/AppScrollArea.d.ts +12 -0
- package/dist/types/components/primitives/AppScrollText.d.ts +7 -0
- package/dist/types/components/primitives/AppSelect.d.ts +46 -0
- package/dist/types/components/primitives/AppSeparator.d.ts +8 -0
- package/dist/types/components/primitives/AppSheet.d.ts +32 -0
- package/dist/types/components/primitives/AppSidebar.d.ts +59 -0
- package/dist/types/components/primitives/AppSkeleton.d.ts +6 -0
- package/dist/types/components/primitives/AppSpinner.d.ts +13 -0
- package/dist/types/components/primitives/AppSwitch.d.ts +8 -0
- package/dist/types/components/primitives/AppTable.d.ts +53 -0
- package/dist/types/components/primitives/AppTabs.d.ts +10 -0
- package/dist/types/components/primitives/AppTextarea.d.ts +9 -0
- package/dist/types/components/primitives/AppThemeProvider.d.ts +46 -0
- package/dist/types/components/primitives/AppToaster.d.ts +7 -0
- package/dist/types/components/primitives/AppToggle.d.ts +9 -0
- package/dist/types/components/primitives/AppToggleGroup.d.ts +18 -0
- package/dist/types/components/primitives/AppTooltip.d.ts +26 -0
- package/dist/types/components/primitives/AppTypography.d.ts +80 -0
- package/dist/types/components/primitives/index.d.ts +57 -0
- package/dist/types/components/ui/accordion.d.ts +7 -0
- package/dist/types/components/ui/alert-dialog.d.ts +20 -0
- package/dist/types/components/ui/alert.d.ts +8 -0
- package/dist/types/components/ui/aspect-ratio.d.ts +4 -0
- package/dist/types/components/ui/avatar.d.ts +6 -0
- package/dist/types/components/ui/badge.d.ts +9 -0
- package/dist/types/components/ui/breadcrumb.d.ts +19 -0
- package/dist/types/components/ui/button.d.ts +13 -0
- package/dist/types/components/ui/calendar.d.ts +8 -0
- package/dist/types/components/ui/card.d.ts +11 -0
- package/dist/types/components/ui/carousel.d.ts +28 -0
- package/dist/types/components/ui/chart.d.ts +48 -0
- package/dist/types/components/ui/checkbox.d.ts +4 -0
- package/dist/types/components/ui/collapsible.d.ts +6 -0
- package/dist/types/components/ui/combobox.d.ts +83 -0
- package/dist/types/components/ui/command.d.ts +82 -0
- package/dist/types/components/ui/context-menu.d.ts +27 -0
- package/dist/types/components/ui/dialog.d.ts +19 -0
- package/dist/types/components/ui/drawer.d.ts +23 -0
- package/dist/types/components/ui/dropdown-menu.d.ts +27 -0
- package/dist/types/components/ui/empty.d.ts +14 -0
- package/dist/types/components/ui/field.d.ts +40 -0
- package/dist/types/components/ui/form.d.ts +22 -0
- package/dist/types/components/ui/hover-card.d.ts +6 -0
- package/dist/types/components/ui/input.d.ts +3 -0
- package/dist/types/components/ui/kbd.d.ts +4 -0
- package/dist/types/components/ui/label.d.ts +4 -0
- package/dist/types/components/ui/menubar.d.ts +30 -0
- package/dist/types/components/ui/navigation-menu.d.ts +12 -0
- package/dist/types/components/ui/pagination.d.ts +28 -0
- package/dist/types/components/ui/popover.d.ts +6 -0
- package/dist/types/components/ui/progress.d.ts +4 -0
- package/dist/types/components/ui/radio-group.d.ts +5 -0
- package/dist/types/components/ui/scroll-area.d.ts +5 -0
- package/dist/types/components/ui/scroll-text.d.ts +6 -0
- package/dist/types/components/ui/select.d.ts +13 -0
- package/dist/types/components/ui/separator.d.ts +4 -0
- package/dist/types/components/ui/sheet.d.ts +25 -0
- package/dist/types/components/ui/sidebar.d.ts +69 -0
- package/dist/types/components/ui/skeleton.d.ts +2 -0
- package/dist/types/components/ui/sonner.d.ts +2 -0
- package/dist/types/components/ui/switch.d.ts +4 -0
- package/dist/types/components/ui/table.d.ts +10 -0
- package/dist/types/components/ui/tabs.d.ts +19 -0
- package/dist/types/components/ui/textarea.d.ts +5 -0
- package/dist/types/components/ui/toggle-group.d.ts +15 -0
- package/dist/types/components/ui/toggle.d.ts +12 -0
- package/dist/types/components/ui/tooltip.d.ts +7 -0
- package/dist/types/hooks/use-mobile.d.ts +13 -0
- package/dist/types/hooks/use-page-title.d.ts +23 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/lib/utils.d.ts +2 -0
- package/dist/ui-kit.css +1 -0
- package/package.json +117 -0
- package/rules/accordion.md +60 -0
- package/rules/alert-dialog.md +62 -0
- package/rules/alert.md +61 -0
- package/rules/aspect-ratio.md +47 -0
- package/rules/avatar.md +52 -0
- package/rules/badge.md +55 -0
- package/rules/bento-menu.md +86 -0
- package/rules/breadcrumb.md +80 -0
- package/rules/button-group.md +58 -0
- package/rules/button.md +66 -0
- package/rules/calendar.md +97 -0
- package/rules/card.md +84 -0
- package/rules/carousel.md +113 -0
- package/rules/chart.md +125 -0
- package/rules/checkbox.md +49 -0
- package/rules/collapsible.md +57 -0
- package/rules/combobox.md +133 -0
- package/rules/command.md +73 -0
- package/rules/context-menu.md +65 -0
- package/rules/dashboard.md +368 -0
- package/rules/data-table.md +91 -0
- package/rules/date-picker.md +65 -0
- package/rules/dialog.md +60 -0
- package/rules/drawer.md +65 -0
- package/rules/dropdown-menu.md +72 -0
- package/rules/empty.md +110 -0
- package/rules/field.md +149 -0
- package/rules/form.md +60 -0
- package/rules/header.md +245 -0
- package/rules/hover-card.md +53 -0
- package/rules/icons.md +141 -0
- package/rules/input.md +66 -0
- package/rules/kbd.md +58 -0
- package/rules/label.md +30 -0
- package/rules/location-tree-filter.md +165 -0
- package/rules/logo.md +58 -0
- package/rules/menubar.md +75 -0
- package/rules/navigation-menu.md +68 -0
- package/rules/notifications-menu.md +137 -0
- package/rules/pagetitle.md +160 -0
- package/rules/pagination.md +71 -0
- package/rules/popover.md +48 -0
- package/rules/profile.md +125 -0
- package/rules/progress.md +41 -0
- package/rules/radio-group.md +44 -0
- package/rules/scroll-area.md +32 -0
- package/rules/scroll-text.md +40 -0
- package/rules/select.md +86 -0
- package/rules/separator.md +43 -0
- package/rules/sheet.md +76 -0
- package/rules/sidebar.md +442 -0
- package/rules/skeleton.md +46 -0
- package/rules/spinner.md +43 -0
- package/rules/switch.md +46 -0
- package/rules/table-manager.md +306 -0
- package/rules/table.md +177 -0
- package/rules/tabs.md +82 -0
- package/rules/text.md +3 -0
- package/rules/textarea.md +38 -0
- package/rules/toaster.md +58 -0
- package/rules/toggle-group.md +50 -0
- package/rules/toggle.md +40 -0
- package/rules/tokens.md +88 -0
- package/rules/tooltip.md +78 -0
- package/rules/typography.md +81 -0
- package/scripts/scaffold.mjs +28 -0
package/rules/command.md
ADDED
|
@@ -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
|