@thomasfosterau/components 0.0.0 → 0.2.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/LICENSE +21 -0
- package/README.md +241 -56
- package/dist/canvas/VectorCanvas.svelte +320 -0
- package/dist/canvas/VectorCanvas.svelte.d.ts +105 -0
- package/dist/canvas/history.d.ts +105 -0
- package/dist/canvas/history.js +147 -0
- package/dist/canvas/index.d.ts +15 -0
- package/dist/canvas/index.js +14 -0
- package/dist/canvas/types.d.ts +91 -0
- package/dist/canvas/types.js +13 -0
- package/dist/canvas/utils.d.ts +66 -0
- package/dist/canvas/utils.js +114 -0
- package/dist/charts/Chart.svelte +300 -0
- package/dist/charts/Chart.svelte.d.ts +50 -0
- package/dist/charts/index.d.ts +11 -0
- package/dist/charts/index.js +10 -0
- package/dist/charts/types.d.ts +28 -0
- package/dist/charts/types.js +6 -0
- package/dist/citations/BookCitation.svelte +53 -0
- package/dist/citations/BookCitation.svelte.d.ts +41 -0
- package/dist/citations/ChapterCitation.svelte +38 -0
- package/dist/citations/ChapterCitation.svelte.d.ts +50 -0
- package/dist/citations/Citation.svelte +47 -0
- package/dist/citations/Citation.svelte.d.ts +24 -0
- package/dist/citations/CreditList.svelte +69 -0
- package/dist/citations/CreditList.svelte.d.ts +47 -0
- package/dist/citations/DOILink.svelte +28 -0
- package/dist/citations/DOILink.svelte.d.ts +19 -0
- package/dist/citations/Footnote.svelte +39 -0
- package/dist/citations/Footnote.svelte.d.ts +17 -0
- package/dist/citations/FootnoteList.svelte +36 -0
- package/dist/citations/FootnoteList.svelte.d.ts +21 -0
- package/dist/citations/ISBNLink.svelte +29 -0
- package/dist/citations/ISBNLink.svelte.d.ts +19 -0
- package/dist/citations/ISSNLink.svelte +29 -0
- package/dist/citations/ISSNLink.svelte.d.ts +19 -0
- package/dist/citations/Publisher.svelte +34 -0
- package/dist/citations/Publisher.svelte.d.ts +14 -0
- package/dist/citations/ReferenceList.svelte +53 -0
- package/dist/citations/ReferenceList.svelte.d.ts +21 -0
- package/dist/citations/ReportCitation.svelte +41 -0
- package/dist/citations/ReportCitation.svelte.d.ts +36 -0
- package/dist/citations/ScholarlyArticleCitation.svelte +64 -0
- package/dist/citations/ScholarlyArticleCitation.svelte.d.ts +41 -0
- package/dist/citations/ThesisCitation.svelte +35 -0
- package/dist/citations/ThesisCitation.svelte.d.ts +29 -0
- package/dist/citations/bibliography.svelte.d.ts +55 -0
- package/dist/citations/bibliography.svelte.js +78 -0
- package/dist/citations/citation.d.ts +71 -0
- package/dist/citations/citation.js +121 -0
- package/dist/citations/csl.d.ts +102 -0
- package/dist/citations/csl.js +20 -0
- package/dist/citations/index.d.ts +31 -0
- package/dist/citations/index.js +36 -0
- package/dist/citations/list-format.d.ts +34 -0
- package/dist/citations/list-format.js +40 -0
- package/dist/context.svelte.d.ts +46 -0
- package/dist/context.svelte.js +51 -0
- package/dist/data/ChatBubble.svelte +48 -0
- package/dist/data/ChatBubble.svelte.d.ts +33 -0
- package/dist/data/DataGrid.svelte +150 -0
- package/dist/data/DataGrid.svelte.d.ts +118 -0
- package/dist/data/DescriptionList.svelte +53 -0
- package/dist/data/DescriptionList.svelte.d.ts +26 -0
- package/dist/data/DescriptionRow.svelte +56 -0
- package/dist/data/DescriptionRow.svelte.d.ts +21 -0
- package/dist/data/DiffText.svelte +29 -0
- package/dist/data/DiffText.svelte.d.ts +19 -0
- package/dist/data/ItemList.svelte +80 -0
- package/dist/data/ItemList.svelte.d.ts +52 -0
- package/dist/data/LinkListItem.svelte +46 -0
- package/dist/data/LinkListItem.svelte.d.ts +21 -0
- package/dist/data/MessageThread.svelte +29 -0
- package/dist/data/MessageThread.svelte.d.ts +17 -0
- package/dist/data/Pagination.svelte +136 -0
- package/dist/data/Pagination.svelte.d.ts +79 -0
- package/dist/data/PaginationFooter.svelte +42 -0
- package/dist/data/PaginationFooter.svelte.d.ts +61 -0
- package/dist/data/ResultCount.svelte +27 -0
- package/dist/data/ResultCount.svelte.d.ts +18 -0
- package/dist/data/Table.svelte +151 -0
- package/dist/data/Table.svelte.d.ts +75 -0
- package/dist/data/TreeList.svelte +41 -0
- package/dist/data/TreeList.svelte.d.ts +17 -0
- package/dist/data/TreeListItem.svelte +29 -0
- package/dist/data/TreeListItem.svelte.d.ts +10 -0
- package/dist/data/description-context.d.ts +39 -0
- package/dist/data/description-context.js +36 -0
- package/dist/data/diff.d.ts +14 -0
- package/dist/data/diff.js +10 -0
- package/dist/data/index.d.ts +37 -0
- package/dist/data/index.js +37 -0
- package/dist/data/list-item.d.ts +30 -0
- package/dist/data/list-item.js +19 -0
- package/dist/data/pagination.d.ts +81 -0
- package/dist/data/pagination.js +79 -0
- package/dist/data/table-types.d.ts +71 -0
- package/dist/data/table-types.js +35 -0
- package/dist/feedback/ConfirmDialog.svelte +79 -0
- package/dist/feedback/ConfirmDialog.svelte.d.ts +82 -0
- package/dist/feedback/Dialog.svelte +47 -0
- package/dist/feedback/Dialog.svelte.d.ts +36 -0
- package/dist/feedback/DialogFrame.svelte +64 -0
- package/dist/feedback/DialogFrame.svelte.d.ts +23 -0
- package/dist/feedback/Drawer.svelte +43 -0
- package/dist/feedback/Drawer.svelte.d.ts +43 -0
- package/dist/feedback/LoadingBoundary.svelte +61 -0
- package/dist/feedback/LoadingBoundary.svelte.d.ts +34 -0
- package/dist/feedback/ProgressBar.svelte +46 -0
- package/dist/feedback/ProgressBar.svelte.d.ts +28 -0
- package/dist/feedback/SegmentBar.svelte +83 -0
- package/dist/feedback/SegmentBar.svelte.d.ts +37 -0
- package/dist/feedback/StatTile.svelte +77 -0
- package/dist/feedback/StatTile.svelte.d.ts +50 -0
- package/dist/feedback/Stats.svelte +18 -0
- package/dist/feedback/Stats.svelte.d.ts +16 -0
- package/dist/feedback/Steps.svelte +72 -0
- package/dist/feedback/Steps.svelte.d.ts +61 -0
- package/dist/feedback/Timeline.svelte +86 -0
- package/dist/feedback/Timeline.svelte.d.ts +55 -0
- package/dist/feedback/Toaster.svelte +78 -0
- package/dist/feedback/Toaster.svelte.d.ts +32 -0
- package/dist/feedback/index.d.ts +34 -0
- package/dist/feedback/index.js +29 -0
- package/dist/feedback/sizes.d.ts +41 -0
- package/dist/feedback/sizes.js +69 -0
- package/dist/feedback/toaster.d.ts +48 -0
- package/dist/feedback/toaster.js +29 -0
- package/dist/fields/Calendar.svelte +60 -0
- package/dist/fields/Calendar.svelte.d.ts +11 -0
- package/dist/fields/CalendarMonths.svelte +86 -0
- package/dist/fields/CalendarMonths.svelte.d.ts +30 -0
- package/dist/fields/Checkbox.svelte +33 -0
- package/dist/fields/Checkbox.svelte.d.ts +30 -0
- package/dist/fields/CheckboxGroup.svelte +41 -0
- package/dist/fields/CheckboxGroup.svelte.d.ts +40 -0
- package/dist/fields/Combobox.svelte +229 -0
- package/dist/fields/Combobox.svelte.d.ts +133 -0
- package/dist/fields/DateField.svelte +37 -0
- package/dist/fields/DateField.svelte.d.ts +20 -0
- package/dist/fields/DateInput.svelte +31 -0
- package/dist/fields/DateInput.svelte.d.ts +35 -0
- package/dist/fields/DatePicker.svelte +47 -0
- package/dist/fields/DatePicker.svelte.d.ts +25 -0
- package/dist/fields/DateRangePicker.svelte +70 -0
- package/dist/fields/DateRangePicker.svelte.d.ts +43 -0
- package/dist/fields/Dropzone.svelte +232 -0
- package/dist/fields/Dropzone.svelte.d.ts +103 -0
- package/dist/fields/FieldErrors.svelte +30 -0
- package/dist/fields/FieldErrors.svelte.d.ts +11 -0
- package/dist/fields/Fieldset.svelte +53 -0
- package/dist/fields/Fieldset.svelte.d.ts +27 -0
- package/dist/fields/FileInput.svelte +68 -0
- package/dist/fields/FileInput.svelte.d.ts +39 -0
- package/dist/fields/FormField.svelte +78 -0
- package/dist/fields/FormField.svelte.d.ts +29 -0
- package/dist/fields/ImageInput.svelte +87 -0
- package/dist/fields/ImageInput.svelte.d.ts +45 -0
- package/dist/fields/MultiSelect.svelte +112 -0
- package/dist/fields/MultiSelect.svelte.d.ts +75 -0
- package/dist/fields/NumberField.svelte +190 -0
- package/dist/fields/NumberField.svelte.d.ts +76 -0
- package/dist/fields/PasswordInput.svelte +95 -0
- package/dist/fields/PasswordInput.svelte.d.ts +58 -0
- package/dist/fields/PickerPopover.svelte +47 -0
- package/dist/fields/PickerPopover.svelte.d.ts +16 -0
- package/dist/fields/PinInput.svelte +83 -0
- package/dist/fields/PinInput.svelte.d.ts +66 -0
- package/dist/fields/PushToggle.svelte +93 -0
- package/dist/fields/PushToggle.svelte.d.ts +55 -0
- package/dist/fields/RadioGroup.svelte +88 -0
- package/dist/fields/RadioGroup.svelte.d.ts +41 -0
- package/dist/fields/RangeCalendar.svelte +51 -0
- package/dist/fields/RangeCalendar.svelte.d.ts +23 -0
- package/dist/fields/Rating.svelte +127 -0
- package/dist/fields/Rating.svelte.d.ts +86 -0
- package/dist/fields/SearchInput.svelte +58 -0
- package/dist/fields/SearchInput.svelte.d.ts +33 -0
- package/dist/fields/SegmentGroup.svelte +91 -0
- package/dist/fields/SegmentGroup.svelte.d.ts +20 -0
- package/dist/fields/Select.svelte +36 -0
- package/dist/fields/Select.svelte.d.ts +35 -0
- package/dist/fields/Slider.svelte +194 -0
- package/dist/fields/Slider.svelte.d.ts +100 -0
- package/dist/fields/TagsInput.svelte +256 -0
- package/dist/fields/TagsInput.svelte.d.ts +102 -0
- package/dist/fields/TextInput.svelte +26 -0
- package/dist/fields/TextInput.svelte.d.ts +36 -0
- package/dist/fields/Textarea.svelte +22 -0
- package/dist/fields/Textarea.svelte.d.ts +31 -0
- package/dist/fields/TimeField.svelte +30 -0
- package/dist/fields/TimeField.svelte.d.ts +19 -0
- package/dist/fields/Toggle.svelte +72 -0
- package/dist/fields/Toggle.svelte.d.ts +38 -0
- package/dist/fields/VideoInput.svelte +35 -0
- package/dist/fields/VideoInput.svelte.d.ts +46 -0
- package/dist/fields/calendar-props.d.ts +119 -0
- package/dist/fields/calendar-props.js +51 -0
- package/dist/fields/dates.d.ts +28 -0
- package/dist/fields/dates.js +26 -0
- package/dist/fields/field-types.d.ts +80 -0
- package/dist/fields/field-types.js +92 -0
- package/dist/fields/file-validation.d.ts +30 -0
- package/dist/fields/file-validation.js +51 -0
- package/dist/fields/index.d.ts +43 -0
- package/dist/fields/index.js +42 -0
- package/dist/fields/latest-search.svelte.d.ts +38 -0
- package/dist/fields/latest-search.svelte.js +85 -0
- package/dist/fields/number-format.d.ts +52 -0
- package/dist/fields/number-format.js +89 -0
- package/dist/fields/segmented-field.d.ts +128 -0
- package/dist/fields/segmented-field.js +52 -0
- package/dist/fields/slider-keys.d.ts +21 -0
- package/dist/fields/slider-keys.js +37 -0
- package/dist/formatting/Countdown.svelte +110 -0
- package/dist/formatting/Countdown.svelte.d.ts +35 -0
- package/dist/formatting/DateTime.svelte +35 -0
- package/dist/formatting/DateTime.svelte.d.ts +26 -0
- package/dist/formatting/Duration.svelte +18 -0
- package/dist/formatting/Duration.svelte.d.ts +20 -0
- package/dist/formatting/FormatList.svelte +31 -0
- package/dist/formatting/FormatList.svelte.d.ts +46 -0
- package/dist/formatting/Highlight.svelte +51 -0
- package/dist/formatting/Highlight.svelte.d.ts +19 -0
- package/dist/formatting/Number.svelte +35 -0
- package/dist/formatting/Number.svelte.d.ts +43 -0
- package/dist/formatting/RelativeTime.svelte +69 -0
- package/dist/formatting/RelativeTime.svelte.d.ts +26 -0
- package/dist/formatting/Year.svelte +39 -0
- package/dist/formatting/Year.svelte.d.ts +21 -0
- package/dist/formatting/duration.d.ts +44 -0
- package/dist/formatting/duration.js +125 -0
- package/dist/formatting/index.d.ts +15 -0
- package/dist/formatting/index.js +17 -0
- package/dist/forms/EntityForm.svelte +185 -0
- package/dist/forms/EntityForm.svelte.d.ts +66 -0
- package/dist/forms/FormActions.svelte +29 -0
- package/dist/forms/FormActions.svelte.d.ts +37 -0
- package/dist/forms/FormErrors.svelte +21 -0
- package/dist/forms/FormErrors.svelte.d.ts +16 -0
- package/dist/forms/HiddenField.svelte +22 -0
- package/dist/forms/HiddenField.svelte.d.ts +11 -0
- package/dist/forms/SearchForm.svelte +43 -0
- package/dist/forms/SearchForm.svelte.d.ts +36 -0
- package/dist/forms/entity-form.d.ts +12 -0
- package/dist/forms/entity-form.js +12 -0
- package/dist/forms/index.d.ts +14 -0
- package/dist/forms/index.js +14 -0
- package/dist/hotkeys/HotkeyBadge.svelte +39 -0
- package/dist/hotkeys/HotkeyBadge.svelte.d.ts +25 -0
- package/dist/hotkeys/HotkeyHelpDialog.svelte +68 -0
- package/dist/hotkeys/HotkeyHelpDialog.svelte.d.ts +35 -0
- package/dist/hotkeys/HotkeyProvider.svelte +92 -0
- package/dist/hotkeys/HotkeyProvider.svelte.d.ts +4 -0
- package/dist/hotkeys/context.svelte.d.ts +47 -0
- package/dist/hotkeys/context.svelte.js +72 -0
- package/dist/hotkeys/index.d.ts +28 -0
- package/dist/hotkeys/index.js +27 -0
- package/dist/hotkeys/match.d.ts +65 -0
- package/dist/hotkeys/match.js +135 -0
- package/dist/hotkeys/registry.svelte.d.ts +55 -0
- package/dist/hotkeys/registry.svelte.js +110 -0
- package/dist/hotkeys/types.d.ts +74 -0
- package/dist/hotkeys/types.js +18 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +37 -0
- package/dist/infobox/Infobox.svelte +79 -0
- package/dist/infobox/Infobox.svelte.d.ts +33 -0
- package/dist/infobox/InfoboxHeader.svelte +35 -0
- package/dist/infobox/InfoboxHeader.svelte.d.ts +18 -0
- package/dist/infobox/InfoboxImage.svelte +38 -0
- package/dist/infobox/InfoboxImage.svelte.d.ts +21 -0
- package/dist/infobox/InfoboxRow.svelte +50 -0
- package/dist/infobox/InfoboxRow.svelte.d.ts +25 -0
- package/dist/infobox/InfoboxSection.svelte +24 -0
- package/dist/infobox/InfoboxSection.svelte.d.ts +12 -0
- package/dist/infobox/index.d.ts +21 -0
- package/dist/infobox/index.js +20 -0
- package/dist/infobox/types.d.ts +86 -0
- package/dist/infobox/types.js +27 -0
- package/dist/layout/AppShell.svelte +50 -0
- package/dist/layout/AppShell.svelte.d.ts +28 -0
- package/dist/layout/Breadcrumbs.svelte +52 -0
- package/dist/layout/Breadcrumbs.svelte.d.ts +18 -0
- package/dist/layout/Cluster.svelte +28 -0
- package/dist/layout/Cluster.svelte.d.ts +27 -0
- package/dist/layout/DetailLayout.svelte +50 -0
- package/dist/layout/DetailLayout.svelte.d.ts +19 -0
- package/dist/layout/FilterBar.svelte +40 -0
- package/dist/layout/FilterBar.svelte.d.ts +12 -0
- package/dist/layout/Fits.svelte +27 -0
- package/dist/layout/Fits.svelte.d.ts +13 -0
- package/dist/layout/Flow.svelte +46 -0
- package/dist/layout/Flow.svelte.d.ts +16 -0
- package/dist/layout/Footer.svelte +32 -0
- package/dist/layout/Footer.svelte.d.ts +12 -0
- package/dist/layout/Grid.svelte +23 -0
- package/dist/layout/Grid.svelte.d.ts +26 -0
- package/dist/layout/HStack.svelte +12 -0
- package/dist/layout/HStack.svelte.d.ts +34 -0
- package/dist/layout/Hero.svelte +76 -0
- package/dist/layout/Hero.svelte.d.ts +36 -0
- package/dist/layout/Main.svelte +30 -0
- package/dist/layout/Main.svelte.d.ts +15 -0
- package/dist/layout/Navbar.svelte +68 -0
- package/dist/layout/Navbar.svelte.d.ts +31 -0
- package/dist/layout/PageHeader.svelte +77 -0
- package/dist/layout/PageHeader.svelte.d.ts +33 -0
- package/dist/layout/Section.svelte +72 -0
- package/dist/layout/Section.svelte.d.ts +40 -0
- package/dist/layout/Sidebar.svelte +54 -0
- package/dist/layout/Sidebar.svelte.d.ts +27 -0
- package/dist/layout/Spacer.svelte +12 -0
- package/dist/layout/Spacer.svelte.d.ts +6 -0
- package/dist/layout/Tabs.svelte +85 -0
- package/dist/layout/Tabs.svelte.d.ts +42 -0
- package/dist/layout/VStack.svelte +12 -0
- package/dist/layout/VStack.svelte.d.ts +29 -0
- package/dist/layout/index.d.ts +38 -0
- package/dist/layout/index.js +38 -0
- package/dist/layout/space.d.ts +44 -0
- package/dist/layout/space.js +76 -0
- package/dist/layout/types.d.ts +52 -0
- package/dist/layout/types.js +27 -0
- package/dist/links/ContextLinks.svelte +28 -0
- package/dist/links/ContextLinks.svelte.d.ts +20 -0
- package/dist/links/EmailLink.svelte +26 -0
- package/dist/links/EmailLink.svelte.d.ts +20 -0
- package/dist/links/index.d.ts +7 -0
- package/dist/links/index.js +7 -0
- package/dist/media/Figure.svelte +26 -0
- package/dist/media/Figure.svelte.d.ts +12 -0
- package/dist/media/Image.svelte +76 -0
- package/dist/media/Image.svelte.d.ts +41 -0
- package/dist/media/Video.svelte +65 -0
- package/dist/media/Video.svelte.d.ts +29 -0
- package/dist/media/image-dimensions.d.ts +28 -0
- package/dist/media/image-dimensions.js +34 -0
- package/dist/media/index.d.ts +10 -0
- package/dist/media/index.js +10 -0
- package/dist/search/CommandPalette.svelte +257 -0
- package/dist/search/CommandPalette.svelte.d.ts +59 -0
- package/dist/search/index.d.ts +13 -0
- package/dist/search/index.js +13 -0
- package/dist/search/types.d.ts +40 -0
- package/dist/search/types.js +20 -0
- package/dist/seo/Head.svelte +190 -0
- package/dist/seo/Head.svelte.d.ts +86 -0
- package/dist/seo/JsonLd.svelte +30 -0
- package/dist/seo/JsonLd.svelte.d.ts +20 -0
- package/dist/seo/index.d.ts +18 -0
- package/dist/seo/index.js +17 -0
- package/dist/seo/json-ld.d.ts +33 -0
- package/dist/seo/json-ld.js +29 -0
- package/dist/seo/og-image.d.ts +72 -0
- package/dist/seo/og-image.js +82 -0
- package/dist/seo/types.d.ts +43 -0
- package/dist/seo/types.js +6 -0
- package/dist/theme.css +161 -0
- package/dist/tips/PopoverTip.svelte +80 -0
- package/dist/tips/PopoverTip.svelte.d.ts +33 -0
- package/dist/tips/Tip.svelte +91 -0
- package/dist/tips/Tip.svelte.d.ts +25 -0
- package/dist/tips/index.d.ts +15 -0
- package/dist/tips/index.js +14 -0
- package/dist/tips/tip-stack.d.ts +26 -0
- package/dist/tips/tip-stack.js +37 -0
- package/dist/tips/tip-store.svelte.d.ts +75 -0
- package/dist/tips/tip-store.svelte.js +158 -0
- package/dist/tips/types.d.ts +46 -0
- package/dist/tips/types.js +6 -0
- package/dist/ui/Accordion.svelte +75 -0
- package/dist/ui/Accordion.svelte.d.ts +50 -0
- package/dist/ui/AccordionItem.svelte +73 -0
- package/dist/ui/AccordionItem.svelte.d.ts +18 -0
- package/dist/ui/Alert.svelte +61 -0
- package/dist/ui/Alert.svelte.d.ts +37 -0
- package/dist/ui/Badge.svelte +39 -0
- package/dist/ui/Badge.svelte.d.ts +32 -0
- package/dist/ui/Button.svelte +44 -0
- package/dist/ui/Button.svelte.d.ts +29 -0
- package/dist/ui/ButtonGroup.svelte +24 -0
- package/dist/ui/ButtonGroup.svelte.d.ts +17 -0
- package/dist/ui/Card.svelte +49 -0
- package/dist/ui/Card.svelte.d.ts +44 -0
- package/dist/ui/Chip.svelte +58 -0
- package/dist/ui/Chip.svelte.d.ts +21 -0
- package/dist/ui/ConfirmButton.svelte +75 -0
- package/dist/ui/ConfirmButton.svelte.d.ts +48 -0
- package/dist/ui/ContextMenu.svelte +75 -0
- package/dist/ui/ContextMenu.svelte.d.ts +25 -0
- package/dist/ui/Disclosure.svelte +46 -0
- package/dist/ui/Disclosure.svelte.d.ts +22 -0
- package/dist/ui/Divider.svelte +47 -0
- package/dist/ui/Divider.svelte.d.ts +28 -0
- package/dist/ui/DropdownMenu.svelte +44 -0
- package/dist/ui/DropdownMenu.svelte.d.ts +30 -0
- package/dist/ui/EmptyState.svelte +37 -0
- package/dist/ui/EmptyState.svelte.d.ts +22 -0
- package/dist/ui/ExternalLink.svelte +38 -0
- package/dist/ui/ExternalLink.svelte.d.ts +34 -0
- package/dist/ui/Heading.svelte +58 -0
- package/dist/ui/Heading.svelte.d.ts +22 -0
- package/dist/ui/Link.svelte +34 -0
- package/dist/ui/Link.svelte.d.ts +20 -0
- package/dist/ui/LinkButton.svelte +51 -0
- package/dist/ui/LinkButton.svelte.d.ts +33 -0
- package/dist/ui/Menu.svelte +24 -0
- package/dist/ui/Menu.svelte.d.ts +13 -0
- package/dist/ui/MenuCheckboxItem.svelte +33 -0
- package/dist/ui/MenuCheckboxItem.svelte.d.ts +20 -0
- package/dist/ui/MenuItem.svelte +73 -0
- package/dist/ui/MenuItem.svelte.d.ts +21 -0
- package/dist/ui/MenuRadioGroup.svelte +25 -0
- package/dist/ui/MenuRadioGroup.svelte.d.ts +20 -0
- package/dist/ui/MenuRadioItem.svelte +20 -0
- package/dist/ui/MenuRadioItem.svelte.d.ts +15 -0
- package/dist/ui/MenuSeparator.svelte +27 -0
- package/dist/ui/MenuSeparator.svelte.d.ts +8 -0
- package/dist/ui/MenuSub.svelte +24 -0
- package/dist/ui/MenuSub.svelte.d.ts +15 -0
- package/dist/ui/Popover.svelte +63 -0
- package/dist/ui/Popover.svelte.d.ts +40 -0
- package/dist/ui/ShareButton.svelte +64 -0
- package/dist/ui/ShareButton.svelte.d.ts +39 -0
- package/dist/ui/Skeleton.svelte +43 -0
- package/dist/ui/Skeleton.svelte.d.ts +22 -0
- package/dist/ui/Spinner.svelte +41 -0
- package/dist/ui/Spinner.svelte.d.ts +35 -0
- package/dist/ui/Stack.svelte +36 -0
- package/dist/ui/Stack.svelte.d.ts +48 -0
- package/dist/ui/ThemeToggle.svelte +65 -0
- package/dist/ui/ThemeToggle.svelte.d.ts +24 -0
- package/dist/ui/ToggleButton.svelte +58 -0
- package/dist/ui/ToggleButton.svelte.d.ts +45 -0
- package/dist/ui/ToggleGroup.svelte +142 -0
- package/dist/ui/ToggleGroup.svelte.d.ts +86 -0
- package/dist/ui/Toolbar.svelte +40 -0
- package/dist/ui/Toolbar.svelte.d.ts +20 -0
- package/dist/ui/ToolbarButton.svelte +29 -0
- package/dist/ui/ToolbarButton.svelte.d.ts +21 -0
- package/dist/ui/ToolbarLink.svelte +21 -0
- package/dist/ui/ToolbarLink.svelte.d.ts +12 -0
- package/dist/ui/ToolbarSeparator.svelte +22 -0
- package/dist/ui/ToolbarSeparator.svelte.d.ts +12 -0
- package/dist/ui/ToolbarToggleGroup.svelte +66 -0
- package/dist/ui/ToolbarToggleGroup.svelte.d.ts +52 -0
- package/dist/ui/Tooltip.svelte +54 -0
- package/dist/ui/Tooltip.svelte.d.ts +35 -0
- package/dist/ui/VisuallyHidden.svelte +23 -0
- package/dist/ui/VisuallyHidden.svelte.d.ts +10 -0
- package/dist/ui/accordion-context.d.ts +26 -0
- package/dist/ui/accordion-context.js +23 -0
- package/dist/ui/colour-token.d.ts +41 -0
- package/dist/ui/colour-token.js +49 -0
- package/dist/ui/context-menu.d.ts +13 -0
- package/dist/ui/context-menu.js +13 -0
- package/dist/ui/index.d.ts +63 -0
- package/dist/ui/index.js +62 -0
- package/dist/ui/menu-context.d.ts +20 -0
- package/dist/ui/menu-context.js +22 -0
- package/dist/ui/menu-parts/CheckboxItemPart.svelte +26 -0
- package/dist/ui/menu-parts/CheckboxItemPart.svelte.d.ts +5 -0
- package/dist/ui/menu-parts/ItemPart.svelte +29 -0
- package/dist/ui/menu-parts/ItemPart.svelte.d.ts +5 -0
- package/dist/ui/menu-parts/RadioGroupPart.svelte +24 -0
- package/dist/ui/menu-parts/RadioGroupPart.svelte.d.ts +5 -0
- package/dist/ui/menu-parts/RadioItemPart.svelte +22 -0
- package/dist/ui/menu-parts/RadioItemPart.svelte.d.ts +5 -0
- package/dist/ui/menu-parts/SeparatorPart.svelte +16 -0
- package/dist/ui/menu-parts/SeparatorPart.svelte.d.ts +5 -0
- package/dist/ui/menu-parts/SubPart.svelte +28 -0
- package/dist/ui/menu-parts/SubPart.svelte.d.ts +5 -0
- package/dist/ui/menu-parts/menu-parts.d.ts +104 -0
- package/dist/ui/menu-parts/menu-parts.js +31 -0
- package/dist/ui/menu-parts/parts.d.ts +12 -0
- package/dist/ui/menu-parts/parts.js +27 -0
- package/dist/ui/slug.d.ts +19 -0
- package/dist/ui/slug.js +25 -0
- package/dist/ui/toggle-classes.d.ts +39 -0
- package/dist/ui/toggle-classes.js +36 -0
- package/dist/ui/tones.d.ts +103 -0
- package/dist/ui/tones.js +240 -0
- package/package.json +41 -25
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
One horizontal bar split into proportional, coloured segments: a vote share, a storage breakdown, a pass/fail split.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
SegmentBar — one horizontal bar split into proportional, coloured segments:
|
|
6
|
+
a vote share, a storage breakdown, a pass/fail split.
|
|
7
|
+
|
|
8
|
+
ARIA contract, and the whole reason this is a component: the bar is a
|
|
9
|
+
SINGLE `role="img"` whose `aria-label` spells out every segment ("Storage:
|
|
10
|
+
photos 62%, video 31%, other 7%"), so assistive technology gets the picture
|
|
11
|
+
in one read. The alternative — a run of coloured boxes, each with its own
|
|
12
|
+
label — is a dozen unlabelled or half-labelled announcements that never add
|
|
13
|
+
up to the comparison the bar is drawn to make. Every segment is therefore
|
|
14
|
+
`aria-hidden`, and the in-segment percentages are decorative.
|
|
15
|
+
|
|
16
|
+
Fractions are given, not derived from values: the caller already knows its
|
|
17
|
+
denominator (and whether the remainder should stay unfilled), and passing
|
|
18
|
+
shares keeps this component out of the business of summing anything. They
|
|
19
|
+
are clamped, and a total under 1 leaves the track showing.
|
|
20
|
+
|
|
21
|
+
A segment's colour is either a semantic `tone` or a `colourToken` — a CSS
|
|
22
|
+
custom-property NAME the app's theme declares in both its light and dark
|
|
23
|
+
themes. The value never appears here; see `ui/colour-token.ts`.
|
|
24
|
+
-->
|
|
25
|
+
<script lang="ts">import { getComponentsContext } from "../context.svelte.js";
|
|
26
|
+
import { backgroundTone } from "../ui/tones.js";
|
|
27
|
+
import { colourTokenStyle } from "../ui/colour-token.js";
|
|
28
|
+
import { barSize } from "./sizes.js";
|
|
29
|
+
/** The custom property a segment's `colourToken` is bound to. */
|
|
30
|
+
const SEGMENT_COLOUR_PROPERTY = "--segment-colour";
|
|
31
|
+
let { label, segments, showValues = false, marker, size = "md", locales, class: className, ...rest } = $props();
|
|
32
|
+
const context = getComponentsContext();
|
|
33
|
+
const clamp = (fraction) => Math.min(1, Math.max(0, fraction));
|
|
34
|
+
const percent = $derived(new Intl.NumberFormat(locales ?? context.locale(), {
|
|
35
|
+
style: "percent",
|
|
36
|
+
maximumFractionDigits: 1
|
|
37
|
+
}));
|
|
38
|
+
const shares = $derived(segments.map((segment) => ({
|
|
39
|
+
segment,
|
|
40
|
+
fraction: clamp(segment.fraction)
|
|
41
|
+
})));
|
|
42
|
+
const description = $derived(`${label}: ${shares.map(({ segment, fraction }) => `${segment.label} ${percent.format(fraction)}`).join(", ")}`);
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<div
|
|
46
|
+
{...rest}
|
|
47
|
+
role="img"
|
|
48
|
+
aria-label={description}
|
|
49
|
+
class={[
|
|
50
|
+
'bg-base-300 relative flex w-full overflow-hidden rounded-(--radius-selector)',
|
|
51
|
+
barSize[size],
|
|
52
|
+
className,
|
|
53
|
+
]}
|
|
54
|
+
>
|
|
55
|
+
{#each shares as { segment, fraction }, index (index)}
|
|
56
|
+
<div
|
|
57
|
+
aria-hidden="true"
|
|
58
|
+
class={[
|
|
59
|
+
'flex h-full items-center justify-center overflow-hidden text-xs font-medium whitespace-nowrap',
|
|
60
|
+
segment.colourToken === undefined
|
|
61
|
+
? [backgroundTone[segment.tone ?? 'neutral'], 'text-neutral-content']
|
|
62
|
+
: 'text-base-100 bg-(--segment-colour)',
|
|
63
|
+
]}
|
|
64
|
+
style={[
|
|
65
|
+
`width: ${(fraction * 100).toFixed(2)}%`,
|
|
66
|
+
colourTokenStyle(SEGMENT_COLOUR_PROPERTY, segment.colourToken),
|
|
67
|
+
]
|
|
68
|
+
.filter((part) => part !== undefined)
|
|
69
|
+
.join('; ')}
|
|
70
|
+
>
|
|
71
|
+
{#if showValues && size !== 'sm' && fraction >= 0.08}
|
|
72
|
+
{percent.format(fraction)}
|
|
73
|
+
{/if}
|
|
74
|
+
</div>
|
|
75
|
+
{/each}
|
|
76
|
+
{#if marker !== undefined}
|
|
77
|
+
<div
|
|
78
|
+
aria-hidden="true"
|
|
79
|
+
class="bg-base-content absolute inset-y-0 w-0.5"
|
|
80
|
+
style={`left: ${(clamp(marker) * 100).toFixed(2)}%`}
|
|
81
|
+
></div>
|
|
82
|
+
{/if}
|
|
83
|
+
</div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import { type Tone } from '../ui/tones.ts';
|
|
3
|
+
import { type BarSize } from './sizes.ts';
|
|
4
|
+
/** One part of a `SegmentBar`: its label, its share of the bar, and its colour. */
|
|
5
|
+
export interface BarSegment {
|
|
6
|
+
/** Read out for this segment in the bar's accessible label. */
|
|
7
|
+
readonly label: string;
|
|
8
|
+
/** Share of the whole bar, in `[0, 1]`. */
|
|
9
|
+
readonly fraction: number;
|
|
10
|
+
/** A CSS custom-property name the app's theme declares (`--party-alp`). */
|
|
11
|
+
readonly colourToken?: string | undefined;
|
|
12
|
+
/** Semantic colour, used when there is no `colourToken`. */
|
|
13
|
+
readonly tone?: Tone | undefined;
|
|
14
|
+
}
|
|
15
|
+
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'role'> {
|
|
16
|
+
/** What the bar shows. Leads the accessible label. */
|
|
17
|
+
label: string;
|
|
18
|
+
/** The parts, in order; widths are proportional to their values. */
|
|
19
|
+
segments: readonly BarSegment[];
|
|
20
|
+
/** Print each segment's percentage inside it when it fits. */
|
|
21
|
+
showValues?: boolean | undefined;
|
|
22
|
+
/** Draw a marker at this fraction — a 50% majority line, a quota. */
|
|
23
|
+
marker?: number | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Bar height step.
|
|
26
|
+
* @defaultValue `'md'`
|
|
27
|
+
*/
|
|
28
|
+
size?: BarSize | undefined;
|
|
29
|
+
/** Locale(s) for the percentages. Defaults to the components context's. */
|
|
30
|
+
locales?: string | readonly string[] | undefined;
|
|
31
|
+
/** Extra classes, merged last. */
|
|
32
|
+
class?: string | undefined;
|
|
33
|
+
}
|
|
34
|
+
/** One horizontal bar split into proportional, coloured segments: a vote share, a storage breakdown, a pass/fail split. */
|
|
35
|
+
declare const SegmentBar: import("svelte").Component<Props, {}, "">;
|
|
36
|
+
type SegmentBar = ReturnType<typeof SegmentBar>;
|
|
37
|
+
export default SegmentBar;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
One daisyUI `stat`: a headline figure with its label and optional change line and description; wrap a row in `Stats`.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
StatTile — one daisyUI `stat`: a headline figure with its label, an optional
|
|
6
|
+
change line and an optional description. Wrap a row of them in `Stats`.
|
|
7
|
+
|
|
8
|
+
ARIA contract: no roles, on purpose. A stat is text, and daisyUI's
|
|
9
|
+
`stat-title` / `stat-value` / `stat-desc` order puts it in the reading order
|
|
10
|
+
a reader expects — label, then figure, then the change. What the markup
|
|
11
|
+
cannot convey is the DIRECTION of the change: the arrow that tells a sighted
|
|
12
|
+
reader "up" is `aria-hidden`, so the direction is also spelled out in
|
|
13
|
+
visually hidden text beside it, and the tone colour is never the only
|
|
14
|
+
carrier.
|
|
15
|
+
|
|
16
|
+
Numbers are formatted through `Intl` for the context's locale; pass a
|
|
17
|
+
pre-formatted string for anything that is not a plain count.
|
|
18
|
+
-->
|
|
19
|
+
<script lang="ts">import { Minus, TrendingDown, TrendingUp } from "@lucide/svelte";
|
|
20
|
+
import { getComponentsContext } from "../context.svelte.js";
|
|
21
|
+
let { label, value, delta, description, upLabel = "Up", downLabel = "Down", flatLabel = "No change", locales, figure, class: className, ...rest } = $props();
|
|
22
|
+
const context = getComponentsContext();
|
|
23
|
+
const chosenLocales = $derived(locales ?? context.locale());
|
|
24
|
+
const countFormat = $derived(new Intl.NumberFormat(chosenLocales));
|
|
25
|
+
const signedCount = $derived(new Intl.NumberFormat(chosenLocales, {
|
|
26
|
+
signDisplay: "exceptZero",
|
|
27
|
+
maximumFractionDigits: 0
|
|
28
|
+
}));
|
|
29
|
+
const signedDecimal = $derived(new Intl.NumberFormat(chosenLocales, {
|
|
30
|
+
signDisplay: "exceptZero",
|
|
31
|
+
maximumFractionDigits: 1
|
|
32
|
+
}));
|
|
33
|
+
const signedPercent = $derived(new Intl.NumberFormat(chosenLocales, {
|
|
34
|
+
style: "percent",
|
|
35
|
+
signDisplay: "exceptZero",
|
|
36
|
+
maximumFractionDigits: 1
|
|
37
|
+
}));
|
|
38
|
+
const formattedValue = $derived(typeof value === "number" ? countFormat.format(value) : value);
|
|
39
|
+
const deltaText = $derived.by(() => {
|
|
40
|
+
if (delta === undefined) return "";
|
|
41
|
+
const unit = delta.unit ?? "count";
|
|
42
|
+
const number = unit === "count" ? signedCount.format(delta.value) : unit === "percent" ? signedPercent.format(delta.value / 100) : signedDecimal.format(delta.value);
|
|
43
|
+
return delta.label === undefined ? number : `${number} ${delta.label}`;
|
|
44
|
+
});
|
|
45
|
+
const direction = $derived(delta === undefined || delta.value === 0 ? "flat" : delta.value > 0 ? "up" : "down");
|
|
46
|
+
const deltaClass = {
|
|
47
|
+
up: "text-success",
|
|
48
|
+
down: "text-error",
|
|
49
|
+
flat: "text-base-content/70"
|
|
50
|
+
};
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<div {...rest} class={['stat', className]}>
|
|
54
|
+
{#if figure}
|
|
55
|
+
<div class="stat-figure">{@render figure()}</div>
|
|
56
|
+
{/if}
|
|
57
|
+
<div class="stat-title">{label}</div>
|
|
58
|
+
<div class="stat-value tabular-nums">{formattedValue}</div>
|
|
59
|
+
{#if delta !== undefined}
|
|
60
|
+
<div class={['stat-desc flex items-center gap-1 tabular-nums', deltaClass[direction]]}>
|
|
61
|
+
{#if direction === 'up'}
|
|
62
|
+
<TrendingUp class="size-4" aria-hidden="true" />
|
|
63
|
+
<span class="sr-only">{upLabel}</span>
|
|
64
|
+
{:else if direction === 'down'}
|
|
65
|
+
<TrendingDown class="size-4" aria-hidden="true" />
|
|
66
|
+
<span class="sr-only">{downLabel}</span>
|
|
67
|
+
{:else}
|
|
68
|
+
<Minus class="size-4" aria-hidden="true" />
|
|
69
|
+
<span class="sr-only">{flatLabel}</span>
|
|
70
|
+
{/if}
|
|
71
|
+
<span>{deltaText}</span>
|
|
72
|
+
</div>
|
|
73
|
+
{/if}
|
|
74
|
+
{#if description !== undefined}
|
|
75
|
+
<div class="stat-desc">{description}</div>
|
|
76
|
+
{/if}
|
|
77
|
+
</div>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
/** The change line a `StatTile` shows under its value: a signed amount, how to render it, and trailing words. */
|
|
4
|
+
export interface StatDelta {
|
|
5
|
+
/**
|
|
6
|
+
* The change. Positive is up. With `unit: 'percent'` it is read as a
|
|
7
|
+
* percentage — `3.2` renders as `+3.2%`.
|
|
8
|
+
*/
|
|
9
|
+
readonly value: number;
|
|
10
|
+
/**
|
|
11
|
+
* How to render it: a whole count, a percentage, or a decimal whose unit
|
|
12
|
+
* the caller names in `label` (`'pts swing'`).
|
|
13
|
+
*/
|
|
14
|
+
readonly unit?: 'count' | 'percent' | 'points' | undefined;
|
|
15
|
+
/** Trailing words, e.g. `swing` or `since April`. */
|
|
16
|
+
readonly label?: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
19
|
+
/** The `stat-title`. */
|
|
20
|
+
label: string;
|
|
21
|
+
/** The headline figure; a number is formatted as a count. */
|
|
22
|
+
value: string | number;
|
|
23
|
+
/** Change line under the value. */
|
|
24
|
+
delta?: StatDelta | undefined;
|
|
25
|
+
/** Plain description, rendered after the delta when both are present. */
|
|
26
|
+
description?: string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Announced in place of the rising arrow.
|
|
29
|
+
* @defaultValue `'Up'`
|
|
30
|
+
*/
|
|
31
|
+
upLabel?: string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Announced in place of the falling arrow.
|
|
34
|
+
* @defaultValue `'Down'`
|
|
35
|
+
*/
|
|
36
|
+
downLabel?: string | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Announced in place of the flat marker.
|
|
39
|
+
* @defaultValue `'No change'`
|
|
40
|
+
*/
|
|
41
|
+
flatLabel?: string | undefined;
|
|
42
|
+
/** Locale(s) for the figures. Defaults to the components context's. */
|
|
43
|
+
locales?: string | readonly string[] | undefined;
|
|
44
|
+
/** Icon or sparkline in the `stat-figure` slot. */
|
|
45
|
+
figure?: Snippet<[]> | undefined;
|
|
46
|
+
}
|
|
47
|
+
/** One daisyUI `stat`: a headline figure with its label and optional change line and description; wrap a row in `Stats`. */
|
|
48
|
+
declare const StatTile: import("svelte").Component<Props, {}, "">;
|
|
49
|
+
type StatTile = ReturnType<typeof StatTile>;
|
|
50
|
+
export default StatTile;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The daisyUI `stats` wrapper a row of `StatTile`s sits in, drawing the dividers between them.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Stats — the daisyUI `stats` wrapper a row of `StatTile`s sits in. It is what
|
|
6
|
+
draws the dividers between tiles, so a lone tile still wants one.
|
|
7
|
+
|
|
8
|
+
No ARIA of its own: it is a grouping box around text. When a row of stats
|
|
9
|
+
needs a name (a dashboard with several), give it `aria-label` — the native
|
|
10
|
+
attributes spread — or put it inside a `Section` that already has a heading.
|
|
11
|
+
-->
|
|
12
|
+
<script lang="ts">import { statsOrientation } from "./sizes.js";
|
|
13
|
+
let { orientation = "responsive", children, class: className, ...rest } = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<div {...rest} class={['stats', statsOrientation[orientation], className]}>
|
|
17
|
+
{@render children()}
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { type StatsOrientation } from './sizes.ts';
|
|
4
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
/**
|
|
6
|
+
* Row, column, or stacked-then-row from the `sm` breakpoint up.
|
|
7
|
+
* @defaultValue `'responsive'`
|
|
8
|
+
*/
|
|
9
|
+
orientation?: StatsOrientation | undefined;
|
|
10
|
+
/** The `StatTile`s. */
|
|
11
|
+
children: Snippet<[]>;
|
|
12
|
+
}
|
|
13
|
+
/** The daisyUI `stats` wrapper a row of `StatTile`s sits in, drawing the dividers between them. */
|
|
14
|
+
declare const Stats: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type Stats = ReturnType<typeof Stats>;
|
|
16
|
+
export default Stats;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The stages of a multi-step flow as daisyUI `steps`, with the current one marked.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Steps — a short, fixed sequence (a sign-up wizard, an order's fulfilment,
|
|
6
|
+
"Plan → Sow → Transplant → Harvest") where position and state are the
|
|
7
|
+
content. Unlike `Timeline`, which is dated, open-ended history.
|
|
8
|
+
|
|
9
|
+
Each step's state comes from its own `state`, or, when that is omitted,
|
|
10
|
+
from the list's `current` index: before it is complete, at it is current,
|
|
11
|
+
after it is upcoming. An explicit `state` always wins, so an `error` step
|
|
12
|
+
can sit in a `current`-driven wizard.
|
|
13
|
+
|
|
14
|
+
ARIA contract: an `<ol>` named by `label`, because order is the content.
|
|
15
|
+
Colour carries nothing on its own (WCAG 1.4.1): each step reads its label
|
|
16
|
+
followed by a visually hidden state ("Sow, Completed"). The marker, the
|
|
17
|
+
step number or a ✓ / ✕ glyph, is always a real `step-icon` span with
|
|
18
|
+
`aria-hidden`. Rendering one suppresses daisyUI's `::after` number, and
|
|
19
|
+
CSS generated content would otherwise join the accessible name. The
|
|
20
|
+
current step carries `aria-current="step"`: on its link in link mode, on
|
|
21
|
+
the `<li>` otherwise. Only steps with an `href` are links; whether an
|
|
22
|
+
upcoming step is navigable is the caller's call, not this component's.
|
|
23
|
+
-->
|
|
24
|
+
<script lang="ts">import { getComponentsContext } from "../context.svelte.js";
|
|
25
|
+
import { stepTone } from "../ui/tones.js";
|
|
26
|
+
import { stepsOrientation } from "./sizes.js";
|
|
27
|
+
let { items, label, current, orientation = "horizontal", tone = "primary", completeLabel = "Completed", currentLabel = "Current step", upcomingLabel = "Not started", errorLabel = "Error", marker, class: className, ...rest } = $props();
|
|
28
|
+
const context = getComponentsContext();
|
|
29
|
+
function stateOf(step, index) {
|
|
30
|
+
if (step.state !== undefined) return step.state;
|
|
31
|
+
if (current === undefined || index > current) return "upcoming";
|
|
32
|
+
return index < current ? "complete" : "current";
|
|
33
|
+
}
|
|
34
|
+
const stateLabels = $derived({
|
|
35
|
+
complete: completeLabel,
|
|
36
|
+
current: currentLabel,
|
|
37
|
+
upcoming: upcomingLabel,
|
|
38
|
+
error: errorLabel
|
|
39
|
+
});
|
|
40
|
+
const stateClasses = $derived({
|
|
41
|
+
complete: stepTone[tone],
|
|
42
|
+
current: stepTone[tone],
|
|
43
|
+
upcoming: "",
|
|
44
|
+
error: stepTone.error
|
|
45
|
+
});
|
|
46
|
+
const glyphs = {
|
|
47
|
+
complete: "✓",
|
|
48
|
+
error: "✕"
|
|
49
|
+
};
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<ol {...rest} aria-label={label} class={['steps', stepsOrientation[orientation], className]}>
|
|
53
|
+
{#each items as step, index (step.id)}
|
|
54
|
+
{@const state = stateOf(step, index)}
|
|
55
|
+
{@const ariaCurrent = state === 'current' ? 'step' : undefined}
|
|
56
|
+
<li
|
|
57
|
+
class={['step', stateClasses[state]]}
|
|
58
|
+
aria-current={step.href === undefined ? ariaCurrent : undefined}
|
|
59
|
+
>
|
|
60
|
+
<span class="step-icon" aria-hidden="true">
|
|
61
|
+
{#if marker}{@render marker(step, index)}{:else}{glyphs[state] ?? index + 1}{/if}
|
|
62
|
+
</span>
|
|
63
|
+
{#if step.href !== undefined}
|
|
64
|
+
<a href={context.href(step.href)} class="link link-hover" aria-current={ariaCurrent}>
|
|
65
|
+
{step.label}<span class="sr-only">, {stateLabels[state]}</span>
|
|
66
|
+
</a>
|
|
67
|
+
{:else}
|
|
68
|
+
<span>{step.label}<span class="sr-only">, {stateLabels[state]}</span></span>
|
|
69
|
+
{/if}
|
|
70
|
+
</li>
|
|
71
|
+
{/each}
|
|
72
|
+
</ol>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLOlAttributes } from 'svelte/elements';
|
|
3
|
+
import { type Tone } from '../ui/tones.ts';
|
|
4
|
+
import { type StepsOrientation } from './sizes.ts';
|
|
5
|
+
/** Where a step stands in the flow. */
|
|
6
|
+
export type StepState = 'complete' | 'current' | 'upcoming' | 'error';
|
|
7
|
+
/** One stage of a `Steps` list. */
|
|
8
|
+
export interface StepItem {
|
|
9
|
+
/** Stable key for the step. */
|
|
10
|
+
readonly id: string;
|
|
11
|
+
/** The step's name, read first. */
|
|
12
|
+
readonly label: string;
|
|
13
|
+
/** Overrides the state derived from the list's `current` index. */
|
|
14
|
+
readonly state?: StepState | undefined;
|
|
15
|
+
/** Makes the step a link (to revisit it), resolved through the components context's `href`. */
|
|
16
|
+
readonly href?: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
interface Props extends Omit<HTMLOlAttributes, 'children'> {
|
|
19
|
+
/** The steps, in order. */
|
|
20
|
+
items: readonly StepItem[];
|
|
21
|
+
/** Accessible name of the list, e.g. `'Checkout progress'`. */
|
|
22
|
+
label: string;
|
|
23
|
+
/**
|
|
24
|
+
* Index of the current step. Steps before it are complete and steps after
|
|
25
|
+
* it upcoming, unless a step sets its own `state`.
|
|
26
|
+
*/
|
|
27
|
+
current?: number | undefined;
|
|
28
|
+
/** @defaultValue `'horizontal'` */
|
|
29
|
+
orientation?: StepsOrientation | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Tone of the complete and current steps.
|
|
32
|
+
* @defaultValue `'primary'`
|
|
33
|
+
*/
|
|
34
|
+
tone?: Tone | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Read after a complete step's label.
|
|
37
|
+
* @defaultValue `'Completed'`
|
|
38
|
+
*/
|
|
39
|
+
completeLabel?: string | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Read after the current step's label.
|
|
42
|
+
* @defaultValue `'Current step'`
|
|
43
|
+
*/
|
|
44
|
+
currentLabel?: string | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Read after an upcoming step's label.
|
|
47
|
+
* @defaultValue `'Not started'`
|
|
48
|
+
*/
|
|
49
|
+
upcomingLabel?: string | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Read after a failed step's label.
|
|
52
|
+
* @defaultValue `'Error'`
|
|
53
|
+
*/
|
|
54
|
+
errorLabel?: string | undefined;
|
|
55
|
+
/** Custom marker content per step (an icon), rendered in the `aria-hidden` `step-icon`. */
|
|
56
|
+
marker?: Snippet<[StepItem, number]> | undefined;
|
|
57
|
+
}
|
|
58
|
+
/** The stages of a multi-step flow as daisyUI `steps`, with the current one marked. */
|
|
59
|
+
declare const Steps: import("svelte").Component<Props, {}, "">;
|
|
60
|
+
type Steps = ReturnType<typeof Steps>;
|
|
61
|
+
export default Steps;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A vertical daisyUI `timeline` of dated entries.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Timeline — a vertical daisyUI `timeline` of dated entries: offices held,
|
|
6
|
+
releases shipped, a plant's life in a bed.
|
|
7
|
+
|
|
8
|
+
An `<ol>` because the order is the content: read out of sequence the list
|
|
9
|
+
means something else. Each entry shows its span on the start side, a marker
|
|
10
|
+
in the middle (filled for an open-ended, still-current entry, tinted with
|
|
11
|
+
the caller's colour token when given) and a `timeline-box` with the entry
|
|
12
|
+
itself.
|
|
13
|
+
|
|
14
|
+
ARIA contract: native list semantics plus an `aria-label` on the list, so a
|
|
15
|
+
reader hears what the sequence is before its length. The dash between the
|
|
16
|
+
two dates is `aria-hidden` and `toLabel` is read in its place — "May 2019 –
|
|
17
|
+
May 2022" is announced as a range, not a subtraction — and an open-ended
|
|
18
|
+
entry is introduced by `currentLabel` rather than by the filled marker
|
|
19
|
+
alone. Both markers are `aria-hidden`.
|
|
20
|
+
|
|
21
|
+
`colourToken` is a CSS custom-property NAME the app's theme declares; the
|
|
22
|
+
colour value itself never appears here. See `ui/colour-token.ts`.
|
|
23
|
+
-->
|
|
24
|
+
<script lang="ts">import { Circle, CircleDot } from "@lucide/svelte";
|
|
25
|
+
import { getComponentsContext } from "../context.svelte.js";
|
|
26
|
+
import { colourTokenStyle } from "../ui/colour-token.js";
|
|
27
|
+
/** The custom property an entry's `colourToken` is bound to. */
|
|
28
|
+
const TIMELINE_COLOUR_PROPERTY = "--timeline-colour";
|
|
29
|
+
let { items, presentLabel = "present", toLabel = "to", currentLabel = "Current", label = "Timeline", item: itemBody, class: className, ...rest } = $props();
|
|
30
|
+
const context = getComponentsContext();
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<ol
|
|
34
|
+
{...rest}
|
|
35
|
+
aria-label={label}
|
|
36
|
+
class={['timeline timeline-vertical timeline-compact timeline-snap-icon', className]}
|
|
37
|
+
>
|
|
38
|
+
{#each items as entry, index (entry.id)}
|
|
39
|
+
{@const current = entry.end === undefined}
|
|
40
|
+
<li style={colourTokenStyle(TIMELINE_COLOUR_PROPERTY, entry.colourToken)}>
|
|
41
|
+
{#if index > 0}<hr />{/if}
|
|
42
|
+
<div class="timeline-start text-base-content/70 mb-2 text-sm tabular-nums md:mb-0">
|
|
43
|
+
<time datetime={entry.start.dateTime}>{entry.start.label}</time>
|
|
44
|
+
<span aria-hidden="true">–</span>
|
|
45
|
+
<span class="sr-only">{toLabel}</span>
|
|
46
|
+
{#if entry.end === undefined}
|
|
47
|
+
<span>{presentLabel}</span>
|
|
48
|
+
{:else}
|
|
49
|
+
<time datetime={entry.end.dateTime}>{entry.end.label}</time>
|
|
50
|
+
{/if}
|
|
51
|
+
</div>
|
|
52
|
+
<div
|
|
53
|
+
class={[
|
|
54
|
+
'timeline-middle',
|
|
55
|
+
entry.colourToken === undefined
|
|
56
|
+
? 'text-base-content/60'
|
|
57
|
+
: 'text-(--timeline-colour)',
|
|
58
|
+
]}
|
|
59
|
+
>
|
|
60
|
+
{#if current}
|
|
61
|
+
<CircleDot class="size-5" aria-hidden="true" />
|
|
62
|
+
<span class="sr-only">{currentLabel}</span>
|
|
63
|
+
{:else}
|
|
64
|
+
<Circle class="size-5" aria-hidden="true" />
|
|
65
|
+
{/if}
|
|
66
|
+
</div>
|
|
67
|
+
<div class="timeline-end timeline-box">
|
|
68
|
+
{#if itemBody}
|
|
69
|
+
{@render itemBody(entry)}
|
|
70
|
+
{:else}
|
|
71
|
+
<p class="font-medium">
|
|
72
|
+
{#if entry.href !== undefined}
|
|
73
|
+
<a href={context.href(entry.href)} class="link link-hover">{entry.label}</a>
|
|
74
|
+
{:else}
|
|
75
|
+
{entry.label}
|
|
76
|
+
{/if}
|
|
77
|
+
</p>
|
|
78
|
+
{#if entry.subtitle !== undefined}
|
|
79
|
+
<p class="text-base-content/70 text-sm">{entry.subtitle}</p>
|
|
80
|
+
{/if}
|
|
81
|
+
{/if}
|
|
82
|
+
</div>
|
|
83
|
+
{#if index < items.length - 1}<hr />{/if}
|
|
84
|
+
</li>
|
|
85
|
+
{/each}
|
|
86
|
+
</ol>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLOlAttributes } from 'svelte/elements';
|
|
3
|
+
/** One end of a `Timeline` entry's span: display text plus an optional machine-readable `datetime`. */
|
|
4
|
+
export interface TimelineDate {
|
|
5
|
+
/** Display text, e.g. `March 1996`. */
|
|
6
|
+
readonly label: string;
|
|
7
|
+
/** Machine-readable `<time datetime>` value, e.g. `1996-03-02`. */
|
|
8
|
+
readonly dateTime?: string | undefined;
|
|
9
|
+
}
|
|
10
|
+
/** One dated entry of a `Timeline`: a label, a start, an optional end and link, and an optional theme colour. */
|
|
11
|
+
export interface TimelineEntry {
|
|
12
|
+
/** Stable key for the entry. */
|
|
13
|
+
readonly id: string;
|
|
14
|
+
/** The entry itself — the line in the box. */
|
|
15
|
+
readonly label: string;
|
|
16
|
+
/** Second line under it. */
|
|
17
|
+
readonly subtitle?: string | undefined;
|
|
18
|
+
readonly start: TimelineDate;
|
|
19
|
+
/** Omit for an open-ended, still-current entry. */
|
|
20
|
+
readonly end?: TimelineDate | undefined;
|
|
21
|
+
/** Links the entry's label, through the components context. */
|
|
22
|
+
readonly href?: string | undefined;
|
|
23
|
+
/** A CSS custom-property name the app's theme declares (`--party-alp`). */
|
|
24
|
+
readonly colourToken?: string | undefined;
|
|
25
|
+
}
|
|
26
|
+
interface Props extends Omit<HTMLOlAttributes, 'children'> {
|
|
27
|
+
/** The entries, in display order. */
|
|
28
|
+
items: readonly TimelineEntry[];
|
|
29
|
+
/**
|
|
30
|
+
* Shown in place of a missing `end`.
|
|
31
|
+
* @defaultValue `'present'`
|
|
32
|
+
*/
|
|
33
|
+
presentLabel?: string | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Read between the two dates of a span.
|
|
36
|
+
* @defaultValue `'to'`
|
|
37
|
+
*/
|
|
38
|
+
toLabel?: string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Introduces an open-ended entry.
|
|
41
|
+
* @defaultValue `'Current'`
|
|
42
|
+
*/
|
|
43
|
+
currentLabel?: string | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Accessible name of the list.
|
|
46
|
+
* @defaultValue `'Timeline'`
|
|
47
|
+
*/
|
|
48
|
+
label?: string | undefined;
|
|
49
|
+
/** Replaces the default box body. */
|
|
50
|
+
item?: Snippet<[TimelineEntry]> | undefined;
|
|
51
|
+
}
|
|
52
|
+
/** A vertical daisyUI `timeline` of dated entries. */
|
|
53
|
+
declare const Timeline: import("svelte").Component<Props, {}, "">;
|
|
54
|
+
type Timeline = ReturnType<typeof Timeline>;
|
|
55
|
+
export default Timeline;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The notification region, plus the context that lets any descendant push a toast into it (`getToaster().add({ title: 'Saved' })`).
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Toaster — the notification region, plus the context that lets any descendant
|
|
6
|
+
push into it (`getToaster().add({ title: 'Saved' })`).
|
|
7
|
+
|
|
8
|
+
Hand-rolled rather than on a bits-ui primitive, deliberately: there is no
|
|
9
|
+
interaction to get right. A toast takes no focus, traps nothing and has no
|
|
10
|
+
keyboard contract of its own — it is a live region with a queue and a timer,
|
|
11
|
+
and the queue is a plain rune.
|
|
12
|
+
|
|
13
|
+
ARIA contract: ONE `aria-live="polite"` region, named by `regionLabel`, and
|
|
14
|
+
nothing live inside it. The tempting `role="status"` on each toast is the
|
|
15
|
+
bug this replaces: a status inside a live region makes assistive technology
|
|
16
|
+
announce the same text twice, and a region that is only created when the
|
|
17
|
+
first toast arrives is often not announced at all — so the region is in the
|
|
18
|
+
document from mount, empty, and only its contents change. Dismiss is a
|
|
19
|
+
labelled text button, not a bare glyph.
|
|
20
|
+
|
|
21
|
+
Timers are held in a map and cleared on destroy: a toast that outlives its
|
|
22
|
+
page would otherwise write to a component that is gone.
|
|
23
|
+
-->
|
|
24
|
+
<script lang="ts">import { alertTone } from "../ui/tones.js";
|
|
25
|
+
import Button from "../ui/Button.svelte";
|
|
26
|
+
import { toastPosition } from "./sizes.js";
|
|
27
|
+
import { setToaster } from "./toaster.js";
|
|
28
|
+
let { position = "bottom-end", regionLabel = "Notifications", dismissLabel = "Dismiss", durationMs = 6e3, class: className, children } = $props();
|
|
29
|
+
let toasts = $state([]);
|
|
30
|
+
let nextId = 1;
|
|
31
|
+
const timers = new Map();
|
|
32
|
+
const dismiss = (id) => {
|
|
33
|
+
const timer = timers.get(id);
|
|
34
|
+
if (timer !== undefined) {
|
|
35
|
+
clearTimeout(timer);
|
|
36
|
+
timers.delete(id);
|
|
37
|
+
}
|
|
38
|
+
toasts = toasts.filter((toast) => toast.id !== id);
|
|
39
|
+
};
|
|
40
|
+
const api = {
|
|
41
|
+
add(toast, duration = durationMs) {
|
|
42
|
+
const id = nextId++;
|
|
43
|
+
toasts = [...toasts, {
|
|
44
|
+
...toast,
|
|
45
|
+
tone: toast.tone ?? "info",
|
|
46
|
+
id
|
|
47
|
+
}];
|
|
48
|
+
if (duration > 0) timers.set(id, setTimeout(() => dismiss(id), duration));
|
|
49
|
+
return id;
|
|
50
|
+
},
|
|
51
|
+
dismiss
|
|
52
|
+
};
|
|
53
|
+
setToaster(api);
|
|
54
|
+
$effect(() => () => {
|
|
55
|
+
for (const timer of timers.values()) clearTimeout(timer);
|
|
56
|
+
timers.clear();
|
|
57
|
+
});
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
{@render children()}
|
|
61
|
+
|
|
62
|
+
<div
|
|
63
|
+
class={['toast z-50', toastPosition[position], className]}
|
|
64
|
+
aria-live="polite"
|
|
65
|
+
aria-label={regionLabel}
|
|
66
|
+
>
|
|
67
|
+
{#each toasts as toast (toast.id)}
|
|
68
|
+
<div class={['alert items-start shadow-lg', alertTone[toast.tone]]}>
|
|
69
|
+
<div>
|
|
70
|
+
<p class="font-semibold">{toast.title}</p>
|
|
71
|
+
{#if toast.description !== undefined}
|
|
72
|
+
<p class="text-sm">{toast.description}</p>
|
|
73
|
+
{/if}
|
|
74
|
+
</div>
|
|
75
|
+
<Button variant="ghost" size="sm" onclick={() => dismiss(toast.id)}>{dismissLabel}</Button>
|
|
76
|
+
</div>
|
|
77
|
+
{/each}
|
|
78
|
+
</div>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import { type ToastPosition } from './sizes.ts';
|
|
3
|
+
interface Props {
|
|
4
|
+
/**
|
|
5
|
+
* Which corner the stack grows from.
|
|
6
|
+
* @defaultValue `'bottom-end'`
|
|
7
|
+
*/
|
|
8
|
+
position?: ToastPosition | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Accessible name of the live region.
|
|
11
|
+
* @defaultValue `'Notifications'`
|
|
12
|
+
*/
|
|
13
|
+
regionLabel?: string | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Accessible name of every toast's dismiss button.
|
|
16
|
+
* @defaultValue `'Dismiss'`
|
|
17
|
+
*/
|
|
18
|
+
dismissLabel?: string | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* How long a toast lives when `add` is given no duration. `0` = sticky.
|
|
21
|
+
* @defaultValue `6_000`
|
|
22
|
+
*/
|
|
23
|
+
durationMs?: number | undefined;
|
|
24
|
+
/** Extra classes on the region. */
|
|
25
|
+
class?: string | undefined;
|
|
26
|
+
/** The application. Rendered above the region. */
|
|
27
|
+
children: Snippet<[]>;
|
|
28
|
+
}
|
|
29
|
+
/** The notification region, plus the context that lets any descendant push a toast into it (`getToaster().add({ title: 'Saved' })`). */
|
|
30
|
+
declare const Toaster: import("svelte").Component<Props, {}, "">;
|
|
31
|
+
type Toaster = ReturnType<typeof Toaster>;
|
|
32
|
+
export default Toaster;
|