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,53 @@
|
|
|
1
|
+
import type { HTMLInputAttributes } from "svelte/elements";
|
|
2
|
+
import type { SizeVariant } from "../types/variants.js";
|
|
3
|
+
/**
|
|
4
|
+
* A date, picked with the device's own date picker and styled like Input.
|
|
5
|
+
*
|
|
6
|
+
* It is a native `<input type="date">`: an iPhone shows its wheels or
|
|
7
|
+
* calendar, Android its calendar, a desktop browser its own. `value` is
|
|
8
|
+
* always `YYYY-MM-DD`, or `""` while empty, whatever the field shows.
|
|
9
|
+
*
|
|
10
|
+
* What the field shows is the browser's decision: the date in the format
|
|
11
|
+
* of the browser or device, not of the page, and no attribute changes
|
|
12
|
+
* that. To show a date as text in the page's language, use `formatDate`:
|
|
13
|
+
*
|
|
14
|
+
* ```svelte
|
|
15
|
+
* <DateField label="Date" bind:value={date} min="2026-01-01" />
|
|
16
|
+
* <p>{formatDate(date, "sv")}</p> <!-- 6 okt. 2026 -->
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Other attributes (`autocomplete`, `data-*`, `onchange`, ...) land on the
|
|
20
|
+
* `<input>`.
|
|
21
|
+
*/
|
|
22
|
+
type Props = Omit<HTMLInputAttributes, "class" | "type" | "value" | "size" | "min" | "max" | "step" | "required" | "disabled" | "readonly" | "id" | "name"> & {
|
|
23
|
+
/** Omit to auto-generate; pair with FormField's `id` when used inside FormField. */
|
|
24
|
+
id?: string;
|
|
25
|
+
/** The date as `YYYY-MM-DD`, or `""` while empty. Supports `bind:value`. */
|
|
26
|
+
value?: string;
|
|
27
|
+
/** Name the value is submitted under in a form. */
|
|
28
|
+
name?: string;
|
|
29
|
+
label?: string;
|
|
30
|
+
/** True when FormField supplies the visible `<label>`. */
|
|
31
|
+
hideLabel?: boolean;
|
|
32
|
+
/** Help text under the field, read out with it. */
|
|
33
|
+
hint?: string;
|
|
34
|
+
/** An error under the field. It marks the field invalid and is announced. */
|
|
35
|
+
error?: string;
|
|
36
|
+
/** Earliest date that can be picked, as `YYYY-MM-DD`. */
|
|
37
|
+
min?: string;
|
|
38
|
+
/** Latest date that can be picked, as `YYYY-MM-DD`. */
|
|
39
|
+
max?: string;
|
|
40
|
+
/** Steps between dates that can be picked, in days. */
|
|
41
|
+
step?: number | "any";
|
|
42
|
+
required?: boolean;
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
/** Shows the value without letting it be changed; it is still submitted. */
|
|
45
|
+
readonly?: boolean;
|
|
46
|
+
/** Height, on the scale Input and Button use. At least 44px on a touch screen. */
|
|
47
|
+
size?: SizeVariant;
|
|
48
|
+
/** Extra classes for the `<input>`. */
|
|
49
|
+
class?: string;
|
|
50
|
+
};
|
|
51
|
+
declare const DateField: import("svelte").Component<Props, {}, "value">;
|
|
52
|
+
type DateField = ReturnType<typeof DateField>;
|
|
53
|
+
export default DateField;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { cn } from "../util/cn.js";
|
|
3
|
+
|
|
2
4
|
type Orientation = 'horizontal' | 'vertical';
|
|
3
5
|
|
|
4
6
|
interface Props {
|
|
@@ -34,13 +36,11 @@
|
|
|
34
36
|
</script>
|
|
35
37
|
|
|
36
38
|
<div
|
|
37
|
-
class={
|
|
39
|
+
class={cn(
|
|
38
40
|
'flex items-center text-description',
|
|
39
41
|
isVertical ? 'h-full min-h-[1rem] flex-col' : 'w-full flex-row',
|
|
40
42
|
className,
|
|
41
|
-
|
|
42
|
-
.filter(Boolean)
|
|
43
|
-
.join(' ')}
|
|
43
|
+
)}
|
|
44
44
|
>
|
|
45
45
|
<div
|
|
46
46
|
aria-hidden={decorative ? 'true' : undefined}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Component, Snippet } from "svelte";
|
|
3
|
+
import { cn } from "../util/cn.js";
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
6
|
title: string;
|
|
@@ -19,18 +20,18 @@
|
|
|
19
20
|
</script>
|
|
20
21
|
|
|
21
22
|
<article
|
|
22
|
-
class="flex flex-col gap-3 p-6 rounded-
|
|
23
|
+
class={cn("flex flex-col gap-3 p-6 rounded-container bg-surface-1 border border-border transition-colors duration-200 hover:border-border-medium", className)}
|
|
23
24
|
>
|
|
24
25
|
{#if Icon}
|
|
25
26
|
<span
|
|
26
|
-
class="inline-flex items-center justify-center w-10 h-10 rounded-
|
|
27
|
+
class="inline-flex items-center justify-center w-10 h-10 rounded-control bg-brand-50 text-brand-600"
|
|
27
28
|
aria-hidden="true"
|
|
28
29
|
>
|
|
29
30
|
<Icon size={20} />
|
|
30
31
|
</span>
|
|
31
32
|
{/if}
|
|
32
33
|
|
|
33
|
-
<div class="flex flex-col gap-
|
|
34
|
+
<div class="flex flex-col gap-2">
|
|
34
35
|
<h3 class="text-base font-semibold leading-snug text-headline">
|
|
35
36
|
{title}
|
|
36
37
|
</h3>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import CheckCircle from "@lucide/svelte/icons/circle-check-big";
|
|
3
|
+
import AlertCircle from "@lucide/svelte/icons/circle-alert";
|
|
4
|
+
import AlertTriangle from "@lucide/svelte/icons/triangle-alert";
|
|
5
|
+
import { cn } from "../util/cn.js";
|
|
6
|
+
import { fieldHintId, fieldMessageId, type FieldMessageState } from "../util/field.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The text under a field: its status message and its hint. Internal: it is
|
|
10
|
+
* not exported from the package. Input, Textarea and Select render it, and
|
|
11
|
+
* DateField and TimeField through Input, so the markup, the ids and the
|
|
12
|
+
* way a message is announced are the same in all of them.
|
|
13
|
+
*
|
|
14
|
+
* The ids are the ones `fieldDescribedBy` lists on the control.
|
|
15
|
+
*/
|
|
16
|
+
interface Props {
|
|
17
|
+
/** Id of the control the text belongs to. */
|
|
18
|
+
fieldId: string;
|
|
19
|
+
/** From `fieldMessageState`. */
|
|
20
|
+
status: FieldMessageState;
|
|
21
|
+
hint?: string;
|
|
22
|
+
/** Distance from the control, and between the two: Textarea and Select sit 4px closer. */
|
|
23
|
+
gap?: "mt-1" | "mt-2";
|
|
24
|
+
/** Extra classes for the status message. */
|
|
25
|
+
messageClass?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let { fieldId, status, hint = "", gap = "mt-2", messageClass = "" }: Props = $props();
|
|
29
|
+
|
|
30
|
+
// Message text uses the `-text` step (700), which clears 4.5:1 on a page
|
|
31
|
+
// surface; the solid fill step (600) is for fills, not for small text.
|
|
32
|
+
const toneClass = $derived(
|
|
33
|
+
status.variant === "error"
|
|
34
|
+
? "text-error-text"
|
|
35
|
+
: status.variant === "success"
|
|
36
|
+
? "text-success-text"
|
|
37
|
+
: status.variant === "warning"
|
|
38
|
+
? "text-warning-text"
|
|
39
|
+
: "text-description",
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const Icon = $derived(
|
|
43
|
+
status.variant === "error"
|
|
44
|
+
? AlertCircle
|
|
45
|
+
: status.variant === "success"
|
|
46
|
+
? CheckCircle
|
|
47
|
+
: status.variant === "warning"
|
|
48
|
+
? AlertTriangle
|
|
49
|
+
: null,
|
|
50
|
+
);
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
{#if status.showMessage}
|
|
54
|
+
<p
|
|
55
|
+
id={fieldMessageId(fieldId)}
|
|
56
|
+
class={cn("flex items-center gap-2 text-sm", gap, toneClass, messageClass)}
|
|
57
|
+
role={status.variant === "error" ? "alert" : "status"}
|
|
58
|
+
aria-live={status.variant === "error" ? "assertive" : "polite"}
|
|
59
|
+
>
|
|
60
|
+
{#if Icon}
|
|
61
|
+
<Icon size={14} class="shrink-0" />
|
|
62
|
+
{/if}
|
|
63
|
+
<span>{status.message}</span>
|
|
64
|
+
</p>
|
|
65
|
+
{/if}
|
|
66
|
+
{#if status.showHint}
|
|
67
|
+
<!-- Not a live region: a hint is there from the start and is read with the field. -->
|
|
68
|
+
<p id={fieldHintId(fieldId)} class={cn("text-sm text-description", gap)}>{hint}</p>
|
|
69
|
+
{/if}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type FieldMessageState } from "../util/field.js";
|
|
2
|
+
/**
|
|
3
|
+
* The text under a field: its status message and its hint. Internal: it is
|
|
4
|
+
* not exported from the package. Input, Textarea and Select render it, and
|
|
5
|
+
* DateField and TimeField through Input, so the markup, the ids and the
|
|
6
|
+
* way a message is announced are the same in all of them.
|
|
7
|
+
*
|
|
8
|
+
* The ids are the ones `fieldDescribedBy` lists on the control.
|
|
9
|
+
*/
|
|
10
|
+
interface Props {
|
|
11
|
+
/** Id of the control the text belongs to. */
|
|
12
|
+
fieldId: string;
|
|
13
|
+
/** From `fieldMessageState`. */
|
|
14
|
+
status: FieldMessageState;
|
|
15
|
+
hint?: string;
|
|
16
|
+
/** Distance from the control, and between the two: Textarea and Select sit 4px closer. */
|
|
17
|
+
gap?: "mt-1" | "mt-2";
|
|
18
|
+
/** Extra classes for the status message. */
|
|
19
|
+
messageClass?: string;
|
|
20
|
+
}
|
|
21
|
+
declare const FieldMessages: import("svelte").Component<Props, {}, "">;
|
|
22
|
+
type FieldMessages = ReturnType<typeof FieldMessages>;
|
|
23
|
+
export default FieldMessages;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Component } from "svelte";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
import Plus from "@lucide/svelte/icons/plus";
|
|
5
|
+
import { findScrollParent, isInsideAppShell } from "../util/app-shell.js";
|
|
6
|
+
import { cn } from "../util/cn.js";
|
|
7
|
+
import { reserveScrollPaddingBottom } from "../util/scroll-padding.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The one main thing to do on a screen, as a round button that floats over
|
|
11
|
+
* the content: new quiz, compose, add.
|
|
12
|
+
*
|
|
13
|
+
* Inside an `AppShell` it is placed against the shell, 16px above the tab
|
|
14
|
+
* bar. On its own it is fixed to the screen, 16px above the home
|
|
15
|
+
* indicator; if something else is fixed to the bottom there (a
|
|
16
|
+
* `BottomTabBar` on its own), say how tall it is with
|
|
17
|
+
* `--fab-bottom-offset` on the button or any ancestor:
|
|
18
|
+
*
|
|
19
|
+
* ```svelte
|
|
20
|
+
* <FloatingActionButton
|
|
21
|
+
* label="New quiz"
|
|
22
|
+
* onclick={create}
|
|
23
|
+
* style="--fab-bottom-offset: 65px"
|
|
24
|
+
* />
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* It lies over the content, so the last row would stay under it at the
|
|
28
|
+
* end of the page. Give the content room to scroll clear: `pb-24` (96px)
|
|
29
|
+
* on the list covers the button and its margins.
|
|
30
|
+
*
|
|
31
|
+
* While it is mounted it sets `scroll-padding-bottom` on what scrolls
|
|
32
|
+
* under it (the shell's content, or the page) to the height it takes
|
|
33
|
+
* from the bottom, so a row that takes keyboard focus is scrolled clear
|
|
34
|
+
* of the button and not left half under it.
|
|
35
|
+
*/
|
|
36
|
+
type Props = Omit<HTMLAttributes<HTMLElement>, "class"> & {
|
|
37
|
+
/** What the button does. Its accessible name, and its text when `extended`. */
|
|
38
|
+
label: string;
|
|
39
|
+
/** An icon component, as `@lucide/svelte` icons are. A plus sign by default. */
|
|
40
|
+
icon?: Component<{ size?: number; class?: string }>;
|
|
41
|
+
/** Shows the label as text beside the icon. */
|
|
42
|
+
extended?: boolean;
|
|
43
|
+
/** Makes it a link to this address. Without it, it is a button. */
|
|
44
|
+
href?: string;
|
|
45
|
+
/**
|
|
46
|
+
* The bottom corner it sits in. `bottom-end` is the right in a
|
|
47
|
+
* left-to-right page and the left in a right-to-left one.
|
|
48
|
+
*/
|
|
49
|
+
position?: "bottom-end" | "bottom-start" | "bottom-center";
|
|
50
|
+
class?: string;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
let {
|
|
54
|
+
label,
|
|
55
|
+
icon,
|
|
56
|
+
extended = false,
|
|
57
|
+
href,
|
|
58
|
+
position = "bottom-end",
|
|
59
|
+
class: className = "",
|
|
60
|
+
...restProps
|
|
61
|
+
}: Props = $props();
|
|
62
|
+
|
|
63
|
+
const inShell = isInsideAppShell();
|
|
64
|
+
const Icon = $derived(icon ?? Plus);
|
|
65
|
+
|
|
66
|
+
let host = $state<HTMLElement>();
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The browser scrolls a focused control into view, to the edge of the
|
|
70
|
+
* scroll container: under this button, which lies over that edge. The
|
|
71
|
+
* room it takes, from its top edge to the bottom of the container, is
|
|
72
|
+
* reserved through the helper the bars use, so the largest request wins.
|
|
73
|
+
*/
|
|
74
|
+
$effect(() => {
|
|
75
|
+
const button = host;
|
|
76
|
+
if (!button) return;
|
|
77
|
+
const scroller = findScrollParent(button);
|
|
78
|
+
const reservation = reserveScrollPaddingBottom(scroller ?? document.documentElement);
|
|
79
|
+
const reserve = () => {
|
|
80
|
+
const top = button.getBoundingClientRect().top;
|
|
81
|
+
const bottom = scroller
|
|
82
|
+
? scroller.getBoundingClientRect().bottom
|
|
83
|
+
: document.documentElement.clientHeight;
|
|
84
|
+
// No layout (a test DOM, a hidden button): nothing to keep clear of.
|
|
85
|
+
reservation.set(button.offsetHeight > 0 ? Math.max(0, Math.ceil(bottom - top)) : 0);
|
|
86
|
+
};
|
|
87
|
+
reserve();
|
|
88
|
+
const observer =
|
|
89
|
+
typeof ResizeObserver === "function" ? new ResizeObserver(reserve) : undefined;
|
|
90
|
+
observer?.observe(button);
|
|
91
|
+
if (scroller) observer?.observe(scroller);
|
|
92
|
+
window.addEventListener("resize", reserve);
|
|
93
|
+
return () => {
|
|
94
|
+
observer?.disconnect();
|
|
95
|
+
window.removeEventListener("resize", reserve);
|
|
96
|
+
reservation.release();
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 16px from the edges, in px: a margin that grew with the text size would
|
|
102
|
+
* push the button into the content it floats over. The side clears a
|
|
103
|
+
* notch in landscape, whichever side that is on.
|
|
104
|
+
*/
|
|
105
|
+
const positionClasses = $derived(
|
|
106
|
+
{
|
|
107
|
+
"bottom-end":
|
|
108
|
+
"end-[calc(16px+max(env(safe-area-inset-left,0px),env(safe-area-inset-right,0px)))]",
|
|
109
|
+
"bottom-start":
|
|
110
|
+
"start-[calc(16px+max(env(safe-area-inset-left,0px),env(safe-area-inset-right,0px)))]",
|
|
111
|
+
// Not `left-1/2` with a shift back: that leaves the button half
|
|
112
|
+
// the width to lay its label out in.
|
|
113
|
+
"bottom-center": "inset-x-0 mx-auto w-fit",
|
|
114
|
+
}[position] ??
|
|
115
|
+
"end-[calc(16px+max(env(safe-area-inset-left,0px),env(safe-area-inset-right,0px)))]",
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const classes = $derived(
|
|
119
|
+
cn(
|
|
120
|
+
"focus-ring z-sticky inline-flex cursor-pointer items-center justify-center gap-2 rounded-pill no-underline shadow-lg select-none",
|
|
121
|
+
// Round: 56px in px, like the 24px icon in it, so it does not
|
|
122
|
+
// double with the text size and cover twice the content.
|
|
123
|
+
// Extended: it holds text, so its height follows the text; it
|
|
124
|
+
// grows sideways, and downwards if the label wraps.
|
|
125
|
+
extended ? "min-h-14 min-w-14" : "size-[56px]",
|
|
126
|
+
// Transparent until forced-colors mode draws it: the fill is gone there.
|
|
127
|
+
"border border-transparent",
|
|
128
|
+
"bg-action-primary text-action-primary",
|
|
129
|
+
"transition-[background-color,scale] duration-150 active:scale-[0.96] motion-reduce:transition-none motion-reduce:active:scale-100",
|
|
130
|
+
extended ? "px-5 py-2 text-sm font-medium" : "p-0",
|
|
131
|
+
// Never wider than the screen it floats on, margins included.
|
|
132
|
+
"[max-inline-size:calc(100%_-_32px)]",
|
|
133
|
+
inShell
|
|
134
|
+
? "absolute bottom-[calc(var(--app-shell-bottom-inset,0px)+var(--fab-bottom-offset,0px)+16px)]"
|
|
135
|
+
: "fixed bottom-[calc(env(safe-area-inset-bottom,0px)+var(--fab-bottom-offset,0px)+16px)]",
|
|
136
|
+
positionClasses,
|
|
137
|
+
className,
|
|
138
|
+
),
|
|
139
|
+
);
|
|
140
|
+
</script>
|
|
141
|
+
|
|
142
|
+
{#snippet content()}
|
|
143
|
+
<!-- Decorative: the label names the button, shown or not. -->
|
|
144
|
+
<span class="flex size-[24px] shrink-0" aria-hidden="true">
|
|
145
|
+
<Icon size={24} />
|
|
146
|
+
</span>
|
|
147
|
+
{#if extended}
|
|
148
|
+
<span class="min-w-0 [overflow-wrap:anywhere]">{label}</span>
|
|
149
|
+
{/if}
|
|
150
|
+
{/snippet}
|
|
151
|
+
|
|
152
|
+
{#if href !== undefined}
|
|
153
|
+
<a
|
|
154
|
+
bind:this={host}
|
|
155
|
+
{href}
|
|
156
|
+
class={classes}
|
|
157
|
+
aria-label={extended ? undefined : label}
|
|
158
|
+
data-position={position}
|
|
159
|
+
{...restProps}
|
|
160
|
+
>
|
|
161
|
+
{@render content()}
|
|
162
|
+
</a>
|
|
163
|
+
{:else}
|
|
164
|
+
<button
|
|
165
|
+
bind:this={host}
|
|
166
|
+
type="button"
|
|
167
|
+
class={classes}
|
|
168
|
+
aria-label={extended ? undefined : label}
|
|
169
|
+
data-position={position}
|
|
170
|
+
{...restProps}
|
|
171
|
+
>
|
|
172
|
+
{@render content()}
|
|
173
|
+
</button>
|
|
174
|
+
{/if}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Component } from "svelte";
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
/**
|
|
4
|
+
* The one main thing to do on a screen, as a round button that floats over
|
|
5
|
+
* the content: new quiz, compose, add.
|
|
6
|
+
*
|
|
7
|
+
* Inside an `AppShell` it is placed against the shell, 16px above the tab
|
|
8
|
+
* bar. On its own it is fixed to the screen, 16px above the home
|
|
9
|
+
* indicator; if something else is fixed to the bottom there (a
|
|
10
|
+
* `BottomTabBar` on its own), say how tall it is with
|
|
11
|
+
* `--fab-bottom-offset` on the button or any ancestor:
|
|
12
|
+
*
|
|
13
|
+
* ```svelte
|
|
14
|
+
* <FloatingActionButton
|
|
15
|
+
* label="New quiz"
|
|
16
|
+
* onclick={create}
|
|
17
|
+
* style="--fab-bottom-offset: 65px"
|
|
18
|
+
* />
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* It lies over the content, so the last row would stay under it at the
|
|
22
|
+
* end of the page. Give the content room to scroll clear: `pb-24` (96px)
|
|
23
|
+
* on the list covers the button and its margins.
|
|
24
|
+
*
|
|
25
|
+
* While it is mounted it sets `scroll-padding-bottom` on what scrolls
|
|
26
|
+
* under it (the shell's content, or the page) to the height it takes
|
|
27
|
+
* from the bottom, so a row that takes keyboard focus is scrolled clear
|
|
28
|
+
* of the button and not left half under it.
|
|
29
|
+
*/
|
|
30
|
+
type Props = Omit<HTMLAttributes<HTMLElement>, "class"> & {
|
|
31
|
+
/** What the button does. Its accessible name, and its text when `extended`. */
|
|
32
|
+
label: string;
|
|
33
|
+
/** An icon component, as `@lucide/svelte` icons are. A plus sign by default. */
|
|
34
|
+
icon?: Component<{
|
|
35
|
+
size?: number;
|
|
36
|
+
class?: string;
|
|
37
|
+
}>;
|
|
38
|
+
/** Shows the label as text beside the icon. */
|
|
39
|
+
extended?: boolean;
|
|
40
|
+
/** Makes it a link to this address. Without it, it is a button. */
|
|
41
|
+
href?: string;
|
|
42
|
+
/**
|
|
43
|
+
* The bottom corner it sits in. `bottom-end` is the right in a
|
|
44
|
+
* left-to-right page and the left in a right-to-left one.
|
|
45
|
+
*/
|
|
46
|
+
position?: "bottom-end" | "bottom-start" | "bottom-center";
|
|
47
|
+
class?: string;
|
|
48
|
+
};
|
|
49
|
+
declare const FloatingActionButton: Component<Props, {}, "">;
|
|
50
|
+
type FloatingActionButton = ReturnType<typeof FloatingActionButton>;
|
|
51
|
+
export default FloatingActionButton;
|
|
@@ -1,38 +1,99 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
import { cn } from "../util/cn.js";
|
|
5
|
+
import type { OnFillTone } from "../types/variants.js";
|
|
6
|
+
|
|
7
|
+
/** Semantic heading level — also the default visual size. */
|
|
8
|
+
type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
9
|
+
|
|
10
|
+
type Props = Omit<HTMLAttributes<HTMLHeadingElement>, "class"> & {
|
|
11
|
+
level?: HeadingLevel;
|
|
12
|
+
/**
|
|
13
|
+
* Visual size, when it should differ from the semantic level — an `h2`
|
|
14
|
+
* that needs to look like an `h4` keeps the document outline correct
|
|
15
|
+
* without forcing the wrong tag.
|
|
16
|
+
*/
|
|
17
|
+
size?: HeadingLevel;
|
|
18
|
+
/** Heading text. Ignored when `children` is provided. */
|
|
19
|
+
text?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Text colour. `headline` (the default) is for a page or a card. On a
|
|
22
|
+
* filled block use `inherit` (the block's own colour), `on-brand` or
|
|
23
|
+
* `on-accent`.
|
|
24
|
+
*/
|
|
25
|
+
tone?: "headline" | OnFillTone;
|
|
26
|
+
class?: string;
|
|
27
|
+
children?: Snippet;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
let {
|
|
31
|
+
level = 1,
|
|
32
|
+
size,
|
|
33
|
+
text = "",
|
|
34
|
+
tone = "headline",
|
|
35
|
+
class: className = "",
|
|
36
|
+
children,
|
|
37
|
+
...restProps
|
|
38
|
+
}: Props = $props();
|
|
39
|
+
|
|
40
|
+
const toneClasses: Record<"headline" | OnFillTone, string> = {
|
|
41
|
+
headline: "text-headline",
|
|
42
|
+
inherit: "text-inherit",
|
|
43
|
+
"on-brand": "text-on-brand",
|
|
44
|
+
"on-accent": "text-on-accent",
|
|
19
45
|
};
|
|
20
46
|
|
|
21
|
-
const
|
|
22
|
-
|
|
47
|
+
const visualSize = $derived(size ?? level);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Display sizes tighten as they grow. Untracked 36px type with default
|
|
51
|
+
* 40px leading is the single clearest "this is stock Tailwind" tell;
|
|
52
|
+
* negative tracking and a tighter leading is most of what separates
|
|
53
|
+
* display type from body type set large.
|
|
54
|
+
*/
|
|
55
|
+
const sizeClasses: Record<HeadingLevel, string> = {
|
|
56
|
+
1: "text-4xl leading-10 tracking-[-0.02em] font-bold",
|
|
57
|
+
2: "text-3xl leading-9 tracking-[-0.015em] font-bold",
|
|
58
|
+
3: "text-2xl leading-8 tracking-[-0.01em] font-semibold",
|
|
59
|
+
4: "text-xl leading-7 tracking-[-0.005em] font-semibold",
|
|
60
|
+
5: "text-lg leading-7 font-semibold",
|
|
61
|
+
6: "text-base leading-6 font-semibold",
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const headingClasses = $derived(
|
|
65
|
+
cn(`${toneClasses[tone] ?? toneClasses.headline} ${sizeClasses[visualSize] ?? sizeClasses[6]} ${className}`),
|
|
23
66
|
);
|
|
24
67
|
</script>
|
|
25
68
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
69
|
+
<!--
|
|
70
|
+
The font family comes from `--font-family-heading`, which the theme applies
|
|
71
|
+
to h1–h6 in its base layer and which defaults to `--font-family-sans`. This
|
|
72
|
+
component used to carry its own `font-family: "Nunito Sans"` in a local
|
|
73
|
+
<style> block, which meant a consumer who rebranded the font token got a
|
|
74
|
+
rebranded body and Nunito Sans headings.
|
|
75
|
+
-->
|
|
76
|
+
{#snippet content()}
|
|
77
|
+
{#if children}
|
|
78
|
+
{@render children()}
|
|
79
|
+
{:else}
|
|
80
|
+
{text}
|
|
81
|
+
{/if}
|
|
82
|
+
{/snippet}
|
|
83
|
+
|
|
84
|
+
<!-- One branch per level, not a dynamic element: hydration takes a dynamic
|
|
85
|
+
element out and puts it back, which blurs a control inside it that the user
|
|
86
|
+
had already tabbed to. -->
|
|
87
|
+
{#if level === 1}
|
|
88
|
+
<h1 class={headingClasses} {...restProps}>{@render content()}</h1>
|
|
89
|
+
{:else if level === 2}
|
|
90
|
+
<h2 class={headingClasses} {...restProps}>{@render content()}</h2>
|
|
91
|
+
{:else if level === 3}
|
|
92
|
+
<h3 class={headingClasses} {...restProps}>{@render content()}</h3>
|
|
93
|
+
{:else if level === 4}
|
|
94
|
+
<h4 class={headingClasses} {...restProps}>{@render content()}</h4>
|
|
95
|
+
{:else if level === 5}
|
|
96
|
+
<h5 class={headingClasses} {...restProps}>{@render content()}</h5>
|
|
97
|
+
{:else}
|
|
98
|
+
<h6 class={headingClasses} {...restProps}>{@render content()}</h6>
|
|
99
|
+
{/if}
|
|
@@ -1,7 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
import type { OnFillTone } from "../types/variants.js";
|
|
4
|
+
/** Semantic heading level — also the default visual size. */
|
|
5
|
+
type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
6
|
+
type Props = Omit<HTMLAttributes<HTMLHeadingElement>, "class"> & {
|
|
7
|
+
level?: HeadingLevel;
|
|
8
|
+
/**
|
|
9
|
+
* Visual size, when it should differ from the semantic level — an `h2`
|
|
10
|
+
* that needs to look like an `h4` keeps the document outline correct
|
|
11
|
+
* without forcing the wrong tag.
|
|
12
|
+
*/
|
|
13
|
+
size?: HeadingLevel;
|
|
14
|
+
/** Heading text. Ignored when `children` is provided. */
|
|
15
|
+
text?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Text colour. `headline` (the default) is for a page or a card. On a
|
|
18
|
+
* filled block use `inherit` (the block's own colour), `on-brand` or
|
|
19
|
+
* `on-accent`.
|
|
20
|
+
*/
|
|
21
|
+
tone?: "headline" | OnFillTone;
|
|
22
|
+
class?: string;
|
|
23
|
+
children?: Snippet;
|
|
24
|
+
};
|
|
5
25
|
declare const Heading: import("svelte").Component<Props, {}, "">;
|
|
6
26
|
type Heading = ReturnType<typeof Heading>;
|
|
7
27
|
export default Heading;
|