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,187 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
import { cn } from "../util/cn.js";
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<HTMLElement>, "class"> & {
|
|
7
|
+
/**
|
|
8
|
+
* The caption that names the quotation ("Säg så här i luren"), read
|
|
9
|
+
* before it. A string, or a snippet for a caption in the app's own
|
|
10
|
+
* text style.
|
|
11
|
+
*/
|
|
12
|
+
label?: string | Snippet;
|
|
13
|
+
/** Keeps the caption for assistive technology and takes it off the screen. */
|
|
14
|
+
labelHidden?: boolean;
|
|
15
|
+
/** The side the tail is on: `end` (default) or `start`. Follows the text direction. */
|
|
16
|
+
side?: "end" | "start";
|
|
17
|
+
/**
|
|
18
|
+
* `ink` (default): the headline colour as fill, the page colour as
|
|
19
|
+
* text, so it is dark in light and light in dark. `paper`: the two
|
|
20
|
+
* swapped, for a bubble on a filled block. A pair of your own:
|
|
21
|
+
* `--zabi-bubble-fill` and `--zabi-bubble-text`, which win over both.
|
|
22
|
+
*/
|
|
23
|
+
tone?: "ink" | "paper";
|
|
24
|
+
/**
|
|
25
|
+
* A drawing on the top corner of the tail's side, half over the edge
|
|
26
|
+
* (a sparkle, a quotation mark). Hidden from assistive technology;
|
|
27
|
+
* the app sizes and colours what it passes.
|
|
28
|
+
*/
|
|
29
|
+
decoration?: Snippet;
|
|
30
|
+
class?: string;
|
|
31
|
+
/** The quoted text: phrasing content or paragraphs. */
|
|
32
|
+
children?: Snippet;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
let {
|
|
36
|
+
label,
|
|
37
|
+
labelHidden = false,
|
|
38
|
+
side = "end",
|
|
39
|
+
tone = "ink",
|
|
40
|
+
decoration,
|
|
41
|
+
class: className = "",
|
|
42
|
+
children,
|
|
43
|
+
...restProps
|
|
44
|
+
}: Props = $props();
|
|
45
|
+
|
|
46
|
+
/* The type is in utility classes, so a call-site class can replace it;
|
|
47
|
+
the quotation inherits it. */
|
|
48
|
+
const hostClasses = $derived(cn("speech-bubble flex flex-col gap-2 text-lg font-medium", className));
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<figure
|
|
52
|
+
class={hostClasses}
|
|
53
|
+
data-side={side === "start" ? "start" : "end"}
|
|
54
|
+
data-tone={tone === "paper" ? "paper" : "ink"}
|
|
55
|
+
{...restProps}
|
|
56
|
+
>
|
|
57
|
+
{#if label}
|
|
58
|
+
<figcaption class={cn("text-description text-sm font-normal", labelHidden && "sr-only")}>
|
|
59
|
+
{#if typeof label === "string"}{label}{:else}{@render label()}{/if}
|
|
60
|
+
</figcaption>
|
|
61
|
+
{/if}
|
|
62
|
+
<blockquote class="quote">
|
|
63
|
+
<span class="art" aria-hidden="true">
|
|
64
|
+
<span class="fill"></span>
|
|
65
|
+
<svg class="tail" viewBox="0 0 30 24" focusable="false">
|
|
66
|
+
<path d="M1 0C1 9 9 20 29 23 22 18 19 10 21 0Z" />
|
|
67
|
+
</svg>
|
|
68
|
+
</span>
|
|
69
|
+
{#if decoration}
|
|
70
|
+
<span class="decoration" aria-hidden="true">{@render decoration()}</span>
|
|
71
|
+
{/if}
|
|
72
|
+
{@render children?.()}
|
|
73
|
+
</blockquote>
|
|
74
|
+
</figure>
|
|
75
|
+
|
|
76
|
+
<style>
|
|
77
|
+
/*
|
|
78
|
+
* What an app may set, on the component or on anything around it (they
|
|
79
|
+
* inherit); read with a fallback and never declared here:
|
|
80
|
+
* --zabi-bubble-fill the bubble and its tail; default by `tone`
|
|
81
|
+
* --zabi-bubble-text the quoted text; default by `tone`
|
|
82
|
+
* --zabi-bubble-radius any border-radius value, the eight-value form
|
|
83
|
+
* included; default 1.5rem
|
|
84
|
+
* --zabi-bubble-tilt turns the fill and the tail, never the text;
|
|
85
|
+
* default 0deg
|
|
86
|
+
* Inside a filled block (`on-brand`, `on-accent`, `on-fill`) the headline
|
|
87
|
+
* role is the block's label colour; `--zabi-theme-headline` is the
|
|
88
|
+
* theme's own, kept by the block's parent, so the bubble is the same
|
|
89
|
+
* object on a block as on the page.
|
|
90
|
+
*/
|
|
91
|
+
.quote {
|
|
92
|
+
--_bubble-ink: var(--zabi-theme-headline, var(--color-headline));
|
|
93
|
+
--_bubble-paper: var(--color-surface-base);
|
|
94
|
+
--_bubble-fill: var(--zabi-bubble-fill, var(--_bubble-ink));
|
|
95
|
+
position: relative;
|
|
96
|
+
isolation: isolate;
|
|
97
|
+
/* The tail hangs 0.8rem under the bubble; this keeps it off what follows. */
|
|
98
|
+
margin: 0 0 1rem;
|
|
99
|
+
padding: 1.125rem 1.25rem 1.25rem;
|
|
100
|
+
color: var(--zabi-bubble-text, var(--_bubble-paper));
|
|
101
|
+
font-style: normal;
|
|
102
|
+
overflow-wrap: anywhere;
|
|
103
|
+
-webkit-user-select: text;
|
|
104
|
+
-moz-user-select: text;
|
|
105
|
+
user-select: text;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.speech-bubble[data-tone="paper"] .quote {
|
|
109
|
+
--_bubble-fill: var(--zabi-bubble-fill, var(--_bubble-paper));
|
|
110
|
+
color: var(--zabi-bubble-text, var(--_bubble-ink));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.art {
|
|
114
|
+
position: absolute;
|
|
115
|
+
inset: 0;
|
|
116
|
+
z-index: -1;
|
|
117
|
+
pointer-events: none;
|
|
118
|
+
rotate: var(--zabi-bubble-tilt, 0deg);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.fill {
|
|
122
|
+
position: absolute;
|
|
123
|
+
inset: 0;
|
|
124
|
+
border-radius: var(--zabi-bubble-radius, 1.5rem);
|
|
125
|
+
background-color: var(--_bubble-fill);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* A drawn curl that turns outward, towards the side it is on. Its top
|
|
129
|
+
0.4rem is under the fill; all of it is in rem, so it grows with the text. */
|
|
130
|
+
.tail {
|
|
131
|
+
position: absolute;
|
|
132
|
+
inset-block-start: calc(100% - 0.4rem);
|
|
133
|
+
inset-inline-end: 1.5rem;
|
|
134
|
+
inline-size: 1.5rem;
|
|
135
|
+
block-size: 1.2rem;
|
|
136
|
+
fill: var(--_bubble-fill);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.decoration {
|
|
140
|
+
position: absolute;
|
|
141
|
+
inset-block-start: 0;
|
|
142
|
+
inset-inline-end: 0;
|
|
143
|
+
display: flex;
|
|
144
|
+
line-height: 0;
|
|
145
|
+
pointer-events: none;
|
|
146
|
+
translate: 25% -55%;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.speech-bubble[data-side="start"] .tail {
|
|
150
|
+
inset-inline: 1.5rem auto;
|
|
151
|
+
scale: -1 1;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.speech-bubble[data-side="start"] .decoration {
|
|
155
|
+
inset-inline: 0 auto;
|
|
156
|
+
translate: -25% -55%;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* The path is drawn turning right; the other three cases follow from it. */
|
|
160
|
+
.speech-bubble:dir(rtl) .tail {
|
|
161
|
+
scale: -1 1;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.speech-bubble:dir(rtl) .decoration {
|
|
165
|
+
translate: -25% -55%;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.speech-bubble[data-side="start"]:dir(rtl) .tail {
|
|
169
|
+
scale: none;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.speech-bubble[data-side="start"]:dir(rtl) .decoration {
|
|
173
|
+
translate: 25% -55%;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* Forced colours drop the fill: the shape is an outline in the text
|
|
177
|
+
colour, tilt and radius kept, and the tail is not drawn. */
|
|
178
|
+
@media (forced-colors: active) {
|
|
179
|
+
.fill {
|
|
180
|
+
outline: 0.125rem solid CanvasText;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.tail {
|
|
184
|
+
display: none;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
</style>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
type Props = Omit<HTMLAttributes<HTMLElement>, "class"> & {
|
|
4
|
+
/**
|
|
5
|
+
* The caption that names the quotation ("Säg så här i luren"), read
|
|
6
|
+
* before it. A string, or a snippet for a caption in the app's own
|
|
7
|
+
* text style.
|
|
8
|
+
*/
|
|
9
|
+
label?: string | Snippet;
|
|
10
|
+
/** Keeps the caption for assistive technology and takes it off the screen. */
|
|
11
|
+
labelHidden?: boolean;
|
|
12
|
+
/** The side the tail is on: `end` (default) or `start`. Follows the text direction. */
|
|
13
|
+
side?: "end" | "start";
|
|
14
|
+
/**
|
|
15
|
+
* `ink` (default): the headline colour as fill, the page colour as
|
|
16
|
+
* text, so it is dark in light and light in dark. `paper`: the two
|
|
17
|
+
* swapped, for a bubble on a filled block. A pair of your own:
|
|
18
|
+
* `--zabi-bubble-fill` and `--zabi-bubble-text`, which win over both.
|
|
19
|
+
*/
|
|
20
|
+
tone?: "ink" | "paper";
|
|
21
|
+
/**
|
|
22
|
+
* A drawing on the top corner of the tail's side, half over the edge
|
|
23
|
+
* (a sparkle, a quotation mark). Hidden from assistive technology;
|
|
24
|
+
* the app sizes and colours what it passes.
|
|
25
|
+
*/
|
|
26
|
+
decoration?: Snippet;
|
|
27
|
+
class?: string;
|
|
28
|
+
/** The quoted text: phrasing content or paragraphs. */
|
|
29
|
+
children?: Snippet;
|
|
30
|
+
};
|
|
31
|
+
declare const SpeechBubble: import("svelte").Component<Props, {}, "">;
|
|
32
|
+
type SpeechBubble = ReturnType<typeof SpeechBubble>;
|
|
33
|
+
export default SpeechBubble;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
import { cn } from "../util/cn.js";
|
|
4
|
+
|
|
5
|
+
type Props = Omit<HTMLAttributes<HTMLSpanElement>, "class"> & {
|
|
6
|
+
/**
|
|
7
|
+
* Diameter, on the scale the built-in loading states use: 12, 14, 16
|
|
8
|
+
* and 20px. For another size pass a `size-*` utility through `class`.
|
|
9
|
+
*/
|
|
10
|
+
size?: "xs" | "sm" | "md" | "lg";
|
|
11
|
+
/**
|
|
12
|
+
* What is loading. With a label the spinner is a `status` and the
|
|
13
|
+
* label is read out; without one it is decorative and hidden from
|
|
14
|
+
* assistive technology, for use beside text that already says so.
|
|
15
|
+
*/
|
|
16
|
+
label?: string;
|
|
17
|
+
/** Extra classes for the ring: a size, a colour, an opacity. */
|
|
18
|
+
class?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
let {
|
|
22
|
+
size = "md",
|
|
23
|
+
label = "",
|
|
24
|
+
class: className = "",
|
|
25
|
+
...restProps
|
|
26
|
+
}: Props = $props();
|
|
27
|
+
|
|
28
|
+
const SIZES = {
|
|
29
|
+
xs: "size-3",
|
|
30
|
+
sm: "size-3.5",
|
|
31
|
+
md: "size-4",
|
|
32
|
+
lg: "size-5",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The same ring Button, IconButton and Input draw while loading, in the
|
|
37
|
+
* text colour. Rotation is the motion a reduced-motion preference is
|
|
38
|
+
* about, so there the ring stays still and fades in and out instead:
|
|
39
|
+
* something must still show that work is going on.
|
|
40
|
+
*/
|
|
41
|
+
const ringClasses = $derived(
|
|
42
|
+
cn(
|
|
43
|
+
"inline-block shrink-0 animate-spin rounded-full border-2 border-current border-t-transparent opacity-80 motion-reduce:animate-pulse",
|
|
44
|
+
SIZES[size],
|
|
45
|
+
className,
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
{#if label}
|
|
51
|
+
<span class="inline-flex shrink-0" role="status" {...restProps}>
|
|
52
|
+
<span class={ringClasses} aria-hidden="true"></span>
|
|
53
|
+
<span class="sr-only">{label}</span>
|
|
54
|
+
</span>
|
|
55
|
+
{:else}
|
|
56
|
+
<span class={ringClasses} aria-hidden="true" {...restProps}></span>
|
|
57
|
+
{/if}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
2
|
+
type Props = Omit<HTMLAttributes<HTMLSpanElement>, "class"> & {
|
|
3
|
+
/**
|
|
4
|
+
* Diameter, on the scale the built-in loading states use: 12, 14, 16
|
|
5
|
+
* and 20px. For another size pass a `size-*` utility through `class`.
|
|
6
|
+
*/
|
|
7
|
+
size?: "xs" | "sm" | "md" | "lg";
|
|
8
|
+
/**
|
|
9
|
+
* What is loading. With a label the spinner is a `status` and the
|
|
10
|
+
* label is read out; without one it is decorative and hidden from
|
|
11
|
+
* assistive technology, for use beside text that already says so.
|
|
12
|
+
*/
|
|
13
|
+
label?: string;
|
|
14
|
+
/** Extra classes for the ring: a size, a colour, an opacity. */
|
|
15
|
+
class?: string;
|
|
16
|
+
};
|
|
17
|
+
declare const Spinner: import("svelte").Component<Props, {}, "">;
|
|
18
|
+
type Spinner = ReturnType<typeof Spinner>;
|
|
19
|
+
export default Spinner;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
import { cn } from "../util/cn.js";
|
|
5
|
+
import { displayVoice } from "../util/display-voice.js";
|
|
6
|
+
|
|
7
|
+
type StatSize = "sm" | "md" | "lg";
|
|
8
|
+
|
|
9
|
+
type Props = Omit<HTMLAttributes<HTMLDivElement>, "class"> & {
|
|
10
|
+
/** The figure, shown as given: the app formats numbers for its locale. */
|
|
11
|
+
value: string | number;
|
|
12
|
+
label?: string;
|
|
13
|
+
/** Drawn after the value, smaller, on the same baseline ("av 19"). */
|
|
14
|
+
unit?: string;
|
|
15
|
+
size?: StatSize;
|
|
16
|
+
align?: "start" | "center" | "end";
|
|
17
|
+
labelPosition?: "below" | "above";
|
|
18
|
+
class?: string;
|
|
19
|
+
/** Replaces `value` for a figure that needs markup. */
|
|
20
|
+
children?: Snippet;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
let {
|
|
24
|
+
value,
|
|
25
|
+
label = "",
|
|
26
|
+
unit = "",
|
|
27
|
+
size = "md",
|
|
28
|
+
align = "start",
|
|
29
|
+
labelPosition = "below",
|
|
30
|
+
class: className = "",
|
|
31
|
+
children,
|
|
32
|
+
...restProps
|
|
33
|
+
}: Props = $props();
|
|
34
|
+
|
|
35
|
+
/** Value 24 / 36 / 48px, unit 14 / 16 / 20px, label 12 / 14 / 14px. */
|
|
36
|
+
const sizeClasses: Record<StatSize, { value: string; unit: string; label: string }> = {
|
|
37
|
+
sm: { value: "text-2xl", unit: "text-sm", label: "text-xs" },
|
|
38
|
+
md: { value: "text-4xl", unit: "text-base", label: "text-sm" },
|
|
39
|
+
lg: { value: "text-5xl", unit: "text-xl", label: "text-sm" },
|
|
40
|
+
};
|
|
41
|
+
const alignClasses = {
|
|
42
|
+
start: "items-start text-start",
|
|
43
|
+
center: "items-center text-center",
|
|
44
|
+
end: "items-end text-end",
|
|
45
|
+
} as const;
|
|
46
|
+
|
|
47
|
+
const s = $derived(sizeClasses[size] ?? sizeClasses.md);
|
|
48
|
+
const hostClasses = $derived(
|
|
49
|
+
cn(`flex flex-col gap-1 ${alignClasses[align] ?? alignClasses.start} ${className}`),
|
|
50
|
+
);
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
{#snippet figure()}
|
|
54
|
+
<div class="inline-flex items-baseline gap-1 whitespace-nowrap">
|
|
55
|
+
<span class="font-display text-headline tabular-nums leading-none {displayVoice} {s.value}">
|
|
56
|
+
{#if children}{@render children()}{:else}{value}{/if}
|
|
57
|
+
</span>
|
|
58
|
+
{#if unit}
|
|
59
|
+
<span class="text-description font-medium {s.unit}">{unit}</span>
|
|
60
|
+
{/if}
|
|
61
|
+
</div>
|
|
62
|
+
{/snippet}
|
|
63
|
+
|
|
64
|
+
<div class={hostClasses} {...restProps}>
|
|
65
|
+
{#if labelPosition === "above"}
|
|
66
|
+
{#if label}<span class="text-description {s.label}">{label}</span>{/if}
|
|
67
|
+
{@render figure()}
|
|
68
|
+
{:else}
|
|
69
|
+
{@render figure()}
|
|
70
|
+
{#if label}<span class="text-description {s.label}">{label}</span>{/if}
|
|
71
|
+
{/if}
|
|
72
|
+
</div>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
type StatSize = "sm" | "md" | "lg";
|
|
4
|
+
type Props = Omit<HTMLAttributes<HTMLDivElement>, "class"> & {
|
|
5
|
+
/** The figure, shown as given: the app formats numbers for its locale. */
|
|
6
|
+
value: string | number;
|
|
7
|
+
label?: string;
|
|
8
|
+
/** Drawn after the value, smaller, on the same baseline ("av 19"). */
|
|
9
|
+
unit?: string;
|
|
10
|
+
size?: StatSize;
|
|
11
|
+
align?: "start" | "center" | "end";
|
|
12
|
+
labelPosition?: "below" | "above";
|
|
13
|
+
class?: string;
|
|
14
|
+
/** Replaces `value` for a figure that needs markup. */
|
|
15
|
+
children?: Snippet;
|
|
16
|
+
};
|
|
17
|
+
declare const Stat: import("svelte").Component<Props, {}, "">;
|
|
18
|
+
type Stat = ReturnType<typeof Stat>;
|
|
19
|
+
export default Stat;
|
package/dist/atoms/Table.svelte
CHANGED
|
@@ -1,23 +1,168 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLTableAttributes } from 'svelte/elements';
|
|
3
4
|
import { cn } from "../util/cn.js";
|
|
5
|
+
import { generateId } from "../util/ssr-safe.js";
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
/** `true` stacks at every width; a breakpoint name stacks below it. */
|
|
8
|
+
export type TableStacked = boolean | "sm" | "md" | "lg";
|
|
9
|
+
|
|
10
|
+
/** Other attributes (`id`, `data-*`, `aria-*`, ...) land on the `<table>`. */
|
|
11
|
+
type Props = Omit<HTMLTableAttributes, 'class' | 'children'> & {
|
|
12
|
+
/** `<caption>`, and the table's accessible name, when set. */
|
|
7
13
|
caption?: string;
|
|
14
|
+
/** Keeps the caption as the accessible name but hides it from view. */
|
|
15
|
+
captionHidden?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Lays each row out as a block of label and value pairs instead of
|
|
18
|
+
* scrolling sideways. The label of a cell is its `data-label`
|
|
19
|
+
* attribute, which the caller sets on every `<td>`.
|
|
20
|
+
*/
|
|
21
|
+
stacked?: TableStacked;
|
|
8
22
|
class?: string;
|
|
9
23
|
children?: Snippet;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
let {
|
|
27
|
+
caption,
|
|
28
|
+
captionHidden = false,
|
|
29
|
+
stacked = false,
|
|
30
|
+
class: className = '',
|
|
31
|
+
children,
|
|
32
|
+
...restProps
|
|
33
|
+
}: Props = $props();
|
|
34
|
+
|
|
35
|
+
const captionId = generateId("table-caption");
|
|
36
|
+
let tableElement = $state<HTMLTableElement>();
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The rows arrive as `children`, so the stacked layout is written from the
|
|
40
|
+
* table down. Tailwind only generates classes it can read whole, which is
|
|
41
|
+
* why each breakpoint repeats the list rather than building it.
|
|
42
|
+
*
|
|
43
|
+
* The header row is hidden from view, not removed, so cells keep their
|
|
44
|
+
* column header. The visible label is the cell's `data-label` drawn in
|
|
45
|
+
* `::before`; where the browser supports alternative text for generated
|
|
46
|
+
* content it is given an empty one, so a screen reader reads the column
|
|
47
|
+
* header once instead of the header and then the label.
|
|
48
|
+
*
|
|
49
|
+
* The label takes the start of the line with an auto margin after it, and
|
|
50
|
+
* the cell packs everything else at the end. So a cell's own children stay
|
|
51
|
+
* together however many there are, and a cell with no label still has its
|
|
52
|
+
* value on the value side. An empty cell collapses to nothing but is not
|
|
53
|
+
* hidden: taking it out of the tree would shift the cells after it under
|
|
54
|
+
* the wrong column headers.
|
|
55
|
+
*/
|
|
56
|
+
const STACKED_CLASS = {
|
|
57
|
+
always:
|
|
58
|
+
"block min-w-0 [&>:not(thead)]:block [&>thead]:sr-only [&>*>tr]:block [&>*>tr]:py-2 " +
|
|
59
|
+
"[&>*>tr>*]:flex [&>*>tr>*]:items-baseline [&>*>tr>*]:justify-end " +
|
|
60
|
+
"[&>*>tr>*]:gap-4 [&>*>tr>*]:py-1 [&>*>tr>*]:text-end " +
|
|
61
|
+
"[&>*>tr>:empty]:py-0 [&>*>tr>[data-label]:not(:empty)]:before:me-auto " +
|
|
62
|
+
"[&>*>tr>[data-label]:not(:empty)]:before:shrink-0 " +
|
|
63
|
+
"[&>*>tr>[data-label]:not(:empty)]:before:text-start " +
|
|
64
|
+
"[&>*>tr>[data-label]:not(:empty)]:before:font-medium " +
|
|
65
|
+
"[&>*>tr>[data-label]:not(:empty)]:before:text-headline " +
|
|
66
|
+
"[&>*>tr>[data-label]:not(:empty)]:before:content-[attr(data-label)] " +
|
|
67
|
+
"supports-[content:'x'/'']:[&>*>tr>[data-label]:not(:empty)]:before:content-[attr(data-label)/'']",
|
|
68
|
+
sm:
|
|
69
|
+
"max-sm:block max-sm:min-w-0 max-sm:[&>:not(thead)]:block max-sm:[&>thead]:sr-only " +
|
|
70
|
+
"max-sm:[&>*>tr]:block max-sm:[&>*>tr]:py-2 max-sm:[&>*>tr>*]:flex " +
|
|
71
|
+
"max-sm:[&>*>tr>*]:items-baseline " +
|
|
72
|
+
"max-sm:[&>*>tr>*]:justify-end max-sm:[&>*>tr>*]:gap-4 " +
|
|
73
|
+
"max-sm:[&>*>tr>*]:py-1 max-sm:[&>*>tr>*]:text-end max-sm:[&>*>tr>:empty]:py-0 " +
|
|
74
|
+
"max-sm:[&>*>tr>[data-label]:not(:empty)]:before:me-auto " +
|
|
75
|
+
"max-sm:[&>*>tr>[data-label]:not(:empty)]:before:shrink-0 " +
|
|
76
|
+
"max-sm:[&>*>tr>[data-label]:not(:empty)]:before:text-start " +
|
|
77
|
+
"max-sm:[&>*>tr>[data-label]:not(:empty)]:before:font-medium " +
|
|
78
|
+
"max-sm:[&>*>tr>[data-label]:not(:empty)]:before:text-headline " +
|
|
79
|
+
"max-sm:[&>*>tr>[data-label]:not(:empty)]:before:content-[attr(data-label)] " +
|
|
80
|
+
"max-sm:supports-[content:'x'/'']:[&>*>tr>[data-label]:not(:empty)]:before:content-[attr(data-label)/'']",
|
|
81
|
+
md:
|
|
82
|
+
"max-md:block max-md:min-w-0 max-md:[&>:not(thead)]:block max-md:[&>thead]:sr-only " +
|
|
83
|
+
"max-md:[&>*>tr]:block max-md:[&>*>tr]:py-2 max-md:[&>*>tr>*]:flex " +
|
|
84
|
+
"max-md:[&>*>tr>*]:items-baseline " +
|
|
85
|
+
"max-md:[&>*>tr>*]:justify-end max-md:[&>*>tr>*]:gap-4 " +
|
|
86
|
+
"max-md:[&>*>tr>*]:py-1 max-md:[&>*>tr>*]:text-end max-md:[&>*>tr>:empty]:py-0 " +
|
|
87
|
+
"max-md:[&>*>tr>[data-label]:not(:empty)]:before:me-auto " +
|
|
88
|
+
"max-md:[&>*>tr>[data-label]:not(:empty)]:before:shrink-0 " +
|
|
89
|
+
"max-md:[&>*>tr>[data-label]:not(:empty)]:before:text-start " +
|
|
90
|
+
"max-md:[&>*>tr>[data-label]:not(:empty)]:before:font-medium " +
|
|
91
|
+
"max-md:[&>*>tr>[data-label]:not(:empty)]:before:text-headline " +
|
|
92
|
+
"max-md:[&>*>tr>[data-label]:not(:empty)]:before:content-[attr(data-label)] " +
|
|
93
|
+
"max-md:supports-[content:'x'/'']:[&>*>tr>[data-label]:not(:empty)]:before:content-[attr(data-label)/'']",
|
|
94
|
+
lg:
|
|
95
|
+
"max-lg:block max-lg:min-w-0 max-lg:[&>:not(thead)]:block max-lg:[&>thead]:sr-only " +
|
|
96
|
+
"max-lg:[&>*>tr]:block max-lg:[&>*>tr]:py-2 max-lg:[&>*>tr>*]:flex " +
|
|
97
|
+
"max-lg:[&>*>tr>*]:items-baseline " +
|
|
98
|
+
"max-lg:[&>*>tr>*]:justify-end max-lg:[&>*>tr>*]:gap-4 " +
|
|
99
|
+
"max-lg:[&>*>tr>*]:py-1 max-lg:[&>*>tr>*]:text-end max-lg:[&>*>tr>:empty]:py-0 " +
|
|
100
|
+
"max-lg:[&>*>tr>[data-label]:not(:empty)]:before:me-auto " +
|
|
101
|
+
"max-lg:[&>*>tr>[data-label]:not(:empty)]:before:shrink-0 " +
|
|
102
|
+
"max-lg:[&>*>tr>[data-label]:not(:empty)]:before:text-start " +
|
|
103
|
+
"max-lg:[&>*>tr>[data-label]:not(:empty)]:before:font-medium " +
|
|
104
|
+
"max-lg:[&>*>tr>[data-label]:not(:empty)]:before:text-headline " +
|
|
105
|
+
"max-lg:[&>*>tr>[data-label]:not(:empty)]:before:content-[attr(data-label)] " +
|
|
106
|
+
"max-lg:supports-[content:'x'/'']:[&>*>tr>[data-label]:not(:empty)]:before:content-[attr(data-label)/'']",
|
|
107
|
+
} as const;
|
|
108
|
+
|
|
109
|
+
const stackedClass = $derived(
|
|
110
|
+
stacked === true ? STACKED_CLASS.always : stacked ? STACKED_CLASS[stacked] : "",
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Some browsers stop treating a table as one once its boxes are no longer
|
|
115
|
+
* table boxes, and the rows then reach a screen reader as loose text.
|
|
116
|
+
* Explicit roles keep the structure whatever `display` says. The rows are
|
|
117
|
+
* the caller's markup, so the roles are set on the rendered elements and
|
|
118
|
+
* kept up as rows come and go; a role the caller set is left alone.
|
|
119
|
+
*/
|
|
120
|
+
function restoreTableRoles(table: HTMLTableElement) {
|
|
121
|
+
const set = (element: Element, role: string) => {
|
|
122
|
+
if (!element.hasAttribute("role")) element.setAttribute("role", role);
|
|
123
|
+
};
|
|
124
|
+
for (const group of table.querySelectorAll(":scope > :is(thead, tbody, tfoot)")) {
|
|
125
|
+
set(group, "rowgroup");
|
|
126
|
+
for (const row of group.querySelectorAll(":scope > tr")) {
|
|
127
|
+
set(row, "row");
|
|
128
|
+
for (const cell of row.querySelectorAll(":scope > :is(td, th)")) {
|
|
129
|
+
if (cell.tagName === "TD") set(cell, "cell");
|
|
130
|
+
else if (cell.getAttribute("scope") === "row") set(cell, "rowheader");
|
|
131
|
+
else if (cell.getAttribute("scope") === "col") set(cell, "columnheader");
|
|
132
|
+
else set(cell, group.tagName === "THEAD" ? "columnheader" : "rowheader");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
10
136
|
}
|
|
11
137
|
|
|
12
|
-
|
|
138
|
+
$effect(() => {
|
|
139
|
+
const table = tableElement;
|
|
140
|
+
if (!table || !stacked) return;
|
|
141
|
+
|
|
142
|
+
restoreTableRoles(table);
|
|
143
|
+
const observer = new MutationObserver(() => restoreTableRoles(table));
|
|
144
|
+
observer.observe(table, { childList: true, subtree: true });
|
|
145
|
+
return () => observer.disconnect();
|
|
146
|
+
});
|
|
13
147
|
</script>
|
|
14
148
|
|
|
15
149
|
<div
|
|
16
|
-
class={cn("overflow-x-auto rounded-control border border-border shadow-sm", className)}
|
|
150
|
+
class={cn("overflow-x-auto rounded-control border border-border bg-card shadow-sm", className)}
|
|
17
151
|
>
|
|
18
|
-
<table
|
|
152
|
+
<table
|
|
153
|
+
bind:this={tableElement}
|
|
154
|
+
class={cn("w-full min-w-[20rem] border-collapse text-left text-sm text-body", stackedClass)}
|
|
155
|
+
role={stacked ? "table" : undefined}
|
|
156
|
+
aria-labelledby={stacked && caption ? captionId : undefined}
|
|
157
|
+
{...restProps}
|
|
158
|
+
>
|
|
19
159
|
{#if caption}
|
|
20
|
-
<caption
|
|
160
|
+
<caption
|
|
161
|
+
id={captionId}
|
|
162
|
+
class={captionHidden
|
|
163
|
+
? "sr-only"
|
|
164
|
+
: "border-b border-border bg-surface-elevated px-4 py-3 text-left text-headline"}
|
|
165
|
+
>
|
|
21
166
|
{caption}
|
|
22
167
|
</caption>
|
|
23
168
|
{/if}
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import type { HTMLTableAttributes } from 'svelte/elements';
|
|
3
|
+
/** `true` stacks at every width; a breakpoint name stacks below it. */
|
|
4
|
+
export type TableStacked = boolean | "sm" | "md" | "lg";
|
|
5
|
+
/** Other attributes (`id`, `data-*`, `aria-*`, ...) land on the `<table>`. */
|
|
6
|
+
type Props = Omit<HTMLTableAttributes, 'class' | 'children'> & {
|
|
7
|
+
/** `<caption>`, and the table's accessible name, when set. */
|
|
4
8
|
caption?: string;
|
|
9
|
+
/** Keeps the caption as the accessible name but hides it from view. */
|
|
10
|
+
captionHidden?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Lays each row out as a block of label and value pairs instead of
|
|
13
|
+
* scrolling sideways. The label of a cell is its `data-label`
|
|
14
|
+
* attribute, which the caller sets on every `<td>`.
|
|
15
|
+
*/
|
|
16
|
+
stacked?: TableStacked;
|
|
5
17
|
class?: string;
|
|
6
18
|
children?: Snippet;
|
|
7
|
-
}
|
|
19
|
+
};
|
|
8
20
|
declare const Table: import("svelte").Component<Props, {}, "">;
|
|
9
21
|
type Table = ReturnType<typeof Table>;
|
|
10
22
|
export default Table;
|