@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/sidebar.md
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
# AppSidebar
|
|
2
|
+
|
|
3
|
+
> Docs: https://ui-kit.vercel.app/docs/components/sidebar
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import {
|
|
7
|
+
AppSidebarProvider,
|
|
8
|
+
AppSidebar,
|
|
9
|
+
AppSidebarBrand,
|
|
10
|
+
AppSidebarTrigger,
|
|
11
|
+
AppSidebarRail,
|
|
12
|
+
AppSidebarInset,
|
|
13
|
+
AppSidebarHeader,
|
|
14
|
+
AppSidebarContent,
|
|
15
|
+
AppSidebarFooter,
|
|
16
|
+
AppSidebarSeparator,
|
|
17
|
+
AppSidebarInput,
|
|
18
|
+
AppSidebarGroup,
|
|
19
|
+
AppSidebarGroupLabel,
|
|
20
|
+
AppSidebarGroupAction,
|
|
21
|
+
AppSidebarGroupContent,
|
|
22
|
+
AppSidebarMenu,
|
|
23
|
+
AppSidebarMenuItem,
|
|
24
|
+
AppSidebarMenuButton,
|
|
25
|
+
AppSidebarMenuAction,
|
|
26
|
+
AppSidebarMenuBadge,
|
|
27
|
+
AppSidebarMenuSkeleton,
|
|
28
|
+
AppSidebarMenuSub,
|
|
29
|
+
AppSidebarMenuSubItem,
|
|
30
|
+
AppSidebarMenuSubButton,
|
|
31
|
+
useSidebar,
|
|
32
|
+
} from "@/components/primitives/AppSidebar"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## AppSidebarProvider
|
|
36
|
+
|
|
37
|
+
| Prop | Type | Default | Description |
|
|
38
|
+
| :--- | :--- | :--- | :--- |
|
|
39
|
+
| `defaultOpen` | `boolean` | `true` | Initial open state (uncontrolled). |
|
|
40
|
+
| `open` | `boolean` | — | Controlled open state. |
|
|
41
|
+
| `onOpenChange` | `(open: boolean) => void` | — | Callback for open state changes. |
|
|
42
|
+
|
|
43
|
+
## AppSidebar
|
|
44
|
+
|
|
45
|
+
| Prop | Type | Default | Description |
|
|
46
|
+
| :--- | :--- | :--- | :--- |
|
|
47
|
+
| `side` | `"left" \| "right"` | `"left"` | Which edge the sidebar is anchored to. |
|
|
48
|
+
| `variant` | `"sidebar" \| "floating" \| "inset"` | `"sidebar"` | Visual presentation style. |
|
|
49
|
+
| `collapsible` | `"offcanvas" \| "icon" \| "none"` | `"offcanvas"` | How the sidebar collapses. |
|
|
50
|
+
|
|
51
|
+
## AppSidebarBrand
|
|
52
|
+
|
|
53
|
+
Place as the first child of `AppSidebarHeader`. The logo is always **horizontally centered**. When a `dropdown` is provided, the chevron is absolutely positioned to the right edge so it does not shift the logo off-center.
|
|
54
|
+
|
|
55
|
+
| Prop | Type | Default | Description |
|
|
56
|
+
| :--- | :--- | :--- | :--- |
|
|
57
|
+
| `logo` | `string \| ReactNode` | `<WhiteLogo width={90} height={28} />` | Text label or logo component. Defaults to the white UI Kit logo for dark backgrounds. |
|
|
58
|
+
| `collapsedLogo` | `ReactNode` | `<WhiteSymbol width={24} height={24} />` | Icon shown when the sidebar is collapsed to icon mode. |
|
|
59
|
+
| `dropdown` | `AppSidebarBrandDropdownItem[]` | — | When provided, wraps the brand in a dropdown trigger. Omit for a non-interactive header. |
|
|
60
|
+
| `showChevron` | `boolean` | `true` | Show the caret icon. Only applies when `dropdown` is set. |
|
|
61
|
+
| `className` | `string` | — | Additional classes for the brand container. Supports `--sidebar-brand-px` CSS variable (see below). |
|
|
62
|
+
|
|
63
|
+
### Collapsed brand padding
|
|
64
|
+
|
|
65
|
+
The brand container uses `--sidebar-brand-px` (default `0.5rem` = `px-2`) for horizontal padding. Override via `className` to make the symbol flush when collapsed:
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
// Zero padding — symbol fills the full icon-mode width
|
|
69
|
+
<AppSidebarBrand className="[--sidebar-brand-px:0]" />
|
|
70
|
+
|
|
71
|
+
// Or via AppDashboard brand prop
|
|
72
|
+
<AppDashboard brand={{ className: "[--sidebar-brand-px:0]" }}>...</AppDashboard>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The `data-sidebar-brand` attribute is present on the wrapper for CSS selector hooks if needed.
|
|
76
|
+
|
|
77
|
+
### AppSidebarBrandDropdownItem
|
|
78
|
+
|
|
79
|
+
Two shapes are accepted in the same array:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
// Regular item
|
|
83
|
+
{ label: string; onClick?: () => void; icon?: ReactNode; disabled?: boolean }
|
|
84
|
+
|
|
85
|
+
// Separator
|
|
86
|
+
{ separator: true }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## DEFAULT_NAV
|
|
90
|
+
|
|
91
|
+
A built-in navigation constant exported from `AppSidebar`. It pre-wires the four standard UI Kit nav sections with custom inline SVG icons and active/default icon pairs — no manual setup required.
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { DEFAULT_NAV } from "@/components/primitives/AppSidebar"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Structure
|
|
98
|
+
|
|
99
|
+
| Group label | Menu item |
|
|
100
|
+
|---|---|
|
|
101
|
+
| *(no label)* | Dashboard |
|
|
102
|
+
| MANAGE | Site, Devices, Sensor |
|
|
103
|
+
| INSIGHTS | X-ray, Manifest |
|
|
104
|
+
| DOWNLOADS | Installers |
|
|
105
|
+
|
|
106
|
+
All `href` values default to `"#"`. Override by passing a custom `nav` prop to `AppDashboard`, or by iterating `DEFAULT_NAV` and replacing `href` values in your app.
|
|
107
|
+
|
|
108
|
+
### Using DEFAULT_NAV directly
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
import { DEFAULT_NAV } from "@/components/primitives/AppSidebar"
|
|
112
|
+
|
|
113
|
+
<AppSidebarContent>
|
|
114
|
+
{DEFAULT_NAV.map((section, i) => (
|
|
115
|
+
<AppSidebarGroup key={i}>
|
|
116
|
+
{section.label && (
|
|
117
|
+
<AppSidebarGroupLabel>{section.label}</AppSidebarGroupLabel>
|
|
118
|
+
)}
|
|
119
|
+
<AppSidebarGroupContent>
|
|
120
|
+
<AppSidebarMenu>
|
|
121
|
+
{section.items.map((item) => (
|
|
122
|
+
<AppSidebarMenuItem key={item.title}>
|
|
123
|
+
<AppSidebarMenuButton
|
|
124
|
+
isActive={item.title === "Dashboard"}
|
|
125
|
+
tooltip={item.title}
|
|
126
|
+
>
|
|
127
|
+
<item.icon />
|
|
128
|
+
<span>{item.title}</span>
|
|
129
|
+
</AppSidebarMenuButton>
|
|
130
|
+
</AppSidebarMenuItem>
|
|
131
|
+
))}
|
|
132
|
+
</AppSidebarMenu>
|
|
133
|
+
</AppSidebarGroupContent>
|
|
134
|
+
</AppSidebarGroup>
|
|
135
|
+
))}
|
|
136
|
+
</AppSidebarContent>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
When using `AppDashboard`, the default nav renders automatically — no prop needed. See [AppDashboard rules](/rules/dashboard.md).
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Active/default icon swap
|
|
144
|
+
|
|
145
|
+
Each `DEFAULT_NAV` icon component renders **two** icon variants simultaneously — the default state icon and the active state icon. Visibility is controlled entirely by CSS using the `group/menu-button` data attribute on `AppSidebarMenuButton`:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
default state → group-data-[active=true]/menu-button:hidden (visible by default, hidden when active)
|
|
149
|
+
active state → hidden group-data-[active=true]/menu-button:block (hidden by default, shown when active)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
This mechanism is internal to the nav-icon components and requires no code from consumers. Simply pass `isActive={true}` to `AppSidebarMenuButton` and both the background fill and the icon variant update automatically.
|
|
153
|
+
|
|
154
|
+
**Custom icon with active swap:**
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
function MyNavIcon() {
|
|
158
|
+
return (
|
|
159
|
+
<>
|
|
160
|
+
<span className="group-data-[active=true]/menu-button:hidden">
|
|
161
|
+
<MyDefaultIcon />
|
|
162
|
+
</span>
|
|
163
|
+
<span className="hidden group-data-[active=true]/menu-button:block">
|
|
164
|
+
<MyActiveIcon />
|
|
165
|
+
</span>
|
|
166
|
+
</>
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
<AppSidebarMenuButton isActive={isCurrentRoute} tooltip="My Section">
|
|
171
|
+
<MyNavIcon />
|
|
172
|
+
<span>My Section</span>
|
|
173
|
+
</AppSidebarMenuButton>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
SVG icons must be rendered as React components (inline SVG), not `<img>` tags, so they respond to CSS.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## AppSidebarMenuButton
|
|
181
|
+
|
|
182
|
+
No background fill by default or on hover. The **primary brand color** background is applied **only when `isActive={true}`** — using `bg-primary` and `text-primary-foreground`.
|
|
183
|
+
|
|
184
|
+
> **Note:** Tailwind v4 compiles `data-active:` to the CSS selector `[data-active]`, which matches all buttons (the attribute is always present). `AppSidebarMenuButton` corrects this by overriding with `data-active:bg-transparent` and re-applying the primary color only via `data-[active=true]:bg-primary data-[active=true]:text-primary-foreground`.
|
|
185
|
+
|
|
186
|
+
**Size overrides:** `AppSidebarMenuButton` bumps the shadcn defaults for a slightly larger feel:
|
|
187
|
+
- Icons: `[&_svg]:size-5` (20 px vs shadcn's 16 px)
|
|
188
|
+
- Font: `text-base` (16 px vs shadcn's 14 px)
|
|
189
|
+
|
|
190
|
+
| Prop | Type | Default | Description |
|
|
191
|
+
| :--- | :--- | :--- | :--- |
|
|
192
|
+
| `asChild` | `boolean` | `false` | Render as child element (e.g. a router Link). |
|
|
193
|
+
| `isActive` | `boolean` | `false` | Marks this item as the active route. Applies accent background + medium font weight + active icon variant. |
|
|
194
|
+
| `variant` | `"default" \| "outline"` | `"default"` | Visual style. |
|
|
195
|
+
| `size` | `"default" \| "sm" \| "lg"` | `"default"` | Height and text size. |
|
|
196
|
+
| `tooltip` | `string \| TooltipContentProps` | — | Tooltip shown when sidebar is collapsed to icon mode. |
|
|
197
|
+
|
|
198
|
+
## AppSidebarMenuSubButton
|
|
199
|
+
|
|
200
|
+
| Prop | Type | Default | Description |
|
|
201
|
+
| :--- | :--- | :--- | :--- |
|
|
202
|
+
| `asChild` | `boolean` | `false` | Render as child element. |
|
|
203
|
+
| `isActive` | `boolean` | `false` | Marks the sub-item as active. |
|
|
204
|
+
| `size` | `"sm" \| "md"` | `"md"` | Text size. |
|
|
205
|
+
|
|
206
|
+
## AppSidebarMenuSkeleton
|
|
207
|
+
|
|
208
|
+
| Prop | Type | Default | Description |
|
|
209
|
+
| :--- | :--- | :--- | :--- |
|
|
210
|
+
| `showIcon` | `boolean` | `false` | Show a skeleton icon placeholder. |
|
|
211
|
+
|
|
212
|
+
## useSidebar
|
|
213
|
+
|
|
214
|
+
Returns `{ state, open, setOpen, openMobile, setOpenMobile, isMobile, toggleSidebar }`.
|
|
215
|
+
|
|
216
|
+
Must be called inside an `AppSidebarProvider`.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Usage
|
|
221
|
+
|
|
222
|
+
### Default (App logo, no dropdown)
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
<AppSidebarHeader>
|
|
226
|
+
<AppSidebarBrand />
|
|
227
|
+
</AppSidebarHeader>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Text logo
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
<AppSidebarHeader>
|
|
234
|
+
<AppSidebarBrand logo="My App" />
|
|
235
|
+
</AppSidebarHeader>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Image logo
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
import { WhiteLogo } from "@/assets/logos"
|
|
242
|
+
|
|
243
|
+
<AppSidebarHeader>
|
|
244
|
+
<AppSidebarBrand logo={<WhiteLogo width={90} height={28} />} />
|
|
245
|
+
</AppSidebarHeader>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### With workspace dropdown
|
|
249
|
+
|
|
250
|
+
```tsx
|
|
251
|
+
<AppSidebarBrand
|
|
252
|
+
dropdown={[
|
|
253
|
+
{ label: "Acme Corp", onClick: () => switchWorkspace("acme") },
|
|
254
|
+
{ label: "Personal", onClick: () => switchWorkspace("personal") },
|
|
255
|
+
{ separator: true },
|
|
256
|
+
{ label: "Create workspace", onClick: openCreateModal },
|
|
257
|
+
]}
|
|
258
|
+
/>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Dropdown with icons
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
import { UserIcon, CreditCardIcon, LogOutIcon } from "lucide-react"
|
|
265
|
+
|
|
266
|
+
<AppSidebarBrand
|
|
267
|
+
dropdown={[
|
|
268
|
+
{ label: "Profile", icon: <UserIcon className="size-4" />, onClick: goToProfile },
|
|
269
|
+
{ label: "Billing", icon: <CreditCardIcon className="size-4" />, onClick: goToBilling },
|
|
270
|
+
{ separator: true },
|
|
271
|
+
{ label: "Log out", icon: <LogOutIcon className="size-4" />, onClick: logout },
|
|
272
|
+
]}
|
|
273
|
+
/>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Disable the chevron
|
|
277
|
+
|
|
278
|
+
```tsx
|
|
279
|
+
<AppSidebarBrand dropdown={items} showChevron={false} />
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Use `showChevron={false}` when the logo itself already communicates the affordance, or for a minimal header style. The dropdown still works — the entire brand area remains clickable.
|
|
283
|
+
|
|
284
|
+
### Full layout with DEFAULT_NAV
|
|
285
|
+
|
|
286
|
+
Use the built-in nav — no icons to import, no sections to define:
|
|
287
|
+
|
|
288
|
+
```tsx
|
|
289
|
+
import { DEFAULT_NAV } from "@/components/primitives/AppSidebar"
|
|
290
|
+
|
|
291
|
+
<AppSidebarProvider>
|
|
292
|
+
<AppSidebar collapsible="icon">
|
|
293
|
+
<AppSidebarHeader>
|
|
294
|
+
<AppSidebarBrand dropdown={workspaces} />
|
|
295
|
+
</AppSidebarHeader>
|
|
296
|
+
<AppSidebarContent>
|
|
297
|
+
{DEFAULT_NAV.map((section, i) => (
|
|
298
|
+
<AppSidebarGroup key={i}>
|
|
299
|
+
{section.label && (
|
|
300
|
+
<AppSidebarGroupLabel>{section.label}</AppSidebarGroupLabel>
|
|
301
|
+
)}
|
|
302
|
+
<AppSidebarGroupContent>
|
|
303
|
+
<AppSidebarMenu>
|
|
304
|
+
{section.items.map((item) => (
|
|
305
|
+
<AppSidebarMenuItem key={item.title}>
|
|
306
|
+
<AppSidebarMenuButton
|
|
307
|
+
isActive={item.title === "Dashboard"}
|
|
308
|
+
tooltip={item.title}
|
|
309
|
+
>
|
|
310
|
+
<item.icon />
|
|
311
|
+
<span>{item.title}</span>
|
|
312
|
+
</AppSidebarMenuButton>
|
|
313
|
+
</AppSidebarMenuItem>
|
|
314
|
+
))}
|
|
315
|
+
</AppSidebarMenu>
|
|
316
|
+
</AppSidebarGroupContent>
|
|
317
|
+
</AppSidebarGroup>
|
|
318
|
+
))}
|
|
319
|
+
</AppSidebarContent>
|
|
320
|
+
<AppSidebarFooter>
|
|
321
|
+
<span className="text-xs text-sidebar-foreground/50">v1.0.0</span>
|
|
322
|
+
</AppSidebarFooter>
|
|
323
|
+
<AppSidebarRail />
|
|
324
|
+
</AppSidebar>
|
|
325
|
+
<AppSidebarInset>
|
|
326
|
+
<header className="flex items-center gap-2 border-b border-border px-4 py-3">
|
|
327
|
+
<AppSidebarTrigger />
|
|
328
|
+
</header>
|
|
329
|
+
<main>Page content</main>
|
|
330
|
+
</AppSidebarInset>
|
|
331
|
+
</AppSidebarProvider>
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Full layout with custom nav sections
|
|
335
|
+
|
|
336
|
+
To use your own icons and items instead of DEFAULT_NAV:
|
|
337
|
+
|
|
338
|
+
```tsx
|
|
339
|
+
function MyDashboardNavIcon() {
|
|
340
|
+
return (
|
|
341
|
+
<>
|
|
342
|
+
<span className="group-data-[active=true]/menu-button:hidden">
|
|
343
|
+
<MyDefaultIcon />
|
|
344
|
+
</span>
|
|
345
|
+
<span className="hidden group-data-[active=true]/menu-button:block">
|
|
346
|
+
<MyActiveIcon />
|
|
347
|
+
</span>
|
|
348
|
+
</>
|
|
349
|
+
)
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const myNav = [
|
|
353
|
+
{ items: [{ title: "Home", icon: MyDashboardNavIcon }] },
|
|
354
|
+
]
|
|
355
|
+
|
|
356
|
+
<AppSidebarProvider>
|
|
357
|
+
<AppSidebar collapsible="icon">
|
|
358
|
+
...
|
|
359
|
+
<AppSidebarContent>
|
|
360
|
+
{myNav.map((section, i) => (
|
|
361
|
+
<AppSidebarGroup key={i}>
|
|
362
|
+
<AppSidebarGroupContent>
|
|
363
|
+
<AppSidebarMenu>
|
|
364
|
+
{section.items.map((item) => (
|
|
365
|
+
<AppSidebarMenuItem key={item.title}>
|
|
366
|
+
<AppSidebarMenuButton isActive tooltip={item.title}>
|
|
367
|
+
<item.icon />
|
|
368
|
+
<span>{item.title}</span>
|
|
369
|
+
</AppSidebarMenuButton>
|
|
370
|
+
</AppSidebarMenuItem>
|
|
371
|
+
))}
|
|
372
|
+
</AppSidebarMenu>
|
|
373
|
+
</AppSidebarGroupContent>
|
|
374
|
+
</AppSidebarGroup>
|
|
375
|
+
))}
|
|
376
|
+
</AppSidebarContent>
|
|
377
|
+
</AppSidebar>
|
|
378
|
+
</AppSidebarProvider>
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Menu button as link
|
|
382
|
+
|
|
383
|
+
```tsx
|
|
384
|
+
<AppSidebarMenuButton asChild isActive>
|
|
385
|
+
<a href="/dashboard">Dashboard</a>
|
|
386
|
+
</AppSidebarMenuButton>
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### With submenu
|
|
390
|
+
|
|
391
|
+
```tsx
|
|
392
|
+
<AppSidebarMenu>
|
|
393
|
+
<AppSidebarMenuItem>
|
|
394
|
+
<AppSidebarMenuButton>Projects</AppSidebarMenuButton>
|
|
395
|
+
<AppSidebarMenuSub>
|
|
396
|
+
<AppSidebarMenuSubItem>
|
|
397
|
+
<AppSidebarMenuSubButton asChild>
|
|
398
|
+
<a href="/projects/alpha">Alpha</a>
|
|
399
|
+
</AppSidebarMenuSubButton>
|
|
400
|
+
</AppSidebarMenuSubItem>
|
|
401
|
+
</AppSidebarMenuSub>
|
|
402
|
+
</AppSidebarMenuItem>
|
|
403
|
+
</AppSidebarMenu>
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Containing sidebar inside a preview box
|
|
407
|
+
|
|
408
|
+
When embedding a sidebar inside a fixed-height container (e.g. a component preview), the sidebar uses `position: fixed` which breaks out of the parent. Add `[contain:layout]` to the wrapper to create a containing block. The sidebar has a transparent background, so the wrapper must provide a dark background:
|
|
409
|
+
|
|
410
|
+
```tsx
|
|
411
|
+
<div className="dark relative h-96 overflow-hidden rounded-lg border bg-linear-to-br from-background via-muted to-card [contain:layout]">
|
|
412
|
+
<AppSidebarProvider className="min-h-0 h-full">
|
|
413
|
+
<AppSidebar collapsible="icon">...</AppSidebar>
|
|
414
|
+
<AppSidebarInset>...</AppSidebarInset>
|
|
415
|
+
</AppSidebarProvider>
|
|
416
|
+
</div>
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Rules
|
|
422
|
+
|
|
423
|
+
- **Do** use `DEFAULT_NAV` as the starting point — it pre-wires all standard UI Kit nav sections with correct icons and active/default swap.
|
|
424
|
+
- **Do** always include an icon and a `<span>` label inside each `AppSidebarMenuButton` — both are required for icon-only collapsed mode.
|
|
425
|
+
- **Do** place the sidebar inside a dark container (e.g. `AppDashboard` or a dark gradient wrapper) — the sidebar background is transparent by default with light text.
|
|
426
|
+
- **Do** wrap the entire page layout in `AppSidebarProvider` — it manages state for all children.
|
|
427
|
+
- **Do** use `AppSidebarInset` as the wrapper for your main content area.
|
|
428
|
+
- **Do** add `AppSidebarRail` inside `AppSidebar` to allow drag-to-resize on desktop.
|
|
429
|
+
- **Do** place `AppSidebarBrand` inside `AppSidebarHeader` as the first child.
|
|
430
|
+
- **Do** pass a `tooltip` to `AppSidebarMenuButton` when using `collapsible="icon"` so labels remain accessible.
|
|
431
|
+
- **Do** use `AppSidebarMenuButton asChild` with a router `<Link>` for navigation items.
|
|
432
|
+
- **Do** use `isActive` to mark the current route — never apply manual background classes to menu items.
|
|
433
|
+
- **Do** render custom icons as React components (inline SVG) — not `<img>` tags — so they respond to CSS for the active icon swap.
|
|
434
|
+
- **Don't** nest `AppSidebarProvider` — one per layout root.
|
|
435
|
+
- **Don't** use raw `<button>` or `<a>` tags for menu items; always go through `AppSidebarMenuButton`.
|
|
436
|
+
- **Don't** use `AppSidebarMenuSub` more than one level deep.
|
|
437
|
+
- **Don't** skip `AppSidebarBrand` and wire up a logo manually — use the component for consistent centering and interaction.
|
|
438
|
+
- **Don't** add `hover:bg-*` or `bg-*` classes to `AppSidebarMenuButton` — the fill behaviour is intentionally controlled by `isActive` only.
|
|
439
|
+
- **Don't** import `DashboardNavIcon`, `SiteNavIcon`, or other internal nav-icon wrapper components — they are not exported. Use `DEFAULT_NAV` or build your own using the active/default swap pattern above.
|
|
440
|
+
- **Don't** add global CSS or `!important` overrides to change sidebar brand padding — use `className="[--sidebar-brand-px:0]"` on `AppSidebarBrand` instead.
|
|
441
|
+
|
|
442
|
+
If a prop you need is missing, stop and inform the design team.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# AppSkeleton
|
|
2
|
+
|
|
3
|
+
> Docs: https://ui-kit.vercel.app/docs/components/skeleton
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { AppSkeleton } from "@/components/primitives/AppSkeleton"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## AppSkeleton
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| :--- | :--- | :--- | :--- |
|
|
13
|
+
| `className` | `string` | - | Used to set dimensions and shape (e.g. `h-10 w-10 rounded-full`). |
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Simple Card Skeleton
|
|
18
|
+
```tsx
|
|
19
|
+
<div className="flex items-center space-x-4">
|
|
20
|
+
<AppSkeleton className="h-12 w-12 rounded-full" />
|
|
21
|
+
<div className="space-y-2">
|
|
22
|
+
<AppSkeleton className="h-4 w-[250px]" />
|
|
23
|
+
<AppSkeleton className="h-4 w-[200px]" />
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Profile Skeleton
|
|
29
|
+
```tsx
|
|
30
|
+
<div className="flex flex-col space-y-3">
|
|
31
|
+
<AppSkeleton className="h-[125px] w-[250px] rounded-xl" />
|
|
32
|
+
<div className="space-y-2">
|
|
33
|
+
<AppSkeleton className="h-4 w-[250px]" />
|
|
34
|
+
<AppSkeleton className="h-4 w-[200px]" />
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Rules
|
|
40
|
+
|
|
41
|
+
- **Do** use `AppSkeleton` to indicate content is loading, mirroring the actual layout.
|
|
42
|
+
- **Do** use consistent spacing and sizing that matches the final component.
|
|
43
|
+
- **Don't** use `AppSkeleton` for purely decorative elements.
|
|
44
|
+
- **Don't** use too many skeletons at once if it causes excessive flickering on fast connections.
|
|
45
|
+
|
|
46
|
+
If a prop you need is missing, stop and inform the design team.
|
package/rules/spinner.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# AppSpinner
|
|
2
|
+
|
|
3
|
+
> Docs: https://ui-kit.vercel.app/docs/components/spinner
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { AppSpinner } from "@/components/primitives/AppSpinner"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## AppSpinner
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| :--- | :--- | :--- | :--- |
|
|
13
|
+
| `label` | `string` | `"Loading..."` | The accessible label for screen readers. |
|
|
14
|
+
| `className` | `string` | - | Used to set size (`h-x w-x`) and color (`text-x`). |
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
### Default Spinner
|
|
19
|
+
```tsx
|
|
20
|
+
<AppSpinner />
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Colored and Sized Spinner
|
|
24
|
+
```tsx
|
|
25
|
+
<AppSpinner className="h-8 w-8 text-primary" label="Uploading..." />
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Spinner in Button
|
|
29
|
+
```tsx
|
|
30
|
+
<AppButton disabled>
|
|
31
|
+
<AppSpinner className="h-4 w-4" />
|
|
32
|
+
Saving...
|
|
33
|
+
</AppButton>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Rules
|
|
37
|
+
|
|
38
|
+
- **Do** use `AppSpinner` for discrete loading states within components.
|
|
39
|
+
- **Do** provide a descriptive `label` if the loading context isn't obvious.
|
|
40
|
+
- **Don't** use `AppSpinner` for full-page loading if a skeleton is more appropriate.
|
|
41
|
+
- **Don't** forget to disable interaction on buttons when showing a spinner inside them.
|
|
42
|
+
|
|
43
|
+
If a prop you need is missing, stop and inform the design team.
|
package/rules/switch.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# AppSwitch
|
|
2
|
+
|
|
3
|
+
> Docs: https://ui-kit.vercel.app/docs/components/switch
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
import { AppSwitch } from "@/components/primitives/AppSwitch"
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## AppSwitch
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| :--- | :--- | :--- | :--- |
|
|
13
|
+
| `checked` | `boolean` | - | Controlled checked state. |
|
|
14
|
+
| `defaultChecked` | `boolean` | - | Initial checked state. |
|
|
15
|
+
| `onCheckedChange` | `(checked: boolean) => void` | - | Callback for checked state changes. |
|
|
16
|
+
| `disabled` | `boolean` | `false` | When `true`, prevents the user from interacting with the switch. |
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Basic Switch
|
|
21
|
+
```tsx
|
|
22
|
+
<div className="flex items-center space-x-2">
|
|
23
|
+
<AppSwitch id="airplane-mode" />
|
|
24
|
+
<AppLabel htmlFor="airplane-mode">Airplane Mode</AppLabel>
|
|
25
|
+
</div>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Controlled Switch
|
|
29
|
+
```tsx
|
|
30
|
+
const [enabled, setEnabled] = useState(false);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<AppSwitch
|
|
34
|
+
checked={enabled}
|
|
35
|
+
onCheckedChange={setEnabled}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Rules
|
|
41
|
+
|
|
42
|
+
- **Do** use `AppSwitch` for toggling settings that take effect immediately.
|
|
43
|
+
- **Do** always pair `AppSwitch` with a label for accessibility.
|
|
44
|
+
- **Don't** use `AppSwitch` for multiple selection; use `AppCheckbox` instead.
|
|
45
|
+
|
|
46
|
+
If a prop you need is missing, stop and inform the design team.
|