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
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getContext, onDestroy, setContext, untrack, type Snippet } from "svelte";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
import ChevronDown from "@lucide/svelte/icons/chevron-down";
|
|
5
|
+
import { cn } from "../util/cn.js";
|
|
6
|
+
import { generateId } from "../util/ssr-safe.js";
|
|
7
|
+
import {
|
|
8
|
+
COLLAPSIBLE_GROUP,
|
|
9
|
+
type CollapsibleGroupContext,
|
|
10
|
+
type CollapsibleGroupMember,
|
|
11
|
+
type CollapsibleHeadingLevel,
|
|
12
|
+
type CollapsibleTriggerProps,
|
|
13
|
+
type CollapsibleTriggerState,
|
|
14
|
+
} from "../util/collapsible.js";
|
|
15
|
+
|
|
16
|
+
/** Other attributes (`id`, `data-*`, ...) land on the host `<div>`. */
|
|
17
|
+
type Props = Omit<HTMLAttributes<HTMLDivElement>, "class" | "title"> & {
|
|
18
|
+
/** Extra classes for the host element. */
|
|
19
|
+
class?: string;
|
|
20
|
+
/** Extra classes for the default trigger button. */
|
|
21
|
+
triggerClass?: string;
|
|
22
|
+
/** Extra classes for the panel. */
|
|
23
|
+
panelClass?: string;
|
|
24
|
+
/** Whether the panel is shown; supports `bind:open`. */
|
|
25
|
+
open?: boolean;
|
|
26
|
+
/** Called when the user toggles the panel, or a group closes it. */
|
|
27
|
+
onopenchange?: (open: boolean) => void;
|
|
28
|
+
/**
|
|
29
|
+
* The trigger cannot be activated. The panel keeps its current state:
|
|
30
|
+
* a group does not close a disabled panel either.
|
|
31
|
+
*/
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
/** Text of the default trigger, a full-width header button with a chevron. */
|
|
34
|
+
title?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Your own header, in place of the default trigger. Spread the first
|
|
37
|
+
* argument on a `<button>`; the second carries the open state.
|
|
38
|
+
*/
|
|
39
|
+
trigger?: Snippet<[CollapsibleTriggerProps, CollapsibleTriggerState]>;
|
|
40
|
+
/** Wraps the default trigger in `<h1>`–`<h6>`. No heading when omitted. */
|
|
41
|
+
headingLevel?: CollapsibleHeadingLevel;
|
|
42
|
+
/**
|
|
43
|
+
* Closed content is kept in the DOM under `hidden`, so a form inside it
|
|
44
|
+
* keeps its values. Set this to remove the content while closed instead.
|
|
45
|
+
*/
|
|
46
|
+
unmountOnClose?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Gives the panel `role="region"`, which makes it a landmark. Defaults
|
|
49
|
+
* to true only inside a single-open `CollapsibleGroup`.
|
|
50
|
+
*/
|
|
51
|
+
region?: boolean;
|
|
52
|
+
children?: Snippet;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
let {
|
|
56
|
+
class: className = "",
|
|
57
|
+
triggerClass = "",
|
|
58
|
+
panelClass = "",
|
|
59
|
+
open = $bindable<Exclude<Props["open"], undefined>>(),
|
|
60
|
+
onopenchange,
|
|
61
|
+
disabled = false,
|
|
62
|
+
title,
|
|
63
|
+
trigger,
|
|
64
|
+
headingLevel,
|
|
65
|
+
unmountOnClose = false,
|
|
66
|
+
region,
|
|
67
|
+
children,
|
|
68
|
+
...restProps
|
|
69
|
+
}: Props = $props();
|
|
70
|
+
|
|
71
|
+
// No fallback on a bindable prop: Svelte refuses `bind:…={undefined}` on
|
|
72
|
+
// one that has a fallback (`props_invalid_value`), and a page that throws
|
|
73
|
+
// while it hydrates never becomes interactive. The default is applied
|
|
74
|
+
// here instead: at once, for the server and the first render, and again
|
|
75
|
+
// whenever a parent hands back `undefined`.
|
|
76
|
+
const applyDefaults = () => {
|
|
77
|
+
if (open === undefined) open = false;
|
|
78
|
+
};
|
|
79
|
+
applyDefaults();
|
|
80
|
+
$effect.pre(applyDefaults);
|
|
81
|
+
|
|
82
|
+
const triggerId = generateId("collapsible-trigger");
|
|
83
|
+
const panelId = generateId("collapsible-panel");
|
|
84
|
+
|
|
85
|
+
const group = getContext<CollapsibleGroupContext | undefined>(COLLAPSIBLE_GROUP);
|
|
86
|
+
// A Collapsible inside this panel is not a member of the group around it:
|
|
87
|
+
// opening it must not close the panel it lives in.
|
|
88
|
+
setContext(COLLAPSIBLE_GROUP, undefined);
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* True for a panel that asked to start open in a single-open group that
|
|
92
|
+
* already had one. It renders closed from the first render, the server's
|
|
93
|
+
* included, and `open` is brought in line after mount. Nobody changed
|
|
94
|
+
* anything, so `onopenchange` is not called for it.
|
|
95
|
+
*/
|
|
96
|
+
let startClosed = $state(false);
|
|
97
|
+
/** What is rendered. Everything below reads this, not `open`. */
|
|
98
|
+
const isOpen = $derived(open && !startClosed);
|
|
99
|
+
|
|
100
|
+
let panelElement: HTMLDivElement | undefined = $state();
|
|
101
|
+
|
|
102
|
+
function setOpen(next: boolean) {
|
|
103
|
+
if (isOpen === next) return;
|
|
104
|
+
open = next;
|
|
105
|
+
onopenchange?.(next);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function toggle() {
|
|
109
|
+
if (disabled) return;
|
|
110
|
+
setOpen(!isOpen);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const member: CollapsibleGroupMember = {
|
|
114
|
+
triggerId,
|
|
115
|
+
// Spelled out rather than `isOpen`: the group asks while this
|
|
116
|
+
// component is still initialising, before `startClosed` is known, and
|
|
117
|
+
// on the server a derived value keeps its first answer.
|
|
118
|
+
isOpen: () => open && !startClosed,
|
|
119
|
+
isDisabled: () => disabled,
|
|
120
|
+
close: () => setOpen(false),
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
if (group) {
|
|
124
|
+
const registration = group.register(member);
|
|
125
|
+
startClosed = registration.startClosed;
|
|
126
|
+
onDestroy(registration.unregister);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// The bound prop cannot be written while the component initialises, so
|
|
130
|
+
// the settled state is written back here, once.
|
|
131
|
+
$effect(() => {
|
|
132
|
+
if (!startClosed) return;
|
|
133
|
+
open = false;
|
|
134
|
+
startClosed = false;
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// An effect rather than a call in `toggle`, so a panel opened from outside
|
|
138
|
+
// through `bind:open` closes its siblings as well. Untracked, because the
|
|
139
|
+
// group reads the siblings' state: tracking that would re-run this effect
|
|
140
|
+
// when a sibling opens, and the two would close each other.
|
|
141
|
+
$effect(() => {
|
|
142
|
+
if (isOpen) untrack(() => group?.opened(member));
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// A panel can close while focus is inside it: the parent sets `open`, or
|
|
146
|
+
// a group closes it. Hidden content cannot hold focus, which would fall
|
|
147
|
+
// to `<body>`, so the trigger takes it. This runs before the panel is
|
|
148
|
+
// hidden, while the focused element can still be found; focus is not
|
|
149
|
+
// touched in any other case.
|
|
150
|
+
$effect.pre(() => {
|
|
151
|
+
if (isOpen || !panelElement) return;
|
|
152
|
+
const panel = panelElement;
|
|
153
|
+
untrack(() => {
|
|
154
|
+
if (panel.contains(document.activeElement)) {
|
|
155
|
+
document.getElementById(triggerId)?.focus();
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const triggerProps = $derived({
|
|
161
|
+
id: triggerId,
|
|
162
|
+
type: "button",
|
|
163
|
+
"aria-expanded": isOpen,
|
|
164
|
+
"aria-controls": panelId,
|
|
165
|
+
disabled,
|
|
166
|
+
onclick: toggle,
|
|
167
|
+
"data-collapsible-trigger": "",
|
|
168
|
+
} satisfies CollapsibleTriggerProps);
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* A region is a landmark, and a page of them is noise (the WAI-ARIA
|
|
172
|
+
* accordion pattern warns against it). In a single-open group at most one
|
|
173
|
+
* panel is exposed at a time, so a region is safe there. Everywhere else
|
|
174
|
+
* the panel is a plain named group unless the caller asks for a region.
|
|
175
|
+
*/
|
|
176
|
+
const panelRole = $derived(
|
|
177
|
+
(region ?? (group ? !group.multiple : false)) ? "region" : "group",
|
|
178
|
+
);
|
|
179
|
+
</script>
|
|
180
|
+
|
|
181
|
+
{#snippet defaultTrigger()}
|
|
182
|
+
<button
|
|
183
|
+
{...triggerProps}
|
|
184
|
+
class={cn(
|
|
185
|
+
"focus-ring flex w-full cursor-pointer items-center justify-between gap-2 rounded-control px-3 py-2 text-start text-sm font-medium text-headline transition-colors duration-150 hover:bg-surface-hover active:bg-surface-active motion-reduce:transition-none pointer-coarse:min-h-11 disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent disabled:active:bg-transparent",
|
|
186
|
+
triggerClass,
|
|
187
|
+
)}
|
|
188
|
+
>
|
|
189
|
+
<span class="min-w-0 flex-1">{title}</span>
|
|
190
|
+
<ChevronDown
|
|
191
|
+
size={16}
|
|
192
|
+
aria-hidden="true"
|
|
193
|
+
class={cn(
|
|
194
|
+
"shrink-0 text-description transition-transform duration-150 motion-reduce:transition-none",
|
|
195
|
+
isOpen && "rotate-180",
|
|
196
|
+
)}
|
|
197
|
+
/>
|
|
198
|
+
</button>
|
|
199
|
+
{/snippet}
|
|
200
|
+
|
|
201
|
+
<div
|
|
202
|
+
class={cn(className)}
|
|
203
|
+
data-state={isOpen ? "open" : "closed"}
|
|
204
|
+
data-disabled={disabled ? "" : undefined}
|
|
205
|
+
{...restProps}
|
|
206
|
+
>
|
|
207
|
+
{#if trigger}
|
|
208
|
+
{@render trigger(triggerProps, { open: isOpen, disabled })}
|
|
209
|
+
{:else if headingLevel === 1}
|
|
210
|
+
<!-- One branch per level, not `<svelte:element>`: hydration takes a
|
|
211
|
+
dynamic element out and puts it back, which blurs the trigger inside
|
|
212
|
+
it if the user had already tabbed to it. -->
|
|
213
|
+
<h1 class="m-0">{@render defaultTrigger()}</h1>
|
|
214
|
+
{:else if headingLevel === 2}
|
|
215
|
+
<h2 class="m-0">{@render defaultTrigger()}</h2>
|
|
216
|
+
{:else if headingLevel === 3}
|
|
217
|
+
<h3 class="m-0">{@render defaultTrigger()}</h3>
|
|
218
|
+
{:else if headingLevel === 4}
|
|
219
|
+
<h4 class="m-0">{@render defaultTrigger()}</h4>
|
|
220
|
+
{:else if headingLevel === 5}
|
|
221
|
+
<h5 class="m-0">{@render defaultTrigger()}</h5>
|
|
222
|
+
{:else if headingLevel === 6}
|
|
223
|
+
<h6 class="m-0">{@render defaultTrigger()}</h6>
|
|
224
|
+
{:else}
|
|
225
|
+
{@render defaultTrigger()}
|
|
226
|
+
{/if}
|
|
227
|
+
|
|
228
|
+
<!-- `hidden` is `display: none`: closed content takes no focus and is not
|
|
229
|
+
in the accessibility tree. The element itself stays, so `aria-controls`
|
|
230
|
+
always points at something. -->
|
|
231
|
+
<div
|
|
232
|
+
bind:this={panelElement}
|
|
233
|
+
id={panelId}
|
|
234
|
+
role={panelRole}
|
|
235
|
+
aria-labelledby={triggerId}
|
|
236
|
+
hidden={!isOpen}
|
|
237
|
+
class={cn(!trigger && "px-3 pb-3 pt-1", panelClass)}
|
|
238
|
+
>
|
|
239
|
+
{#if isOpen || !unmountOnClose}
|
|
240
|
+
{@render children?.()}
|
|
241
|
+
{/if}
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type Snippet } from "svelte";
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
import { type CollapsibleHeadingLevel, type CollapsibleTriggerProps, type CollapsibleTriggerState } from "../util/collapsible.js";
|
|
4
|
+
/** Other attributes (`id`, `data-*`, ...) land on the host `<div>`. */
|
|
5
|
+
type Props = Omit<HTMLAttributes<HTMLDivElement>, "class" | "title"> & {
|
|
6
|
+
/** Extra classes for the host element. */
|
|
7
|
+
class?: string;
|
|
8
|
+
/** Extra classes for the default trigger button. */
|
|
9
|
+
triggerClass?: string;
|
|
10
|
+
/** Extra classes for the panel. */
|
|
11
|
+
panelClass?: string;
|
|
12
|
+
/** Whether the panel is shown; supports `bind:open`. */
|
|
13
|
+
open?: boolean;
|
|
14
|
+
/** Called when the user toggles the panel, or a group closes it. */
|
|
15
|
+
onopenchange?: (open: boolean) => void;
|
|
16
|
+
/**
|
|
17
|
+
* The trigger cannot be activated. The panel keeps its current state:
|
|
18
|
+
* a group does not close a disabled panel either.
|
|
19
|
+
*/
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
/** Text of the default trigger, a full-width header button with a chevron. */
|
|
22
|
+
title?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Your own header, in place of the default trigger. Spread the first
|
|
25
|
+
* argument on a `<button>`; the second carries the open state.
|
|
26
|
+
*/
|
|
27
|
+
trigger?: Snippet<[CollapsibleTriggerProps, CollapsibleTriggerState]>;
|
|
28
|
+
/** Wraps the default trigger in `<h1>`–`<h6>`. No heading when omitted. */
|
|
29
|
+
headingLevel?: CollapsibleHeadingLevel;
|
|
30
|
+
/**
|
|
31
|
+
* Closed content is kept in the DOM under `hidden`, so a form inside it
|
|
32
|
+
* keeps its values. Set this to remove the content while closed instead.
|
|
33
|
+
*/
|
|
34
|
+
unmountOnClose?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Gives the panel `role="region"`, which makes it a landmark. Defaults
|
|
37
|
+
* to true only inside a single-open `CollapsibleGroup`.
|
|
38
|
+
*/
|
|
39
|
+
region?: boolean;
|
|
40
|
+
children?: Snippet;
|
|
41
|
+
};
|
|
42
|
+
declare const Collapsible: import("svelte").Component<Props, {}, "open">;
|
|
43
|
+
type Collapsible = ReturnType<typeof Collapsible>;
|
|
44
|
+
export default Collapsible;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { setContext, untrack, type Snippet } from "svelte";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
import { cn } from "../util/cn.js";
|
|
5
|
+
import {
|
|
6
|
+
COLLAPSIBLE_GROUP,
|
|
7
|
+
nextTriggerIndex,
|
|
8
|
+
type CollapsibleGroupContext,
|
|
9
|
+
type CollapsibleGroupMember,
|
|
10
|
+
} from "../util/collapsible.js";
|
|
11
|
+
|
|
12
|
+
/** Other attributes (`id`, `aria-label`, `data-*`, ...) land on the host `<div>`. */
|
|
13
|
+
type Props = Omit<HTMLAttributes<HTMLDivElement>, "class"> & {
|
|
14
|
+
/** Extra classes for the host element. */
|
|
15
|
+
class?: string;
|
|
16
|
+
/** Lets several panels be open at once. By default opening one closes the others. */
|
|
17
|
+
multiple?: boolean;
|
|
18
|
+
/** The `Collapsible` components to coordinate. */
|
|
19
|
+
children?: Snippet;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
let {
|
|
23
|
+
class: className = "",
|
|
24
|
+
multiple = false,
|
|
25
|
+
onkeydown,
|
|
26
|
+
children,
|
|
27
|
+
...restProps
|
|
28
|
+
}: Props = $props();
|
|
29
|
+
|
|
30
|
+
let hostElement: HTMLDivElement | undefined = $state();
|
|
31
|
+
|
|
32
|
+
/** In the order the Collapsibles were created. */
|
|
33
|
+
const members = new Set<CollapsibleGroupMember>();
|
|
34
|
+
|
|
35
|
+
/** A disabled panel keeps its state, so it neither holds the one open slot nor loses it. */
|
|
36
|
+
function holdsTheSlot(member: CollapsibleGroupMember): boolean {
|
|
37
|
+
return member.isOpen() && !member.isDisabled();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function closeOthers(keep: CollapsibleGroupMember) {
|
|
41
|
+
for (const member of members) {
|
|
42
|
+
if (member !== keep && holdsTheSlot(member)) member.close();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
setContext<CollapsibleGroupContext>(COLLAPSIBLE_GROUP, {
|
|
47
|
+
get multiple() {
|
|
48
|
+
return multiple;
|
|
49
|
+
},
|
|
50
|
+
register(member) {
|
|
51
|
+
// Settled here, while the members initialise, so the first render
|
|
52
|
+
// (the server's included) already shows one open panel.
|
|
53
|
+
const startClosed =
|
|
54
|
+
!multiple &&
|
|
55
|
+
holdsTheSlot(member) &&
|
|
56
|
+
[...members].some(holdsTheSlot);
|
|
57
|
+
members.add(member);
|
|
58
|
+
return { unregister: () => members.delete(member), startClosed };
|
|
59
|
+
},
|
|
60
|
+
opened(member) {
|
|
61
|
+
// A disabled panel is outside the one-open rule in both
|
|
62
|
+
// directions: it is not closed, and it closes nothing.
|
|
63
|
+
if (!multiple && !member.isDisabled()) closeOthers(member);
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Going from `multiple` back to single: the first open panel stays.
|
|
68
|
+
$effect(() => {
|
|
69
|
+
if (multiple) return;
|
|
70
|
+
untrack(() => {
|
|
71
|
+
const first = [...members].find(holdsTheSlot);
|
|
72
|
+
if (first) closeOthers(first);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The optional keys of the accordion pattern, between this group's own
|
|
78
|
+
* header buttons. A trigger nested in a panel belongs to no group, or to
|
|
79
|
+
* an inner one, and is left alone; Tab is never touched.
|
|
80
|
+
*/
|
|
81
|
+
function handleKeydown(
|
|
82
|
+
event: KeyboardEvent & { currentTarget: EventTarget & HTMLDivElement },
|
|
83
|
+
) {
|
|
84
|
+
onkeydown?.(event);
|
|
85
|
+
if (event.defaultPrevented) return;
|
|
86
|
+
if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;
|
|
87
|
+
const target = event.target;
|
|
88
|
+
if (!(target instanceof HTMLElement) || !hostElement) return;
|
|
89
|
+
|
|
90
|
+
const ids = new Set([...members].map((member) => member.triggerId));
|
|
91
|
+
if (!ids.has(target.id)) return;
|
|
92
|
+
|
|
93
|
+
// Read from the DOM so the order is the visual one. A disabled button
|
|
94
|
+
// cannot take focus, so it is skipped.
|
|
95
|
+
const triggers = Array.from(
|
|
96
|
+
hostElement.querySelectorAll<HTMLButtonElement>(
|
|
97
|
+
"[data-collapsible-trigger]",
|
|
98
|
+
),
|
|
99
|
+
).filter((element) => ids.has(element.id) && !element.disabled);
|
|
100
|
+
|
|
101
|
+
const next = nextTriggerIndex(
|
|
102
|
+
event.key,
|
|
103
|
+
triggers.indexOf(target as HTMLButtonElement),
|
|
104
|
+
triggers.length,
|
|
105
|
+
);
|
|
106
|
+
if (next === null) return;
|
|
107
|
+
|
|
108
|
+
// Also keeps the arrow keys from scrolling the page under the header.
|
|
109
|
+
event.preventDefault();
|
|
110
|
+
triggers[next]?.focus();
|
|
111
|
+
}
|
|
112
|
+
</script>
|
|
113
|
+
|
|
114
|
+
<!-- The listener only moves focus between buttons that are already in the
|
|
115
|
+
tab order; the group itself is not interactive. -->
|
|
116
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
117
|
+
<div
|
|
118
|
+
bind:this={hostElement}
|
|
119
|
+
class={cn("flex flex-col", className)}
|
|
120
|
+
data-collapsible-group=""
|
|
121
|
+
data-multiple={multiple ? "" : undefined}
|
|
122
|
+
{...restProps}
|
|
123
|
+
onkeydown={handleKeydown}
|
|
124
|
+
>
|
|
125
|
+
{@render children?.()}
|
|
126
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Snippet } from "svelte";
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
/** Other attributes (`id`, `aria-label`, `data-*`, ...) land on the host `<div>`. */
|
|
4
|
+
type Props = Omit<HTMLAttributes<HTMLDivElement>, "class"> & {
|
|
5
|
+
/** Extra classes for the host element. */
|
|
6
|
+
class?: string;
|
|
7
|
+
/** Lets several panels be open at once. By default opening one closes the others. */
|
|
8
|
+
multiple?: boolean;
|
|
9
|
+
/** The `Collapsible` components to coordinate. */
|
|
10
|
+
children?: Snippet;
|
|
11
|
+
};
|
|
12
|
+
declare const CollapsibleGroup: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
type CollapsibleGroup = ReturnType<typeof CollapsibleGroup>;
|
|
14
|
+
export default CollapsibleGroup;
|
|
@@ -1,14 +1,25 @@
|
|
|
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 CodeBlock from "../atoms/CodeBlock.svelte";
|
|
3
5
|
import Card from "../atoms/Card.svelte";
|
|
4
6
|
import CardHeader from "../atoms/CardHeader.svelte";
|
|
5
7
|
import CardContent from "../atoms/CardContent.svelte";
|
|
8
|
+
import { cn } from "../util/cn.js";
|
|
9
|
+
import {
|
|
10
|
+
DEFAULT_COMPONENT_DEMO_STRINGS,
|
|
11
|
+
type ComponentDemoStrings,
|
|
12
|
+
} from "../util/ready-made-strings.js";
|
|
6
13
|
|
|
7
14
|
interface Props {
|
|
8
15
|
title: string;
|
|
9
16
|
description?: string;
|
|
10
17
|
code: string;
|
|
11
18
|
language?: string;
|
|
19
|
+
/** The words of the switch between the preview and the code. */
|
|
20
|
+
strings?: Partial<ComponentDemoStrings>;
|
|
21
|
+
class?: string;
|
|
22
|
+
/** @deprecated use `class`. */
|
|
12
23
|
className?: string;
|
|
13
24
|
}
|
|
14
25
|
|
|
@@ -17,12 +28,21 @@
|
|
|
17
28
|
description = "",
|
|
18
29
|
code,
|
|
19
30
|
language = "svelte",
|
|
20
|
-
|
|
31
|
+
strings,
|
|
32
|
+
class: classAttr = "",
|
|
33
|
+
className: legacyClass = "",
|
|
21
34
|
children,
|
|
22
35
|
...restProps
|
|
23
36
|
} = $props<Props & { children?: any }>();
|
|
24
37
|
|
|
38
|
+
/** `class` is the public prop; `className` is a deprecated alias.
|
|
39
|
+
* Both are merged here so existing call sites keep working. */
|
|
40
|
+
const className = $derived(cn(`${classAttr} ${legacyClass}`));
|
|
41
|
+
|
|
25
42
|
let showCode = $state(false);
|
|
43
|
+
|
|
44
|
+
const provided = zabiStringsFor("componentDemo");
|
|
45
|
+
const text = $derived(mergeStrings(DEFAULT_COMPONENT_DEMO_STRINGS, provided(), (strings as Partial<ComponentDemoStrings> | undefined)));
|
|
26
46
|
</script>
|
|
27
47
|
|
|
28
48
|
<div class="relative">
|
|
@@ -36,8 +56,8 @@
|
|
|
36
56
|
<CardContent>
|
|
37
57
|
<button
|
|
38
58
|
onclick={() => (showCode = !showCode)}
|
|
39
|
-
class="absolute top-8 right-8 z-10 flex cursor-pointer items-center gap-2 rounded-
|
|
40
|
-
aria-label={showCode ?
|
|
59
|
+
class="absolute top-8 right-8 z-10 flex cursor-pointer items-center gap-2 rounded-control px-3 py-2 pointer-coarse:min-h-11 text-sm text-description transition-colors duration-200 hover:bg-surface-hover hover:text-body active:bg-surface-active"
|
|
60
|
+
aria-label={showCode ? text.showPreview : text.showCode}
|
|
41
61
|
>
|
|
42
62
|
{#if showCode}
|
|
43
63
|
<svg
|
|
@@ -59,7 +79,7 @@
|
|
|
59
79
|
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
|
|
60
80
|
/>
|
|
61
81
|
</svg>
|
|
62
|
-
|
|
82
|
+
{text.preview}
|
|
63
83
|
{:else}
|
|
64
84
|
<svg
|
|
65
85
|
class="w-4 h-4"
|
|
@@ -74,7 +94,7 @@
|
|
|
74
94
|
d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
|
|
75
95
|
/>
|
|
76
96
|
</svg>
|
|
77
|
-
|
|
97
|
+
{text.code}
|
|
78
98
|
{/if}
|
|
79
99
|
</button>
|
|
80
100
|
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import { type ComponentDemoStrings } from "../util/ready-made-strings.js";
|
|
1
2
|
interface Props {
|
|
2
3
|
title: string;
|
|
3
4
|
description?: string;
|
|
4
5
|
code: string;
|
|
5
6
|
language?: string;
|
|
7
|
+
/** The words of the switch between the preview and the code. */
|
|
8
|
+
strings?: Partial<ComponentDemoStrings>;
|
|
9
|
+
class?: string;
|
|
10
|
+
/** @deprecated use `class`. */
|
|
6
11
|
className?: string;
|
|
7
12
|
}
|
|
8
13
|
type $$ComponentProps = Props & {
|