zabi-components 7.0.2 → 8.1.0
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/CHANGELOG.md +1924 -0
- package/README.md +287 -11
- package/THEME.md +149 -332
- package/THEMING.md +1329 -163
- package/dist/atoms/ActionPanel.svelte +24 -9
- package/dist/atoms/ActionPanel.svelte.d.ts +2 -0
- package/dist/atoms/Avatar.svelte +104 -0
- package/dist/atoms/Avatar.svelte.d.ts +34 -0
- package/dist/atoms/Badge.svelte +124 -58
- package/dist/atoms/Badge.svelte.d.ts +17 -5
- package/dist/atoms/Button.svelte +212 -62
- package/dist/atoms/Button.svelte.d.ts +33 -2
- package/dist/atoms/Card.svelte +31 -28
- package/dist/atoms/Card.svelte.d.ts +5 -2
- package/dist/atoms/CardContent.svelte +10 -2
- package/dist/atoms/CardContent.svelte.d.ts +2 -0
- package/dist/atoms/CardFooter.svelte +10 -2
- package/dist/atoms/CardFooter.svelte.d.ts +2 -0
- package/dist/atoms/CardHeader.svelte +26 -6
- package/dist/atoms/CardHeader.svelte.d.ts +2 -0
- package/dist/atoms/Checkbox.svelte +52 -21
- package/dist/atoms/Checkbox.svelte.d.ts +6 -2
- package/dist/atoms/CodeBlock.svelte +35 -9
- package/dist/atoms/CodeBlock.svelte.d.ts +13 -3
- package/dist/atoms/ColorPicker.svelte +272 -52
- package/dist/atoms/ColorPicker.svelte.d.ts +6 -1
- package/dist/atoms/Container.svelte +17 -10
- package/dist/atoms/DateField.svelte +107 -0
- package/dist/atoms/DateField.svelte.d.ts +53 -0
- package/dist/atoms/Divider.svelte +4 -4
- package/dist/atoms/FeatureCard.svelte +4 -3
- package/dist/atoms/FieldMessages.svelte +69 -0
- package/dist/atoms/FieldMessages.svelte.d.ts +23 -0
- package/dist/atoms/FloatingActionButton.svelte +174 -0
- package/dist/atoms/FloatingActionButton.svelte.d.ts +51 -0
- package/dist/atoms/Heading.svelte +93 -32
- package/dist/atoms/Heading.svelte.d.ts +24 -4
- package/dist/atoms/IconButton.svelte +242 -53
- package/dist/atoms/IconButton.svelte.d.ts +49 -4
- package/dist/atoms/Input.svelte +267 -74
- package/dist/atoms/Input.svelte.d.ts +32 -2
- package/dist/atoms/List.svelte +13 -2
- package/dist/atoms/List.svelte.d.ts +2 -0
- package/dist/atoms/ListItem.svelte +44 -11
- package/dist/atoms/ListItem.svelte.d.ts +5 -0
- package/dist/atoms/ListItemLeading.svelte +4 -2
- package/dist/atoms/ListItemLeading.svelte.d.ts +1 -1
- package/dist/atoms/OptimizedImage.svelte +11 -2
- package/dist/atoms/OptimizedImage.svelte.d.ts +2 -0
- package/dist/atoms/Progress.svelte +31 -9
- package/dist/atoms/Progress.svelte.d.ts +6 -0
- package/dist/atoms/Radio.svelte +23 -3
- package/dist/atoms/Radio.svelte.d.ts +6 -2
- package/dist/atoms/Rating.svelte +494 -0
- package/dist/atoms/Rating.svelte.d.ts +56 -0
- package/dist/atoms/Select.svelte +475 -135
- package/dist/atoms/Select.svelte.d.ts +52 -2
- package/dist/atoms/SelectionControl.svelte +99 -18
- package/dist/atoms/SelectionControl.svelte.d.ts +6 -3
- package/dist/atoms/Skeleton.svelte +5 -3
- package/dist/atoms/Slider.svelte +309 -0
- package/dist/atoms/Slider.svelte.d.ts +40 -0
- package/dist/atoms/Spinner.svelte +57 -0
- package/dist/atoms/Spinner.svelte.d.ts +19 -0
- package/dist/atoms/Table.svelte +152 -6
- package/dist/atoms/Table.svelte.d.ts +15 -3
- package/dist/atoms/TemporalField.svelte +140 -0
- package/dist/atoms/TemporalField.svelte.d.ts +32 -0
- package/dist/atoms/Text.svelte +56 -15
- package/dist/atoms/Text.svelte.d.ts +13 -4
- package/dist/atoms/Textarea.svelte +57 -45
- package/dist/atoms/Textarea.svelte.d.ts +14 -2
- package/dist/atoms/ThemeToggle.svelte +238 -56
- package/dist/atoms/ThemeToggle.svelte.d.ts +28 -3
- package/dist/atoms/TimeField.svelte +108 -0
- package/dist/atoms/TimeField.svelte.d.ts +54 -0
- package/dist/atoms/Toast.svelte +25 -10
- package/dist/atoms/Toast.svelte.d.ts +2 -0
- package/dist/atoms/Toggle.svelte +60 -19
- package/dist/atoms/Toggle.svelte.d.ts +18 -2
- package/dist/atoms/Tooltip.svelte +583 -40
- package/dist/atoms/Tooltip.svelte.d.ts +26 -0
- package/dist/atoms/ZabiStringsProvider.svelte +45 -0
- package/dist/atoms/ZabiStringsProvider.svelte.d.ts +27 -0
- package/dist/atoms/index.d.ts +17 -0
- package/dist/atoms/index.js +12 -0
- package/dist/atoms/selection-control.styles.d.ts +36 -5
- package/dist/atoms/selection-control.styles.js +40 -9
- package/dist/components/atoms/index.d.ts +17 -0
- package/dist/components/atoms/index.d.ts.map +1 -1
- package/dist/components/atoms/selection-control.styles.d.ts +36 -5
- package/dist/components/atoms/selection-control.styles.d.ts.map +1 -1
- package/dist/components/index.d.ts +83 -3
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/molecules/index.d.ts +46 -0
- package/dist/components/molecules/index.d.ts.map +1 -1
- package/dist/components/molecules/toast-store.d.ts +53 -7
- package/dist/components/molecules/toast-store.d.ts.map +1 -1
- package/dist/components/organisms/index.d.ts +6 -0
- package/dist/components/organisms/index.d.ts.map +1 -1
- package/dist/components/types/variants.d.ts +15 -1
- package/dist/components/types/variants.d.ts.map +1 -1
- package/dist/components/util/app-shell.d.ts +28 -0
- package/dist/components/util/app-shell.d.ts.map +1 -0
- package/dist/components/util/avatar.d.ts +36 -0
- package/dist/components/util/avatar.d.ts.map +1 -0
- package/dist/components/util/bottom-sheet.d.ts +30 -0
- package/dist/components/util/bottom-sheet.d.ts.map +1 -0
- package/dist/components/util/bottom-tab-bar.d.ts +35 -0
- package/dist/components/util/bottom-tab-bar.d.ts.map +1 -0
- package/dist/components/util/calendar.d.ts +56 -0
- package/dist/components/util/calendar.d.ts.map +1 -0
- package/dist/components/util/cn.d.ts +8 -0
- package/dist/components/util/cn.d.ts.map +1 -0
- package/dist/components/util/collapsible.d.ts +58 -0
- package/dist/components/util/collapsible.d.ts.map +1 -0
- package/dist/components/util/confirm-dialog.d.ts +12 -0
- package/dist/components/util/confirm-dialog.d.ts.map +1 -0
- package/dist/components/util/date.d.ts +96 -0
- package/dist/components/util/date.d.ts.map +1 -0
- package/dist/components/util/drawer.d.ts +13 -0
- package/dist/components/util/drawer.d.ts.map +1 -0
- package/dist/components/util/dropdown.d.ts +47 -0
- package/dist/components/util/dropdown.d.ts.map +1 -0
- package/dist/components/util/field.d.ts +39 -0
- package/dist/components/util/field.d.ts.map +1 -0
- package/dist/components/util/fit-in-viewport.d.ts +201 -0
- package/dist/components/util/fit-in-viewport.d.ts.map +1 -0
- package/dist/components/util/focus-utils.d.ts +75 -2
- package/dist/components/util/focus-utils.d.ts.map +1 -1
- package/dist/components/util/hydration.d.ts +45 -0
- package/dist/components/util/hydration.d.ts.map +1 -0
- package/dist/components/util/keyboard-inset.d.ts +18 -0
- package/dist/components/util/keyboard-inset.d.ts.map +1 -0
- package/dist/components/util/media-grid.d.ts +51 -0
- package/dist/components/util/media-grid.d.ts.map +1 -0
- package/dist/components/util/media.d.ts +6 -0
- package/dist/components/util/media.d.ts.map +1 -0
- package/dist/components/util/overlay-chrome.d.ts +53 -0
- package/dist/components/util/overlay-chrome.d.ts.map +1 -0
- package/dist/components/util/overlay.d.ts +72 -0
- package/dist/components/util/overlay.d.ts.map +1 -0
- package/dist/components/util/photo.d.ts +215 -0
- package/dist/components/util/photo.d.ts.map +1 -0
- package/dist/components/util/portal.d.ts +23 -0
- package/dist/components/util/portal.d.ts.map +1 -0
- package/dist/components/util/pull-to-refresh.d.ts +27 -0
- package/dist/components/util/pull-to-refresh.d.ts.map +1 -0
- package/dist/components/util/radio-keys.d.ts +25 -0
- package/dist/components/util/radio-keys.d.ts.map +1 -0
- package/dist/components/util/rating.d.ts +23 -0
- package/dist/components/util/rating.d.ts.map +1 -0
- package/dist/components/util/ready-made-strings.d.ts +77 -0
- package/dist/components/util/ready-made-strings.d.ts.map +1 -0
- package/dist/components/util/scroll-padding.d.ts +20 -0
- package/dist/components/util/scroll-padding.d.ts.map +1 -0
- package/dist/components/util/segmented-control.d.ts +16 -0
- package/dist/components/util/segmented-control.d.ts.map +1 -0
- package/dist/components/util/select.d.ts +41 -0
- package/dist/components/util/select.d.ts.map +1 -0
- package/dist/components/util/sheet-drag.d.ts +60 -0
- package/dist/components/util/sheet-drag.d.ts.map +1 -0
- package/dist/components/util/sidebar.d.ts +63 -0
- package/dist/components/util/sidebar.d.ts.map +1 -0
- package/dist/components/util/sortable-list.d.ts +65 -0
- package/dist/components/util/sortable-list.d.ts.map +1 -0
- package/dist/components/util/ssr-safe.d.ts +4 -4
- package/dist/components/util/ssr-safe.d.ts.map +1 -1
- package/dist/components/util/stepper.d.ts +40 -0
- package/dist/components/util/stepper.d.ts.map +1 -0
- package/dist/components/util/swipeable-list-item.d.ts +36 -0
- package/dist/components/util/swipeable-list-item.d.ts.map +1 -0
- package/dist/components/util/theme-mode.d.ts +80 -0
- package/dist/components/util/theme-mode.d.ts.map +1 -0
- package/dist/components/util/toaster.d.ts +93 -0
- package/dist/components/util/toaster.d.ts.map +1 -0
- package/dist/components/util/tooltip.d.ts +10 -0
- package/dist/components/util/tooltip.d.ts.map +1 -0
- package/dist/components/util/top-navbar.d.ts +11 -0
- package/dist/components/util/top-navbar.d.ts.map +1 -0
- package/dist/components/util/touch-target.d.ts +31 -0
- package/dist/components/util/touch-target.d.ts.map +1 -0
- package/dist/components/util/zabi-strings.d.ts +133 -0
- package/dist/components/util/zabi-strings.d.ts.map +1 -0
- package/dist/create-theme/cli.js +169 -0
- package/dist/create-theme/index.d.ts +176 -0
- package/dist/create-theme/index.js +817 -0
- package/dist/create-theme/lib/ramp-math.js +128 -0
- package/dist/create-theme/lib/resolve.js +141 -0
- package/dist/create-theme/theme-data.js +1116 -0
- package/dist/index.d.ts +83 -3
- package/dist/index.js +60 -8
- package/dist/molecules/Alert.svelte +73 -66
- package/dist/molecules/Alert.svelte.d.ts +9 -1
- package/dist/molecules/AppBar.svelte +415 -0
- package/dist/molecules/AppBar.svelte.d.ts +69 -0
- package/dist/molecules/AvatarGroup.svelte +116 -0
- package/dist/molecules/AvatarGroup.svelte.d.ts +40 -0
- package/dist/molecules/BottomSheet.svelte +540 -0
- package/dist/molecules/BottomSheet.svelte.d.ts +93 -0
- package/dist/molecules/BottomTabBar.svelte +297 -0
- package/dist/molecules/BottomTabBar.svelte.d.ts +64 -0
- package/dist/molecules/Calendar.svelte +597 -0
- package/dist/molecules/Calendar.svelte.d.ts +72 -0
- package/dist/molecules/Collapsible.svelte +243 -0
- package/dist/molecules/Collapsible.svelte.d.ts +44 -0
- package/dist/molecules/CollapsibleGroup.svelte +126 -0
- package/dist/molecules/CollapsibleGroup.svelte.d.ts +14 -0
- package/dist/molecules/ComponentDemo.svelte +25 -5
- package/dist/molecules/ComponentDemo.svelte.d.ts +5 -0
- package/dist/molecules/ConfirmDialog.svelte +253 -0
- package/dist/molecules/ConfirmDialog.svelte.d.ts +55 -0
- package/dist/molecules/ContactForm.svelte +46 -19
- package/dist/molecules/ContactForm.svelte.d.ts +10 -0
- package/dist/molecules/Drawer.svelte +394 -0
- package/dist/molecules/Drawer.svelte.d.ts +55 -0
- package/dist/molecules/Dropdown.svelte +540 -50
- package/dist/molecules/Dropdown.svelte.d.ts +49 -6
- package/dist/molecules/DropdownItem.svelte +122 -0
- package/dist/molecules/DropdownItem.svelte.d.ts +28 -0
- package/dist/molecules/EmptyState.svelte +56 -10
- package/dist/molecules/EmptyState.svelte.d.ts +8 -0
- package/dist/molecules/Form.svelte +25 -14
- package/dist/molecules/Form.svelte.d.ts +13 -5
- package/dist/molecules/FormField.svelte +11 -2
- package/dist/molecules/FormField.svelte.d.ts +2 -0
- package/dist/molecules/Header.svelte +13 -3
- package/dist/molecules/Header.svelte.d.ts +2 -0
- package/dist/molecules/ImageUpload.svelte +422 -70
- package/dist/molecules/ImageUpload.svelte.d.ts +61 -5
- package/dist/molecules/MediaGrid.svelte +527 -0
- package/dist/molecules/MediaGrid.svelte.d.ts +77 -0
- package/dist/molecules/Modal.svelte +340 -45
- package/dist/molecules/Modal.svelte.d.ts +59 -7
- package/dist/molecules/NavigationMenu.svelte +15 -3
- package/dist/molecules/NavigationMenu.svelte.d.ts +4 -0
- package/dist/molecules/NavigationMenuContent.svelte +91 -36
- package/dist/molecules/NavigationMenuContent.svelte.d.ts +2 -0
- package/dist/molecules/NavigationMenuItem.svelte +10 -3
- package/dist/molecules/NavigationMenuItem.svelte.d.ts +2 -0
- package/dist/molecules/NavigationMenuLink.svelte +10 -2
- package/dist/molecules/NavigationMenuLink.svelte.d.ts +2 -0
- package/dist/molecules/NavigationMenuList.svelte +19 -4
- package/dist/molecules/NavigationMenuList.svelte.d.ts +2 -0
- package/dist/molecules/NavigationMenuTrigger.svelte +16 -3
- package/dist/molecules/NavigationMenuTrigger.svelte.d.ts +2 -0
- package/dist/molecules/Page.svelte +38 -2
- package/dist/molecules/Page.svelte.d.ts +13 -0
- package/dist/molecules/PhotoGrid.svelte +433 -0
- package/dist/molecules/PhotoGrid.svelte.d.ts +62 -0
- package/dist/molecules/PhotoViewer.svelte +1116 -0
- package/dist/molecules/PhotoViewer.svelte.d.ts +56 -0
- package/dist/molecules/PropsTable.svelte +26 -11
- package/dist/molecules/PropsTable.svelte.d.ts +5 -0
- package/dist/molecules/PullToRefresh.svelte +263 -0
- package/dist/molecules/PullToRefresh.svelte.d.ts +52 -0
- package/dist/molecules/RadioGroup.svelte +57 -15
- package/dist/molecules/RadioGroup.svelte.d.ts +16 -3
- package/dist/molecules/Section.svelte +13 -5
- package/dist/molecules/Section.svelte.d.ts +3 -1
- package/dist/molecules/SegmentedControl.svelte +323 -0
- package/dist/molecules/SegmentedControl.svelte.d.ts +34 -0
- package/dist/molecules/SidebarBrandHeader.svelte +24 -5
- package/dist/molecules/SidebarBrandHeader.svelte.d.ts +5 -0
- package/dist/molecules/SidebarFooter.svelte +39 -8
- package/dist/molecules/SidebarFooter.svelte.d.ts +5 -0
- package/dist/molecules/SidebarNavSection.svelte +12 -4
- package/dist/molecules/SidebarNavSection.svelte.d.ts +2 -0
- package/dist/molecules/SlideUp.svelte +253 -30
- package/dist/molecules/SlideUp.svelte.d.ts +31 -4
- package/dist/molecules/SortableList.svelte +632 -0
- package/dist/molecules/SortableList.svelte.d.ts +69 -0
- package/dist/molecules/Stepper.svelte +548 -0
- package/dist/molecules/Stepper.svelte.d.ts +39 -0
- package/dist/molecules/StickyActionBar.svelte +191 -0
- package/dist/molecules/StickyActionBar.svelte.d.ts +65 -0
- package/dist/molecules/SwipeableListItem.svelte +334 -0
- package/dist/molecules/SwipeableListItem.svelte.d.ts +54 -0
- package/dist/molecules/Tabs.svelte +254 -24
- package/dist/molecules/Tabs.svelte.d.ts +15 -4
- package/dist/molecules/Toaster.svelte +352 -6
- package/dist/molecules/Toaster.svelte.d.ts +95 -2
- package/dist/molecules/ToasterToast.svelte +279 -62
- package/dist/molecules/ToasterToast.svelte.d.ts +11 -0
- package/dist/molecules/UnsavedChangesBar.svelte +212 -0
- package/dist/molecules/UnsavedChangesBar.svelte.d.ts +43 -0
- package/dist/molecules/index.d.ts +46 -0
- package/dist/molecules/index.js +27 -0
- package/dist/molecules/toast-store.d.ts +53 -7
- package/dist/molecules/toast-store.js +21 -0
- package/dist/organisms/AppShell.svelte +196 -0
- package/dist/organisms/AppShell.svelte.d.ts +61 -0
- package/dist/organisms/SidebarAccountPanel.svelte +111 -12
- package/dist/organisms/SidebarAccountPanel.svelte.d.ts +21 -0
- package/dist/organisms/SidebarNavigation.svelte +193 -69
- package/dist/organisms/SidebarNavigation.svelte.d.ts +31 -1
- package/dist/organisms/SidebarPanel.svelte +45 -16
- package/dist/organisms/SidebarPanel.svelte.d.ts +2 -0
- package/dist/organisms/SidebarShell.svelte +263 -0
- package/dist/organisms/SidebarShell.svelte.d.ts +106 -0
- package/dist/organisms/TopNavbar.svelte +329 -33
- package/dist/organisms/TopNavbar.svelte.d.ts +28 -0
- package/dist/organisms/index.d.ts +6 -0
- package/dist/organisms/index.js +4 -0
- package/dist/routes/lib/variant-utils.d.ts +26 -0
- package/dist/routes/lib/{variant-utils.ts → variant-utils.js} +15 -46
- package/dist/types/components.d.ts +4 -0
- package/dist/types/components.d.ts.map +1 -1
- package/dist/types/events.js +1 -0
- package/dist/types/index.d.ts +605 -25
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +3 -0
- package/dist/types/variants.ts +17 -1
- package/dist/util/app-shell.d.ts +27 -0
- package/dist/util/app-shell.js +72 -0
- package/dist/util/avatar.d.ts +35 -0
- package/dist/util/avatar.js +52 -0
- package/dist/util/bottom-sheet.d.ts +29 -0
- package/dist/util/bottom-sheet.js +43 -0
- package/dist/util/bottom-tab-bar.d.ts +34 -0
- package/dist/util/bottom-tab-bar.js +54 -0
- package/dist/util/calendar.d.ts +55 -0
- package/dist/util/calendar.js +74 -0
- package/dist/util/cn.d.ts +7 -0
- package/dist/util/cn.js +48 -0
- package/dist/util/collapsible.d.ts +57 -0
- package/dist/util/collapsible.js +23 -0
- package/dist/util/confirm-dialog.d.ts +11 -0
- package/dist/util/confirm-dialog.js +2 -0
- package/dist/util/date.d.ts +95 -0
- package/dist/util/date.js +237 -0
- package/dist/util/drawer.d.ts +12 -0
- package/dist/util/drawer.js +7 -0
- package/dist/util/dropdown.d.ts +46 -0
- package/dist/util/dropdown.js +21 -0
- package/dist/util/field.d.ts +38 -0
- package/dist/util/field.js +38 -0
- package/dist/util/fit-in-viewport.d.ts +200 -0
- package/dist/util/fit-in-viewport.js +399 -0
- package/dist/util/focus-utils.d.ts +75 -2
- package/dist/util/focus-utils.js +182 -9
- package/dist/util/hydration.d.ts +44 -0
- package/dist/util/hydration.js +58 -0
- package/dist/util/keyboard-inset.d.ts +17 -0
- package/dist/util/keyboard-inset.js +53 -0
- package/dist/util/media-grid.d.ts +50 -0
- package/dist/util/media-grid.js +81 -0
- package/dist/util/media.d.ts +5 -0
- package/dist/util/media.js +10 -0
- package/dist/util/overlay-chrome.d.ts +52 -0
- package/dist/util/overlay-chrome.js +56 -0
- package/dist/util/overlay.d.ts +71 -0
- package/dist/util/overlay.js +240 -0
- package/dist/util/photo.d.ts +214 -0
- package/dist/util/photo.js +206 -0
- package/dist/util/portal.d.ts +22 -0
- package/dist/util/portal.js +50 -0
- package/dist/util/pull-to-refresh.d.ts +26 -0
- package/dist/util/pull-to-refresh.js +30 -0
- package/dist/util/radio-keys.d.ts +24 -0
- package/dist/util/radio-keys.js +49 -0
- package/dist/util/rating.d.ts +22 -0
- package/dist/util/rating.js +26 -0
- package/dist/util/ready-made-strings.d.ts +76 -0
- package/dist/util/ready-made-strings.js +67 -0
- package/dist/util/scroll-padding.d.ts +19 -0
- package/dist/util/scroll-padding.js +44 -0
- package/dist/util/segmented-control.d.ts +15 -0
- package/dist/util/segmented-control.js +1 -0
- package/dist/util/select.d.ts +40 -0
- package/dist/util/select.js +63 -0
- package/dist/util/sheet-drag.d.ts +59 -0
- package/dist/util/sheet-drag.js +241 -0
- package/dist/util/sidebar.d.ts +62 -0
- package/dist/util/sidebar.js +38 -0
- package/dist/util/sortable-list.d.ts +64 -0
- package/dist/util/sortable-list.js +53 -0
- package/dist/util/ssr-safe.d.ts +4 -4
- package/dist/util/stepper.d.ts +39 -0
- package/dist/util/stepper.js +38 -0
- package/dist/util/swipeable-list-item.d.ts +35 -0
- package/dist/util/swipeable-list-item.js +32 -0
- package/dist/util/theme-mode.d.ts +79 -0
- package/dist/util/theme-mode.js +121 -0
- package/dist/util/toaster.d.ts +92 -0
- package/dist/util/toaster.js +75 -0
- package/dist/util/tooltip.d.ts +9 -0
- package/dist/util/tooltip.js +18 -0
- package/dist/util/top-navbar.d.ts +10 -0
- package/dist/util/top-navbar.js +5 -0
- package/dist/util/touch-target.d.ts +30 -0
- package/dist/util/touch-target.js +30 -0
- package/dist/util/zabi-strings.d.ts +132 -0
- package/dist/util/zabi-strings.js +105 -0
- package/dist/zabi-components-colors.css +5 -2
- package/dist/zabi-components-theme-dark-only.css +574 -225
- package/dist/zabi-components-theme-dark.css +574 -225
- package/dist/zabi-components-theme-only.css +1680 -317
- package/dist/zabi-components-theme.css +1680 -317
- package/dist/zabi-components.css +4473 -1158
- package/docs/lucide-icons.md +41 -16
- package/docs/theme-imports.md +81 -11
- package/package.json +51 -29
- package/dist/lib/layout-width-tokens.d.ts +0 -17
- package/dist/lib/layout-width-tokens.d.ts.map +0 -1
- package/dist/lib/showcase/component-docs/Button.d.ts +0 -3
- package/dist/lib/showcase/component-docs/Button.d.ts.map +0 -1
- package/dist/lib/showcase/component-docs/Input.d.ts +0 -3
- package/dist/lib/showcase/component-docs/Input.d.ts.map +0 -1
- package/dist/lib/showcase/component-docs/List.d.ts +0 -3
- package/dist/lib/showcase/component-docs/List.d.ts.map +0 -1
- package/dist/lib/showcase/component-docs/Modal.d.ts +0 -3
- package/dist/lib/showcase/component-docs/Modal.d.ts.map +0 -1
- package/dist/lib/showcase/component-docs/Radio.d.ts +0 -3
- package/dist/lib/showcase/component-docs/Radio.d.ts.map +0 -1
- package/dist/lib/showcase/component-docs/SidebarNavigation.d.ts +0 -3
- package/dist/lib/showcase/component-docs/SidebarNavigation.d.ts.map +0 -1
- package/dist/lib/showcase/component-docs/Skeleton.d.ts +0 -3
- package/dist/lib/showcase/component-docs/Skeleton.d.ts.map +0 -1
- package/dist/lib/showcase/component-docs/_shared.d.ts +0 -12
- package/dist/lib/showcase/component-docs/_shared.d.ts.map +0 -1
- package/dist/lib/showcase/component-docs/index.d.ts +0 -4
- package/dist/lib/showcase/component-docs/index.d.ts.map +0 -1
- package/dist/lib/showcase/components-catalog.d.ts +0 -3
- package/dist/lib/showcase/components-catalog.d.ts.map +0 -1
- package/dist/lib/showcase/components-showcase-constants.d.ts +0 -89
- package/dist/lib/showcase/components-showcase-constants.d.ts.map +0 -1
- package/dist/lib/showcase/docs-sidebar-helpers.d.ts +0 -15
- package/dist/lib/showcase/docs-sidebar-helpers.d.ts.map +0 -1
- package/dist/routes/lib/focus-utils.d.ts +0 -12
- package/dist/routes/lib/focus-utils.ts +0 -110
- package/dist/routes/lib/ssr-safe.ts +0 -58
- package/scripts/fix-lucide-svelte-icon-dts.js +0 -35
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { mergeStrings } from "../util/ready-made-strings.js";
|
|
3
|
+
import { zabiStringsFor } from "../util/zabi-strings.js";
|
|
2
4
|
import SidebarPanel, {
|
|
3
5
|
type SidebarPanelItem,
|
|
4
6
|
} from "./SidebarPanel.svelte";
|
|
5
7
|
import { generateId } from "../util/ssr-safe.js";
|
|
6
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
DEFAULT_SIDEBAR_ACCOUNT_PANEL_STRINGS,
|
|
10
|
+
type SidebarAccountPanelStrings,
|
|
11
|
+
} from "../util/sidebar.js";
|
|
12
|
+
import {
|
|
13
|
+
getThemeMode,
|
|
14
|
+
isThemeDark,
|
|
15
|
+
setThemeMode,
|
|
16
|
+
THEME_MODES,
|
|
17
|
+
type ThemeMode,
|
|
18
|
+
} from "../util/theme-mode.js";
|
|
19
|
+
import LogOut from "@lucide/svelte/icons/log-out";
|
|
20
|
+
import Monitor from "@lucide/svelte/icons/monitor";
|
|
21
|
+
import Moon from "@lucide/svelte/icons/moon";
|
|
22
|
+
import Sun from "@lucide/svelte/icons/sun";
|
|
23
|
+
import User from "@lucide/svelte/icons/user";
|
|
7
24
|
|
|
8
25
|
interface Props {
|
|
26
|
+
/** Extra classes for the host element. */
|
|
27
|
+
class?: string;
|
|
9
28
|
/** Target id for `aria-controls` from the sidebar footer/nav. */
|
|
10
29
|
panelId?: string;
|
|
11
30
|
style?: string;
|
|
@@ -16,6 +35,23 @@
|
|
|
16
35
|
showLogout?: boolean;
|
|
17
36
|
isLightMode?: boolean;
|
|
18
37
|
onThemeToggle?: (nextIsLightMode: boolean) => void;
|
|
38
|
+
/**
|
|
39
|
+
* `"two"` (the default): the theme row flips `isLightMode` and calls
|
|
40
|
+
* `onThemeToggle`; the app switches the page. `"three"`: the row
|
|
41
|
+
* steps through system, light and dark, switches the page itself
|
|
42
|
+
* (`data-theme` on `<html>`, as ThemeToggle does) and calls
|
|
43
|
+
* `onThemeModeChange`.
|
|
44
|
+
*/
|
|
45
|
+
themeModes?: "two" | "three";
|
|
46
|
+
/** With `themeModes="three"`: called with the mode the row has switched to. */
|
|
47
|
+
onThemeModeChange?: (mode: ThemeMode) => void;
|
|
48
|
+
/**
|
|
49
|
+
* With `themeModes="three"`: the `localStorage` key the choice is kept
|
|
50
|
+
* under. Default `"theme"`, as ThemeToggle; `null` keeps nothing.
|
|
51
|
+
*/
|
|
52
|
+
themeStorageKey?: string | null;
|
|
53
|
+
/** Every word the panel says by itself, for another language. `logoutLabel` is its own prop. */
|
|
54
|
+
strings?: Partial<SidebarAccountPanelStrings>;
|
|
19
55
|
onLogout?: () => void;
|
|
20
56
|
onAccount?: () => void;
|
|
21
57
|
onClose?: () => void;
|
|
@@ -24,6 +60,7 @@
|
|
|
24
60
|
}
|
|
25
61
|
|
|
26
62
|
let {
|
|
63
|
+
class: className = "",
|
|
27
64
|
panelId = generateId("account-panel"),
|
|
28
65
|
style = "",
|
|
29
66
|
profileName = "Account",
|
|
@@ -31,8 +68,12 @@
|
|
|
31
68
|
logoutLabel = "Log out",
|
|
32
69
|
showThemeToggle = true,
|
|
33
70
|
showLogout = true,
|
|
34
|
-
isLightMode = $bindable(
|
|
71
|
+
isLightMode = $bindable<Exclude<Props["isLightMode"], undefined>>(),
|
|
35
72
|
onThemeToggle,
|
|
73
|
+
themeModes = "two",
|
|
74
|
+
onThemeModeChange,
|
|
75
|
+
themeStorageKey,
|
|
76
|
+
strings,
|
|
36
77
|
onLogout,
|
|
37
78
|
onAccount,
|
|
38
79
|
onClose,
|
|
@@ -41,24 +82,70 @@
|
|
|
41
82
|
...restProps
|
|
42
83
|
}: Props = $props();
|
|
43
84
|
|
|
85
|
+
// No fallback on a bindable prop: Svelte refuses `bind:…={undefined}` on
|
|
86
|
+
// one that has a fallback (`props_invalid_value`), and a page that throws
|
|
87
|
+
// while it hydrates never becomes interactive. The default is applied
|
|
88
|
+
// here instead: at once, for the server and the first render, and again
|
|
89
|
+
// whenever a parent hands back `undefined`.
|
|
90
|
+
const applyDefaults = () => {
|
|
91
|
+
if (isLightMode === undefined) isLightMode = false;
|
|
92
|
+
};
|
|
93
|
+
applyDefaults();
|
|
94
|
+
$effect.pre(applyDefaults);
|
|
95
|
+
|
|
44
96
|
let selectedItemId = $state("");
|
|
45
97
|
|
|
98
|
+
/** The app-wide words for this component, from a `ZabiStringsProvider` above it, if there is one. */
|
|
99
|
+
const provided = zabiStringsFor("sidebarAccountPanel");
|
|
100
|
+
const text = $derived(mergeStrings(DEFAULT_SIDEBAR_ACCOUNT_PANEL_STRINGS, provided(), strings));
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* With three modes: the page's mode, read when the panel mounts, after
|
|
104
|
+
* each step, and when something else switches the page (a ThemeToggle in
|
|
105
|
+
* the bar, the app's own script) while the panel is there.
|
|
106
|
+
*/
|
|
107
|
+
let themeMode = $state<ThemeMode>("light");
|
|
108
|
+
$effect(() => {
|
|
109
|
+
if (themeModes !== "three") return;
|
|
110
|
+
themeMode = getThemeMode();
|
|
111
|
+
if (typeof MutationObserver === "undefined") return;
|
|
112
|
+
const observer = new MutationObserver(() => {
|
|
113
|
+
themeMode = getThemeMode();
|
|
114
|
+
});
|
|
115
|
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class", "data-theme"] });
|
|
116
|
+
return () => observer.disconnect();
|
|
117
|
+
});
|
|
118
|
+
|
|
46
119
|
const items = $derived.by((): SidebarPanelItem[] => {
|
|
47
120
|
const list: SidebarPanelItem[] = [
|
|
48
121
|
{
|
|
49
122
|
id: "account",
|
|
50
|
-
label:
|
|
123
|
+
label: text.account,
|
|
51
124
|
description: profileName,
|
|
52
125
|
icon: User,
|
|
53
126
|
},
|
|
54
127
|
];
|
|
55
128
|
|
|
56
|
-
if (showThemeToggle) {
|
|
129
|
+
if (showThemeToggle && themeModes === "three") {
|
|
57
130
|
list.push({
|
|
58
131
|
id: "theme",
|
|
59
|
-
label:
|
|
60
|
-
description:
|
|
61
|
-
|
|
132
|
+
label: text.theme,
|
|
133
|
+
description:
|
|
134
|
+
themeMode === "auto"
|
|
135
|
+
? text.systemMode
|
|
136
|
+
: themeMode === "light"
|
|
137
|
+
? text.lightMode
|
|
138
|
+
: text.darkMode,
|
|
139
|
+
badgeText:
|
|
140
|
+
themeMode === "auto" ? text.system : themeMode === "light" ? text.light : text.dark,
|
|
141
|
+
icon: themeMode === "auto" ? Monitor : themeMode === "light" ? Sun : Moon,
|
|
142
|
+
});
|
|
143
|
+
} else if (showThemeToggle) {
|
|
144
|
+
list.push({
|
|
145
|
+
id: "theme",
|
|
146
|
+
label: text.theme,
|
|
147
|
+
description: isLightMode ? text.lightMode : text.darkMode,
|
|
148
|
+
badgeText: isLightMode ? text.light : text.dark,
|
|
62
149
|
icon: isLightMode ? Sun : Moon,
|
|
63
150
|
});
|
|
64
151
|
}
|
|
@@ -67,7 +154,7 @@
|
|
|
67
154
|
list.push({
|
|
68
155
|
id: "logout",
|
|
69
156
|
label: logoutLabel,
|
|
70
|
-
description:
|
|
157
|
+
description: text.signOut,
|
|
71
158
|
icon: LogOut,
|
|
72
159
|
});
|
|
73
160
|
}
|
|
@@ -76,6 +163,16 @@
|
|
|
76
163
|
});
|
|
77
164
|
|
|
78
165
|
function toggleTheme(): void {
|
|
166
|
+
if (themeModes === "three") {
|
|
167
|
+
// From where the page is now, which another control may have changed.
|
|
168
|
+
const current = getThemeMode();
|
|
169
|
+
const next = THEME_MODES[(THEME_MODES.indexOf(current) + 1) % THEME_MODES.length];
|
|
170
|
+
setThemeMode(next, themeStorageKey === undefined ? {} : { storageKey: themeStorageKey });
|
|
171
|
+
themeMode = next;
|
|
172
|
+
isLightMode = !isThemeDark();
|
|
173
|
+
onThemeModeChange?.(next);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
79
176
|
isLightMode = !isLightMode;
|
|
80
177
|
onThemeToggle?.(isLightMode);
|
|
81
178
|
}
|
|
@@ -96,16 +193,18 @@
|
|
|
96
193
|
<div
|
|
97
194
|
id={panelId}
|
|
98
195
|
{style}
|
|
196
|
+
class={className}
|
|
99
197
|
role="dialog"
|
|
100
198
|
aria-modal="false"
|
|
101
|
-
aria-label=
|
|
199
|
+
aria-label={text.panelLabel}
|
|
102
200
|
{...restProps}
|
|
103
201
|
>
|
|
104
202
|
<SidebarPanel
|
|
105
|
-
title=
|
|
203
|
+
title={text.title}
|
|
106
204
|
subtitle={profileEmail}
|
|
107
|
-
ariaLabel=
|
|
108
|
-
closeLabel=
|
|
205
|
+
ariaLabel={text.panelLabel}
|
|
206
|
+
closeLabel={text.closeLabel}
|
|
207
|
+
selectLabel={text.listLabel}
|
|
109
208
|
{widthClass}
|
|
110
209
|
{variant}
|
|
111
210
|
showSearch={false}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { type SidebarAccountPanelStrings } from "../util/sidebar.js";
|
|
2
|
+
import { type ThemeMode } from "../util/theme-mode.js";
|
|
1
3
|
interface Props {
|
|
4
|
+
/** Extra classes for the host element. */
|
|
5
|
+
class?: string;
|
|
2
6
|
/** Target id for `aria-controls` from the sidebar footer/nav. */
|
|
3
7
|
panelId?: string;
|
|
4
8
|
style?: string;
|
|
@@ -9,6 +13,23 @@ interface Props {
|
|
|
9
13
|
showLogout?: boolean;
|
|
10
14
|
isLightMode?: boolean;
|
|
11
15
|
onThemeToggle?: (nextIsLightMode: boolean) => void;
|
|
16
|
+
/**
|
|
17
|
+
* `"two"` (the default): the theme row flips `isLightMode` and calls
|
|
18
|
+
* `onThemeToggle`; the app switches the page. `"three"`: the row
|
|
19
|
+
* steps through system, light and dark, switches the page itself
|
|
20
|
+
* (`data-theme` on `<html>`, as ThemeToggle does) and calls
|
|
21
|
+
* `onThemeModeChange`.
|
|
22
|
+
*/
|
|
23
|
+
themeModes?: "two" | "three";
|
|
24
|
+
/** With `themeModes="three"`: called with the mode the row has switched to. */
|
|
25
|
+
onThemeModeChange?: (mode: ThemeMode) => void;
|
|
26
|
+
/**
|
|
27
|
+
* With `themeModes="three"`: the `localStorage` key the choice is kept
|
|
28
|
+
* under. Default `"theme"`, as ThemeToggle; `null` keeps nothing.
|
|
29
|
+
*/
|
|
30
|
+
themeStorageKey?: string | null;
|
|
31
|
+
/** Every word the panel says by itself, for another language. `logoutLabel` is its own prop. */
|
|
32
|
+
strings?: Partial<SidebarAccountPanelStrings>;
|
|
12
33
|
onLogout?: () => void;
|
|
13
34
|
onAccount?: () => void;
|
|
14
35
|
onClose?: () => void;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { mergeStrings } from "../util/ready-made-strings.js";
|
|
3
|
+
import { zabiStringsFor, zabiCommonStrings } from "../util/zabi-strings.js";
|
|
2
4
|
import Badge from "../atoms/Badge.svelte";
|
|
3
5
|
import Button from "../atoms/Button.svelte";
|
|
4
6
|
import IconButton from "../atoms/IconButton.svelte";
|
|
@@ -6,10 +8,21 @@
|
|
|
6
8
|
import SidebarBrandHeader from "../molecules/SidebarBrandHeader.svelte";
|
|
7
9
|
import SidebarFooter from "../molecules/SidebarFooter.svelte";
|
|
8
10
|
import SidebarNavSection from "../molecules/SidebarNavSection.svelte";
|
|
9
|
-
import
|
|
11
|
+
import Tooltip from "../atoms/Tooltip.svelte";
|
|
12
|
+
import SidebarShell from "./SidebarShell.svelte";
|
|
13
|
+
import type {
|
|
14
|
+
SidebarDrawerCloseReason,
|
|
15
|
+
SidebarTriggerContext,
|
|
16
|
+
} from "./SidebarShell.svelte";
|
|
17
|
+
import Command from "@lucide/svelte/icons/command";
|
|
18
|
+
import Search from "@lucide/svelte/icons/search";
|
|
10
19
|
import type { Snippet } from "svelte";
|
|
11
20
|
import type { Component } from "svelte";
|
|
12
21
|
import type { ButtonVariant, SizeVariant } from "../types/variants.js";
|
|
22
|
+
import {
|
|
23
|
+
DEFAULT_SIDEBAR_NAVIGATION_STRINGS,
|
|
24
|
+
type SidebarNavigationStrings,
|
|
25
|
+
} from "../util/sidebar.js";
|
|
13
26
|
|
|
14
27
|
export interface SidebarNavigationItem {
|
|
15
28
|
id: string;
|
|
@@ -34,6 +47,14 @@
|
|
|
34
47
|
items?: SidebarNavigationItem[];
|
|
35
48
|
currentPath?: string;
|
|
36
49
|
ariaLabel?: string;
|
|
50
|
+
/**
|
|
51
|
+
* The words the sidebar says by itself, for another language: the
|
|
52
|
+
* names of its lists, the two lines shown when a search finds
|
|
53
|
+
* nothing, and those of the footer and the brand header in it.
|
|
54
|
+
*/
|
|
55
|
+
strings?: Partial<SidebarNavigationStrings>;
|
|
56
|
+
class?: string;
|
|
57
|
+
/** @deprecated use `class`. */
|
|
37
58
|
className?: string;
|
|
38
59
|
logoSrc?: string;
|
|
39
60
|
logoAlt?: string;
|
|
@@ -69,6 +90,24 @@
|
|
|
69
90
|
profilePanel?: Snippet;
|
|
70
91
|
/** Parent nav href to highlight when `currentPath` is a deeper leaf (e.g. category row). */
|
|
71
92
|
activePrimaryHref?: string;
|
|
93
|
+
/**
|
|
94
|
+
* What the sidebar is below the `lg` breakpoint. `drawer`: the rail is
|
|
95
|
+
* hidden there and the sidebar opens in a Drawer from the start edge.
|
|
96
|
+
* This and the six props after it are SidebarShell's; see there.
|
|
97
|
+
*/
|
|
98
|
+
mobile?: "none" | "drawer";
|
|
99
|
+
/** Whether the drawer is open. Bindable. */
|
|
100
|
+
isOpen?: boolean;
|
|
101
|
+
/** The button that opens the drawer, rendered in the rail's place below `lg`. */
|
|
102
|
+
trigger?: Snippet<[SidebarTriggerContext]>;
|
|
103
|
+
/** Heading of the drawer. Without it, `ariaLabel` is. */
|
|
104
|
+
drawerTitle?: string;
|
|
105
|
+
/** Accessible name of the drawer's close button. */
|
|
106
|
+
closeLabel?: string;
|
|
107
|
+
/** Fired when the drawer closes itself, with why. */
|
|
108
|
+
onclose?: (detail: { reason: SidebarDrawerCloseReason }) => void;
|
|
109
|
+
/** Accessible name of the scrolling region between header and footer. */
|
|
110
|
+
label?: string;
|
|
72
111
|
}
|
|
73
112
|
|
|
74
113
|
let {
|
|
@@ -78,7 +117,9 @@
|
|
|
78
117
|
currentPath = "",
|
|
79
118
|
activePrimaryHref = "",
|
|
80
119
|
ariaLabel = "Sidebar navigation",
|
|
81
|
-
|
|
120
|
+
strings,
|
|
121
|
+
class: classAttr = "",
|
|
122
|
+
className: legacyClass = "",
|
|
82
123
|
logoSrc = "",
|
|
83
124
|
logoAlt = "",
|
|
84
125
|
brandName = "",
|
|
@@ -88,8 +129,8 @@
|
|
|
88
129
|
profileInitials = "ZA",
|
|
89
130
|
showSearch = true,
|
|
90
131
|
searchMode = "input",
|
|
91
|
-
searchPlaceholder
|
|
92
|
-
searchValue = $bindable
|
|
132
|
+
searchPlaceholder: searchPlaceholderGiven,
|
|
133
|
+
searchValue = $bindable<Exclude<Props["searchValue"], undefined>>(),
|
|
93
134
|
searchTriggerIcon = Command,
|
|
94
135
|
searchTriggerVariant = "outline",
|
|
95
136
|
searchTriggerSize = "sm",
|
|
@@ -97,7 +138,7 @@
|
|
|
97
138
|
logoutLabel = "Logout",
|
|
98
139
|
showThemeToggle = true,
|
|
99
140
|
lightModeLabel = "Light mode",
|
|
100
|
-
isLightMode = $bindable(
|
|
141
|
+
isLightMode = $bindable<Exclude<Props["isLightMode"], undefined>>(),
|
|
101
142
|
emptyStateTitle = "Create your first navigation item",
|
|
102
143
|
emptyStateDescription = "Add your first sidebar item so users can start navigating your product.",
|
|
103
144
|
emptyStateActionLabel = "Add navigation item",
|
|
@@ -110,11 +151,43 @@
|
|
|
110
151
|
profilePanelOpen = false,
|
|
111
152
|
profilePanelControlsId = "",
|
|
112
153
|
profilePanel,
|
|
154
|
+
mobile = "none",
|
|
155
|
+
isOpen = $bindable<Exclude<Props["isOpen"], undefined>>(),
|
|
156
|
+
trigger,
|
|
157
|
+
drawerTitle,
|
|
158
|
+
closeLabel,
|
|
159
|
+
onclose,
|
|
160
|
+
label,
|
|
113
161
|
...restProps
|
|
114
162
|
}: Props = $props();
|
|
115
163
|
|
|
164
|
+
// No fallback on a bindable prop: Svelte refuses `bind:…={undefined}` on
|
|
165
|
+
// one that has a fallback (`props_invalid_value`), and a page that throws
|
|
166
|
+
// while it hydrates never becomes interactive. The default is applied
|
|
167
|
+
// here instead: at once, for the server and the first render, and again
|
|
168
|
+
// whenever a parent hands back `undefined`.
|
|
169
|
+
const applyDefaults = () => {
|
|
170
|
+
if (searchValue === undefined) searchValue = "";
|
|
171
|
+
if (isLightMode === undefined) isLightMode = false;
|
|
172
|
+
if (isOpen === undefined) isOpen = false;
|
|
173
|
+
};
|
|
174
|
+
applyDefaults();
|
|
175
|
+
$effect.pre(applyDefaults);
|
|
176
|
+
|
|
177
|
+
/** Words many components share: a `ZabiStringsProvider` above this one may give them; else English. */
|
|
178
|
+
const common = zabiCommonStrings();
|
|
179
|
+
const searchPlaceholder = $derived(searchPlaceholderGiven ?? common().search);
|
|
180
|
+
|
|
181
|
+
/** `class` is the public prop; `className` is a deprecated alias.
|
|
182
|
+
* Both are merged here so existing call sites keep working. */
|
|
183
|
+
|
|
184
|
+
/** The app-wide words for this component, from a `ZabiStringsProvider` above it, if there is one. */
|
|
185
|
+
const provided = zabiStringsFor("sidebarNavigation");
|
|
186
|
+
const text = $derived(mergeStrings(DEFAULT_SIDEBAR_NAVIGATION_STRINGS, provided(), strings));
|
|
187
|
+
/** For the brand header and the footer: the provider's words for this sidebar, then the instance's. */
|
|
188
|
+
const handedOn = $derived(mergeStrings<Partial<SidebarNavigationStrings>>({}, provided(), strings));
|
|
189
|
+
|
|
116
190
|
const isCollapsed = $derived(mode === "collapsed");
|
|
117
|
-
const isCard = $derived(layout === "card");
|
|
118
191
|
const showBrandRow = $derived(
|
|
119
192
|
Boolean(logoSrc.trim() || brandName.trim()),
|
|
120
193
|
);
|
|
@@ -178,24 +251,6 @@
|
|
|
178
251
|
partitionBySection(filteredPrimaryItems),
|
|
179
252
|
);
|
|
180
253
|
|
|
181
|
-
const insetX = $derived(isCollapsed ? "px-2.5" : "px-4");
|
|
182
|
-
|
|
183
|
-
const containerClasses = $derived.by(() => {
|
|
184
|
-
const widthClass = isCollapsed ? "w-[104px]" : "w-[266px]";
|
|
185
|
-
const railSurface = "border-r border-border bg-background text-headline";
|
|
186
|
-
const cardSurface =
|
|
187
|
-
"border-r border-border bg-background text-headline shadow-sm";
|
|
188
|
-
const surfaceClasses = isCard ? cardSurface : railSurface;
|
|
189
|
-
const verticalPad = isCard ? "py-4" : "py-5";
|
|
190
|
-
const baseClasses = `flex h-full min-h-0 max-h-full flex-col overflow-visible ${verticalPad}`;
|
|
191
|
-
|
|
192
|
-
return `${baseClasses} ${widthClass} ${surfaceClasses} ${className}`.trim();
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
const headerStackClasses = $derived(
|
|
196
|
-
`flex w-full shrink-0 flex-col gap-5 ${insetX}`,
|
|
197
|
-
);
|
|
198
|
-
|
|
199
254
|
const iconContainerClasses = $derived(
|
|
200
255
|
"flex size-6 shrink-0 items-center justify-center leading-none text-current",
|
|
201
256
|
);
|
|
@@ -210,21 +265,49 @@
|
|
|
210
265
|
return isMuted ? "text-description" : "text-headline";
|
|
211
266
|
}
|
|
212
267
|
|
|
213
|
-
|
|
214
|
-
|
|
268
|
+
/**
|
|
269
|
+
* The selected row used to be carried by its fill alone, and the fill was
|
|
270
|
+
* 1.05:1 against the sidebar in light mode — not a fill, a rumour. Active
|
|
271
|
+
* and idle labels were #18181b and #27272a at the same weight, a 15-unit
|
|
272
|
+
* difference in one channel that nobody can see. So in light mode there
|
|
273
|
+
* was effectively no indication of where you were.
|
|
274
|
+
*
|
|
275
|
+
* Three cues now, only one of which is colour-discrimination dependent:
|
|
276
|
+
* the label takes --color-nav-menu-item-active (defined all along and
|
|
277
|
+
* never referenced — the row said `text-inherit`), a 3px bar marks the
|
|
278
|
+
* leading edge, and the tint stays as reinforcement rather than as the
|
|
279
|
+
* whole message.
|
|
280
|
+
*/
|
|
281
|
+
function isItemActive(item: SidebarNavigationItem): boolean {
|
|
282
|
+
return (
|
|
215
283
|
currentPath === item.href ||
|
|
216
|
-
(Boolean(activePrimaryHref) && item.href === activePrimaryHref)
|
|
284
|
+
(Boolean(activePrimaryHref) && item.href === activePrimaryHref)
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function getNavItemClasses(item: SidebarNavigationItem): string {
|
|
289
|
+
const isActive = isItemActive(item);
|
|
217
290
|
const layoutClasses = isCollapsed
|
|
218
|
-
? "flex min-h-10 items-center justify-center px-0 py-2"
|
|
219
|
-
: "flex min-h-10 items-center gap-
|
|
291
|
+
? "flex min-h-10 pointer-coarse:min-h-11 items-center justify-center px-0 py-2"
|
|
292
|
+
: "flex min-h-10 pointer-coarse:min-h-11 items-center gap-3 px-2 py-2";
|
|
220
293
|
const structural =
|
|
221
|
-
"focus-ring focus-ring--nav w-full cursor-pointer rounded-
|
|
294
|
+
"focus-ring focus-ring--nav relative w-full cursor-pointer rounded-control no-underline transition-colors duration-150 outline-none";
|
|
222
295
|
|
|
223
296
|
if (isActive) {
|
|
224
|
-
|
|
297
|
+
// In forced colours all three cues are gone: fills (the tint and
|
|
298
|
+
// the bar) become the canvas and every link takes the system's
|
|
299
|
+
// link colour. An outline is a shape and is drawn there, so the
|
|
300
|
+
// current row keeps one. Inset, so a focused row's ring (2px
|
|
301
|
+
// outside) reads as a different thing.
|
|
302
|
+
return (
|
|
303
|
+
`${structural} ${layoutClasses} bg-nav-menu-active ` +
|
|
304
|
+
"text-nav-menu-item-active hover:bg-nav-menu-active " +
|
|
305
|
+
"active:bg-nav-menu-active-hover " +
|
|
306
|
+
"forced-colors:outline-solid forced-colors:outline-2 forced-colors:-outline-offset-2"
|
|
307
|
+
);
|
|
225
308
|
}
|
|
226
309
|
|
|
227
|
-
return `${structural} ${layoutClasses} text-nav-menu-item hover:bg-nav-menu-hover hover:text-nav-menu-item-hover active:bg-
|
|
310
|
+
return `${structural} ${layoutClasses} text-nav-menu-item hover:bg-nav-menu-hover hover:text-nav-menu-item-hover active:bg-surface-active`;
|
|
228
311
|
}
|
|
229
312
|
|
|
230
313
|
function handleNavigate(item: SidebarNavigationItem, event: MouseEvent) {
|
|
@@ -268,13 +351,25 @@
|
|
|
268
351
|
}
|
|
269
352
|
</script>
|
|
270
353
|
|
|
271
|
-
<
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
354
|
+
<SidebarShell
|
|
355
|
+
{mode}
|
|
356
|
+
{layout}
|
|
357
|
+
{ariaLabel}
|
|
358
|
+
class={classAttr}
|
|
359
|
+
className={legacyClass}
|
|
360
|
+
{mobile}
|
|
361
|
+
bind:isOpen
|
|
362
|
+
{trigger}
|
|
363
|
+
{drawerTitle}
|
|
364
|
+
{closeLabel}
|
|
365
|
+
{onclose}
|
|
366
|
+
{label}
|
|
367
|
+
{...restProps}
|
|
368
|
+
>
|
|
369
|
+
{#snippet header()}
|
|
276
370
|
{#if showBrandRow}
|
|
277
371
|
<SidebarBrandHeader
|
|
372
|
+
strings={handedOn}
|
|
278
373
|
collapsed={isCollapsed}
|
|
279
374
|
{brandName}
|
|
280
375
|
logoSrc={logoSrc.trim()}
|
|
@@ -307,10 +402,10 @@
|
|
|
307
402
|
<Button
|
|
308
403
|
variant={searchTriggerVariant}
|
|
309
404
|
size={searchTriggerSize}
|
|
310
|
-
|
|
405
|
+
fullWidth
|
|
311
406
|
onclick={handleSearchClick}
|
|
312
407
|
>
|
|
313
|
-
<span class="flex w-full items-center justify-start gap-
|
|
408
|
+
<span class="flex w-full items-center justify-start gap-3">
|
|
314
409
|
<span class={iconContainerClasses} aria-hidden="true">
|
|
315
410
|
<TriggerIcon size={17} />
|
|
316
411
|
</span>
|
|
@@ -334,18 +429,13 @@
|
|
|
334
429
|
bind:value={searchValue}
|
|
335
430
|
placeholder={searchPlaceholder}
|
|
336
431
|
aria-label={searchPlaceholder}
|
|
337
|
-
class="focus-ring focus-ring--nav w-full min-w-0 min-h-10 rounded-
|
|
432
|
+
class="focus-ring focus-ring--nav w-full min-w-0 min-h-10 pointer-coarse:min-h-11 rounded-container border-transparent !bg-transparent py-2 pl-10 text-sm ring-1 ring-input-border hover:!bg-input-hover focus:!bg-transparent"
|
|
338
433
|
/>
|
|
339
434
|
</div>
|
|
340
435
|
{/if}
|
|
341
436
|
{/if}
|
|
342
|
-
|
|
437
|
+
{/snippet}
|
|
343
438
|
|
|
344
|
-
<div
|
|
345
|
-
class={`flex min-h-0 min-w-0 flex-1 flex-col gap-3 overflow-y-auto overflow-x-hidden overscroll-y-contain pt-4 pb-1.5 ${insetX}`}
|
|
346
|
-
role="region"
|
|
347
|
-
aria-label="Navigation links"
|
|
348
|
-
>
|
|
349
439
|
{#if hasFilteredItems}
|
|
350
440
|
<div
|
|
351
441
|
class="flex w-full min-w-0 flex-col divide-y divide-border"
|
|
@@ -356,13 +446,26 @@
|
|
|
356
446
|
title={group.sectionLabel ?? ""}
|
|
357
447
|
sectionKey={`p-${gi}`}
|
|
358
448
|
listAriaLabel={group.sectionLabel
|
|
359
|
-
?
|
|
360
|
-
:
|
|
449
|
+
? text.sectionNavigation(group.sectionLabel)
|
|
450
|
+
: text.primaryNavigation}
|
|
361
451
|
collapsed={isCollapsed}
|
|
362
452
|
>
|
|
363
453
|
{#each group.items as item (item.id)}
|
|
364
454
|
{@const Icon = item.icon}
|
|
365
455
|
<li>
|
|
456
|
+
<!--
|
|
457
|
+
Collapsed rows are icon-only. aria-label
|
|
458
|
+
covers screen readers, but a sighted user
|
|
459
|
+
got an unlabelled glyph with no hover
|
|
460
|
+
affordance at all.
|
|
461
|
+
-->
|
|
462
|
+
<Tooltip
|
|
463
|
+
content={item.label}
|
|
464
|
+
placement="right"
|
|
465
|
+
disabled={!isCollapsed}
|
|
466
|
+
block
|
|
467
|
+
fixed
|
|
468
|
+
>
|
|
366
469
|
<a
|
|
367
470
|
href={item.href}
|
|
368
471
|
class={getNavItemClasses(item)}
|
|
@@ -370,6 +473,12 @@
|
|
|
370
473
|
aria-current={getAriaCurrent(item)}
|
|
371
474
|
aria-label={isCollapsed ? item.label : undefined}
|
|
372
475
|
>
|
|
476
|
+
{#if isItemActive(item)}
|
|
477
|
+
<span
|
|
478
|
+
class="absolute left-0 top-1/2 h-5 w-[3px] -translate-y-1/2 rounded-pill bg-nav-menu-item-active"
|
|
479
|
+
aria-hidden="true"
|
|
480
|
+
></span>
|
|
481
|
+
{/if}
|
|
373
482
|
{#if Icon}
|
|
374
483
|
<span
|
|
375
484
|
class={iconContainerClasses}
|
|
@@ -384,16 +493,31 @@
|
|
|
384
493
|
>{item.label}</span
|
|
385
494
|
>
|
|
386
495
|
{/if}
|
|
387
|
-
{#if
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
496
|
+
{#if getItemBadgeText(item) !== null}
|
|
497
|
+
{#if isCollapsed}
|
|
498
|
+
<!--
|
|
499
|
+
A notification count that
|
|
500
|
+
disappears when you collapse
|
|
501
|
+
the rail is a real loss; the
|
|
502
|
+
count becomes a dot rather
|
|
503
|
+
than nothing.
|
|
504
|
+
-->
|
|
505
|
+
<span
|
|
506
|
+
class="absolute right-2 top-2 size-2 rounded-pill bg-error"
|
|
507
|
+
aria-hidden="true"
|
|
508
|
+
></span>
|
|
509
|
+
{:else}
|
|
510
|
+
<span class="ml-auto">
|
|
511
|
+
<Badge
|
|
512
|
+
variant="default"
|
|
513
|
+
size="sm"
|
|
514
|
+
text={getItemBadgeText(item) ?? ""}
|
|
515
|
+
/>
|
|
516
|
+
</span>
|
|
517
|
+
{/if}
|
|
395
518
|
{/if}
|
|
396
519
|
</a>
|
|
520
|
+
</Tooltip>
|
|
397
521
|
</li>
|
|
398
522
|
{/each}
|
|
399
523
|
</SidebarNavSection>
|
|
@@ -408,7 +532,7 @@
|
|
|
408
532
|
>
|
|
409
533
|
<SidebarNavSection
|
|
410
534
|
sectionKey="secondary"
|
|
411
|
-
listAriaLabel=
|
|
535
|
+
listAriaLabel={text.secondaryNavigation}
|
|
412
536
|
collapsed={isCollapsed}
|
|
413
537
|
>
|
|
414
538
|
{#each filteredSecondaryItems as item (item.id)}
|
|
@@ -446,22 +570,22 @@
|
|
|
446
570
|
{/if}
|
|
447
571
|
{:else}
|
|
448
572
|
<div
|
|
449
|
-
class="rounded-
|
|
573
|
+
class="rounded-container border border-border border-dashed bg-transparent px-4 py-4"
|
|
450
574
|
>
|
|
451
575
|
<h3 class="text-sm font-semibold {getTextToneClass()}">
|
|
452
576
|
{normalizedSearchTerm && searchMode === "input"
|
|
453
|
-
?
|
|
577
|
+
? text.noMatchesTitle
|
|
454
578
|
: emptyStateTitle}
|
|
455
579
|
</h3>
|
|
456
580
|
<p class="mt-1 text-sm {getTextToneClass(true)}">
|
|
457
581
|
{normalizedSearchTerm && searchMode === "input"
|
|
458
|
-
?
|
|
582
|
+
? text.noMatchesDescription(searchValue)
|
|
459
583
|
: emptyStateDescription}
|
|
460
584
|
</p>
|
|
461
585
|
{#if !(normalizedSearchTerm && searchMode === "input")}
|
|
462
586
|
<button
|
|
463
587
|
type="button"
|
|
464
|
-
class="focus-ring focus-ring--nav mt-3 inline-flex min-h-10 cursor-pointer items-center rounded-
|
|
588
|
+
class="focus-ring focus-ring--nav mt-3 inline-flex min-h-10 pointer-coarse:min-h-11 cursor-pointer items-center rounded-control bg-action-primary px-3 py-2 text-sm font-medium text-action-primary outline-none transition-colors hover:bg-action-primary-hover"
|
|
465
589
|
onclick={handleEmptyStateAction}
|
|
466
590
|
>
|
|
467
591
|
{emptyStateActionLabel}
|
|
@@ -469,11 +593,10 @@
|
|
|
469
593
|
{/if}
|
|
470
594
|
</div>
|
|
471
595
|
{/if}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
collapsed={isCollapsed}
|
|
596
|
+
{#snippet footer({ insetX })}
|
|
597
|
+
<SidebarFooter
|
|
598
|
+
collapsed={isCollapsed}
|
|
599
|
+
strings={handedOn}
|
|
477
600
|
{showProfile}
|
|
478
601
|
{profileName}
|
|
479
602
|
{profileEmail}
|
|
@@ -489,6 +612,7 @@
|
|
|
489
612
|
{profilePanelOpen}
|
|
490
613
|
{profilePanelControlsId}
|
|
491
614
|
{profilePanel}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
615
|
+
className={insetX}
|
|
616
|
+
/>
|
|
617
|
+
{/snippet}
|
|
618
|
+
</SidebarShell>
|