@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,64 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
Hands a title, a URL and some text to the platform share sheet.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
ShareButton — hands a title, a URL and some text to the platform share
|
|
6
|
+
sheet.
|
|
7
|
+
|
|
8
|
+
It renders NOTHING where the Web Share API is absent — every desktop
|
|
9
|
+
Firefox, and the server. A button that opens nothing is worse than no
|
|
10
|
+
button, and the caller cannot know which it has before hydration, so the
|
|
11
|
+
decision is made here and made after mount: reading `navigator.share` during
|
|
12
|
+
SSR would render a button the client then has to remove, which is a layout
|
|
13
|
+
shift on every page that carries one.
|
|
14
|
+
|
|
15
|
+
`canShare`, where the browser has it, is consulted with the SAME payload
|
|
16
|
+
that will be shared — the original implementation tested one
|
|
17
|
+
object and shared another. Where it is missing the only way to find out is
|
|
18
|
+
to try, and the rejection path handles "no". A share sheet the reader
|
|
19
|
+
dismisses also rejects; `onError` sees both, because the API does not
|
|
20
|
+
distinguish them.
|
|
21
|
+
|
|
22
|
+
ARIA contract: a plain `Button`, so nothing beyond its label. The icon is
|
|
23
|
+
decorative.
|
|
24
|
+
-->
|
|
25
|
+
<script lang="ts">import { Share2 } from "@lucide/svelte";
|
|
26
|
+
import Button from "./Button.svelte";
|
|
27
|
+
let { title, text, url, label = "Share", tone, variant = "ghost", size = "sm", class: className, onShare, onError, children } = $props();
|
|
28
|
+
/**
|
|
29
|
+
* Whether this browser can share at all. Set from an effect, never at
|
|
30
|
+
* module or render scope: `navigator` does not exist on the server.
|
|
31
|
+
*/
|
|
32
|
+
let shareable = $state(false);
|
|
33
|
+
$effect(() => {
|
|
34
|
+
shareable = typeof navigator !== "undefined" && typeof navigator.share === "function";
|
|
35
|
+
});
|
|
36
|
+
const payload = $derived({
|
|
37
|
+
...title === undefined ? {} : { title },
|
|
38
|
+
...text === undefined ? {} : { text },
|
|
39
|
+
...url === undefined ? {} : { url }
|
|
40
|
+
});
|
|
41
|
+
const share = async () => {
|
|
42
|
+
if (typeof navigator.canShare === "function" && !navigator.canShare(payload)) {
|
|
43
|
+
onError?.(new Error("This browser cannot share that payload."));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
await navigator.share(payload);
|
|
48
|
+
onShare?.(payload);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
onError?.(error);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
{#if shareable}
|
|
56
|
+
<Button {tone} {variant} {size} class={className} onclick={share}>
|
|
57
|
+
{#if children}
|
|
58
|
+
{@render children()}
|
|
59
|
+
{:else}
|
|
60
|
+
<Share2 class="size-4" aria-hidden="true" />
|
|
61
|
+
{label}
|
|
62
|
+
{/if}
|
|
63
|
+
</Button>
|
|
64
|
+
{/if}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { ButtonVariant, Size, Tone } from './tones.ts';
|
|
3
|
+
interface Props {
|
|
4
|
+
/** Share sheet title. */
|
|
5
|
+
title?: string | undefined;
|
|
6
|
+
/** Body text offered alongside the link. */
|
|
7
|
+
text?: string | undefined;
|
|
8
|
+
/** The URL to share; the current page when omitted. */
|
|
9
|
+
url?: string | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* The button's text.
|
|
12
|
+
* @defaultValue `'Share'`
|
|
13
|
+
*/
|
|
14
|
+
label?: string | undefined;
|
|
15
|
+
/** Semantic colour. */
|
|
16
|
+
tone?: Tone | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* daisyUI button style.
|
|
19
|
+
* @defaultValue `'ghost'`
|
|
20
|
+
*/
|
|
21
|
+
variant?: ButtonVariant | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* daisyUI size step.
|
|
24
|
+
* @defaultValue `'sm'`
|
|
25
|
+
*/
|
|
26
|
+
size?: Size | undefined;
|
|
27
|
+
/** Extra classes, merged last. */
|
|
28
|
+
class?: string | undefined;
|
|
29
|
+
/** The share sheet completed. */
|
|
30
|
+
onShare?: ((data: ShareData) => void) | undefined;
|
|
31
|
+
/** The share sheet failed, or the reader dismissed it. */
|
|
32
|
+
onError?: ((error: unknown) => void) | undefined;
|
|
33
|
+
/** Replaces the label and icon entirely. */
|
|
34
|
+
children?: Snippet<[]> | undefined;
|
|
35
|
+
}
|
|
36
|
+
/** Hands a title, a URL and some text to the platform share sheet. */
|
|
37
|
+
declare const ShareButton: import("svelte").Component<Props, {}, "">;
|
|
38
|
+
type ShareButton = ReturnType<typeof ShareButton>;
|
|
39
|
+
export default ShareButton;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
daisyUI `skeleton` placeholders — a block, a circle or lines of text — for a surface whose data has not arrived.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Skeleton — daisyUI `skeleton` placeholders for a surface whose data has not
|
|
6
|
+
arrived. Three shapes: a `block` (one box, sized by the caller's `class`), a
|
|
7
|
+
`circle` (an avatar), or `text` (`lines` rows of decreasing width, so the
|
|
8
|
+
shimmer reads as a paragraph rather than a bar).
|
|
9
|
+
|
|
10
|
+
ARIA contract: the shimmer conveys "loading" by animation alone, which is
|
|
11
|
+
nothing to a screen reader, so the wrapper is a polite live region
|
|
12
|
+
(`role="status"`) marked `aria-busy="true"` and named by `label`, and every
|
|
13
|
+
shimmering box is `aria-hidden`. The label is an `aria-label` rather than
|
|
14
|
+
visually hidden text because `status` does not take its name from its
|
|
15
|
+
content — and it is the ONLY thing announced, since the fake paragraph
|
|
16
|
+
shapes must not be read as content.
|
|
17
|
+
-->
|
|
18
|
+
<script lang="ts">let { variant = "block", lines = 3, label = "Loading", class: className, ...rest } = $props();
|
|
19
|
+
const widths = [
|
|
20
|
+
"w-full",
|
|
21
|
+
"w-11/12",
|
|
22
|
+
"w-4/5",
|
|
23
|
+
"w-3/4",
|
|
24
|
+
"w-2/3",
|
|
25
|
+
"w-1/2"
|
|
26
|
+
];
|
|
27
|
+
const rows = $derived(Array.from({ length: Math.max(1, lines) }, (_, index) => widths[index % widths.length] ?? "w-full"));
|
|
28
|
+
export {};
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<div {...rest} role="status" aria-busy="true" aria-label={label} class={className}>
|
|
32
|
+
{#if variant === 'text'}
|
|
33
|
+
<div class="flex flex-col gap-2" aria-hidden="true">
|
|
34
|
+
{#each rows as width, index (index)}
|
|
35
|
+
<div class={['skeleton h-4', width]}></div>
|
|
36
|
+
{/each}
|
|
37
|
+
</div>
|
|
38
|
+
{:else if variant === 'circle'}
|
|
39
|
+
<div class="skeleton size-12 shrink-0 rounded-full" aria-hidden="true"></div>
|
|
40
|
+
{:else}
|
|
41
|
+
<div class="skeleton h-24 w-full" aria-hidden="true"></div>
|
|
42
|
+
{/if}
|
|
43
|
+
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
/**
|
|
4
|
+
* The placeholder shape.
|
|
5
|
+
* @defaultValue `'block'`
|
|
6
|
+
*/
|
|
7
|
+
variant?: 'block' | 'text' | 'circle' | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Rows for the `text` variant.
|
|
10
|
+
* @defaultValue `3`
|
|
11
|
+
*/
|
|
12
|
+
lines?: number | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* What assistive technology announces in place of the shimmer.
|
|
15
|
+
* @defaultValue `'Loading'`
|
|
16
|
+
*/
|
|
17
|
+
label?: string | undefined;
|
|
18
|
+
}
|
|
19
|
+
/** daisyUI `skeleton` placeholders — a block, a circle or lines of text — for a surface whose data has not arrived. */
|
|
20
|
+
declare const Skeleton: import("svelte").Component<Props, {}, "">;
|
|
21
|
+
type Skeleton = ReturnType<typeof Skeleton>;
|
|
22
|
+
export default Skeleton;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
An indeterminate loading indicator in daisyUI's `loading` shapes, named for assistive technology unless it is decorative.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Spinner — "something is happening, and there is no shape to preview": a
|
|
6
|
+
panel waiting on a fetch, a lazy section, an inline "Checking…". When the
|
|
7
|
+
content's shape is known, `Skeleton` is the better placeholder.
|
|
8
|
+
|
|
9
|
+
ARIA contract, mirroring `Skeleton`'s on purpose: the wrapper is
|
|
10
|
+
`role="status"` (a polite live region, so its appearance is announced)
|
|
11
|
+
named by `aria-label={label}` — `status` does not take its name from its
|
|
12
|
+
content — and the animated shape is `aria-hidden`. With `showLabel` the
|
|
13
|
+
visible text is `aria-hidden` too, so the label is announced once.
|
|
14
|
+
|
|
15
|
+
`decorative` is for a spinner whose meaning something else already
|
|
16
|
+
carries — `Button`'s `aria-busy`, a live region around it — and renders the
|
|
17
|
+
shape alone, `aria-hidden`, with no role. Never nest a non-decorative
|
|
18
|
+
spinner inside another live region: two regions announce twice.
|
|
19
|
+
|
|
20
|
+
Motion: daisyUI's `loading` already slows its animation under
|
|
21
|
+
`prefers-reduced-motion: reduce` rather than stopping it — a frozen spinner
|
|
22
|
+
reads as "hung" (WCAG 2.3.3) — so nothing is added here.
|
|
23
|
+
-->
|
|
24
|
+
<script lang="ts">import { loadingSize, loadingVariant, textTone } from "./tones.js";
|
|
25
|
+
let { variant = "spinner", size = "md", tone, label = "Loading", showLabel = false, decorative = false, class: className, ...rest } = $props();
|
|
26
|
+
const shape = $derived([
|
|
27
|
+
"loading",
|
|
28
|
+
loadingVariant[variant],
|
|
29
|
+
loadingSize[size],
|
|
30
|
+
tone !== undefined && textTone[tone]
|
|
31
|
+
]);
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
{#if decorative}
|
|
35
|
+
<span {...rest} aria-hidden="true" class={[shape, className]}></span>
|
|
36
|
+
{:else}
|
|
37
|
+
<span {...rest} role="status" aria-label={label} class={['inline-flex items-center gap-2', className]}>
|
|
38
|
+
<span aria-hidden="true" class={shape}></span>
|
|
39
|
+
{#if showLabel}<span aria-hidden="true">{label}</span>{/if}
|
|
40
|
+
</span>
|
|
41
|
+
{/if}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import { type Size, type SpinnerVariant, type Tone } from './tones.ts';
|
|
3
|
+
interface Props extends HTMLAttributes<HTMLSpanElement> {
|
|
4
|
+
/**
|
|
5
|
+
* The daisyUI `loading` shape.
|
|
6
|
+
* @defaultValue `'spinner'`
|
|
7
|
+
*/
|
|
8
|
+
variant?: SpinnerVariant | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* daisyUI size step.
|
|
11
|
+
* @defaultValue `'md'`
|
|
12
|
+
*/
|
|
13
|
+
size?: Size | undefined;
|
|
14
|
+
/** Colour, through `textTone`; inherits `currentColor` when omitted. */
|
|
15
|
+
tone?: Tone | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* What assistive technology announces.
|
|
18
|
+
* @defaultValue `'Loading'`
|
|
19
|
+
*/
|
|
20
|
+
label?: string | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Print `label` beside the spinner.
|
|
23
|
+
* @defaultValue `false`
|
|
24
|
+
*/
|
|
25
|
+
showLabel?: boolean | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Something else already says it is loading: render the shape only, `aria-hidden`, with no role.
|
|
28
|
+
* @defaultValue `false`
|
|
29
|
+
*/
|
|
30
|
+
decorative?: boolean | undefined;
|
|
31
|
+
}
|
|
32
|
+
/** An indeterminate loading indicator in daisyUI's `loading` shapes, named for assistive technology unless it is decorative. */
|
|
33
|
+
declare const Spinner: import("svelte").Component<Props, {}, "">;
|
|
34
|
+
type Spinner = ReturnType<typeof Spinner>;
|
|
35
|
+
export default Spinner;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
Overlapping cards or images on daisyUI `stack`: only the top item is exposed, the rest are visual depth.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Stack — a pile with a peek of what is behind: a "3 photos" thumbnail, a
|
|
6
|
+
collapsed pile of notifications. The first item is on top.
|
|
7
|
+
|
|
8
|
+
The rule this component exists for: daisyUI's `stack` only paints the
|
|
9
|
+
items behind; every child stays in the DOM, so a screen reader would read
|
|
10
|
+
all three cards and Tab would land on links hidden behind the top one.
|
|
11
|
+
So every item after the first is `inert` (not focusable, not clickable)
|
|
12
|
+
and `aria-hidden` (not read). The depth is then reported in words: the top
|
|
13
|
+
item ends with a visually hidden `countLabel(count)` ("3 items") whenever
|
|
14
|
+
there is more than one, so it is not visual-only.
|
|
15
|
+
|
|
16
|
+
The items are data, not children: `stack.css` positions them with
|
|
17
|
+
`.stack > *:nth-child(n)`, so each must be a direct child of the root and
|
|
18
|
+
no wrapper (not even `display: contents`) can group the ones behind.
|
|
19
|
+
-->
|
|
20
|
+
<script lang="ts" generics="T">import { stackDirection } from "./tones.js";
|
|
21
|
+
let { items, item, direction = "bottom", count, countLabel = (n) => `${n} items`, class: className, ...rest } = $props();
|
|
22
|
+
const total = $derived(count ?? items.length);
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<div {...rest} class={['stack', stackDirection[direction], className]}>
|
|
26
|
+
{#each items as entry, index (index)}
|
|
27
|
+
{#if index === 0}
|
|
28
|
+
<div>
|
|
29
|
+
{@render item(entry, true)}
|
|
30
|
+
{#if total > 1}<span class="sr-only">{countLabel(total)}</span>{/if}
|
|
31
|
+
</div>
|
|
32
|
+
{:else}
|
|
33
|
+
<div inert aria-hidden="true">{@render item(entry, false)}</div>
|
|
34
|
+
{/if}
|
|
35
|
+
{/each}
|
|
36
|
+
</div>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { type StackDirection } from './tones.ts';
|
|
4
|
+
declare function $$render<T>(): {
|
|
5
|
+
props: Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
|
|
6
|
+
/** The items, top first. Only the first is exposed; the rest are depth. */
|
|
7
|
+
items: readonly T[];
|
|
8
|
+
/** Draws one item; `top` is true for the first. */
|
|
9
|
+
item: Snippet<[item: T, top: boolean]>;
|
|
10
|
+
/**
|
|
11
|
+
* Which side the items behind peek out from.
|
|
12
|
+
* @defaultValue `'bottom'`
|
|
13
|
+
*/
|
|
14
|
+
direction?: StackDirection | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Total count when more exist than are passed (3 shown of 12).
|
|
17
|
+
* @defaultValue `items.length`
|
|
18
|
+
*/
|
|
19
|
+
count?: number | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Words for the depth, read after the top item.
|
|
22
|
+
* @defaultValue `(n) => \`${n} items\``
|
|
23
|
+
*/
|
|
24
|
+
countLabel?: ((count: number) => string) | undefined;
|
|
25
|
+
};
|
|
26
|
+
exports: {};
|
|
27
|
+
bindings: "";
|
|
28
|
+
slots: {};
|
|
29
|
+
events: {};
|
|
30
|
+
};
|
|
31
|
+
declare class __sveltets_Render<T> {
|
|
32
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
33
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
34
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
35
|
+
bindings(): "";
|
|
36
|
+
exports(): {};
|
|
37
|
+
}
|
|
38
|
+
interface $$IsomorphicComponent {
|
|
39
|
+
new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
40
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
41
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
42
|
+
<T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
43
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
44
|
+
}
|
|
45
|
+
/** Overlapping cards or images on daisyUI `stack`: only the top item is exposed, the rest are visual depth. */
|
|
46
|
+
declare const Stack: $$IsomorphicComponent;
|
|
47
|
+
type Stack<T> = InstanceType<typeof Stack<T>>;
|
|
48
|
+
export default Stack;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The light/dark switch: sets `data-theme` on the document element and remembers the choice in `localStorage`.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
ThemeToggle — the light / dark switch: a daisyUI `swap` label around a
|
|
6
|
+
checkbox, which writes the chosen theme name to
|
|
7
|
+
`document.documentElement.dataset.theme` and remembers it in
|
|
8
|
+
`localStorage`.
|
|
9
|
+
|
|
10
|
+
Generic on purpose. The two theme NAMES are props, because this library
|
|
11
|
+
ships tokens rather than a brand and an app may call its themes anything;
|
|
12
|
+
`storageKey` is a prop for the same reason.
|
|
13
|
+
|
|
14
|
+
**The pre-paint script is the app's job.** This component can only run
|
|
15
|
+
after hydration, so a returning visitor whose choice was dark would flash
|
|
16
|
+
light first. The fix is three lines the app inlines in its document head,
|
|
17
|
+
before any stylesheet, reading the same key:
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<script>
|
|
21
|
+
try {
|
|
22
|
+
const t = localStorage.getItem('theme');
|
|
23
|
+
if (t) document.documentElement.dataset.theme = t;
|
|
24
|
+
} catch {}
|
|
25
|
+
</script>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Every `localStorage` access here is wrapped: it throws outright in a private
|
|
29
|
+
window and with site data blocked, and a remembered theme is a convenience
|
|
30
|
+
that must never be able to stop the control rendering.
|
|
31
|
+
|
|
32
|
+
ARIA contract: a real checkbox with `role="switch"` — on/off, not
|
|
33
|
+
checked/unchecked — named by `label`. Both icons are `aria-hidden`; they
|
|
34
|
+
are the visual half of the state the switch already announces. Note that
|
|
35
|
+
daisyUI's `theme-controller` class is deliberately NOT used: it applies a
|
|
36
|
+
theme through CSS scoped to the checkbox, which would fight with the
|
|
37
|
+
`data-theme` this component sets on the document element.
|
|
38
|
+
-->
|
|
39
|
+
<script lang="ts">import { Moon, Sun } from "@lucide/svelte";
|
|
40
|
+
let { lightTheme, darkTheme, storageKey = "theme", label = "Toggle dark mode", value = $bindable(), class: className } = $props();
|
|
41
|
+
// Read the remembered choice after mount: `localStorage` does not exist on
|
|
42
|
+
// the server, and a value read during render would not survive hydration.
|
|
43
|
+
$effect(() => {
|
|
44
|
+
try {
|
|
45
|
+
const stored = globalThis.localStorage?.getItem(storageKey);
|
|
46
|
+
if (stored === darkTheme || stored === lightTheme) value = stored;
|
|
47
|
+
} catch {}
|
|
48
|
+
});
|
|
49
|
+
const active = $derived(value ?? lightTheme);
|
|
50
|
+
const dark = $derived(active === darkTheme);
|
|
51
|
+
const onchange = (event) => {
|
|
52
|
+
const next = event.currentTarget.checked ? darkTheme : lightTheme;
|
|
53
|
+
value = next;
|
|
54
|
+
document.documentElement.dataset.theme = next;
|
|
55
|
+
try {
|
|
56
|
+
globalThis.localStorage?.setItem(storageKey, next);
|
|
57
|
+
} catch {}
|
|
58
|
+
};
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<label class={['swap swap-rotate btn btn-ghost btn-circle', className]}>
|
|
62
|
+
<input type="checkbox" role="switch" checked={dark} aria-label={label} {onchange} />
|
|
63
|
+
<Sun class="swap-off size-5" aria-hidden="true" />
|
|
64
|
+
<Moon class="swap-on size-5" aria-hidden="true" />
|
|
65
|
+
</label>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/** The theme name applied when the switch is off. */
|
|
3
|
+
lightTheme: string;
|
|
4
|
+
/** The theme name applied when the switch is on. */
|
|
5
|
+
darkTheme: string;
|
|
6
|
+
/**
|
|
7
|
+
* `localStorage` key the choice is remembered under.
|
|
8
|
+
* @defaultValue `'theme'`
|
|
9
|
+
*/
|
|
10
|
+
storageKey?: string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Accessible name of the switch.
|
|
13
|
+
* @defaultValue `'Toggle dark mode'`
|
|
14
|
+
*/
|
|
15
|
+
label?: string | undefined;
|
|
16
|
+
/** The active theme name. Bindable; defaults to `lightTheme`. */
|
|
17
|
+
value?: string | undefined;
|
|
18
|
+
/** Extra classes, merged last. */
|
|
19
|
+
class?: string | undefined;
|
|
20
|
+
}
|
|
21
|
+
/** The light/dark switch: sets `data-theme` on the document element and remembers the choice in `localStorage`. */
|
|
22
|
+
declare const ThemeToggle: import("svelte").Component<Props, {}, "value">;
|
|
23
|
+
type ThemeToggle = ReturnType<typeof ThemeToggle>;
|
|
24
|
+
export default ThemeToggle;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A button that stays pressed (`aria-pressed`), on bits-ui `Toggle`.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
ToggleButton — "Bold", "Show frost dates", "Mute", "Favourite": a button
|
|
6
|
+
whose state persists between presses. Not a `fields/Toggle` (a switch: a
|
|
7
|
+
setting that takes effect, `role="switch"`), not a `Checkbox` (a form
|
|
8
|
+
value).
|
|
9
|
+
|
|
10
|
+
ARIA contract: bits-ui's `aria-pressed`, and Space / Enter both toggle.
|
|
11
|
+
The accessible name never changes with state: "Mute" stays "Mute" when
|
|
12
|
+
pressed, because the state is `aria-pressed`'s job. An icon-only button
|
|
13
|
+
must have a `label` (the types enforce it), read as visually hidden text;
|
|
14
|
+
`tooltip` opts in to showing it on hover and focus. `data-state="on" |
|
|
15
|
+
"off"` is a supported styling hook. Pressed is not colour alone: see
|
|
16
|
+
`toggle-classes.ts`; `pressedIcon` adds a shape change.
|
|
17
|
+
-->
|
|
18
|
+
<script lang="ts">import { Toggle } from "bits-ui";
|
|
19
|
+
import { toggleClasses } from "./toggle-classes.js";
|
|
20
|
+
import { buttonSize } from "./tones.js";
|
|
21
|
+
import Tooltip from "./Tooltip.svelte";
|
|
22
|
+
let { pressed = $bindable(false), onPressedChange, tone = "neutral", variant = "ghost", size = "md", icon, pressedIcon, tooltip = false, iconOnly = false, label, children, disabled, class: className, ...rest } = $props();
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
{#snippet button(extra: Record<string, unknown>)}
|
|
26
|
+
<Toggle.Root
|
|
27
|
+
{...extra}
|
|
28
|
+
bind:pressed
|
|
29
|
+
{...onPressedChange === undefined ? {} : { onPressedChange }}
|
|
30
|
+
{...disabled == null ? {} : { disabled }}
|
|
31
|
+
>
|
|
32
|
+
{#snippet child({ props, pressed: on })}
|
|
33
|
+
<button
|
|
34
|
+
{...rest}
|
|
35
|
+
{...props}
|
|
36
|
+
type="button"
|
|
37
|
+
class={[
|
|
38
|
+
'btn',
|
|
39
|
+
buttonSize[size],
|
|
40
|
+
toggleClasses(on, tone, variant),
|
|
41
|
+
iconOnly && 'btn-square',
|
|
42
|
+
className,
|
|
43
|
+
]}
|
|
44
|
+
>
|
|
45
|
+
{#if on && pressedIcon}{@render pressedIcon()}{:else if icon}{@render icon()}{/if}
|
|
46
|
+
{#if iconOnly}<span class="sr-only">{label}</span>{:else}{@render children?.()}{/if}
|
|
47
|
+
</button>
|
|
48
|
+
{/snippet}
|
|
49
|
+
</Toggle.Root>
|
|
50
|
+
{/snippet}
|
|
51
|
+
|
|
52
|
+
{#if tooltip && label !== undefined}
|
|
53
|
+
<Tooltip text={label}>
|
|
54
|
+
{#snippet children({ props })}{@render button(props)}{/snippet}
|
|
55
|
+
</Tooltip>
|
|
56
|
+
{:else}
|
|
57
|
+
{@render button({})}
|
|
58
|
+
{/if}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
+
import { type ButtonVariant, type Size, type Tone } from './tones.ts';
|
|
4
|
+
type Props = Omit<HTMLButtonAttributes, 'type' | 'children'> & {
|
|
5
|
+
/** Whether the button is pressed. Bindable. */
|
|
6
|
+
pressed?: boolean | undefined;
|
|
7
|
+
/** Called with the next state after a press. */
|
|
8
|
+
onPressedChange?: ((pressed: boolean) => void) | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Colour while pressed.
|
|
11
|
+
* @defaultValue `'neutral'`
|
|
12
|
+
*/
|
|
13
|
+
tone?: Tone | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Look while not pressed.
|
|
16
|
+
* @defaultValue `'ghost'`
|
|
17
|
+
*/
|
|
18
|
+
variant?: ButtonVariant | undefined;
|
|
19
|
+
/** @defaultValue `'md'` */
|
|
20
|
+
size?: Size | undefined;
|
|
21
|
+
/** Leading icon. */
|
|
22
|
+
icon?: Snippet<[]> | undefined;
|
|
23
|
+
/** Icon shown in place of `icon` while pressed (an outlined star becomes a filled one). */
|
|
24
|
+
pressedIcon?: Snippet<[]> | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Show the label in a tooltip on hover and focus (icon-only buttons).
|
|
27
|
+
* @defaultValue `false`
|
|
28
|
+
*/
|
|
29
|
+
tooltip?: boolean | undefined;
|
|
30
|
+
} & ({
|
|
31
|
+
iconOnly?: false | undefined;
|
|
32
|
+
label?: undefined;
|
|
33
|
+
/** The button text; its accessible name. */
|
|
34
|
+
children: Snippet<[]>;
|
|
35
|
+
} | {
|
|
36
|
+
/** Hide the text: only the icon shows, and `label` is the accessible name. */
|
|
37
|
+
iconOnly: true;
|
|
38
|
+
/** The accessible name of an icon-only button. Constant across states. */
|
|
39
|
+
label: string;
|
|
40
|
+
children?: undefined;
|
|
41
|
+
});
|
|
42
|
+
/** A button that stays pressed (`aria-pressed`), on bits-ui `Toggle`. */
|
|
43
|
+
declare const ToggleButton: import("svelte").Component<Props, {}, "pressed">;
|
|
44
|
+
type ToggleButton = ReturnType<typeof ToggleButton>;
|
|
45
|
+
export default ToggleButton;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A set of toggle buttons answering one question, exclusively or independently, on bits-ui `ToggleGroup`.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
ToggleGroup — a segmented control (`type="single"`: Grid | List | Map,
|
|
6
|
+
Day | Week | Month) or a set of independent toggles (`type="multiple"`:
|
|
7
|
+
B / I / U, "Show: Annuals Perennials Bulbs"), as daisyUI `btn`s in a
|
|
8
|
+
`join`. One Tab stop, arrow keys between items (bits-ui's roving focus).
|
|
9
|
+
|
|
10
|
+
ARIA contract:
|
|
11
|
+
- `type="multiple"`: a `role="group"` of buttons with `aria-pressed`;
|
|
12
|
+
arrows move focus, Space / Enter toggles.
|
|
13
|
+
- `type="single"`: bits-ui makes the items `role="radio"` with
|
|
14
|
+
`aria-checked` but keeps its root a `group`; radios belong in a
|
|
15
|
+
`radiogroup`, so the root's role is overridden. As in an APG radio
|
|
16
|
+
group, arrows move focus AND select (bits-ui only moves focus, so the
|
|
17
|
+
root completes the move), and Tab into the group lands on the checked
|
|
18
|
+
item, not the first. With `required`, pressing the checked item does
|
|
19
|
+
nothing, so one item always stays selected.
|
|
20
|
+
- Named by `label` (`aria-label`) or, inside a `FormField`, by the label
|
|
21
|
+
element (`labelId` → `aria-labelledby`); `describedBy` and `invalid` as
|
|
22
|
+
every field control. An item's name never changes with state; an
|
|
23
|
+
icon-only item reads its `label` as visually hidden text, and
|
|
24
|
+
`tooltip` opts in to showing it on hover and focus.
|
|
25
|
+
- With `name`, the selection posts with a form: one hidden input per
|
|
26
|
+
selected value (bits-ui's group has no hidden inputs of its own).
|
|
27
|
+
-->
|
|
28
|
+
<script lang="ts" generics="V extends string">import { Check } from "@lucide/svelte";
|
|
29
|
+
import { ToggleGroup } from "bits-ui";
|
|
30
|
+
import { toggleClasses, toggleSetters } from "./toggle-classes.js";
|
|
31
|
+
import { buttonSize } from "./tones.js";
|
|
32
|
+
import Tooltip from "./Tooltip.svelte";
|
|
33
|
+
let { type, items, value = $bindable(), onValueChange, required = false, label, labelId, describedBy = "", invalid = false, name, orientation = "horizontal", loop = true, tone = "primary", variant = "solid", size = "md", block = false, showCheck = false, tooltip = false, disabled = false, item: itemBody, class: className, ...rest } = $props();
|
|
34
|
+
const selected = $derived(value === undefined || value === "" ? [] : typeof value === "string" ? [value] : value);
|
|
35
|
+
const setters = toggleSetters({
|
|
36
|
+
required: () => required,
|
|
37
|
+
assign: (next) => value = next,
|
|
38
|
+
notify: () => onValueChange
|
|
39
|
+
});
|
|
40
|
+
const MOVE_KEYS = new Set([
|
|
41
|
+
"ArrowLeft",
|
|
42
|
+
"ArrowRight",
|
|
43
|
+
"ArrowUp",
|
|
44
|
+
"ArrowDown",
|
|
45
|
+
"Home",
|
|
46
|
+
"End"
|
|
47
|
+
]);
|
|
48
|
+
/** Single mode: once bits-ui has moved focus, select what it moved to. */
|
|
49
|
+
function selectFollowsFocus(event) {
|
|
50
|
+
if (type !== "single" || !MOVE_KEYS.has(event.key)) return;
|
|
51
|
+
const focused = document.activeElement;
|
|
52
|
+
if (!(focused instanceof HTMLElement)) return;
|
|
53
|
+
const next = focused.dataset["value"];
|
|
54
|
+
if (next !== undefined && next !== value && !focused.hasAttribute("data-disabled")) setters.single(next);
|
|
55
|
+
}
|
|
56
|
+
/** Single mode: Tab into the group lands on the checked item. */
|
|
57
|
+
function focusChecked(event) {
|
|
58
|
+
const root = event.currentTarget;
|
|
59
|
+
if (type !== "single" || !(root instanceof HTMLElement)) return;
|
|
60
|
+
if (event.relatedTarget instanceof Node && root.contains(event.relatedTarget)) return;
|
|
61
|
+
const checked = root.querySelector("[aria-checked=\"true\"]");
|
|
62
|
+
if (checked !== null && checked !== event.target) checked.focus();
|
|
63
|
+
}
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
{#snippet root({ props }: { props: Record<string, unknown> })}
|
|
67
|
+
<div
|
|
68
|
+
{...props}
|
|
69
|
+
{...rest}
|
|
70
|
+
role={type === 'single' ? 'radiogroup' : 'group'}
|
|
71
|
+
aria-label={labelId === undefined ? label : undefined}
|
|
72
|
+
aria-labelledby={labelId}
|
|
73
|
+
aria-describedby={describedBy === '' ? undefined : describedBy}
|
|
74
|
+
aria-invalid={invalid ? 'true' : undefined}
|
|
75
|
+
aria-required={type === 'single' && required ? 'true' : undefined}
|
|
76
|
+
aria-orientation={orientation}
|
|
77
|
+
onkeydown={selectFollowsFocus}
|
|
78
|
+
onfocusin={focusChecked}
|
|
79
|
+
class={['join', orientation === 'vertical' && 'join-vertical', block && 'flex w-full', className]}
|
|
80
|
+
>
|
|
81
|
+
{#each items as entry (entry.value)}
|
|
82
|
+
{#if tooltip && entry.iconOnly}
|
|
83
|
+
<Tooltip text={entry.label}>
|
|
84
|
+
{#snippet children({ props: tip })}{@render itemButton(entry, tip)}{/snippet}
|
|
85
|
+
</Tooltip>
|
|
86
|
+
{:else}
|
|
87
|
+
{@render itemButton(entry, {})}
|
|
88
|
+
{/if}
|
|
89
|
+
{/each}
|
|
90
|
+
</div>
|
|
91
|
+
{/snippet}
|
|
92
|
+
|
|
93
|
+
{#snippet itemButton(entry: ToggleGroupItem<V>, extra: Record<string, unknown>)}
|
|
94
|
+
<ToggleGroup.Item {...extra} value={entry.value} disabled={entry.disabled ?? false}>
|
|
95
|
+
{#snippet child({ props, pressed })}
|
|
96
|
+
<button
|
|
97
|
+
{...props}
|
|
98
|
+
type="button"
|
|
99
|
+
class={[
|
|
100
|
+
'btn join-item',
|
|
101
|
+
buttonSize[size],
|
|
102
|
+
toggleClasses(pressed, tone, variant),
|
|
103
|
+
block && 'flex-1',
|
|
104
|
+
entry.iconOnly && !block && 'btn-square',
|
|
105
|
+
]}
|
|
106
|
+
>
|
|
107
|
+
{#if itemBody}
|
|
108
|
+
{@render itemBody(entry, { pressed })}
|
|
109
|
+
{:else}
|
|
110
|
+
{#if showCheck && pressed}<Check class="size-4" aria-hidden="true" />{/if}
|
|
111
|
+
{@render entry.icon?.()}
|
|
112
|
+
{#if entry.iconOnly}<span class="sr-only">{entry.label}</span>{:else}{entry.label}{/if}
|
|
113
|
+
{/if}
|
|
114
|
+
</button>
|
|
115
|
+
{/snippet}
|
|
116
|
+
</ToggleGroup.Item>
|
|
117
|
+
{/snippet}
|
|
118
|
+
|
|
119
|
+
{#if type === 'single'}
|
|
120
|
+
<ToggleGroup.Root
|
|
121
|
+
type="single"
|
|
122
|
+
bind:value={() => (typeof value === 'string' ? value : ''), setters.single}
|
|
123
|
+
{orientation}
|
|
124
|
+
{loop}
|
|
125
|
+
{disabled}
|
|
126
|
+
child={root}
|
|
127
|
+
/>
|
|
128
|
+
{:else}
|
|
129
|
+
<ToggleGroup.Root
|
|
130
|
+
type="multiple"
|
|
131
|
+
bind:value={() => [...selected], setters.multiple}
|
|
132
|
+
{orientation}
|
|
133
|
+
{loop}
|
|
134
|
+
{disabled}
|
|
135
|
+
child={root}
|
|
136
|
+
/>
|
|
137
|
+
{/if}
|
|
138
|
+
{#if name !== undefined}
|
|
139
|
+
{#each selected as selectedValue (selectedValue)}
|
|
140
|
+
<input type="hidden" {name} value={selectedValue} />
|
|
141
|
+
{/each}
|
|
142
|
+
{/if}
|