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,57 @@
|
|
|
1
|
+
/** Types and pure helpers for `Collapsible` and `CollapsibleGroup`. Kept out of the components so they can be tested without a DOM. */
|
|
2
|
+
/** Heading element the default trigger is wrapped in. */
|
|
3
|
+
export type CollapsibleHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
4
|
+
/**
|
|
5
|
+
* First argument of the `trigger` snippet. Spread it on your own `<button>`:
|
|
6
|
+
* it carries the whole wiring, so the button needs nothing else to work.
|
|
7
|
+
*/
|
|
8
|
+
export type CollapsibleTriggerProps = {
|
|
9
|
+
id: string;
|
|
10
|
+
/** Keeps a trigger inside a `<form>` from submitting it. */
|
|
11
|
+
type: "button";
|
|
12
|
+
"aria-expanded": boolean;
|
|
13
|
+
"aria-controls": string;
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
onclick: (event: MouseEvent) => void;
|
|
16
|
+
/** How a `CollapsibleGroup` finds its header buttons for the arrow keys. */
|
|
17
|
+
"data-collapsible-trigger": "";
|
|
18
|
+
};
|
|
19
|
+
/** Second argument of the `trigger` snippet. */
|
|
20
|
+
export interface CollapsibleTriggerState {
|
|
21
|
+
open: boolean;
|
|
22
|
+
disabled: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** What a `Collapsible` hands its group. */
|
|
25
|
+
export interface CollapsibleGroupMember {
|
|
26
|
+
triggerId: string;
|
|
27
|
+
isOpen: () => boolean;
|
|
28
|
+
/** A disabled member keeps its state: the group neither closes it nor counts it. */
|
|
29
|
+
isDisabled: () => boolean;
|
|
30
|
+
close: () => void;
|
|
31
|
+
}
|
|
32
|
+
/** What a member gets back when it joins a group. */
|
|
33
|
+
export interface CollapsibleGroupRegistration {
|
|
34
|
+
/** Removes the member again. */
|
|
35
|
+
unregister: () => void;
|
|
36
|
+
/**
|
|
37
|
+
* True when the member asked to start open in a single-open group that
|
|
38
|
+
* already has an open panel. The member then renders closed from the
|
|
39
|
+
* start, on the server too, instead of opening and being closed again.
|
|
40
|
+
*/
|
|
41
|
+
startClosed: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** What a `CollapsibleGroup` offers the Collapsibles inside it, through context. */
|
|
44
|
+
export interface CollapsibleGroupContext {
|
|
45
|
+
/** False when opening one panel closes the others. */
|
|
46
|
+
readonly multiple: boolean;
|
|
47
|
+
register: (member: CollapsibleGroupMember) => CollapsibleGroupRegistration;
|
|
48
|
+
/** Called whenever a member is open, however it got there. */
|
|
49
|
+
opened: (member: CollapsibleGroupMember) => void;
|
|
50
|
+
}
|
|
51
|
+
/** Context key shared by the two components. */
|
|
52
|
+
export declare const COLLAPSIBLE_GROUP: unique symbol;
|
|
53
|
+
/**
|
|
54
|
+
* Index of the header button an accordion key moves focus to, or `null` when
|
|
55
|
+
* the key is not one of them. Arrow keys wrap, as they do in Tabs and Dropdown.
|
|
56
|
+
*/
|
|
57
|
+
export declare function nextTriggerIndex(key: string, current: number, count: number): number | null;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Types and pure helpers for `Collapsible` and `CollapsibleGroup`. Kept out of the components so they can be tested without a DOM. */
|
|
2
|
+
/** Context key shared by the two components. */
|
|
3
|
+
export const COLLAPSIBLE_GROUP = Symbol("zabi-collapsible-group");
|
|
4
|
+
/**
|
|
5
|
+
* Index of the header button an accordion key moves focus to, or `null` when
|
|
6
|
+
* the key is not one of them. Arrow keys wrap, as they do in Tabs and Dropdown.
|
|
7
|
+
*/
|
|
8
|
+
export function nextTriggerIndex(key, current, count) {
|
|
9
|
+
if (count === 0)
|
|
10
|
+
return null;
|
|
11
|
+
switch (key) {
|
|
12
|
+
case "ArrowDown":
|
|
13
|
+
return (current + 1) % count;
|
|
14
|
+
case "ArrowUp":
|
|
15
|
+
return (current - 1 + count) % count;
|
|
16
|
+
case "Home":
|
|
17
|
+
return 0;
|
|
18
|
+
case "End":
|
|
19
|
+
return count - 1;
|
|
20
|
+
default:
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Public types for `ConfirmDialog`. */
|
|
2
|
+
/** Sets the confirm button's style and the icon beside the message. */
|
|
3
|
+
export type ConfirmDialogVariant = "danger" | "warning" | "info";
|
|
4
|
+
/** How the user backed out: the cancel button, or one of Modal's own ways to close. */
|
|
5
|
+
export type ConfirmDialogCancelReason = "cancel-button" | "escape" | "backdrop" | "close-button";
|
|
6
|
+
/**
|
|
7
|
+
* What `onconfirm` may return. `false`, returned or resolved, keeps the dialog
|
|
8
|
+
* open; anything else closes it. A promise puts the dialog in its loading
|
|
9
|
+
* state until it settles.
|
|
10
|
+
*/
|
|
11
|
+
export type ConfirmDialogResult = void | boolean | Promise<void | boolean>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calendar dates as strings: `YYYY-MM-DD` for a day, `YYYY-MM` for a month,
|
|
3
|
+
* `HH:mm` (or `HH:mm:ss`) for a time of day. The formats a native date or
|
|
4
|
+
* time input reads and writes.
|
|
5
|
+
*
|
|
6
|
+
* A date here is a day on the calendar, not a moment. Nothing in this file
|
|
7
|
+
* goes through a local `Date`: the arithmetic is on the numbers, or on UTC,
|
|
8
|
+
* where every day has 24 hours. So a date never moves to the day before or
|
|
9
|
+
* after because of a time zone, and a day on which the clocks change is a day
|
|
10
|
+
* like any other.
|
|
11
|
+
*
|
|
12
|
+
* Years 0001 to 9999, four digits: within that, two dates compare as strings.
|
|
13
|
+
*/
|
|
14
|
+
export interface DateParts {
|
|
15
|
+
year: number;
|
|
16
|
+
/** 1 to 12. */
|
|
17
|
+
month: number;
|
|
18
|
+
day: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function isLeapYear(year: number): boolean;
|
|
21
|
+
/** Days in a month; `month` is 1 to 12. */
|
|
22
|
+
export declare function daysInMonth(year: number, month: number): number;
|
|
23
|
+
/** The parts of a `YYYY-MM-DD` string, or null when it is not a real date. */
|
|
24
|
+
export declare function parseIsoDate(value: string | null | undefined): DateParts | null;
|
|
25
|
+
export declare function isIsoDate(value: string | null | undefined): value is string;
|
|
26
|
+
/** The parts of a `YYYY-MM` string, or null when it is not a real month. */
|
|
27
|
+
export declare function parseIsoMonth(value: string | null | undefined): {
|
|
28
|
+
year: number;
|
|
29
|
+
month: number;
|
|
30
|
+
} | null;
|
|
31
|
+
export declare function toIsoDate(year: number, month: number, day: number): string;
|
|
32
|
+
export declare function toIsoMonth(year: number, month: number): string;
|
|
33
|
+
/** The month a date is in: `2026-10-06` gives `2026-10`. Null for a string that is not a date. */
|
|
34
|
+
export declare function monthOf(date: string | null | undefined): string | null;
|
|
35
|
+
/** The date `count` days later (earlier when negative), or null outside years 1 to 9999. */
|
|
36
|
+
export declare function addDays(date: string, count: number): string | null;
|
|
37
|
+
/** The month `count` months later (earlier when negative), or null outside years 1 to 9999. */
|
|
38
|
+
export declare function addMonthsToMonth(month: string, count: number): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* The same day of the month `count` months later. A day the target month does
|
|
41
|
+
* not have becomes its last one: 31 January plus a month is 28 or 29 February.
|
|
42
|
+
*/
|
|
43
|
+
export declare function addMonths(date: string, count: number): string | null;
|
|
44
|
+
/** Day of the week, 0 for Sunday to 6 for Saturday. -1 for a string that is not a date. */
|
|
45
|
+
export declare function weekdayOf(date: string): number;
|
|
46
|
+
/** A whole number from 0 to 6 for the first day of the week; anything else is Monday. */
|
|
47
|
+
export declare function normaliseWeekStart(weekStartsOn: number | undefined): number;
|
|
48
|
+
/** The first day of the week a date is in. */
|
|
49
|
+
export declare function startOfWeek(date: string, weekStartsOn?: number): string | null;
|
|
50
|
+
/** The last day of the week a date is in. */
|
|
51
|
+
export declare function endOfWeek(date: string, weekStartsOn?: number): string | null;
|
|
52
|
+
/**
|
|
53
|
+
* The weeks of a month, each seven entries from the first day of the week. A
|
|
54
|
+
* day of the month is its ISO date; a place before the 1st or after the last
|
|
55
|
+
* day is null. There are as many weeks as the month touches: four (a
|
|
56
|
+
* 28-day February that starts on the first day of the week), five or six.
|
|
57
|
+
*/
|
|
58
|
+
export declare function monthGrid(month: string, weekStartsOn?: number): (string | null)[][];
|
|
59
|
+
/** The seven days of the week as numbers (0 for Sunday), from the first day of the week. */
|
|
60
|
+
export declare function weekdayOrder(weekStartsOn?: number): number[];
|
|
61
|
+
/**
|
|
62
|
+
* Today where the user is, as `YYYY-MM-DD`. This is the one place that reads
|
|
63
|
+
* the local clock: "today" is a local idea. Call it in the browser; on a
|
|
64
|
+
* server it is the server's day.
|
|
65
|
+
*/
|
|
66
|
+
export declare function todayIso(now?: Date): string;
|
|
67
|
+
/** Today in UTC: the same on a server and in a browser at the same moment. */
|
|
68
|
+
export declare function todayIsoUtc(now?: Date): string;
|
|
69
|
+
/** A date held between `min` and `max`, either of which may be missing or invalid. */
|
|
70
|
+
export declare function clampDate(date: string, min?: string | null, max?: string | null): string;
|
|
71
|
+
/**
|
|
72
|
+
* A date for reading: `formatDate("2026-10-06", "sv")` is "6 okt. 2026",
|
|
73
|
+
* `formatDate("2026-10-06", "en-GB")` is "6 Oct 2026".
|
|
74
|
+
*
|
|
75
|
+
* `value` is `YYYY-MM-DD`, what a DateField holds. The day shown is always
|
|
76
|
+
* the day in the string: it does not depend on the time zone of the browser
|
|
77
|
+
* or the server. An empty or invalid value gives an empty string.
|
|
78
|
+
*
|
|
79
|
+
* Pass the `locale` of the page. Without it the runtime's own is used, which
|
|
80
|
+
* on a server is the server's and may differ from the reader's, so text
|
|
81
|
+
* rendered on the server and again in the browser may not match.
|
|
82
|
+
*
|
|
83
|
+
* `options` are those of `Intl.DateTimeFormat`; `timeZone` is not one you can
|
|
84
|
+
* set here.
|
|
85
|
+
*/
|
|
86
|
+
export declare function formatDate(value: string | null | undefined, locale?: string | string[], options?: Intl.DateTimeFormatOptions): string;
|
|
87
|
+
/**
|
|
88
|
+
* A time of day for reading: `formatTime("19:00", "sv")` is "19:00",
|
|
89
|
+
* `formatTime("19:00", "en-US")` is "7:00 PM".
|
|
90
|
+
*
|
|
91
|
+
* `value` is `HH:mm` or `HH:mm:ss`, what a TimeField holds. It is a time on
|
|
92
|
+
* the clock, with no zone: nothing shifts it. An empty or invalid value gives
|
|
93
|
+
* an empty string. `locale` and `options` as for `formatDate`.
|
|
94
|
+
*/
|
|
95
|
+
export declare function formatTime(value: string | null | undefined, locale?: string | string[], options?: Intl.DateTimeFormatOptions): string;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calendar dates as strings: `YYYY-MM-DD` for a day, `YYYY-MM` for a month,
|
|
3
|
+
* `HH:mm` (or `HH:mm:ss`) for a time of day. The formats a native date or
|
|
4
|
+
* time input reads and writes.
|
|
5
|
+
*
|
|
6
|
+
* A date here is a day on the calendar, not a moment. Nothing in this file
|
|
7
|
+
* goes through a local `Date`: the arithmetic is on the numbers, or on UTC,
|
|
8
|
+
* where every day has 24 hours. So a date never moves to the day before or
|
|
9
|
+
* after because of a time zone, and a day on which the clocks change is a day
|
|
10
|
+
* like any other.
|
|
11
|
+
*
|
|
12
|
+
* Years 0001 to 9999, four digits: within that, two dates compare as strings.
|
|
13
|
+
*/
|
|
14
|
+
const ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
15
|
+
const ISO_MONTH = /^(\d{4})-(\d{2})$/;
|
|
16
|
+
const ISO_TIME = /^(\d{2}):(\d{2})(?::(\d{2})(?:\.\d+)?)?$/;
|
|
17
|
+
const pad = (value, length = 2) => String(value).padStart(length, "0");
|
|
18
|
+
export function isLeapYear(year) {
|
|
19
|
+
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
|
20
|
+
}
|
|
21
|
+
/** Days in a month; `month` is 1 to 12. */
|
|
22
|
+
export function daysInMonth(year, month) {
|
|
23
|
+
if (month === 2)
|
|
24
|
+
return isLeapYear(year) ? 29 : 28;
|
|
25
|
+
return [4, 6, 9, 11].includes(month) ? 30 : 31;
|
|
26
|
+
}
|
|
27
|
+
/** The parts of a `YYYY-MM-DD` string, or null when it is not a real date. */
|
|
28
|
+
export function parseIsoDate(value) {
|
|
29
|
+
const match = ISO_DATE.exec(value ?? "");
|
|
30
|
+
if (!match)
|
|
31
|
+
return null;
|
|
32
|
+
const year = Number(match[1]);
|
|
33
|
+
const month = Number(match[2]);
|
|
34
|
+
const day = Number(match[3]);
|
|
35
|
+
if (year < 1 || month < 1 || month > 12 || day < 1 || day > daysInMonth(year, month))
|
|
36
|
+
return null;
|
|
37
|
+
return { year, month, day };
|
|
38
|
+
}
|
|
39
|
+
export function isIsoDate(value) {
|
|
40
|
+
return parseIsoDate(value) !== null;
|
|
41
|
+
}
|
|
42
|
+
/** The parts of a `YYYY-MM` string, or null when it is not a real month. */
|
|
43
|
+
export function parseIsoMonth(value) {
|
|
44
|
+
const match = ISO_MONTH.exec(value ?? "");
|
|
45
|
+
if (!match)
|
|
46
|
+
return null;
|
|
47
|
+
const year = Number(match[1]);
|
|
48
|
+
const month = Number(match[2]);
|
|
49
|
+
if (year < 1 || month < 1 || month > 12)
|
|
50
|
+
return null;
|
|
51
|
+
return { year, month };
|
|
52
|
+
}
|
|
53
|
+
export function toIsoDate(year, month, day) {
|
|
54
|
+
return `${pad(year, 4)}-${pad(month)}-${pad(day)}`;
|
|
55
|
+
}
|
|
56
|
+
export function toIsoMonth(year, month) {
|
|
57
|
+
return `${pad(year, 4)}-${pad(month)}`;
|
|
58
|
+
}
|
|
59
|
+
/** The month a date is in: `2026-10-06` gives `2026-10`. Null for a string that is not a date. */
|
|
60
|
+
export function monthOf(date) {
|
|
61
|
+
const parts = parseIsoDate(date);
|
|
62
|
+
return parts ? toIsoMonth(parts.year, parts.month) : null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A UTC timestamp for the day. `Date.UTC` reads a year under 100 as 19xx, so
|
|
66
|
+
* the year is set afterwards.
|
|
67
|
+
*/
|
|
68
|
+
function utcOf({ year, month, day }) {
|
|
69
|
+
const date = new Date(Date.UTC(2000, month - 1, day));
|
|
70
|
+
date.setUTCFullYear(year);
|
|
71
|
+
return date;
|
|
72
|
+
}
|
|
73
|
+
function isoOfUtc(date) {
|
|
74
|
+
return toIsoDate(date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate());
|
|
75
|
+
}
|
|
76
|
+
const inRange = (year) => year >= 1 && year <= 9999;
|
|
77
|
+
/** The date `count` days later (earlier when negative), or null outside years 1 to 9999. */
|
|
78
|
+
export function addDays(date, count) {
|
|
79
|
+
const parts = parseIsoDate(date);
|
|
80
|
+
if (!parts)
|
|
81
|
+
return null;
|
|
82
|
+
const moved = utcOf(parts);
|
|
83
|
+
moved.setUTCDate(moved.getUTCDate() + count);
|
|
84
|
+
return inRange(moved.getUTCFullYear()) ? isoOfUtc(moved) : null;
|
|
85
|
+
}
|
|
86
|
+
/** The month `count` months later (earlier when negative), or null outside years 1 to 9999. */
|
|
87
|
+
export function addMonthsToMonth(month, count) {
|
|
88
|
+
const parts = parseIsoMonth(month);
|
|
89
|
+
if (!parts)
|
|
90
|
+
return null;
|
|
91
|
+
const index = parts.year * 12 + (parts.month - 1) + count;
|
|
92
|
+
const year = Math.floor(index / 12);
|
|
93
|
+
return inRange(year) ? toIsoMonth(year, (index % 12 + 12) % 12 + 1) : null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The same day of the month `count` months later. A day the target month does
|
|
97
|
+
* not have becomes its last one: 31 January plus a month is 28 or 29 February.
|
|
98
|
+
*/
|
|
99
|
+
export function addMonths(date, count) {
|
|
100
|
+
const parts = parseIsoDate(date);
|
|
101
|
+
if (!parts)
|
|
102
|
+
return null;
|
|
103
|
+
const target = parseIsoMonth(addMonthsToMonth(toIsoMonth(parts.year, parts.month), count));
|
|
104
|
+
if (!target)
|
|
105
|
+
return null;
|
|
106
|
+
const day = Math.min(parts.day, daysInMonth(target.year, target.month));
|
|
107
|
+
return toIsoDate(target.year, target.month, day);
|
|
108
|
+
}
|
|
109
|
+
/** Day of the week, 0 for Sunday to 6 for Saturday. -1 for a string that is not a date. */
|
|
110
|
+
export function weekdayOf(date) {
|
|
111
|
+
const parts = parseIsoDate(date);
|
|
112
|
+
return parts ? utcOf(parts).getUTCDay() : -1;
|
|
113
|
+
}
|
|
114
|
+
/** A whole number from 0 to 6 for the first day of the week; anything else is Monday. */
|
|
115
|
+
export function normaliseWeekStart(weekStartsOn) {
|
|
116
|
+
return Number.isInteger(weekStartsOn) && weekStartsOn >= 0 && weekStartsOn <= 6
|
|
117
|
+
? weekStartsOn
|
|
118
|
+
: 1;
|
|
119
|
+
}
|
|
120
|
+
/** The first day of the week a date is in. */
|
|
121
|
+
export function startOfWeek(date, weekStartsOn = 1) {
|
|
122
|
+
const weekday = weekdayOf(date);
|
|
123
|
+
if (weekday === -1)
|
|
124
|
+
return null;
|
|
125
|
+
return addDays(date, -((weekday - normaliseWeekStart(weekStartsOn) + 7) % 7));
|
|
126
|
+
}
|
|
127
|
+
/** The last day of the week a date is in. */
|
|
128
|
+
export function endOfWeek(date, weekStartsOn = 1) {
|
|
129
|
+
const start = startOfWeek(date, weekStartsOn);
|
|
130
|
+
return start ? addDays(start, 6) : null;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* The weeks of a month, each seven entries from the first day of the week. A
|
|
134
|
+
* day of the month is its ISO date; a place before the 1st or after the last
|
|
135
|
+
* day is null. There are as many weeks as the month touches: four (a
|
|
136
|
+
* 28-day February that starts on the first day of the week), five or six.
|
|
137
|
+
*/
|
|
138
|
+
export function monthGrid(month, weekStartsOn = 1) {
|
|
139
|
+
const parts = parseIsoMonth(month);
|
|
140
|
+
if (!parts)
|
|
141
|
+
return [];
|
|
142
|
+
const first = toIsoDate(parts.year, parts.month, 1);
|
|
143
|
+
const lead = (weekdayOf(first) - normaliseWeekStart(weekStartsOn) + 7) % 7;
|
|
144
|
+
const days = daysInMonth(parts.year, parts.month);
|
|
145
|
+
const cells = Array.from({ length: lead }, () => null);
|
|
146
|
+
for (let day = 1; day <= days; day += 1)
|
|
147
|
+
cells.push(toIsoDate(parts.year, parts.month, day));
|
|
148
|
+
while (cells.length % 7 !== 0)
|
|
149
|
+
cells.push(null);
|
|
150
|
+
const weeks = [];
|
|
151
|
+
for (let index = 0; index < cells.length; index += 7)
|
|
152
|
+
weeks.push(cells.slice(index, index + 7));
|
|
153
|
+
return weeks;
|
|
154
|
+
}
|
|
155
|
+
/** The seven days of the week as numbers (0 for Sunday), from the first day of the week. */
|
|
156
|
+
export function weekdayOrder(weekStartsOn = 1) {
|
|
157
|
+
const start = normaliseWeekStart(weekStartsOn);
|
|
158
|
+
return Array.from({ length: 7 }, (_, index) => (start + index) % 7);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Today where the user is, as `YYYY-MM-DD`. This is the one place that reads
|
|
162
|
+
* the local clock: "today" is a local idea. Call it in the browser; on a
|
|
163
|
+
* server it is the server's day.
|
|
164
|
+
*/
|
|
165
|
+
export function todayIso(now = new Date()) {
|
|
166
|
+
return toIsoDate(now.getFullYear(), now.getMonth() + 1, now.getDate());
|
|
167
|
+
}
|
|
168
|
+
/** Today in UTC: the same on a server and in a browser at the same moment. */
|
|
169
|
+
export function todayIsoUtc(now = new Date()) {
|
|
170
|
+
return isoOfUtc(now);
|
|
171
|
+
}
|
|
172
|
+
/** A date held between `min` and `max`, either of which may be missing or invalid. */
|
|
173
|
+
export function clampDate(date, min, max) {
|
|
174
|
+
if (isIsoDate(min) && date < min)
|
|
175
|
+
return min;
|
|
176
|
+
if (isIsoDate(max) && date > max)
|
|
177
|
+
return max;
|
|
178
|
+
return date;
|
|
179
|
+
}
|
|
180
|
+
function formatter(locale, options) {
|
|
181
|
+
try {
|
|
182
|
+
// Formatted in UTC, where the value was put: the reader's zone never moves it.
|
|
183
|
+
return new Intl.DateTimeFormat(locale || undefined, { ...options, timeZone: "UTC" });
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
// An unknown locale tag or option: fall back to the runtime's own.
|
|
187
|
+
try {
|
|
188
|
+
return new Intl.DateTimeFormat(undefined, { ...options, timeZone: "UTC" });
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* A date for reading: `formatDate("2026-10-06", "sv")` is "6 okt. 2026",
|
|
197
|
+
* `formatDate("2026-10-06", "en-GB")` is "6 Oct 2026".
|
|
198
|
+
*
|
|
199
|
+
* `value` is `YYYY-MM-DD`, what a DateField holds. The day shown is always
|
|
200
|
+
* the day in the string: it does not depend on the time zone of the browser
|
|
201
|
+
* or the server. An empty or invalid value gives an empty string.
|
|
202
|
+
*
|
|
203
|
+
* Pass the `locale` of the page. Without it the runtime's own is used, which
|
|
204
|
+
* on a server is the server's and may differ from the reader's, so text
|
|
205
|
+
* rendered on the server and again in the browser may not match.
|
|
206
|
+
*
|
|
207
|
+
* `options` are those of `Intl.DateTimeFormat`; `timeZone` is not one you can
|
|
208
|
+
* set here.
|
|
209
|
+
*/
|
|
210
|
+
export function formatDate(value, locale, options = { day: "numeric", month: "short", year: "numeric" }) {
|
|
211
|
+
const parts = parseIsoDate(value);
|
|
212
|
+
if (!parts)
|
|
213
|
+
return "";
|
|
214
|
+
return formatter(locale, options)?.format(utcOf(parts)) ?? value;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* A time of day for reading: `formatTime("19:00", "sv")` is "19:00",
|
|
218
|
+
* `formatTime("19:00", "en-US")` is "7:00 PM".
|
|
219
|
+
*
|
|
220
|
+
* `value` is `HH:mm` or `HH:mm:ss`, what a TimeField holds. It is a time on
|
|
221
|
+
* the clock, with no zone: nothing shifts it. An empty or invalid value gives
|
|
222
|
+
* an empty string. `locale` and `options` as for `formatDate`.
|
|
223
|
+
*/
|
|
224
|
+
export function formatTime(value, locale,
|
|
225
|
+
// The locale's own short time: "07:05" in Swedish, "7:05 AM" in American English.
|
|
226
|
+
options = { timeStyle: "short" }) {
|
|
227
|
+
const match = ISO_TIME.exec(value ?? "");
|
|
228
|
+
if (!match)
|
|
229
|
+
return "";
|
|
230
|
+
const hours = Number(match[1]);
|
|
231
|
+
const minutes = Number(match[2]);
|
|
232
|
+
const seconds = Number(match[3] ?? "0");
|
|
233
|
+
if (hours > 23 || minutes > 59 || seconds > 59)
|
|
234
|
+
return "";
|
|
235
|
+
const moment = new Date(Date.UTC(2000, 0, 1, hours, minutes, seconds));
|
|
236
|
+
return formatter(locale, options)?.format(moment) ?? value;
|
|
237
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Public types and pure helpers for `Drawer`. */
|
|
2
|
+
/**
|
|
3
|
+
* The edge the drawer is anchored to. `left` and `right` are physical and stay
|
|
4
|
+
* put in a right-to-left page; `start` and `end` follow the writing direction.
|
|
5
|
+
*/
|
|
6
|
+
export type DrawerSide = "left" | "right" | "start" | "end";
|
|
7
|
+
/** Panel width on wide screens. On a phone the panel is never wider than the screen. */
|
|
8
|
+
export type DrawerSize = "sm" | "md" | "lg";
|
|
9
|
+
/** What the user did to close the drawer. The same values Modal reports. */
|
|
10
|
+
export type DrawerCloseReason = "escape" | "backdrop" | "close-button";
|
|
11
|
+
/** The physical edge a side resolves to, given the writing direction. */
|
|
12
|
+
export declare function resolveDrawerEdge(side: DrawerSide, rtl: boolean): "left" | "right";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Public types and pure helpers for `Drawer`. */
|
|
2
|
+
/** The physical edge a side resolves to, given the writing direction. */
|
|
3
|
+
export function resolveDrawerEdge(side, rtl) {
|
|
4
|
+
if (side === "left" || side === "right")
|
|
5
|
+
return side;
|
|
6
|
+
return (side === "start") !== rtl ? "left" : "right";
|
|
7
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Component } from "svelte";
|
|
2
|
+
/** An icon component, as `@lucide/svelte` icons are. */
|
|
3
|
+
export type DropdownItemIcon = Component<{
|
|
4
|
+
size?: number;
|
|
5
|
+
class?: string;
|
|
6
|
+
}>;
|
|
7
|
+
export type DropdownItemTone = "default" | "danger";
|
|
8
|
+
/** One entry of Dropdown's `options`. */
|
|
9
|
+
export interface DropdownOption {
|
|
10
|
+
value: string | number;
|
|
11
|
+
label: string;
|
|
12
|
+
/**
|
|
13
|
+
* A disabled item stays focusable, so the arrow keys still reach it and a
|
|
14
|
+
* screen reader can read why it is unavailable; it cannot be chosen.
|
|
15
|
+
*/
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/** Rendered before the label, at 16px. Decorative: the label names the item. */
|
|
18
|
+
icon?: DropdownItemIcon;
|
|
19
|
+
/** `danger` for a destructive action such as Delete. */
|
|
20
|
+
tone?: DropdownItemTone;
|
|
21
|
+
/** Second line under the label, e.g. why the item is disabled. */
|
|
22
|
+
description?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* How a Dropdown's menu is shown: `popover` under its trigger, `sheet` in a
|
|
26
|
+
* BottomSheet, or `auto`: a sheet on a phone, the pop-over everywhere else.
|
|
27
|
+
*/
|
|
28
|
+
export type DropdownPresentation = "auto" | "popover" | "sheet";
|
|
29
|
+
/**
|
|
30
|
+
* A phone, for `auto`: a touch screen (`pointer: coarse`) narrower than the
|
|
31
|
+
* `sm` breakpoint. A tablet has the room for a pop-over under its trigger,
|
|
32
|
+
* and a narrow window with a mouse has the precision for one.
|
|
33
|
+
*/
|
|
34
|
+
export declare const SHEET_MEDIA_QUERY = "(pointer: coarse) and (max-width: 639.98px)";
|
|
35
|
+
/**
|
|
36
|
+
* Whether a menu asked for as `presentation` opens in a sheet right now.
|
|
37
|
+
* Read when the menu opens, in the browser: on the server it is never a sheet,
|
|
38
|
+
* so what is rendered before anyone touches the control is the same everywhere.
|
|
39
|
+
*/
|
|
40
|
+
export declare function opensAsSheet(presentation: DropdownPresentation): boolean;
|
|
41
|
+
/** What a Dropdown tells the items inside it. */
|
|
42
|
+
export interface DropdownContext {
|
|
43
|
+
/** `option` inside a listbox, `menuitem` inside a menu. */
|
|
44
|
+
readonly itemRole: "menuitem" | "option";
|
|
45
|
+
}
|
|
46
|
+
export declare const DROPDOWN_CONTEXT_KEY: unique symbol;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A phone, for `auto`: a touch screen (`pointer: coarse`) narrower than the
|
|
3
|
+
* `sm` breakpoint. A tablet has the room for a pop-over under its trigger,
|
|
4
|
+
* and a narrow window with a mouse has the precision for one.
|
|
5
|
+
*/
|
|
6
|
+
export const SHEET_MEDIA_QUERY = "(pointer: coarse) and (max-width: 639.98px)";
|
|
7
|
+
/**
|
|
8
|
+
* Whether a menu asked for as `presentation` opens in a sheet right now.
|
|
9
|
+
* Read when the menu opens, in the browser: on the server it is never a sheet,
|
|
10
|
+
* so what is rendered before anyone touches the control is the same everywhere.
|
|
11
|
+
*/
|
|
12
|
+
export function opensAsSheet(presentation) {
|
|
13
|
+
if (presentation === "sheet")
|
|
14
|
+
return true;
|
|
15
|
+
if (presentation !== "auto")
|
|
16
|
+
return false;
|
|
17
|
+
return (typeof window !== "undefined" &&
|
|
18
|
+
typeof window.matchMedia === "function" &&
|
|
19
|
+
window.matchMedia(SHEET_MEDIA_QUERY).matches);
|
|
20
|
+
}
|
|
21
|
+
export const DROPDOWN_CONTEXT_KEY = Symbol("dropdown");
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What Input, Textarea and Select share about the text under a field, and
|
|
3
|
+
* DateField and TimeField through Input. Kept in one place so the four cannot
|
|
4
|
+
* drift: which message shows, in which variant, and what the control is
|
|
5
|
+
* described by.
|
|
6
|
+
*/
|
|
7
|
+
import type { SemanticVariant } from "../types/variants.js";
|
|
8
|
+
export interface FieldMessageInput {
|
|
9
|
+
variant?: SemanticVariant;
|
|
10
|
+
message?: string;
|
|
11
|
+
hint?: string;
|
|
12
|
+
error?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface FieldMessageState {
|
|
15
|
+
/** The variant the control is drawn in: `error` whenever there is an error. */
|
|
16
|
+
variant: SemanticVariant;
|
|
17
|
+
/** The text of the status message: the error, or else `message`. */
|
|
18
|
+
message: string;
|
|
19
|
+
/** Whether the status message is rendered. A `message` without a variant is not. */
|
|
20
|
+
showMessage: boolean;
|
|
21
|
+
/** Whether the hint is rendered. */
|
|
22
|
+
showHint: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* `error` wins over `variant` and `message`: it sets the error variant and is
|
|
26
|
+
* the message. Without it, `message` shows in a `success`, `warning` or
|
|
27
|
+
* `error` variant, as it always has, and not in `default`: text for a field
|
|
28
|
+
* that is neither is a `hint`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function fieldMessageState({ variant, message, hint, error, }: FieldMessageInput): FieldMessageState;
|
|
31
|
+
export declare const fieldHintId: (fieldId: string) => string;
|
|
32
|
+
export declare const fieldMessageId: (fieldId: string) => string;
|
|
33
|
+
/**
|
|
34
|
+
* The ids a control is described by: the caller's own (a FormField around the
|
|
35
|
+
* field, say), then the hint, then the status message. Only ids of elements
|
|
36
|
+
* that are rendered; `undefined` when there are none, so no empty attribute.
|
|
37
|
+
*/
|
|
38
|
+
export declare function fieldDescribedBy(fieldId: string, state: Pick<FieldMessageState, "showMessage" | "showHint">, own?: string | null): string | undefined;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What Input, Textarea and Select share about the text under a field, and
|
|
3
|
+
* DateField and TimeField through Input. Kept in one place so the four cannot
|
|
4
|
+
* drift: which message shows, in which variant, and what the control is
|
|
5
|
+
* described by.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* `error` wins over `variant` and `message`: it sets the error variant and is
|
|
9
|
+
* the message. Without it, `message` shows in a `success`, `warning` or
|
|
10
|
+
* `error` variant, as it always has, and not in `default`: text for a field
|
|
11
|
+
* that is neither is a `hint`.
|
|
12
|
+
*/
|
|
13
|
+
export function fieldMessageState({ variant = "default", message = "", hint = "", error = "", }) {
|
|
14
|
+
const resolvedVariant = error ? "error" : variant;
|
|
15
|
+
const resolvedMessage = error || message;
|
|
16
|
+
return {
|
|
17
|
+
variant: resolvedVariant,
|
|
18
|
+
message: resolvedMessage,
|
|
19
|
+
showMessage: !!resolvedMessage && resolvedVariant !== "default",
|
|
20
|
+
showHint: !!hint,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export const fieldHintId = (fieldId) => `${fieldId}-hint`;
|
|
24
|
+
export const fieldMessageId = (fieldId) => `${fieldId}-message`;
|
|
25
|
+
/**
|
|
26
|
+
* The ids a control is described by: the caller's own (a FormField around the
|
|
27
|
+
* field, say), then the hint, then the status message. Only ids of elements
|
|
28
|
+
* that are rendered; `undefined` when there are none, so no empty attribute.
|
|
29
|
+
*/
|
|
30
|
+
export function fieldDescribedBy(fieldId, state, own) {
|
|
31
|
+
return ([
|
|
32
|
+
own,
|
|
33
|
+
state.showHint ? fieldHintId(fieldId) : "",
|
|
34
|
+
state.showMessage ? fieldMessageId(fieldId) : "",
|
|
35
|
+
]
|
|
36
|
+
.filter(Boolean)
|
|
37
|
+
.join(" ") || undefined);
|
|
38
|
+
}
|