@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/header.md
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# AppHeader
|
|
2
|
+
|
|
3
|
+
## When to use
|
|
4
|
+
|
|
5
|
+
`AppHeader` is the top-of-page bar. It is rendered automatically inside `AppDashboard` — you do not need to import or use it directly unless you are building a layout outside `AppDashboard`.
|
|
6
|
+
|
|
7
|
+
To customise the header inside `AppDashboard`, pass props via the `header` prop on `AppDashboard`. See `rules/dashboard.md`.
|
|
8
|
+
|
|
9
|
+
## Default layout
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
AppSidebarTrigger → separator → searchbar → [network combobox] [bell] [bento] [theme toggle] [avatar]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
All right-side controls are included by default. Each can be removed or replaced via props.
|
|
16
|
+
|
|
17
|
+
## Props
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default | Description |
|
|
20
|
+
|------|------|---------|-------------|
|
|
21
|
+
| `searchbar` | `ReactNode` | standard search input | Searchbar slot. Pass `<AppInput />` to customise. `null` removes it entirely. |
|
|
22
|
+
| `actions` | `ReactNode` | network combobox + bento + theme toggle + avatar | Entire right-side slot. `null` removes all actions. Overrides all other action props. |
|
|
23
|
+
| `avatar` | `ReactNode` | `AppAvatar` with fallback `"KA"` | Avatar inside default actions. `null` hides it. Ignored when `actions` is provided. |
|
|
24
|
+
| `networkSelect` | `ReactNode` | `AppHeaderNetworkCombobox` | Network picker inside default actions. `null` hides it. Pass a custom node to override. Ignored when `actions` is provided. |
|
|
25
|
+
| `networks` | `NetworkOption[]` | 2 demo entries | List of networks for the built-in combobox. Ignored when `networkSelect` or `actions` is provided. |
|
|
26
|
+
| `currentNetwork` | `string` | first network in list | Controlled selected network. Omit for uncontrolled. Ignored when `networkSelect` or `actions` is provided. |
|
|
27
|
+
| `onNetworkChange` | `(value: string) => void` | — | Called when user selects a network. Ignored when `networkSelect` or `actions` is provided. |
|
|
28
|
+
| `showThemeToggle` | `boolean` | `true` | Show/hide theme toggle in default actions. Ignored when `actions` is provided. |
|
|
29
|
+
| `showBento` | `boolean` | `true` | Show/hide bento icon button in default actions. Ignored when `actions` is provided. |
|
|
30
|
+
| `bentoApps` | `BentoApp[]` | MeldCX apps | Apps shown in bento dropdown. Ignored when `actions` is provided or `showBento` is false. |
|
|
31
|
+
| `bentoCols` | `number` | `2` | Grid column count inside the bento dropdown. Use `3` for 5+ apps to avoid asymmetric rows. Ignored when `actions` is provided or `showBento` is false. |
|
|
32
|
+
| `showNotifications` | `boolean` | `true` | Show/hide the notifications bell in default actions. Ignored when `actions` is provided. |
|
|
33
|
+
| `notifications` | `AppNotification[]` | `[]` | Notification items for the bell panel. Ignored when `actions` or `notificationsMenu` is provided. |
|
|
34
|
+
| `notificationsTotal` | `number` | — | Total server count for the Show More footer. |
|
|
35
|
+
| `onShowMoreNotifications` | `() => void` | — | Called when Show More is clicked in the notifications panel. |
|
|
36
|
+
| `onMarkAllNotificationsRead` | `() => void` | — | Called when Mark all as read is selected. |
|
|
37
|
+
| `notificationsMenu` | `ReactNode` | — | Replace the entire bell+panel with a custom node. Pass `null` to hide. |
|
|
38
|
+
| `profile` | `AppProfileUser` | — | User data for the avatar profile popover (name, role, initials, optional image). When set, replaces the plain avatar with an interactive `AppProfile`. Ignored when `avatar` or `actions` is provided. |
|
|
39
|
+
| `onSettings` | `() => void` | — | Called when Settings is clicked in the profile menu. |
|
|
40
|
+
| `onAdministrator` | `() => void` | — | Called when Administrator is clicked in the profile menu. |
|
|
41
|
+
| `onLogout` | `() => void` | — | Called when Log Out is clicked in the profile menu. |
|
|
42
|
+
| `profileMenu` | `ReactNode` | — | Replace the entire profile popover with a custom node. Ignored when `avatar` or `actions` is provided. |
|
|
43
|
+
|
|
44
|
+
**Slot resolution rule:** `undefined` = use default content. `null` = remove entirely. Any other node = override.
|
|
45
|
+
|
|
46
|
+
### AppProfileUser type
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
type AppProfileUser = {
|
|
50
|
+
name: string // required — full display name
|
|
51
|
+
role?: string // subtitle below name
|
|
52
|
+
avatarSrc?: string // image URL
|
|
53
|
+
avatarFallback?: string // initials override; derived from name when omitted
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Network combobox
|
|
58
|
+
|
|
59
|
+
The built-in network picker (`AppHeaderNetworkCombobox`) is a searchable combobox:
|
|
60
|
+
|
|
61
|
+
- Current network pinned at the top of the list
|
|
62
|
+
- Remaining networks sorted A–Z by label
|
|
63
|
+
- Shows **5** networks initially; "See N more..." button expands to the full scrollable list
|
|
64
|
+
- Search filters all networks (not just the initial 5); bypasses the initial limit
|
|
65
|
+
- Closing the popover resets to the collapsed 5-item view
|
|
66
|
+
|
|
67
|
+
### NetworkOption type
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
type NetworkOption = { value: string; label: string }
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Controlled usage
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
const [network, setNetwork] = React.useState("meldcx")
|
|
77
|
+
|
|
78
|
+
<AppHeader
|
|
79
|
+
networks={networks}
|
|
80
|
+
currentNetwork={network}
|
|
81
|
+
onNetworkChange={setNetwork}
|
|
82
|
+
/>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Uncontrolled usage (no onChange needed)
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
<AppHeader networks={networks} />
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Custom network picker (override slot)
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
<AppHeader networkSelect={<MyCustomPicker />} />
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Hide network picker
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
<AppHeader networkSelect={null} />
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Sub-components (advanced layouts only)
|
|
104
|
+
|
|
105
|
+
Use these only when building a layout outside `AppDashboard`:
|
|
106
|
+
|
|
107
|
+
| Component | Purpose |
|
|
108
|
+
|-----------|---------|
|
|
109
|
+
| `AppHeaderContent` | Inner flex container with padding and gap. |
|
|
110
|
+
| `AppHeaderTitle` | Optional page label. `shrink-0`, never compresses. |
|
|
111
|
+
| `AppHeaderSearchbar` | `flex-1` slot for search input groups. |
|
|
112
|
+
| `AppHeaderActions` | `ml-auto` right-side slot for controls. |
|
|
113
|
+
| `AppHeaderNetworkCombobox` | Standalone network combobox — use inside a custom `actions` slot. |
|
|
114
|
+
|
|
115
|
+
## Usage inside AppDashboard (standard)
|
|
116
|
+
|
|
117
|
+
Customize via the `header` prop — never import `AppHeader` directly for this:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
// Default (no header prop needed)
|
|
121
|
+
<AppDashboard>...</AppDashboard>
|
|
122
|
+
|
|
123
|
+
// With network list
|
|
124
|
+
<AppDashboard header={{ networks: myNetworks, currentNetwork: selected, onNetworkChange: setSelected }}>
|
|
125
|
+
...
|
|
126
|
+
</AppDashboard>
|
|
127
|
+
|
|
128
|
+
// Remove searchbar
|
|
129
|
+
<AppDashboard header={{ searchbar: null }}>...</AppDashboard>
|
|
130
|
+
|
|
131
|
+
// Remove avatar
|
|
132
|
+
<AppDashboard header={{ avatar: null }}>...</AppDashboard>
|
|
133
|
+
|
|
134
|
+
// Remove network select
|
|
135
|
+
<AppDashboard header={{ networkSelect: null }}>...</AppDashboard>
|
|
136
|
+
|
|
137
|
+
// Hide theme toggle and bento
|
|
138
|
+
<AppDashboard header={{ showThemeToggle: false, showBento: false }}>...</AppDashboard>
|
|
139
|
+
|
|
140
|
+
// Custom right-side actions
|
|
141
|
+
<AppDashboard header={{ actions: <AppButton>Save</AppButton> }}>...</AppDashboard>
|
|
142
|
+
|
|
143
|
+
// Profile popover (avatar becomes interactive)
|
|
144
|
+
<AppDashboard
|
|
145
|
+
header={{
|
|
146
|
+
profile: { name: "Joshua Intern", role: "Admin" },
|
|
147
|
+
onSettings: handleSettings,
|
|
148
|
+
onAdministrator: handleAdministrator,
|
|
149
|
+
onLogout: handleLogout,
|
|
150
|
+
}}
|
|
151
|
+
>...</AppDashboard>
|
|
152
|
+
|
|
153
|
+
// Profile with avatar image
|
|
154
|
+
<AppDashboard
|
|
155
|
+
header={{
|
|
156
|
+
profile: { name: "Joshua Intern", role: "Admin", avatarSrc: "https://..." },
|
|
157
|
+
onLogout: handleLogout,
|
|
158
|
+
}}
|
|
159
|
+
>...</AppDashboard>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Usage standalone (layout outside AppDashboard)
|
|
163
|
+
|
|
164
|
+
Only needed when building a custom layout that does not use `AppDashboard`:
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
import { AppHeader, type NetworkOption } from '@skunkworks/ui'
|
|
168
|
+
|
|
169
|
+
const networks: NetworkOption[] = [
|
|
170
|
+
{ value: "meldcx", label: "MeldCX Network" },
|
|
171
|
+
{ value: "acme", label: "Acme Corp" },
|
|
172
|
+
// ...
|
|
173
|
+
]
|
|
174
|
+
|
|
175
|
+
<AppSidebarProvider
|
|
176
|
+
style={{ "--sidebar-width": "14rem", "--header-height": "3.5rem" } as React.CSSProperties}
|
|
177
|
+
>
|
|
178
|
+
<AppSidebar>...</AppSidebar>
|
|
179
|
+
<AppSidebarInset>
|
|
180
|
+
<AppHeader networks={networks} currentNetwork={selected} onNetworkChange={setSelected} />
|
|
181
|
+
<main>Page content</main>
|
|
182
|
+
</AppSidebarInset>
|
|
183
|
+
</AppSidebarProvider>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
With custom slots:
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
<AppHeader
|
|
190
|
+
searchbar={<AppInput placeholder="Find sites..." className="w-64" />}
|
|
191
|
+
avatar={<AppAvatar className="size-8"><AppAvatarFallback>JD</AppAvatarFallback></AppAvatar>}
|
|
192
|
+
networkSelect={null}
|
|
193
|
+
/>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Searchbar slot
|
|
197
|
+
|
|
198
|
+
The `searchbar` slot accepts any `ReactNode`. Always fill it with an `App*` component — never a raw `<input>`.
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
// ✅ Correct
|
|
202
|
+
import { AppInput } from '@skunkworksai/ui-kit'
|
|
203
|
+
|
|
204
|
+
<AppDashboard header={{
|
|
205
|
+
searchbar: (
|
|
206
|
+
<AppInput
|
|
207
|
+
placeholder="Search sites, users..."
|
|
208
|
+
value={query}
|
|
209
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
210
|
+
className="w-64"
|
|
211
|
+
/>
|
|
212
|
+
)
|
|
213
|
+
}}>
|
|
214
|
+
|
|
215
|
+
// ✅ Also correct — controlled with state
|
|
216
|
+
<AppDashboard header={{
|
|
217
|
+
searchbar: <AppInput placeholder="Search..." value={q} onChange={e => setQ(e.target.value)} />
|
|
218
|
+
}}>
|
|
219
|
+
|
|
220
|
+
// ❌ Wrong — raw <input> with inline classes
|
|
221
|
+
<AppDashboard header={{
|
|
222
|
+
searchbar: <input className="flex h-9 rounded-md border border-input bg-transparent px-3 ..." />
|
|
223
|
+
}}>
|
|
224
|
+
|
|
225
|
+
// ✅ Remove searchbar entirely
|
|
226
|
+
<AppDashboard header={{ searchbar: null }}>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Rules
|
|
230
|
+
|
|
231
|
+
- **Do** provide `networks` with real data — the default 2-entry list is a demo placeholder only.
|
|
232
|
+
- **Do** use controlled `currentNetwork` + `onNetworkChange` when the selected network needs to drive other state.
|
|
233
|
+
- **Do** customize the header via `AppDashboard`'s `header` prop — not by importing `AppHeader` directly.
|
|
234
|
+
- **Do** use `null` to remove a slot, not an empty fragment.
|
|
235
|
+
- **Do** use `actions` prop to replace the entire right-side area; use `avatar`/`networkSelect`/`showThemeToggle`/`showBento` for targeted control.
|
|
236
|
+
- **Do** use `AppInput` for the searchbar slot — never a raw `<input>` with className.
|
|
237
|
+
- **Don't** add `bg-*` or theme classes to `AppHeader` inside the dashboard — it uses transparent background by design.
|
|
238
|
+
- **Don't** use raw `<input>`, `<button>`, or `<select>` inside any slot — always use `AppInput`, `AppButton`, `AppSelect`.
|
|
239
|
+
- **Don't** use `AppSelect` for the network picker — use `AppHeaderNetworkCombobox` or the `networks` prop.
|
|
240
|
+
|
|
241
|
+
If a prop you need is missing, stop and inform the design team.
|
|
242
|
+
|
|
243
|
+
## Responsive
|
|
244
|
+
|
|
245
|
+
On mobile (<768px) the searchbar collapses to an icon button that opens a top Sheet, the network combobox is hidden below `sm` (640px), and the actions gap tightens to `gap-1`. On desktop (≥768px) all slots — searchbar, network combobox, and actions — are visible inline with no consumer intervention required.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# AppHoverCard
|
|
2
|
+
|
|
3
|
+
> Docs: https://ui-kit.vercel.app/docs/components/hover-card
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { AppHoverCard, AppHoverCardTrigger, AppHoverCardContent } from "@/components/primitives/AppHoverCard"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## AppHoverCard
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| :--- | :--- | :--- | :--- |
|
|
13
|
+
| `openDelay` | `number` | `700` | The duration from when the mouse enters the trigger until the hover card opens. |
|
|
14
|
+
| `closeDelay` | `number` | `300` | The duration from when the mouse leaves the trigger or content until the hover card closes. |
|
|
15
|
+
|
|
16
|
+
## AppHoverCardContent
|
|
17
|
+
|
|
18
|
+
| Prop | Type | Default | Description |
|
|
19
|
+
| :--- | :--- | :--- | :--- |
|
|
20
|
+
| `side` | `"top" \| "right" \| "bottom" \| "left"` | `"bottom"` | The preferred side of the trigger to render against when open. |
|
|
21
|
+
| `align` | `"start" \| "center" \| "end"` | `"center"` | The preferred alignment against the trigger. |
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Simple Hover Card
|
|
26
|
+
```tsx
|
|
27
|
+
<AppHoverCard>
|
|
28
|
+
<AppHoverCardTrigger>
|
|
29
|
+
<a href="https://twitter.com/nextjs" className="underline">@nextjs</a>
|
|
30
|
+
</AppHoverCardTrigger>
|
|
31
|
+
<AppHoverCardContent className="w-80">
|
|
32
|
+
<div className="flex justify-between space-x-4">
|
|
33
|
+
<div className="space-y-1">
|
|
34
|
+
<h4 className="text-sm font-semibold">@nextjs</h4>
|
|
35
|
+
<p className="text-sm text-muted-foreground">
|
|
36
|
+
The React Framework – created and maintained by @vercel.
|
|
37
|
+
</p>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</AppHoverCardContent>
|
|
41
|
+
</AppHoverCard>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Rules
|
|
45
|
+
|
|
46
|
+
- **Do** use `AppHoverCard` to provide a preview of content behind a link.
|
|
47
|
+
- **Do** use `AppHoverCard` for sighted users on desktop; ensure information is accessible via other means for mobile/screen readers.
|
|
48
|
+
- **Don't** use `AppHoverCard` for critical actions; it is for informational previews.
|
|
49
|
+
- If a prop you need is missing, stop and inform the design team.
|
|
50
|
+
|
|
51
|
+
## Responsive
|
|
52
|
+
|
|
53
|
+
`AppHoverCardContent` renders `null` on mobile (<768px) — hover previews are not available on touch. Use a tap-triggered `AppPopover` or `AppDrawer` if the content must be accessible on mobile.
|
package/rules/icons.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Icons
|
|
2
|
+
|
|
3
|
+
UI Kit uses two icon systems: custom SVG nav icons for the sidebar, and **lucide-react** for all general-purpose UI icons.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Custom Nav Icons
|
|
8
|
+
|
|
9
|
+
Seven navigation icon pairs ship with UI Kit. Each has a default and an active state. They are used exclusively inside `AppDashboard` nav items — the active/default swap is handled automatically when `isActive` is set on the nav item.
|
|
10
|
+
|
|
11
|
+
Assets ship as raw files in `dist/assets/` (requires `@skunkworksai/ui-kit@>=0.1.5`). They are scaffolded into your project during setup — import from your own files, never from the package directly:
|
|
12
|
+
|
|
13
|
+
### Available pairs
|
|
14
|
+
|
|
15
|
+
| Name | Default | Active |
|
|
16
|
+
|------|---------|--------|
|
|
17
|
+
| Dashboard | `DashboardIcon` | `DashboardActiveIcon` |
|
|
18
|
+
| Site | `SiteIcon` | `SiteActiveIcon` |
|
|
19
|
+
| Devices | `DevicesIcon` | `DevicesActiveIcon` |
|
|
20
|
+
| Sensor | `SensorIcon` | `SensorActiveIcon` |
|
|
21
|
+
| X-ray | `XrayIcon` | `XrayActiveIcon` |
|
|
22
|
+
| Manifest | `ManifestIcon` | `ManifestActiveIcon` |
|
|
23
|
+
| Installer | `InstallerIcon` | `InstallerActiveIcon` |
|
|
24
|
+
|
|
25
|
+
### Import
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import {
|
|
29
|
+
DashboardIcon, DashboardActiveIcon,
|
|
30
|
+
SiteIcon, SiteActiveIcon,
|
|
31
|
+
// … other pairs
|
|
32
|
+
} from "./assets/icons"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
These components accept all standard `SVGProps<SVGSVGElement>`. Default size is 24×24 — override with `width` / `height` props.
|
|
36
|
+
|
|
37
|
+
### Usage in AppDashboard nav
|
|
38
|
+
|
|
39
|
+
Pass the icon component (not `<Icon />`) as the `icon` field. Do not pass the active icon — the sidebar handles the swap internally.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { DashboardIcon, DashboardActiveIcon } from "./assets/icons"
|
|
43
|
+
|
|
44
|
+
function DashboardNavIcon() {
|
|
45
|
+
return <AppSidebarNavIcon icon={<DashboardIcon />} activeIcon={<DashboardActiveIcon />} />
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const nav = [
|
|
49
|
+
{
|
|
50
|
+
items: [
|
|
51
|
+
{ title: "Dashboard", icon: DashboardNavIcon, isActive: true },
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Lucide React
|
|
60
|
+
|
|
61
|
+
All general-purpose icons come from **lucide-react**. It is already installed — do not add a second icon library.
|
|
62
|
+
|
|
63
|
+
### Usage
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { Search, Moon, Sun, LayoutGrid } from "lucide-react"
|
|
67
|
+
|
|
68
|
+
<Search className="size-4" /> // 16px — inline / button icons
|
|
69
|
+
<Search className="size-5" /> // 20px — sidebar nav icons
|
|
70
|
+
<Search className="size-6" /> // 24px — hero / standalone
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Size conventions
|
|
74
|
+
|
|
75
|
+
| Class | Size | When to use |
|
|
76
|
+
|-------|------|-------------|
|
|
77
|
+
| `size-3` | 12px | Badges, labels |
|
|
78
|
+
| `size-4` | 16px | Buttons, inputs, inline |
|
|
79
|
+
| `size-5` | 20px | Sidebar nav, list items |
|
|
80
|
+
| `size-6` | 24px | Hero, standalone callouts |
|
|
81
|
+
|
|
82
|
+
### Color
|
|
83
|
+
|
|
84
|
+
Icons inherit `currentColor` via their `stroke`. Set color with a Tailwind text class — never hardcode a fill or stroke color.
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
<Search className="size-4 text-muted-foreground" />
|
|
88
|
+
<Search className="size-4 text-primary" />
|
|
89
|
+
<Search className="size-4 text-destructive" />
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Service Applets & Apps
|
|
95
|
+
|
|
96
|
+
Branded app imagery for each Skunkworks product. Import from your own scaffolded files:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
import { AudienceMeasurementImg } from "./assets/Service-applets-apps"
|
|
100
|
+
|
|
101
|
+
<img src={AudienceMeasurementImg} alt="Audience Measurement" />
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Service Applets
|
|
105
|
+
|
|
106
|
+
| Export | File |
|
|
107
|
+
|--------|------|
|
|
108
|
+
| `AudienceMeasurementImg` | `audience-measurement.png` |
|
|
109
|
+
| `ContentEffectivenessImg` | `content-effectiveness.png` |
|
|
110
|
+
| `HopTrackingImg` | `hop-tracking.png` |
|
|
111
|
+
| `PeopleCountingImg` | `people-counting.png` |
|
|
112
|
+
| `PetraImg` | `petra.png` |
|
|
113
|
+
| `SamGenericImg` | `sam-generic.png` |
|
|
114
|
+
| `SamiForEnvironmentImg` | `sami-for-environment.png` |
|
|
115
|
+
| `ShelfEngagementImg` | `shelf-engagement.png` |
|
|
116
|
+
| `TrafficManagementImg` | `traffic-management.png` |
|
|
117
|
+
| `ZoneEngagementImg` | `zone-engagement.png` |
|
|
118
|
+
|
|
119
|
+
### Apps
|
|
120
|
+
|
|
121
|
+
| Export | File |
|
|
122
|
+
|--------|------|
|
|
123
|
+
| `CoatroAppImg` | `coatro-app.png` |
|
|
124
|
+
| `JourneysAppImg` | `journeys-app.png` |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Rules
|
|
129
|
+
|
|
130
|
+
- ✅ Import custom nav icons from `./assets/icons` — never from `@skunkworksai/ui-kit`
|
|
131
|
+
- ✅ Import service applet images from `./assets/Service-applets-apps` — never from the package
|
|
132
|
+
- ✅ Always set a `size-*` class on Lucide icons — never rely on the default 24px
|
|
133
|
+
- ✅ Use `text-*` classes for Lucide icon color — icons inherit `currentColor`
|
|
134
|
+
- ❌ Do not import from `lucide-react/dist` — import from the root package
|
|
135
|
+
- ❌ Do not add a second icon library (heroicons, phosphor, etc.) — use lucide-react exclusively
|
|
136
|
+
- ❌ Do not wrap Lucide icons in custom components — use them directly
|
|
137
|
+
- ❌ Do not pass `<Icon />` to the `icon` field in AppDashboard nav — pass the component reference
|
|
138
|
+
|
|
139
|
+
## On package upgrade
|
|
140
|
+
|
|
141
|
+
Re-run the asset scaffold step and diff `src/assets/icons/` against the new `dist/assets/icons/` if icons changed.
|
package/rules/input.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# AppInput
|
|
2
|
+
|
|
3
|
+
> Docs: https://ui-kit.vercel.app/docs/components/input
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { AppInput } from "@/components/primitives/AppInput"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
|------|------|---------|-------------|
|
|
13
|
+
| `leftAdornment` | `ReactNode` | — | Icon or element rendered inside the left edge of the input |
|
|
14
|
+
| `rightAdornment` | `ReactNode` | — | Icon or element rendered inside the right edge of the input |
|
|
15
|
+
| `type` | `string` | `"text"` | HTML input type (text, email, password, number, etc.) |
|
|
16
|
+
| `placeholder` | `string` | — | Placeholder text |
|
|
17
|
+
| `disabled` | `boolean` | `false` | Disables the input |
|
|
18
|
+
| `className` | `string` | — | Additional Tailwind classes applied to the input element |
|
|
19
|
+
|
|
20
|
+
> Accepts all standard HTML `<input>` attributes in addition to the props above.
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
### Basic
|
|
25
|
+
```tsx
|
|
26
|
+
<AppInput type="email" placeholder="you@example.com" />
|
|
27
|
+
<AppInput type="password" placeholder="••••••••" />
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### With adornments
|
|
31
|
+
```tsx
|
|
32
|
+
<AppInput
|
|
33
|
+
type="search"
|
|
34
|
+
placeholder="Search..."
|
|
35
|
+
leftAdornment={<SearchIcon className="size-4" />}
|
|
36
|
+
/>
|
|
37
|
+
|
|
38
|
+
<AppInput
|
|
39
|
+
type="text"
|
|
40
|
+
placeholder="Enter amount"
|
|
41
|
+
leftAdornment={<span className="text-sm text-muted-foreground">$</span>}
|
|
42
|
+
rightAdornment={<span className="text-sm text-muted-foreground">USD</span>}
|
|
43
|
+
/>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Disabled
|
|
47
|
+
```tsx
|
|
48
|
+
<AppInput disabled placeholder="Not editable" />
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### With label (use AppLabel)
|
|
52
|
+
```tsx
|
|
53
|
+
<div className="space-y-1.5">
|
|
54
|
+
<AppLabel htmlFor="email">Email</AppLabel>
|
|
55
|
+
<AppInput id="email" type="email" placeholder="you@example.com" />
|
|
56
|
+
</div>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Rules
|
|
60
|
+
- ✅ Always use `AppInput` — never use a raw `<input>` element
|
|
61
|
+
- ✅ Use `leftAdornment` / `rightAdornment` for icons inside the input — do not wrap `AppInput` in a relative `<div>` to position them manually
|
|
62
|
+
- ✅ Pair with `AppLabel` using matching `id` and `htmlFor` — never use a raw `<label>`
|
|
63
|
+
- ✅ Pair with `AppField` or `AppForm` for full form field layout with error states
|
|
64
|
+
- ❌ Do not add `pl-*` or `pr-*` padding when using adornments — padding is adjusted automatically
|
|
65
|
+
- ❌ Do not set `width` directly on `AppInput` — control width from the parent container
|
|
66
|
+
- ❌ If a prop you need is missing, stop and inform the design team
|
package/rules/kbd.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# AppKbd
|
|
2
|
+
|
|
3
|
+
> Docs: https://ui-kit.vercel.app/docs/components/kbd
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { AppKbd, AppKbdGroup } from "@skunkworksai/ui-kit"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## AppKbd
|
|
10
|
+
|
|
11
|
+
Keyboard key badge. Renders a `<kbd>` element styled as a bordered monospace pill.
|
|
12
|
+
|
|
13
|
+
Accepts all HTML `<kbd>` attributes.
|
|
14
|
+
|
|
15
|
+
## AppKbdGroup
|
|
16
|
+
|
|
17
|
+
Inline row of `AppKbd` keys with consistent `gap-1`.
|
|
18
|
+
|
|
19
|
+
Accepts all `<span>` HTML attributes.
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Single key
|
|
24
|
+
```tsx
|
|
25
|
+
<AppKbd>K</AppKbd>
|
|
26
|
+
<AppKbd>Enter</AppKbd>
|
|
27
|
+
<AppKbd>⌘</AppKbd>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Key combination
|
|
31
|
+
```tsx
|
|
32
|
+
<AppKbdGroup>
|
|
33
|
+
<AppKbd>⌘</AppKbd>
|
|
34
|
+
<AppKbd>K</AppKbd>
|
|
35
|
+
</AppKbdGroup>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Multi-key shortcut
|
|
39
|
+
```tsx
|
|
40
|
+
<AppKbdGroup>
|
|
41
|
+
<AppKbd>Ctrl</AppKbd>
|
|
42
|
+
<AppKbd>Shift</AppKbd>
|
|
43
|
+
<AppKbd>P</AppKbd>
|
|
44
|
+
</AppKbdGroup>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Inside a label or description
|
|
48
|
+
```tsx
|
|
49
|
+
<p className="text-sm text-muted-foreground">
|
|
50
|
+
Press <AppKbdGroup><AppKbd>⌘</AppKbd><AppKbd>K</AppKbd></AppKbdGroup> to open the command palette.
|
|
51
|
+
</p>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Rules
|
|
55
|
+
- ✅ Use `AppKbdGroup` whenever showing two or more keys together
|
|
56
|
+
- ✅ Use platform symbols (⌘, ⌥, ⇧) for Mac shortcuts; use "Ctrl", "Alt", "Shift" for cross-platform
|
|
57
|
+
- ❌ Do not wrap `AppKbd` in extra `<span>` elements for spacing — use `AppKbdGroup`
|
|
58
|
+
- ❌ If a prop you need is missing, stop and inform the design team
|
package/rules/label.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# AppLabel
|
|
2
|
+
|
|
3
|
+
> Docs: https://ui-kit.vercel.app/docs/components/label
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { AppLabel } from "@/components/primitives/AppLabel"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## AppLabel
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| :--- | :--- | :--- | :--- |
|
|
13
|
+
| `htmlFor` | `string` | - | The ID of the form element the label is associated with. |
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Basic Label
|
|
18
|
+
```tsx
|
|
19
|
+
<div className="flex items-center space-x-2">
|
|
20
|
+
<AppCheckbox id="terms" />
|
|
21
|
+
<AppLabel htmlFor="terms">Accept terms and conditions</AppLabel>
|
|
22
|
+
</div>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Rules
|
|
26
|
+
|
|
27
|
+
- **Do** use `AppLabel` for all form control labels to ensure accessibility.
|
|
28
|
+
- **Do** use the `htmlFor` prop to link the label to its corresponding input.
|
|
29
|
+
- **Don't** use raw `<label>` elements.
|
|
30
|
+
- If a prop you need is missing, stop and inform the design team.
|