zabi-components 8.0.0 → 9.0.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 +2935 -0
- package/README.md +243 -10
- package/THEME.md +162 -332
- package/THEMING.md +1419 -259
- package/dist/atoms/ActionPanel.svelte +15 -5
- package/dist/atoms/Avatar.svelte +120 -0
- package/dist/atoms/Avatar.svelte.d.ts +46 -0
- package/dist/atoms/Badge.svelte +71 -13
- package/dist/atoms/Badge.svelte.d.ts +8 -2
- package/dist/atoms/Block.svelte +74 -0
- package/dist/atoms/Block.svelte.d.ts +29 -0
- package/dist/atoms/Button.svelte +217 -30
- package/dist/atoms/Button.svelte.d.ts +33 -4
- package/dist/atoms/Card.svelte +182 -26
- package/dist/atoms/Card.svelte.d.ts +55 -3
- package/dist/atoms/CardHeader.svelte +16 -4
- package/dist/atoms/Checkbox.svelte +81 -21
- package/dist/atoms/Checkbox.svelte.d.ts +31 -2
- package/dist/atoms/Chip.svelte +351 -0
- package/dist/atoms/Chip.svelte.d.ts +57 -0
- package/dist/atoms/CodeBlock.svelte +20 -2
- package/dist/atoms/CodeBlock.svelte.d.ts +4 -0
- package/dist/atoms/CodeField.svelte +385 -0
- package/dist/atoms/CodeField.svelte.d.ts +61 -0
- package/dist/atoms/ColorPicker.svelte +260 -49
- package/dist/atoms/ColorPicker.svelte.d.ts +3 -0
- package/dist/atoms/Container.svelte +16 -8
- package/dist/atoms/DateField.svelte +145 -0
- package/dist/atoms/DateField.svelte.d.ts +81 -0
- package/dist/atoms/FieldMessages.svelte +69 -0
- package/dist/atoms/FieldMessages.svelte.d.ts +23 -0
- package/dist/atoms/FloatingActionButton.svelte +176 -0
- package/dist/atoms/FloatingActionButton.svelte.d.ts +51 -0
- package/dist/atoms/Heading.svelte +63 -5
- package/dist/atoms/Heading.svelte.d.ts +14 -0
- package/dist/atoms/IconButton.svelte +294 -26
- package/dist/atoms/IconButton.svelte.d.ts +62 -4
- package/dist/atoms/Input.svelte +259 -53
- package/dist/atoms/Input.svelte.d.ts +33 -2
- package/dist/atoms/List.svelte +5 -1
- package/dist/atoms/ListItem.svelte +70 -13
- package/dist/atoms/ListItem.svelte.d.ts +11 -0
- package/dist/atoms/PickerField.svelte +239 -0
- package/dist/atoms/PickerField.svelte.d.ts +67 -0
- package/dist/atoms/Progress.svelte +99 -19
- package/dist/atoms/Progress.svelte.d.ts +15 -1
- package/dist/atoms/Radio.svelte +51 -3
- package/dist/atoms/Radio.svelte.d.ts +30 -2
- package/dist/atoms/Rating.svelte +620 -0
- package/dist/atoms/Rating.svelte.d.ts +77 -0
- package/dist/atoms/Select.svelte +438 -98
- package/dist/atoms/Select.svelte.d.ts +61 -3
- package/dist/atoms/SelectionControl.svelte +193 -23
- package/dist/atoms/SelectionControl.svelte.d.ts +29 -3
- package/dist/atoms/Skeleton.svelte +114 -18
- package/dist/atoms/Skeleton.svelte.d.ts +30 -3
- package/dist/atoms/SkeletonGroup.svelte +43 -0
- package/dist/atoms/SkeletonGroup.svelte.d.ts +20 -0
- package/dist/atoms/Slider.svelte +344 -0
- package/dist/atoms/Slider.svelte.d.ts +40 -0
- package/dist/atoms/Sparkline.svelte +109 -0
- package/dist/atoms/Sparkline.svelte.d.ts +27 -0
- package/dist/atoms/SpeechBubble.svelte +187 -0
- package/dist/atoms/SpeechBubble.svelte.d.ts +33 -0
- package/dist/atoms/Spinner.svelte +57 -0
- package/dist/atoms/Spinner.svelte.d.ts +19 -0
- package/dist/atoms/Stat.svelte +72 -0
- package/dist/atoms/Stat.svelte.d.ts +19 -0
- package/dist/atoms/Table.svelte +151 -6
- package/dist/atoms/Table.svelte.d.ts +15 -3
- package/dist/atoms/TemporalField.svelte +472 -0
- package/dist/atoms/TemporalField.svelte.d.ts +48 -0
- package/dist/atoms/Text.svelte +23 -11
- package/dist/atoms/Text.svelte.d.ts +6 -3
- package/dist/atoms/Textarea.svelte +150 -44
- package/dist/atoms/Textarea.svelte.d.ts +35 -2
- package/dist/atoms/ThemeToggle.svelte +223 -44
- package/dist/atoms/ThemeToggle.svelte.d.ts +26 -3
- package/dist/atoms/TimeColumn.svelte +150 -0
- package/dist/atoms/TimeColumn.svelte.d.ts +25 -0
- package/dist/atoms/TimeField.svelte +151 -0
- package/dist/atoms/TimeField.svelte.d.ts +85 -0
- package/dist/atoms/Toast.svelte +22 -8
- package/dist/atoms/Toast.svelte.d.ts +2 -0
- package/dist/atoms/Toggle.svelte +98 -14
- package/dist/atoms/Toggle.svelte.d.ts +26 -2
- package/dist/atoms/Tooltip.svelte +528 -24
- package/dist/atoms/Tooltip.svelte.d.ts +18 -0
- package/dist/atoms/ZabiStringsProvider.svelte +45 -0
- package/dist/atoms/ZabiStringsProvider.svelte.d.ts +27 -0
- package/dist/atoms/index.d.ts +38 -0
- package/dist/atoms/index.js +29 -0
- package/dist/atoms/selection-control.styles.d.ts +47 -5
- package/dist/atoms/selection-control.styles.js +52 -10
- package/dist/components/atoms/index.d.ts +38 -0
- package/dist/components/atoms/index.d.ts.map +1 -1
- package/dist/components/atoms/selection-control.styles.d.ts +47 -5
- package/dist/components/atoms/selection-control.styles.d.ts.map +1 -1
- package/dist/components/index.d.ts +104 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/map.d.ts +11 -0
- package/dist/components/map.d.ts.map +1 -0
- package/dist/components/molecules/index.d.ts +51 -0
- package/dist/components/molecules/index.d.ts.map +1 -1
- package/dist/components/molecules/toast-store.d.ts +83 -7
- package/dist/components/molecules/toast-store.d.ts.map +1 -1
- package/dist/components/organisms/index.d.ts +10 -0
- package/dist/components/organisms/index.d.ts.map +1 -1
- package/dist/components/types/variants.d.ts +24 -1
- package/dist/components/types/variants.d.ts.map +1 -1
- package/dist/components/util/app-shell.d.ts +79 -0
- package/dist/components/util/app-shell.d.ts.map +1 -0
- package/dist/components/util/avatar.d.ts +39 -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 +41 -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/chart.d.ts +140 -0
- package/dist/components/util/chart.d.ts.map +1 -0
- package/dist/components/util/chip.d.ts +66 -0
- package/dist/components/util/chip.d.ts.map +1 -0
- package/dist/components/util/cn.d.ts.map +1 -1
- package/dist/components/util/code-field.d.ts +63 -0
- package/dist/components/util/code-field.d.ts.map +1 -0
- package/dist/components/util/collapsible.d.ts +64 -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/display-voice.d.ts +10 -0
- package/dist/components/util/display-voice.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-control.d.ts +30 -0
- package/dist/components/util/field-control.d.ts.map +1 -0
- package/dist/components/util/field.d.ts +45 -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 +77 -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/map-view.d.ts +144 -0
- package/dist/components/util/map-view.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 +234 -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/progress.d.ts +19 -0
- package/dist/components/util/progress.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-edge.d.ts +33 -0
- package/dist/components/util/scroll-edge.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 +84 -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/skeleton.d.ts +15 -0
- package/dist/components/util/skeleton.d.ts.map +1 -0
- package/dist/components/util/sliding-indicator.d.ts +25 -0
- package/dist/components/util/sliding-indicator.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/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/temporal-field.d.ts +89 -0
- package/dist/components/util/temporal-field.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 +133 -0
- package/dist/components/util/toaster.d.ts.map +1 -0
- package/dist/components/util/tone-surface.d.ts +34 -0
- package/dist/components/util/tone-surface.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 +35 -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 +142 -0
- package/dist/components/util/zabi-strings.d.ts.map +1 -0
- package/dist/create-theme/cli.js +173 -0
- package/dist/create-theme/index.d.ts +190 -0
- package/dist/create-theme/index.js +1034 -0
- package/dist/create-theme/lib/ramp-math.js +128 -0
- package/dist/create-theme/lib/resolve.js +238 -0
- package/dist/create-theme/theme-data.js +2644 -0
- package/dist/index.d.ts +104 -2
- package/dist/index.js +75 -2
- package/dist/map.d.ts +10 -0
- package/dist/map.js +9 -0
- package/dist/molecules/Alert.svelte +63 -16
- package/dist/molecules/Alert.svelte.d.ts +14 -1
- package/dist/molecules/AppBar.svelte +674 -0
- package/dist/molecules/AppBar.svelte.d.ts +131 -0
- package/dist/molecules/AvatarGroup.svelte +116 -0
- package/dist/molecules/AvatarGroup.svelte.d.ts +40 -0
- package/dist/molecules/BarChart.svelte +381 -0
- package/dist/molecules/BarChart.svelte.d.ts +45 -0
- package/dist/molecules/BottomSheet.svelte +608 -0
- package/dist/molecules/BottomSheet.svelte.d.ts +109 -0
- package/dist/molecules/BottomTabBar.svelte +403 -0
- package/dist/molecules/BottomTabBar.svelte.d.ts +98 -0
- package/dist/molecules/Calendar.svelte +597 -0
- package/dist/molecules/Calendar.svelte.d.ts +72 -0
- package/dist/molecules/ChipGroup.svelte +325 -0
- package/dist/molecules/ChipGroup.svelte.d.ts +41 -0
- package/dist/molecules/Collapsible.svelte +347 -0
- package/dist/molecules/Collapsible.svelte.d.ts +61 -0
- package/dist/molecules/CollapsibleGroup.svelte +136 -0
- package/dist/molecules/CollapsibleGroup.svelte.d.ts +14 -0
- package/dist/molecules/ComponentDemo.svelte +16 -4
- package/dist/molecules/ComponentDemo.svelte.d.ts +3 -0
- package/dist/molecules/ConfirmDialog.svelte +257 -0
- package/dist/molecules/ConfirmDialog.svelte.d.ts +58 -0
- package/dist/molecules/ContactForm.svelte +34 -17
- package/dist/molecules/ContactForm.svelte.d.ts +8 -0
- package/dist/molecules/Drawer.svelte +415 -0
- package/dist/molecules/Drawer.svelte.d.ts +55 -0
- package/dist/molecules/Dropdown.svelte +517 -48
- package/dist/molecules/Dropdown.svelte.d.ts +47 -6
- package/dist/molecules/DropdownItem.svelte +122 -0
- package/dist/molecules/DropdownItem.svelte.d.ts +28 -0
- package/dist/molecules/EmptyState.svelte +55 -10
- package/dist/molecules/EmptyState.svelte.d.ts +8 -0
- package/dist/molecules/FormField.svelte +9 -1
- package/dist/molecules/FormField.svelte.d.ts +2 -0
- package/dist/molecules/Header.svelte +1 -1
- package/dist/molecules/ImageUpload.svelte +492 -69
- package/dist/molecules/ImageUpload.svelte.d.ts +82 -2
- package/dist/molecules/LineChart.svelte +459 -0
- package/dist/molecules/LineChart.svelte.d.ts +53 -0
- package/dist/molecules/MapView.svelte +565 -0
- package/dist/molecules/MapView.svelte.d.ts +88 -0
- package/dist/molecules/MediaGrid.svelte +527 -0
- package/dist/molecules/MediaGrid.svelte.d.ts +77 -0
- package/dist/molecules/Modal.svelte +293 -72
- package/dist/molecules/Modal.svelte.d.ts +51 -2
- package/dist/molecules/NavigationMenuContent.svelte +58 -1
- package/dist/molecules/NavigationMenuItem.svelte +0 -1
- package/dist/molecules/NavigationMenuLink.svelte +1 -1
- package/dist/molecules/NavigationMenuList.svelte +10 -3
- package/dist/molecules/NavigationMenuTrigger.svelte +2 -2
- package/dist/molecules/Page.svelte +32 -2
- package/dist/molecules/Page.svelte.d.ts +11 -0
- package/dist/molecules/PhotoGrid.svelte +523 -0
- package/dist/molecules/PhotoGrid.svelte.d.ts +73 -0
- package/dist/molecules/PhotoViewer.svelte +1213 -0
- package/dist/molecules/PhotoViewer.svelte.d.ts +74 -0
- package/dist/molecules/PieChart.svelte +421 -0
- package/dist/molecules/PieChart.svelte.d.ts +51 -0
- package/dist/molecules/PropsTable.svelte +22 -10
- package/dist/molecules/PropsTable.svelte.d.ts +3 -0
- package/dist/molecules/PullToRefresh.svelte +263 -0
- package/dist/molecules/PullToRefresh.svelte.d.ts +52 -0
- package/dist/molecules/RadioGroup.svelte +72 -18
- package/dist/molecules/RadioGroup.svelte.d.ts +19 -3
- package/dist/molecules/Section.svelte +1 -1
- package/dist/molecules/SegmentedControl.svelte +456 -0
- package/dist/molecules/SegmentedControl.svelte.d.ts +40 -0
- package/dist/molecules/SidebarBrandHeader.svelte +11 -1
- package/dist/molecules/SidebarBrandHeader.svelte.d.ts +3 -0
- package/dist/molecules/SidebarFooter.svelte +30 -7
- package/dist/molecules/SidebarFooter.svelte.d.ts +3 -0
- package/dist/molecules/SidebarNavSection.svelte +1 -1
- package/dist/molecules/SlideUp.svelte +220 -61
- package/dist/molecules/SlideUp.svelte.d.ts +26 -0
- package/dist/molecules/SortableList.svelte +633 -0
- package/dist/molecules/SortableList.svelte.d.ts +69 -0
- package/dist/molecules/Stepper.svelte +562 -0
- package/dist/molecules/Stepper.svelte.d.ts +39 -0
- package/dist/molecules/StickyActionBar.svelte +250 -0
- package/dist/molecules/StickyActionBar.svelte.d.ts +78 -0
- package/dist/molecules/SwipeableListItem.svelte +334 -0
- package/dist/molecules/SwipeableListItem.svelte.d.ts +54 -0
- package/dist/molecules/Tabs.svelte +310 -9
- package/dist/molecules/Tabs.svelte.d.ts +7 -0
- package/dist/molecules/Toaster.svelte +514 -5
- package/dist/molecules/Toaster.svelte.d.ts +153 -2
- package/dist/molecules/ToasterToast.svelte +495 -77
- package/dist/molecules/ToasterToast.svelte.d.ts +15 -0
- package/dist/molecules/UnsavedChangesBar.svelte +223 -0
- package/dist/molecules/UnsavedChangesBar.svelte.d.ts +43 -0
- package/dist/molecules/index.d.ts +51 -0
- package/dist/molecules/index.js +31 -0
- package/dist/molecules/toast-store.d.ts +83 -7
- package/dist/molecules/toast-store.js +25 -1
- package/dist/organisms/AppNavigation.svelte +440 -0
- package/dist/organisms/AppNavigation.svelte.d.ts +72 -0
- package/dist/organisms/AppShell.svelte +696 -0
- package/dist/organisms/AppShell.svelte.d.ts +157 -0
- package/dist/organisms/AppShellHeaderPart.svelte +163 -0
- package/dist/organisms/AppShellHeaderPart.svelte.d.ts +57 -0
- package/dist/organisms/SidebarAccountPanel.svelte +107 -12
- package/dist/organisms/SidebarAccountPanel.svelte.d.ts +19 -0
- package/dist/organisms/SidebarNavigation.svelte +111 -43
- package/dist/organisms/SidebarNavigation.svelte.d.ts +29 -1
- package/dist/organisms/SidebarPanel.svelte +34 -17
- package/dist/organisms/SidebarPanel.svelte.d.ts +1 -0
- package/dist/organisms/SidebarShell.svelte +164 -14
- package/dist/organisms/SidebarShell.svelte.d.ts +56 -2
- package/dist/organisms/TopNavbar.svelte +353 -39
- package/dist/organisms/TopNavbar.svelte.d.ts +47 -0
- package/dist/organisms/TopNavbarSheetContent.svelte +145 -0
- package/dist/organisms/TopNavbarSheetContent.svelte.d.ts +24 -0
- package/dist/organisms/index.d.ts +10 -0
- package/dist/organisms/index.js +7 -0
- package/dist/types/components.d.ts +21 -1
- package/dist/types/components.d.ts.map +1 -1
- package/dist/types/index.d.ts +1093 -26
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/variants.ts +28 -1
- package/dist/util/app-shell.d.ts +78 -0
- package/dist/util/app-shell.js +97 -0
- package/dist/util/avatar.d.ts +38 -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 +40 -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/chart.d.ts +139 -0
- package/dist/util/chart.js +305 -0
- package/dist/util/chip.d.ts +65 -0
- package/dist/util/chip.js +58 -0
- package/dist/util/cn.js +28 -2
- package/dist/util/code-field.d.ts +62 -0
- package/dist/util/code-field.js +112 -0
- package/dist/util/collapsible.d.ts +63 -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/display-voice.d.ts +9 -0
- package/dist/util/display-voice.js +9 -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-control.d.ts +29 -0
- package/dist/util/field-control.js +32 -0
- package/dist/util/field.d.ts +44 -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 +77 -2
- package/dist/util/focus-utils.js +186 -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/map-view.d.ts +143 -0
- package/dist/util/map-view.js +121 -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 +233 -0
- package/dist/util/photo.js +209 -0
- package/dist/util/portal.d.ts +22 -0
- package/dist/util/portal.js +50 -0
- package/dist/util/progress.d.ts +18 -0
- package/dist/util/progress.js +17 -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-edge.d.ts +32 -0
- package/dist/util/scroll-edge.js +87 -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 +83 -0
- package/dist/util/sheet-drag.js +311 -0
- package/dist/util/sidebar.d.ts +62 -0
- package/dist/util/sidebar.js +38 -0
- package/dist/util/skeleton.d.ts +14 -0
- package/dist/util/skeleton.js +22 -0
- package/dist/util/sliding-indicator.d.ts +24 -0
- package/dist/util/sliding-indicator.js +44 -0
- package/dist/util/sortable-list.d.ts +64 -0
- package/dist/util/sortable-list.js +53 -0
- 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/temporal-field.d.ts +88 -0
- package/dist/util/temporal-field.js +136 -0
- package/dist/util/theme-mode.d.ts +79 -0
- package/dist/util/theme-mode.js +121 -0
- package/dist/util/toaster.d.ts +132 -0
- package/dist/util/toaster.js +130 -0
- package/dist/util/tone-surface.d.ts +33 -0
- package/dist/util/tone-surface.js +35 -0
- package/dist/util/tooltip.d.ts +9 -0
- package/dist/util/tooltip.js +18 -0
- package/dist/util/top-navbar.d.ts +34 -0
- package/dist/util/top-navbar.js +28 -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 +141 -0
- package/dist/util/zabi-strings.js +105 -0
- package/dist/zabi-components-colors.css +11 -2
- package/dist/zabi-components-theme-dark-only.css +870 -258
- package/dist/zabi-components-theme-dark.css +870 -258
- package/dist/zabi-components-theme-only.css +2419 -368
- package/dist/zabi-components-theme.css +2419 -368
- package/dist/zabi-components.css +6032 -711
- package/docs/lucide-icons.md +40 -17
- package/docs/theme-imports.md +81 -11
- package/package.json +45 -8
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ChevronDown from "@lucide/svelte/icons/chevron-down";
|
|
3
|
+
import type { Snippet } from "svelte";
|
|
4
|
+
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
|
|
5
|
+
import { cn } from "../util/cn.js";
|
|
6
|
+
import { fieldDescribedBy, fieldMessageState } from "../util/field.js";
|
|
7
|
+
import { FIELD_CONTROL_TRIGGER, fieldControlEdge, fieldControlSize } from "../util/field-control.js";
|
|
8
|
+
import { generateId } from "../util/ssr-safe.js";
|
|
9
|
+
import FieldMessages from "./FieldMessages.svelte";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A field-shaped trigger that opens whatever the app gives it, usually its
|
|
13
|
+
* own BottomSheet: the app owns the list, the search and the value. It
|
|
14
|
+
* looks like a Select of the same `size` and is one control: a `<button>`
|
|
15
|
+
* (a link with `href`) named by its label and its current value.
|
|
16
|
+
*
|
|
17
|
+
* Other attributes (`data-*`, `aria-*`, `onfocus`, ...) land on that
|
|
18
|
+
* element. The component does not open anything: `onclick` does, and the
|
|
19
|
+
* app sets `expanded` while its sheet is open.
|
|
20
|
+
*/
|
|
21
|
+
type Props = Omit<
|
|
22
|
+
HTMLButtonAttributes,
|
|
23
|
+
| "class"
|
|
24
|
+
| "value"
|
|
25
|
+
| "name"
|
|
26
|
+
| "disabled"
|
|
27
|
+
| "type"
|
|
28
|
+
| "onclick"
|
|
29
|
+
| "aria-describedby"
|
|
30
|
+
| "aria-haspopup"
|
|
31
|
+
| "aria-expanded"
|
|
32
|
+
| "aria-controls"
|
|
33
|
+
| "children"
|
|
34
|
+
> & {
|
|
35
|
+
/** Extra classes for the host element. */
|
|
36
|
+
class?: string;
|
|
37
|
+
/** Id of the control. Omit to auto-generate. */
|
|
38
|
+
id?: string;
|
|
39
|
+
/** The label above the field. It is part of the control's name. */
|
|
40
|
+
label?: string;
|
|
41
|
+
/** The text of what is chosen. It is display text; `formValue` is what a form sends. */
|
|
42
|
+
value?: string;
|
|
43
|
+
/** Shown in the placeholder colour while there is no `value`. */
|
|
44
|
+
placeholder?: string;
|
|
45
|
+
/** An icon or an avatar before the text. */
|
|
46
|
+
leading?: Snippet;
|
|
47
|
+
/** Replaces the chevron at the end: a calendar or a clock, say. It is decoration, so it should be `aria-hidden`. */
|
|
48
|
+
trailing?: Snippet;
|
|
49
|
+
/** Replaces the value text, for rich content. The control is still named by `value`, so give that too. */
|
|
50
|
+
children?: Snippet;
|
|
51
|
+
size?: "sm" | "md" | "lg";
|
|
52
|
+
disabled?: boolean;
|
|
53
|
+
/** Status text under the field. Shown with a `success`, `warning` or `error` variant; for neutral help, use `hint`. */
|
|
54
|
+
message?: string;
|
|
55
|
+
variant?: "default" | "success" | "warning" | "error";
|
|
56
|
+
/** Help text under the field, read out with it. */
|
|
57
|
+
hint?: string;
|
|
58
|
+
/**
|
|
59
|
+
* An error under the field, announced. A button cannot take
|
|
60
|
+
* `aria-invalid`, so the error is the error edge colour and the
|
|
61
|
+
* described-by message; it wins over `variant` and `message`.
|
|
62
|
+
*/
|
|
63
|
+
error?: string;
|
|
64
|
+
/** What the control opens: `aria-haspopup`. Default `"dialog"`. Not put on a link. */
|
|
65
|
+
haspopup?: "dialog" | "listbox" | "menu" | "true";
|
|
66
|
+
/** Whether what it opens is open now: `aria-expanded`, and the chevron turns. Leave it out and neither is set. Not put on a link. */
|
|
67
|
+
expanded?: boolean;
|
|
68
|
+
/** Id of what it opens: `aria-controls`. */
|
|
69
|
+
controls?: string;
|
|
70
|
+
/** Makes the control a link to this address, which works without scripts: a page that does the picking. With scripts, `onclick` may call `preventDefault()` and open a sheet instead. */
|
|
71
|
+
href?: string;
|
|
72
|
+
/** With `href`: where the link opens. */
|
|
73
|
+
target?: HTMLAnchorAttributes["target"];
|
|
74
|
+
/** With `href`: the link's relationship, such as `noopener`. */
|
|
75
|
+
rel?: HTMLAnchorAttributes["rel"];
|
|
76
|
+
/** The name a hidden input submits `formValue` under. Without it there is no hidden input. */
|
|
77
|
+
name?: string;
|
|
78
|
+
/** What the form submits for the choice, such as an id. */
|
|
79
|
+
formValue?: string;
|
|
80
|
+
/** The inner `<button>` (or `<a>`). Bindable: the app focuses it when its sheet closes, so a keyboard user is back where they were. */
|
|
81
|
+
element?: HTMLButtonElement | HTMLAnchorElement | null;
|
|
82
|
+
/** Ids of other elements that describe the field. The hint and the message are added after them. */
|
|
83
|
+
"aria-describedby"?: string | null;
|
|
84
|
+
onclick?: (event: MouseEvent) => void;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
let {
|
|
88
|
+
class: className = "",
|
|
89
|
+
id: idProp,
|
|
90
|
+
label = "",
|
|
91
|
+
value = "",
|
|
92
|
+
placeholder = "",
|
|
93
|
+
leading,
|
|
94
|
+
trailing,
|
|
95
|
+
children,
|
|
96
|
+
size = "md",
|
|
97
|
+
disabled = false,
|
|
98
|
+
variant = "default",
|
|
99
|
+
message = "",
|
|
100
|
+
hint = "",
|
|
101
|
+
error = "",
|
|
102
|
+
haspopup = "dialog",
|
|
103
|
+
expanded,
|
|
104
|
+
controls,
|
|
105
|
+
href,
|
|
106
|
+
target,
|
|
107
|
+
rel,
|
|
108
|
+
name = "",
|
|
109
|
+
formValue = "",
|
|
110
|
+
element = $bindable(),
|
|
111
|
+
"aria-describedby": describedBy,
|
|
112
|
+
onclick,
|
|
113
|
+
...restProps
|
|
114
|
+
}: Props = $props();
|
|
115
|
+
|
|
116
|
+
const fallbackId = generateId("picker-field");
|
|
117
|
+
const fieldId = $derived(idProp ?? fallbackId);
|
|
118
|
+
const labelId = $derived(`${fieldId}-label`);
|
|
119
|
+
const valueId = $derived(`${fieldId}-value`);
|
|
120
|
+
|
|
121
|
+
const isLink = $derived(href !== undefined && href !== null);
|
|
122
|
+
const status = $derived(fieldMessageState({ variant, message, hint, error }));
|
|
123
|
+
const isEmpty = $derived(value === "");
|
|
124
|
+
const sizeClass = $derived(fieldControlSize(size));
|
|
125
|
+
|
|
126
|
+
const controlClasses = $derived(
|
|
127
|
+
cn(
|
|
128
|
+
FIELD_CONTROL_TRIGGER,
|
|
129
|
+
sizeClass.box,
|
|
130
|
+
sizeClass.text,
|
|
131
|
+
fieldControlEdge(status.variant),
|
|
132
|
+
// `disabled:` does not match an `<a>`: a disabled link wears the pair itself.
|
|
133
|
+
isLink && disabled && "cursor-not-allowed border-input-border bg-input-disabled text-action-disabled-text hover:bg-input-disabled active:bg-input-disabled",
|
|
134
|
+
),
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The name is the label and the value (the placeholder while there is
|
|
139
|
+
* none), as a Select's is. Without a label the content names it. A
|
|
140
|
+
* caller's own `aria-label` or `aria-labelledby` wins.
|
|
141
|
+
*/
|
|
142
|
+
const labelledBy = $derived(label ? `${labelId} ${valueId}` : undefined);
|
|
143
|
+
|
|
144
|
+
/** A disabled link has no `href`, but a pointer can still press it. */
|
|
145
|
+
function handleLinkClick(event: MouseEvent) {
|
|
146
|
+
if (disabled) {
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
event.stopPropagation();
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
onclick?.(event);
|
|
152
|
+
}
|
|
153
|
+
</script>
|
|
154
|
+
|
|
155
|
+
{#snippet content()}
|
|
156
|
+
{#if leading}
|
|
157
|
+
<span class="flex shrink-0 items-center" data-picker-field-leading>{@render leading()}</span>
|
|
158
|
+
{/if}
|
|
159
|
+
<!-- A value has no colour class of its own, and a disabled control none
|
|
160
|
+
at all: the control's `text-body` and its disabled colour are inherited
|
|
161
|
+
(a colour class here beat the disabled one in Select). -->
|
|
162
|
+
<span
|
|
163
|
+
id={valueId}
|
|
164
|
+
class={cn("min-w-0 flex-1 truncate text-start", isEmpty && !disabled && !children && "text-input-placeholder")}
|
|
165
|
+
>
|
|
166
|
+
{#if children}
|
|
167
|
+
{@render children()}
|
|
168
|
+
{:else}
|
|
169
|
+
{isEmpty ? placeholder : value}
|
|
170
|
+
{/if}
|
|
171
|
+
</span>
|
|
172
|
+
{#if trailing}
|
|
173
|
+
<span class="flex shrink-0 items-center text-description" data-picker-field-trailing>{@render trailing()}</span>
|
|
174
|
+
{:else}
|
|
175
|
+
<ChevronDown
|
|
176
|
+
size={20}
|
|
177
|
+
class={cn(
|
|
178
|
+
"shrink-0 text-description transition-transform duration-(--duration-moderate) motion-reduce:transition-none",
|
|
179
|
+
expanded && "rotate-180",
|
|
180
|
+
)}
|
|
181
|
+
aria-hidden="true"
|
|
182
|
+
/>
|
|
183
|
+
{/if}
|
|
184
|
+
{/snippet}
|
|
185
|
+
|
|
186
|
+
<div class={cn("w-full min-w-0", className)}>
|
|
187
|
+
{#if label}
|
|
188
|
+
{#if isLink}
|
|
189
|
+
<!-- A link cannot be a label's control. -->
|
|
190
|
+
<span id={labelId} class="mb-2 block text-sm font-medium text-label">{label}</span>
|
|
191
|
+
{:else}
|
|
192
|
+
<label id={labelId} for={fieldId} class="mb-2 block text-sm font-medium text-label">{label}</label>
|
|
193
|
+
{/if}
|
|
194
|
+
{/if}
|
|
195
|
+
|
|
196
|
+
{#if isLink}
|
|
197
|
+
<!-- With `href` the control is a link with its role left native, and
|
|
198
|
+
no `aria-haspopup` or `aria-expanded`: it goes to a page. Disabled, it
|
|
199
|
+
has no `href` and says it is unavailable, as a disabled Button link. -->
|
|
200
|
+
<a
|
|
201
|
+
bind:this={element}
|
|
202
|
+
id={fieldId}
|
|
203
|
+
href={disabled ? undefined : href}
|
|
204
|
+
{target}
|
|
205
|
+
{rel}
|
|
206
|
+
class={controlClasses}
|
|
207
|
+
role={disabled ? "link" : undefined}
|
|
208
|
+
aria-disabled={disabled ? "true" : undefined}
|
|
209
|
+
aria-labelledby={labelledBy}
|
|
210
|
+
aria-describedby={fieldDescribedBy(fieldId, status, describedBy)}
|
|
211
|
+
{...(restProps as unknown as HTMLAnchorAttributes)}
|
|
212
|
+
onclick={handleLinkClick}
|
|
213
|
+
>
|
|
214
|
+
{@render content()}
|
|
215
|
+
</a>
|
|
216
|
+
{:else}
|
|
217
|
+
<button
|
|
218
|
+
bind:this={element}
|
|
219
|
+
type="button"
|
|
220
|
+
id={fieldId}
|
|
221
|
+
{disabled}
|
|
222
|
+
class={controlClasses}
|
|
223
|
+
aria-haspopup={haspopup}
|
|
224
|
+
aria-expanded={expanded}
|
|
225
|
+
aria-controls={controls}
|
|
226
|
+
aria-labelledby={labelledBy}
|
|
227
|
+
aria-describedby={fieldDescribedBy(fieldId, status, describedBy)}
|
|
228
|
+
{...restProps}
|
|
229
|
+
{onclick}
|
|
230
|
+
>
|
|
231
|
+
{@render content()}
|
|
232
|
+
</button>
|
|
233
|
+
{/if}
|
|
234
|
+
|
|
235
|
+
{#if name}
|
|
236
|
+
<input type="hidden" {name} value={formValue} {disabled} />
|
|
237
|
+
{/if}
|
|
238
|
+
<FieldMessages {fieldId} {status} {hint} gap="mt-1" messageClass="w-full" />
|
|
239
|
+
</div>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
|
|
3
|
+
/**
|
|
4
|
+
* A field-shaped trigger that opens whatever the app gives it, usually its
|
|
5
|
+
* own BottomSheet: the app owns the list, the search and the value. It
|
|
6
|
+
* looks like a Select of the same `size` and is one control: a `<button>`
|
|
7
|
+
* (a link with `href`) named by its label and its current value.
|
|
8
|
+
*
|
|
9
|
+
* Other attributes (`data-*`, `aria-*`, `onfocus`, ...) land on that
|
|
10
|
+
* element. The component does not open anything: `onclick` does, and the
|
|
11
|
+
* app sets `expanded` while its sheet is open.
|
|
12
|
+
*/
|
|
13
|
+
type Props = Omit<HTMLButtonAttributes, "class" | "value" | "name" | "disabled" | "type" | "onclick" | "aria-describedby" | "aria-haspopup" | "aria-expanded" | "aria-controls" | "children"> & {
|
|
14
|
+
/** Extra classes for the host element. */
|
|
15
|
+
class?: string;
|
|
16
|
+
/** Id of the control. Omit to auto-generate. */
|
|
17
|
+
id?: string;
|
|
18
|
+
/** The label above the field. It is part of the control's name. */
|
|
19
|
+
label?: string;
|
|
20
|
+
/** The text of what is chosen. It is display text; `formValue` is what a form sends. */
|
|
21
|
+
value?: string;
|
|
22
|
+
/** Shown in the placeholder colour while there is no `value`. */
|
|
23
|
+
placeholder?: string;
|
|
24
|
+
/** An icon or an avatar before the text. */
|
|
25
|
+
leading?: Snippet;
|
|
26
|
+
/** Replaces the chevron at the end: a calendar or a clock, say. It is decoration, so it should be `aria-hidden`. */
|
|
27
|
+
trailing?: Snippet;
|
|
28
|
+
/** Replaces the value text, for rich content. The control is still named by `value`, so give that too. */
|
|
29
|
+
children?: Snippet;
|
|
30
|
+
size?: "sm" | "md" | "lg";
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
/** Status text under the field. Shown with a `success`, `warning` or `error` variant; for neutral help, use `hint`. */
|
|
33
|
+
message?: string;
|
|
34
|
+
variant?: "default" | "success" | "warning" | "error";
|
|
35
|
+
/** Help text under the field, read out with it. */
|
|
36
|
+
hint?: string;
|
|
37
|
+
/**
|
|
38
|
+
* An error under the field, announced. A button cannot take
|
|
39
|
+
* `aria-invalid`, so the error is the error edge colour and the
|
|
40
|
+
* described-by message; it wins over `variant` and `message`.
|
|
41
|
+
*/
|
|
42
|
+
error?: string;
|
|
43
|
+
/** What the control opens: `aria-haspopup`. Default `"dialog"`. Not put on a link. */
|
|
44
|
+
haspopup?: "dialog" | "listbox" | "menu" | "true";
|
|
45
|
+
/** Whether what it opens is open now: `aria-expanded`, and the chevron turns. Leave it out and neither is set. Not put on a link. */
|
|
46
|
+
expanded?: boolean;
|
|
47
|
+
/** Id of what it opens: `aria-controls`. */
|
|
48
|
+
controls?: string;
|
|
49
|
+
/** Makes the control a link to this address, which works without scripts: a page that does the picking. With scripts, `onclick` may call `preventDefault()` and open a sheet instead. */
|
|
50
|
+
href?: string;
|
|
51
|
+
/** With `href`: where the link opens. */
|
|
52
|
+
target?: HTMLAnchorAttributes["target"];
|
|
53
|
+
/** With `href`: the link's relationship, such as `noopener`. */
|
|
54
|
+
rel?: HTMLAnchorAttributes["rel"];
|
|
55
|
+
/** The name a hidden input submits `formValue` under. Without it there is no hidden input. */
|
|
56
|
+
name?: string;
|
|
57
|
+
/** What the form submits for the choice, such as an id. */
|
|
58
|
+
formValue?: string;
|
|
59
|
+
/** The inner `<button>` (or `<a>`). Bindable: the app focuses it when its sheet closes, so a keyboard user is back where they were. */
|
|
60
|
+
element?: HTMLButtonElement | HTMLAnchorElement | null;
|
|
61
|
+
/** Ids of other elements that describe the field. The hint and the message are added after them. */
|
|
62
|
+
"aria-describedby"?: string | null;
|
|
63
|
+
onclick?: (event: MouseEvent) => void;
|
|
64
|
+
};
|
|
65
|
+
declare const PickerField: import("svelte").Component<Props, {}, "element">;
|
|
66
|
+
type PickerField = ReturnType<typeof PickerField>;
|
|
67
|
+
export default PickerField;
|
|
@@ -1,13 +1,35 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { isDevBuild } from "../util/app-shell.js";
|
|
3
|
+
import {
|
|
4
|
+
PROGRESS_STRINGS,
|
|
5
|
+
canSegment,
|
|
6
|
+
filledSegments,
|
|
7
|
+
type ProgressStrings,
|
|
8
|
+
} from "../util/progress.js";
|
|
9
|
+
import { mergeStrings } from "../util/ready-made-strings.js";
|
|
2
10
|
import { generateId } from "../util/ssr-safe.js";
|
|
11
|
+
import { zabiStringsFor } from "../util/zabi-strings.js";
|
|
3
12
|
|
|
4
13
|
interface Props {
|
|
5
14
|
/** Extra classes for the host element. */
|
|
6
15
|
class?: string;
|
|
7
16
|
value?: number;
|
|
8
17
|
max?: number;
|
|
9
|
-
|
|
18
|
+
/** Height of the bar: 4, 8, 12 and 16px. */
|
|
19
|
+
size?: "sm" | "md" | "lg" | "xl";
|
|
20
|
+
/**
|
|
21
|
+
* Draws `max` separate segments, `value` of them filled, for a count
|
|
22
|
+
* such as 4 of 19. `max` must be a whole number from 2 to 24; any
|
|
23
|
+
* other `max` draws the continuous bar.
|
|
24
|
+
*/
|
|
25
|
+
segmented?: boolean;
|
|
26
|
+
/** Overrides for the built-in strings. */
|
|
27
|
+
strings?: Partial<ProgressStrings>;
|
|
10
28
|
label?: string;
|
|
29
|
+
/** Names the progressbar when there is no visible `label`. Reaches the element with role="progressbar". */
|
|
30
|
+
"aria-label"?: string;
|
|
31
|
+
/** Points the progressbar at another element's id for its name. Reaches the element with role="progressbar". */
|
|
32
|
+
"aria-labelledby"?: string;
|
|
11
33
|
}
|
|
12
34
|
|
|
13
35
|
let {
|
|
@@ -15,43 +37,101 @@
|
|
|
15
37
|
value = 0,
|
|
16
38
|
max = 100,
|
|
17
39
|
size = "md",
|
|
40
|
+
segmented = false,
|
|
41
|
+
strings,
|
|
18
42
|
label = "",
|
|
43
|
+
"aria-label": ariaLabel,
|
|
44
|
+
"aria-labelledby": ariaLabelledby,
|
|
19
45
|
...restProps
|
|
20
46
|
}: Props = $props();
|
|
21
47
|
|
|
22
48
|
const progressId = generateId("progress");
|
|
49
|
+
const labelId = `${progressId}-label`;
|
|
23
50
|
|
|
24
|
-
|
|
51
|
+
// A max that is not a positive, finite number would give an empty or full
|
|
52
|
+
// bar with aria-valuemax=0: fall back to the default.
|
|
53
|
+
let safeMax = $derived(Number.isFinite(max) && max > 0 ? max : 100);
|
|
54
|
+
let safeValue = $derived(
|
|
55
|
+
Number.isFinite(value) ? Math.min(Math.max(value, 0), safeMax) : 0,
|
|
56
|
+
);
|
|
57
|
+
let percentage = $derived((safeValue / safeMax) * 100);
|
|
58
|
+
let labelledby = $derived(
|
|
59
|
+
ariaLabelledby ?? (ariaLabel || !label ? undefined : labelId),
|
|
60
|
+
);
|
|
25
61
|
|
|
26
|
-
|
|
62
|
+
const sizeClasses = {
|
|
27
63
|
sm: "h-1",
|
|
28
64
|
md: "h-2",
|
|
29
65
|
lg: "h-3",
|
|
66
|
+
xl: "h-4",
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** The app-wide words for this component, from a `ZabiStringsProvider` above it, if there is one. */
|
|
70
|
+
const provided = zabiStringsFor("progress");
|
|
71
|
+
const text = $derived(mergeStrings(PROGRESS_STRINGS, provided(), strings));
|
|
72
|
+
|
|
73
|
+
/** Segmented only where `max` can be drawn as segments; otherwise the continuous bar. */
|
|
74
|
+
let asSegments = $derived(segmented && canSegment(max));
|
|
75
|
+
let filled = $derived(filledSegments(value, safeMax));
|
|
76
|
+
let valueText = $derived(asSegments ? text.valueText(filled, safeMax) : undefined);
|
|
77
|
+
|
|
78
|
+
$effect(() => {
|
|
79
|
+
if (!isDevBuild() || !segmented || canSegment(max)) return;
|
|
80
|
+
console.warn(
|
|
81
|
+
"[zabi-components] Progress: `segmented` needs a whole-number `max` from 2 to 24; drawing the continuous bar instead.",
|
|
82
|
+
);
|
|
30
83
|
});
|
|
31
84
|
</script>
|
|
32
85
|
|
|
33
86
|
<div class={className} {...restProps}>
|
|
34
87
|
{#if label}
|
|
35
88
|
<div class="flex justify-between items-center mb-2">
|
|
36
|
-
|
|
37
|
-
|
|
89
|
+
<!-- A span named through aria-labelledby, not a label: `for` only
|
|
90
|
+
names form controls, so it left the progressbar without a name. -->
|
|
91
|
+
<span id={labelId} class="text-sm font-medium text-label"
|
|
92
|
+
>{label}</span
|
|
38
93
|
>
|
|
39
|
-
<span class="text-sm text-caption">{Math.round(percentage)}
|
|
94
|
+
<span class="text-sm text-caption">{asSegments ? valueText : `${Math.round(percentage)}%`}</span>
|
|
40
95
|
</div>
|
|
41
96
|
{/if}
|
|
42
97
|
|
|
43
|
-
|
|
44
|
-
id={progressId}
|
|
45
|
-
class="w-full border border-input-border bg-input rounded-full overflow-hidden {sizeClasses[size]}"
|
|
46
|
-
role="progressbar"
|
|
47
|
-
aria-valuenow={value}
|
|
48
|
-
aria-valuemin="0"
|
|
49
|
-
aria-valuemax={max}
|
|
50
|
-
{...restProps}
|
|
51
|
-
>
|
|
98
|
+
{#if asSegments}
|
|
52
99
|
<div
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
100
|
+
id={progressId}
|
|
101
|
+
class="flex w-full {safeMax > 12 ? 'gap-[2px]' : 'gap-1'} {sizeClasses[size]}"
|
|
102
|
+
role="progressbar"
|
|
103
|
+
aria-label={ariaLabel}
|
|
104
|
+
aria-labelledby={labelledby}
|
|
105
|
+
aria-valuenow={filled}
|
|
106
|
+
aria-valuemin="0"
|
|
107
|
+
aria-valuemax={safeMax}
|
|
108
|
+
aria-valuetext={valueText}
|
|
109
|
+
>
|
|
110
|
+
{#each { length: safeMax } as _, index (index)}
|
|
111
|
+
<!-- Presentational: the count is said once, by the progressbar. -->
|
|
112
|
+
<span
|
|
113
|
+
class="h-full flex-1 min-w-0 rounded-full {index < filled
|
|
114
|
+
? 'bg-progress-fill forced-colors:bg-[Highlight]'
|
|
115
|
+
: 'bg-progress-track border border-progress-track-border forced-colors:border-[CanvasText]'}"
|
|
116
|
+
aria-hidden="true"
|
|
117
|
+
></span>
|
|
118
|
+
{/each}
|
|
119
|
+
</div>
|
|
120
|
+
{:else}
|
|
121
|
+
<div
|
|
122
|
+
id={progressId}
|
|
123
|
+
class="w-full border border-progress-track-border bg-progress-track rounded-full overflow-hidden {sizeClasses[size]}"
|
|
124
|
+
role="progressbar"
|
|
125
|
+
aria-label={ariaLabel}
|
|
126
|
+
aria-labelledby={labelledby}
|
|
127
|
+
aria-valuenow={safeValue}
|
|
128
|
+
aria-valuemin="0"
|
|
129
|
+
aria-valuemax={safeMax}
|
|
130
|
+
>
|
|
131
|
+
<div
|
|
132
|
+
class="h-full bg-progress-fill rounded-full"
|
|
133
|
+
style="width: {percentage}%"
|
|
134
|
+
></div>
|
|
135
|
+
</div>
|
|
136
|
+
{/if}
|
|
57
137
|
</div>
|
|
@@ -1,10 +1,24 @@
|
|
|
1
|
+
import { type ProgressStrings } from "../util/progress.js";
|
|
1
2
|
interface Props {
|
|
2
3
|
/** Extra classes for the host element. */
|
|
3
4
|
class?: string;
|
|
4
5
|
value?: number;
|
|
5
6
|
max?: number;
|
|
6
|
-
|
|
7
|
+
/** Height of the bar: 4, 8, 12 and 16px. */
|
|
8
|
+
size?: "sm" | "md" | "lg" | "xl";
|
|
9
|
+
/**
|
|
10
|
+
* Draws `max` separate segments, `value` of them filled, for a count
|
|
11
|
+
* such as 4 of 19. `max` must be a whole number from 2 to 24; any
|
|
12
|
+
* other `max` draws the continuous bar.
|
|
13
|
+
*/
|
|
14
|
+
segmented?: boolean;
|
|
15
|
+
/** Overrides for the built-in strings. */
|
|
16
|
+
strings?: Partial<ProgressStrings>;
|
|
7
17
|
label?: string;
|
|
18
|
+
/** Names the progressbar when there is no visible `label`. Reaches the element with role="progressbar". */
|
|
19
|
+
"aria-label"?: string;
|
|
20
|
+
/** Points the progressbar at another element's id for its name. Reaches the element with role="progressbar". */
|
|
21
|
+
"aria-labelledby"?: string;
|
|
8
22
|
}
|
|
9
23
|
declare const Progress: import("svelte").Component<Props, {}, "">;
|
|
10
24
|
type Progress = ReturnType<typeof Progress>;
|
package/dist/atoms/Radio.svelte
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { HTMLInputAttributes } from "svelte/elements";
|
|
4
|
+
import type { SemanticVariant } from "../types/variants.js";
|
|
2
5
|
import SelectionControl from "./SelectionControl.svelte";
|
|
3
6
|
import type { SelectionControlMarkProps } from "./SelectionControl.svelte";
|
|
4
7
|
import { RADIO_CHECKED_DOT_CLASSES } from "./selection-control.styles";
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
/** Other attributes (`required`, `data-*`, `aria-*`, ...) land on the `<input>`. */
|
|
10
|
+
type Props = Omit<
|
|
11
|
+
HTMLInputAttributes,
|
|
12
|
+
"class" | "id" | "name" | "value" | "disabled" | "checked" | "type" | "onchange"
|
|
13
|
+
> & {
|
|
7
14
|
/** Extra classes for the host element. */
|
|
8
15
|
class?: string;
|
|
9
16
|
id?: string;
|
|
@@ -15,7 +22,31 @@
|
|
|
15
22
|
checked?: boolean;
|
|
16
23
|
onChange?: (event: Event) => void;
|
|
17
24
|
onchange?: (event: Event) => void;
|
|
18
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Drawn inside the one label, between the box and the label text, as
|
|
27
|
+
* decoration for the name `label` already gives. A leading image
|
|
28
|
+
* should have an empty alt: the label names the row.
|
|
29
|
+
*/
|
|
30
|
+
leading?: Snippet;
|
|
31
|
+
/**
|
|
32
|
+
* A line under the label, tied to the radio with `aria-describedby`.
|
|
33
|
+
* The label names the radio; the description does not join the name.
|
|
34
|
+
*/
|
|
35
|
+
description?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Where the radio sits in the row. `end` puts it after the leading,
|
|
38
|
+
* the label and the description, at the far edge; the row is still
|
|
39
|
+
* one label and fills the width it is given.
|
|
40
|
+
*/
|
|
41
|
+
controlPosition?: "start" | "end";
|
|
42
|
+
variant?: SemanticVariant;
|
|
43
|
+
/** Status text under the control. Shown with a `success`, `warning` or `error` variant; for neutral help, use `hint`. */
|
|
44
|
+
message?: string;
|
|
45
|
+
/** Help text under the control, read out with it. */
|
|
46
|
+
hint?: string;
|
|
47
|
+
/** An error under the control. It marks the input invalid and is announced; it wins over `variant` and `message`. */
|
|
48
|
+
error?: string;
|
|
49
|
+
};
|
|
19
50
|
|
|
20
51
|
let {
|
|
21
52
|
class: className = "",
|
|
@@ -25,11 +56,25 @@
|
|
|
25
56
|
label = "",
|
|
26
57
|
disabled = false,
|
|
27
58
|
defaultChecked = false,
|
|
28
|
-
checked = $bindable(
|
|
59
|
+
checked = $bindable<Exclude<Props["checked"], undefined>>(),
|
|
29
60
|
onChange,
|
|
30
61
|
onchange,
|
|
62
|
+
leading,
|
|
63
|
+
description,
|
|
64
|
+
controlPosition = "start",
|
|
31
65
|
...restProps
|
|
32
66
|
}: Props = $props();
|
|
67
|
+
|
|
68
|
+
// No fallback on a bindable prop: Svelte refuses `bind:…={undefined}` on
|
|
69
|
+
// one that has a fallback (`props_invalid_value`), and a page that throws
|
|
70
|
+
// while it hydrates never becomes interactive. The default is applied
|
|
71
|
+
// here instead: at once, for the server and the first render, and again
|
|
72
|
+
// whenever a parent hands back `undefined`.
|
|
73
|
+
const applyDefaults = () => {
|
|
74
|
+
if (checked === undefined) checked = defaultChecked;
|
|
75
|
+
};
|
|
76
|
+
applyDefaults();
|
|
77
|
+
$effect.pre(applyDefaults);
|
|
33
78
|
</script>
|
|
34
79
|
|
|
35
80
|
{#snippet mark(_props: SelectionControlMarkProps)}
|
|
@@ -49,6 +94,9 @@
|
|
|
49
94
|
{onChange}
|
|
50
95
|
{onchange}
|
|
51
96
|
{mark}
|
|
97
|
+
{leading}
|
|
98
|
+
{description}
|
|
99
|
+
{controlPosition}
|
|
52
100
|
class={className}
|
|
53
101
|
{...restProps}
|
|
54
102
|
/>
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import type { HTMLInputAttributes } from "svelte/elements";
|
|
3
|
+
import type { SemanticVariant } from "../types/variants.js";
|
|
4
|
+
/** Other attributes (`required`, `data-*`, `aria-*`, ...) land on the `<input>`. */
|
|
5
|
+
type Props = Omit<HTMLInputAttributes, "class" | "id" | "name" | "value" | "disabled" | "checked" | "type" | "onchange"> & {
|
|
2
6
|
/** Extra classes for the host element. */
|
|
3
7
|
class?: string;
|
|
4
8
|
id?: string;
|
|
@@ -10,7 +14,31 @@ interface Props {
|
|
|
10
14
|
checked?: boolean;
|
|
11
15
|
onChange?: (event: Event) => void;
|
|
12
16
|
onchange?: (event: Event) => void;
|
|
13
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Drawn inside the one label, between the box and the label text, as
|
|
19
|
+
* decoration for the name `label` already gives. A leading image
|
|
20
|
+
* should have an empty alt: the label names the row.
|
|
21
|
+
*/
|
|
22
|
+
leading?: Snippet;
|
|
23
|
+
/**
|
|
24
|
+
* A line under the label, tied to the radio with `aria-describedby`.
|
|
25
|
+
* The label names the radio; the description does not join the name.
|
|
26
|
+
*/
|
|
27
|
+
description?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Where the radio sits in the row. `end` puts it after the leading,
|
|
30
|
+
* the label and the description, at the far edge; the row is still
|
|
31
|
+
* one label and fills the width it is given.
|
|
32
|
+
*/
|
|
33
|
+
controlPosition?: "start" | "end";
|
|
34
|
+
variant?: SemanticVariant;
|
|
35
|
+
/** Status text under the control. Shown with a `success`, `warning` or `error` variant; for neutral help, use `hint`. */
|
|
36
|
+
message?: string;
|
|
37
|
+
/** Help text under the control, read out with it. */
|
|
38
|
+
hint?: string;
|
|
39
|
+
/** An error under the control. It marks the input invalid and is announced; it wins over `variant` and `message`. */
|
|
40
|
+
error?: string;
|
|
41
|
+
};
|
|
14
42
|
declare const Radio: import("svelte").Component<Props, {}, "checked">;
|
|
15
43
|
type Radio = ReturnType<typeof Radio>;
|
|
16
44
|
export default Radio;
|