@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,150 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A `Table` with client-side sorting, filtering across every column and paging, for a list that is already entirely in hand.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
DataGrid — the three controls a reader wants over a list that is already
|
|
6
|
+
entirely in hand: sort a column, filter across every column, page through
|
|
7
|
+
the result.
|
|
8
|
+
|
|
9
|
+
It draws no table of its own. The rows go through `Table` and the pager
|
|
10
|
+
through `Pagination`, so the cell markup, the empty state, the sort control
|
|
11
|
+
and the disabled-arm rule all have exactly one implementation, and this file
|
|
12
|
+
is the decisions rather than the markup.
|
|
13
|
+
|
|
14
|
+
**Client-side, and that is the constraint.** Every derivation below runs
|
|
15
|
+
over the whole `rows` array on every keystroke, so this is for a bounded set
|
|
16
|
+
the page already holds — a vocabulary, an account's devices, a taxon's
|
|
17
|
+
synonyms. A collection the API pages belongs on `Table` + `PaginationFooter`,
|
|
18
|
+
where the server does the work; pointing this at one would silently sort and
|
|
19
|
+
filter the current page only, which reads as data loss rather than as a
|
|
20
|
+
limitation.
|
|
21
|
+
|
|
22
|
+
ARIA contract: the `Table`'s and the `Pagination`'s. The filter is a
|
|
23
|
+
`<input type="search">` with a real label (visually hidden, because the
|
|
24
|
+
control sits in a toolbar where a visible label would be the only one), and
|
|
25
|
+
the rows-per-page `<select>` is named by `rowsPerPageLabel`.
|
|
26
|
+
-->
|
|
27
|
+
<script lang="ts" generics="T">import { getComponentsContext } from "../context.svelte.js";
|
|
28
|
+
import Pagination from "./Pagination.svelte";
|
|
29
|
+
import Table from "./Table.svelte";
|
|
30
|
+
let { rows, columns, rowKey, filterable = false, paginated = true, pageSize = 10, pageSizeOptions = [
|
|
31
|
+
10,
|
|
32
|
+
25,
|
|
33
|
+
50,
|
|
34
|
+
100
|
|
35
|
+
], caption, captionHidden, size, zebra, pinRows, sort = $bindable(undefined), onSelect, emptyMessage, emptyState, filterLabel = "Search", filterPlaceholder = "Search…", rowsPerPageLabel = "Rows per page", showingLabel = (start, end, total) => `Showing ${start} to ${end} of ${total}`, pageOfLabel = (page, pages) => `Page ${page} of ${pages}`, previousLabel = "Previous", nextLabel = "Next", paginationLabel = "Pagination", sortLabel, locales = getComponentsContext().locale(), class: className, ...rest } = $props();
|
|
36
|
+
let filter = $state("");
|
|
37
|
+
// 0 is "the reader has not chosen": the `pageSize` prop stays authoritative
|
|
38
|
+
// until they pick from the menu, so a page that changes the prop is honoured
|
|
39
|
+
// rather than overridden by state seeded once at mount.
|
|
40
|
+
let chosenSize = $state(0);
|
|
41
|
+
let page = $state(0);
|
|
42
|
+
const limit = $derived(chosenSize === 0 ? pageSize : chosenSize);
|
|
43
|
+
const filtered = $derived.by(() => {
|
|
44
|
+
const needle = filter.trim().toLowerCase();
|
|
45
|
+
if (needle === "") return rows;
|
|
46
|
+
// The filter searches the column's VALUE, not its rendered cell: a cell
|
|
47
|
+
// may be a badge or a link, and a reader typing what they can see is
|
|
48
|
+
// typing the value either way.
|
|
49
|
+
return rows.filter((row) => columns.some((column) => String(column.value(row)).toLowerCase().includes(needle)));
|
|
50
|
+
});
|
|
51
|
+
const sorted = $derived.by(() => {
|
|
52
|
+
const active = sort;
|
|
53
|
+
if (active === undefined) return filtered;
|
|
54
|
+
const column = columns.find((candidate) => candidate.key === active.key);
|
|
55
|
+
if (column === undefined) return filtered;
|
|
56
|
+
const direction = active.direction === "asc" ? 1 : -1;
|
|
57
|
+
// `localeCompare` in the active locale, so a Swedish reader gets Swedish
|
|
58
|
+
// collation rather than code-point order; numbers compare numerically,
|
|
59
|
+
// because "10" sorts before "9" as a string and that is always wrong.
|
|
60
|
+
return filtered.toSorted((left, right) => {
|
|
61
|
+
const a = column.value(left);
|
|
62
|
+
const b = column.value(right);
|
|
63
|
+
if (typeof a === "number" && typeof b === "number") return (a - b) * direction;
|
|
64
|
+
return String(a).localeCompare(String(b), locales) * direction;
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
const total = $derived(sorted.length);
|
|
68
|
+
const pageCount = $derived(paginated ? Math.max(1, Math.ceil(total / limit)) : 1);
|
|
69
|
+
// A filter that shrinks the result out from under the current page would
|
|
70
|
+
// otherwise leave the reader looking at an empty body with rows they cannot
|
|
71
|
+
// reach. Clamping in a derivation rather than in the filter's handler keeps
|
|
72
|
+
// it true however the page count changed — including a `rows` prop that
|
|
73
|
+
// shrank without anyone typing.
|
|
74
|
+
const current = $derived(Math.min(page, pageCount - 1));
|
|
75
|
+
const visible = $derived(paginated ? sorted.slice(current * limit, current * limit + limit) : sorted);
|
|
76
|
+
const from = $derived(total === 0 ? 0 : current * limit + 1);
|
|
77
|
+
const to = $derived(Math.min((current + 1) * limit, total));
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<div {...rest} class={['space-y-3', className]}>
|
|
81
|
+
{#if filterable}
|
|
82
|
+
<label class="input input-sm w-full max-w-xs">
|
|
83
|
+
<span class="sr-only">{filterLabel}</span>
|
|
84
|
+
<input
|
|
85
|
+
type="search"
|
|
86
|
+
bind:value={filter}
|
|
87
|
+
oninput={() => {
|
|
88
|
+
page = 0;
|
|
89
|
+
}}
|
|
90
|
+
placeholder={filterPlaceholder}
|
|
91
|
+
aria-label={filterLabel}
|
|
92
|
+
/>
|
|
93
|
+
</label>
|
|
94
|
+
{/if}
|
|
95
|
+
|
|
96
|
+
<Table
|
|
97
|
+
rows={visible}
|
|
98
|
+
{columns}
|
|
99
|
+
{rowKey}
|
|
100
|
+
{caption}
|
|
101
|
+
{captionHidden}
|
|
102
|
+
{size}
|
|
103
|
+
{zebra}
|
|
104
|
+
{pinRows}
|
|
105
|
+
{onSelect}
|
|
106
|
+
{emptyMessage}
|
|
107
|
+
{emptyState}
|
|
108
|
+
{sortLabel}
|
|
109
|
+
bind:sort
|
|
110
|
+
onSort={() => {
|
|
111
|
+
// A new sort re-orders the whole result, so the reader's place in the
|
|
112
|
+
// old order means nothing; page 1 is the only honest answer.
|
|
113
|
+
page = 0;
|
|
114
|
+
}}
|
|
115
|
+
/>
|
|
116
|
+
|
|
117
|
+
{#if paginated && total > 0}
|
|
118
|
+
<div class="flex flex-wrap items-center justify-between gap-3">
|
|
119
|
+
<div class="flex items-center gap-2">
|
|
120
|
+
<p class="text-base-content/70 text-sm tabular-nums">{showingLabel(from, to, total)}</p>
|
|
121
|
+
<select
|
|
122
|
+
class="select select-sm w-auto"
|
|
123
|
+
aria-label={rowsPerPageLabel}
|
|
124
|
+
value={limit}
|
|
125
|
+
onchange={(event) => {
|
|
126
|
+
chosenSize = Number(event.currentTarget.value);
|
|
127
|
+
page = 0;
|
|
128
|
+
}}
|
|
129
|
+
>
|
|
130
|
+
{#each pageSizeOptions as option (option)}
|
|
131
|
+
<option value={option}>{option}</option>
|
|
132
|
+
{/each}
|
|
133
|
+
</select>
|
|
134
|
+
</div>
|
|
135
|
+
<Pagination
|
|
136
|
+
offset={current * limit}
|
|
137
|
+
{limit}
|
|
138
|
+
{total}
|
|
139
|
+
variant="prevNext"
|
|
140
|
+
label={paginationLabel}
|
|
141
|
+
{previousLabel}
|
|
142
|
+
{nextLabel}
|
|
143
|
+
statusLabel={pageOfLabel}
|
|
144
|
+
onPage={(offset) => {
|
|
145
|
+
page = Math.floor(offset / limit);
|
|
146
|
+
}}
|
|
147
|
+
/>
|
|
148
|
+
</div>
|
|
149
|
+
{/if}
|
|
150
|
+
</div>
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { Size } from '../ui/tones.ts';
|
|
4
|
+
import type { SortState, TableColumn } from './table-types.ts';
|
|
5
|
+
declare function $$render<T>(): {
|
|
6
|
+
props: Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
|
|
7
|
+
/** Every row; sorting, filtering and paging happen here. */
|
|
8
|
+
rows: readonly T[];
|
|
9
|
+
/** Column definitions: header, cell renderer, sort key. */
|
|
10
|
+
columns: readonly TableColumn<T>[];
|
|
11
|
+
/** Stable identity per row — the `{#each}` key. */
|
|
12
|
+
rowKey: (row: T) => string;
|
|
13
|
+
/** Offer the filter box. */
|
|
14
|
+
filterable?: boolean | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Offer the pager; every row renders when false.
|
|
17
|
+
* @defaultValue `true`
|
|
18
|
+
*/
|
|
19
|
+
paginated?: boolean | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Rows per page until the reader picks another size.
|
|
22
|
+
* @defaultValue `10`
|
|
23
|
+
*/
|
|
24
|
+
pageSize?: number | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* The choices offered in the rows-per-page select.
|
|
27
|
+
* @defaultValue `[10, 25, 50, 100]`
|
|
28
|
+
*/
|
|
29
|
+
pageSizeOptions?: readonly number[] | undefined;
|
|
30
|
+
/** The table's accessible name, rendered as its `<caption>`. */
|
|
31
|
+
caption?: string | undefined;
|
|
32
|
+
/** Keep the caption for assistive technology only. */
|
|
33
|
+
captionHidden?: boolean | undefined;
|
|
34
|
+
/** daisyUI size step. */
|
|
35
|
+
size?: Size | undefined;
|
|
36
|
+
/** Stripe alternate rows. */
|
|
37
|
+
zebra?: boolean | undefined;
|
|
38
|
+
/** Stick the header row while the body scrolls; see `Table`. */
|
|
39
|
+
pinRows?: boolean | undefined;
|
|
40
|
+
/** Which column starts sorted. Bindable; `undefined` is the caller's order. */
|
|
41
|
+
sort?: SortState | undefined;
|
|
42
|
+
/** Makes every row activatable by pointer and keyboard; see `Table`. */
|
|
43
|
+
onSelect?: ((row: T) => void) | undefined;
|
|
44
|
+
/** The line shown when no row matches. */
|
|
45
|
+
emptyMessage?: string | undefined;
|
|
46
|
+
/** Richer empty state, in place of `emptyMessage`. */
|
|
47
|
+
emptyState?: Snippet<[]> | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Accessible name of the filter box.
|
|
50
|
+
* @defaultValue `'Search'`
|
|
51
|
+
*/
|
|
52
|
+
filterLabel?: string | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Placeholder in the filter box.
|
|
55
|
+
* @defaultValue `'Search…'`
|
|
56
|
+
*/
|
|
57
|
+
filterPlaceholder?: string | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Label of the rows-per-page select.
|
|
60
|
+
* @defaultValue `'Rows per page'`
|
|
61
|
+
*/
|
|
62
|
+
rowsPerPageLabel?: string | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* The range line under the table.
|
|
65
|
+
* @defaultValue `"Showing <start> to <end> of <total>"`
|
|
66
|
+
*/
|
|
67
|
+
showingLabel?: ((start: number, end: number, total: number) => string) | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* The page status between the pager arms.
|
|
70
|
+
* @defaultValue `"Page <page> of <pages>"`
|
|
71
|
+
*/
|
|
72
|
+
pageOfLabel?: ((page: number, pages: number) => string) | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Text of the previous-page control.
|
|
75
|
+
* @defaultValue `'Previous'`
|
|
76
|
+
*/
|
|
77
|
+
previousLabel?: string | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Text of the next-page control.
|
|
80
|
+
* @defaultValue `'Next'`
|
|
81
|
+
*/
|
|
82
|
+
nextLabel?: string | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Accessible name of the pager landmark.
|
|
85
|
+
* @defaultValue `'Pagination'`
|
|
86
|
+
*/
|
|
87
|
+
paginationLabel?: string | undefined;
|
|
88
|
+
/** How a sortable column’s button is named; see `Table`. */
|
|
89
|
+
sortLabel?: ((column: TableColumn<T>) => string) | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Locale(s) for `Intl` formatting.
|
|
92
|
+
* @defaultValue the components context's `locale()`
|
|
93
|
+
*/
|
|
94
|
+
locales?: string | readonly string[] | undefined;
|
|
95
|
+
};
|
|
96
|
+
exports: {};
|
|
97
|
+
bindings: "sort";
|
|
98
|
+
slots: {};
|
|
99
|
+
events: {};
|
|
100
|
+
};
|
|
101
|
+
declare class __sveltets_Render<T> {
|
|
102
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
103
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
104
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
105
|
+
bindings(): "sort";
|
|
106
|
+
exports(): {};
|
|
107
|
+
}
|
|
108
|
+
interface $$IsomorphicComponent {
|
|
109
|
+
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']>> & {
|
|
110
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
111
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
112
|
+
<T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
113
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
114
|
+
}
|
|
115
|
+
/** A `Table` with client-side sorting, filtering across every column and paging, for a list that is already entirely in hand. */
|
|
116
|
+
declare const DataGrid: $$IsomorphicComponent;
|
|
117
|
+
type DataGrid<T> = InstanceType<typeof DataGrid<T>>;
|
|
118
|
+
export default DataGrid;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
Label/value pairs as a `grid`, a bordered `card`, `divided` rows, `inline` pairs, or `bare` pairs in a layout the caller supplies.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
DescriptionList — label / value pairs, in the four shapes a detail page
|
|
6
|
+
wants them: a two-column `grid`, a bordered `card` with the labels in a
|
|
7
|
+
fixed gutter, `divided` rows, or `inline` pairs running across a line —
|
|
8
|
+
or `bare`, which adds no layout of its own: the `<dl>` takes only the
|
|
9
|
+
caller's `class` (say `grid grid-cols-[auto_1fr] gap-x-4`) and every
|
|
10
|
+
row's `<dt>`/`<dd>` is a direct child of it, so a consumer-owned grid can
|
|
11
|
+
mix `DescriptionRow`s with its own `<dt>`/`<dd>` pairs and keep its columns.
|
|
12
|
+
|
|
13
|
+
One component rather than the two the apps had. They had split it by how the
|
|
14
|
+
VALUE arrives — one took rows as strings, the other took them as markup —
|
|
15
|
+
which meant a page needing a formatted date in one row and a string in the
|
|
16
|
+
next had to choose a component per list. Here the value is a prop or a
|
|
17
|
+
snippet on the ROW, so both live in one list.
|
|
18
|
+
|
|
19
|
+
`mono` marks the values that are identifiers (a formula, an InChIKey, a
|
|
20
|
+
DOI) rather than sentences: those want a fixed-width face and a
|
|
21
|
+
break-anywhere rule, and the ones that are prose do not.
|
|
22
|
+
|
|
23
|
+
ARIA contract: a real `<dl>` of `<dt>`/`<dd>` pairs, which is what makes the
|
|
24
|
+
label / value association exist at all — a screen reader reads a `<dd>` as
|
|
25
|
+
the definition of the `<dt>` before it. The variant reaches the rows through
|
|
26
|
+
context (see `description-context.ts`), never through a class on the list
|
|
27
|
+
that the rows would have to guess at.
|
|
28
|
+
-->
|
|
29
|
+
<script lang="ts">import { setDescriptionListStyle } from "./description-context.js";
|
|
30
|
+
let { variant = "grid", mono = false, showEmpty = false, emptyLabel = "unrecorded", children, class: className, ...rest } = $props();
|
|
31
|
+
// Literal lookup table: Tailwind reads the class names out of the source,
|
|
32
|
+
// so a template string would emit no CSS at all.
|
|
33
|
+
const listClass = {
|
|
34
|
+
grid: "grid grid-cols-1 gap-3 sm:grid-cols-2",
|
|
35
|
+
card: "card card-border card-body bg-base-100 grid grid-cols-1 gap-x-6 gap-y-3 sm:grid-cols-[12rem_1fr]",
|
|
36
|
+
divided: "divide-base-300 divide-y",
|
|
37
|
+
inline: "flex flex-wrap gap-x-6 gap-y-2",
|
|
38
|
+
// The caller's `class` is the whole layout.
|
|
39
|
+
bare: ""
|
|
40
|
+
};
|
|
41
|
+
// A getter, not a snapshot: the rows re-read it, so a list whose `variant`
|
|
42
|
+
// changes re-styles the rows it already mounted.
|
|
43
|
+
setDescriptionListStyle(() => ({
|
|
44
|
+
variant,
|
|
45
|
+
mono,
|
|
46
|
+
showEmpty,
|
|
47
|
+
emptyLabel
|
|
48
|
+
}));
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<dl {...rest} class={[listClass[variant], className]}>
|
|
52
|
+
{@render children()}
|
|
53
|
+
</dl>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { type DescriptionListStyle } from './description-context.ts';
|
|
4
|
+
type Variant = DescriptionListStyle['variant'];
|
|
5
|
+
interface Props extends HTMLAttributes<HTMLElement> {
|
|
6
|
+
/**
|
|
7
|
+
* The layout.
|
|
8
|
+
* @defaultValue `'grid'`
|
|
9
|
+
*/
|
|
10
|
+
variant?: Variant | undefined;
|
|
11
|
+
/** Render values in a fixed-width face that breaks anywhere. */
|
|
12
|
+
mono?: boolean | undefined;
|
|
13
|
+
/** Render rows whose value is empty, rather than dropping them. */
|
|
14
|
+
showEmpty?: boolean | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* What an empty value reads as when `showEmpty`.
|
|
17
|
+
* @defaultValue `'unrecorded'`
|
|
18
|
+
*/
|
|
19
|
+
emptyLabel?: string | undefined;
|
|
20
|
+
/** The rows — `DescriptionRow`s, or any other `<dt>`/`<dd>` pairs. */
|
|
21
|
+
children: Snippet<[]>;
|
|
22
|
+
}
|
|
23
|
+
/** Label/value pairs as a `grid`, a bordered `card`, `divided` rows, `inline` pairs, or `bare` pairs in a layout the caller supplies. */
|
|
24
|
+
declare const DescriptionList: import("svelte").Component<Props, {}, "">;
|
|
25
|
+
type DescriptionList = ReturnType<typeof DescriptionList>;
|
|
26
|
+
export default DescriptionList;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
One label and its value inside a `DescriptionList`.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
DescriptionRow — one label and its value inside a `DescriptionList`.
|
|
6
|
+
|
|
7
|
+
A row with nothing in it renders NOTHING. An empty `<dd>` is a worse answer
|
|
8
|
+
than an absent row: it claims the page looked and found a blank, where the
|
|
9
|
+
absent row claims nothing at all. `showEmpty` is for the lists where the
|
|
10
|
+
absence is the point — a specimen record whose empty fields are what the
|
|
11
|
+
reader is checking — and it renders `emptyLabel` in the value's place.
|
|
12
|
+
Both settings come from the enclosing list by default and can be overridden
|
|
13
|
+
per row.
|
|
14
|
+
|
|
15
|
+
The `card` and `bare` variants' `<dt>` and `<dd>` are siblings of every
|
|
16
|
+
other row's, directly in the `<dl>` (the list's own two-column grid for
|
|
17
|
+
`card`, whatever layout the caller gave it for `bare`): a wrapper would
|
|
18
|
+
break the alignment the grid exists for. Every other variant wraps the
|
|
19
|
+
pair, so the two stay together when the rows wrap.
|
|
20
|
+
|
|
21
|
+
ARIA contract: the `<dt>`/`<dd>` pairing is the whole contract — nothing is
|
|
22
|
+
added to it, and nothing needs to be.
|
|
23
|
+
-->
|
|
24
|
+
<script lang="ts">import { getDescriptionListStyle } from "./description-context.js";
|
|
25
|
+
let { label, value, children, valueClass, labelClass, showEmpty, emptyLabel } = $props();
|
|
26
|
+
const style = getDescriptionListStyle();
|
|
27
|
+
const hasValue = $derived(children !== undefined || value !== undefined && String(value).trim() !== "");
|
|
28
|
+
const visible = $derived(hasValue || (showEmpty ?? style().showEmpty));
|
|
29
|
+
const placeholder = $derived(emptyLabel ?? style().emptyLabel);
|
|
30
|
+
const dtClass = $derived(["text-base-content/60 text-sm", labelClass]);
|
|
31
|
+
const ddClass = $derived([
|
|
32
|
+
"text-sm",
|
|
33
|
+
style().mono && "font-mono break-all",
|
|
34
|
+
!hasValue && "text-base-content/50 italic",
|
|
35
|
+
valueClass
|
|
36
|
+
]);
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
{#snippet pair()}
|
|
40
|
+
<dt class={dtClass}>{label}</dt>
|
|
41
|
+
<dd class={ddClass}>
|
|
42
|
+
{#if children}{@render children()}{:else if hasValue}{value}{:else}{placeholder}{/if}
|
|
43
|
+
</dd>
|
|
44
|
+
{/snippet}
|
|
45
|
+
|
|
46
|
+
{#if visible}
|
|
47
|
+
{#if style().variant === 'card' || style().variant === 'bare'}
|
|
48
|
+
{@render pair()}
|
|
49
|
+
{:else if style().variant === 'inline'}
|
|
50
|
+
<div class="flex items-baseline gap-2">{@render pair()}</div>
|
|
51
|
+
{:else if style().variant === 'divided'}
|
|
52
|
+
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:gap-4">{@render pair()}</div>
|
|
53
|
+
{:else}
|
|
54
|
+
<div class="flex flex-col gap-0.5">{@render pair()}</div>
|
|
55
|
+
{/if}
|
|
56
|
+
{/if}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** The term, rendered as the `<dt>`. */
|
|
4
|
+
label: string;
|
|
5
|
+
/** The value as text. Ignored when `children` is given. */
|
|
6
|
+
value?: string | number | undefined;
|
|
7
|
+
/** The value as markup — a formatted date, a link, a badge. */
|
|
8
|
+
children?: Snippet<[]> | undefined;
|
|
9
|
+
/** Extra classes on the `<dd>`. */
|
|
10
|
+
valueClass?: string | undefined;
|
|
11
|
+
/** Extra classes on the `<dt>`. */
|
|
12
|
+
labelClass?: string | undefined;
|
|
13
|
+
/** Override the list's `showEmpty` for this row. */
|
|
14
|
+
showEmpty?: boolean | undefined;
|
|
15
|
+
/** Override the list's `emptyLabel` for this row. */
|
|
16
|
+
emptyLabel?: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
/** One label and its value inside a `DescriptionList`. */
|
|
19
|
+
declare const DescriptionRow: import("svelte").Component<Props, {}, "">;
|
|
20
|
+
type DescriptionRow = ReturnType<typeof DescriptionRow>;
|
|
21
|
+
export default DescriptionRow;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A word-level diff rendered inline: inserted runs in `<ins>`, deleted runs in `<del>`, unchanged runs plain.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
DiffText — a word-level diff rendered inline: inserted runs in `<ins>`,
|
|
6
|
+
deleted runs in `<del>`, unchanged runs plain.
|
|
7
|
+
|
|
8
|
+
ARIA contract: `<ins>` and `<del>` are the contract. They are what carries
|
|
9
|
+
"added" and "removed" into the accessibility tree and into a copy of the
|
|
10
|
+
page; the colour and the strike-through are the sighted reader's copy of
|
|
11
|
+
the same information, never the only copy. Support for announcing the two
|
|
12
|
+
elements is uneven across screen readers, so `insertLabel` / `deleteLabel`
|
|
13
|
+
add a visually hidden word before a run when the diff is the point of the
|
|
14
|
+
page rather than a detail on it — off by default, because a forty-segment
|
|
15
|
+
diff with a prefix on every run is unreadable.
|
|
16
|
+
|
|
17
|
+
`separator` sits BETWEEN segments rather than inside them: a word-level
|
|
18
|
+
diff needs the space and a character-level one must not have it, and only
|
|
19
|
+
the caller knows which it produced. That is also why the template below is
|
|
20
|
+
written without line breaks between the runs — a newline in the markup is a
|
|
21
|
+
space in the output, and it would make the choice for them.
|
|
22
|
+
-->
|
|
23
|
+
<script lang="ts">import VisuallyHidden from "../ui/VisuallyHidden.svelte";
|
|
24
|
+
let { segments, separator = " ", insertLabel, deleteLabel, class: className, ...rest } = $props();
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
{#snippet run(segment: DiffSegment)}{#if segment.kind === 'insert'}<ins class="bg-success/20 text-success-content decoration-success underline">{#if insertLabel !== undefined}<VisuallyHidden>{insertLabel}</VisuallyHidden>{/if}{segment.text}</ins>{:else if segment.kind === 'delete'}<del class="bg-error/20 text-error-content">{#if deleteLabel !== undefined}<VisuallyHidden>{deleteLabel}</VisuallyHidden>{/if}{segment.text}</del>{:else}{segment.text}{/if}{/snippet}
|
|
28
|
+
|
|
29
|
+
<p {...rest} class={['leading-7', className]}>{#each segments as segment, index (index)}{#if index > 0}{separator}{/if}{@render run(segment)}{/each}</p>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { DiffSegment } from './diff.ts';
|
|
3
|
+
interface Props extends Omit<HTMLAttributes<HTMLParagraphElement>, 'children'> {
|
|
4
|
+
/** The diff, in reading order. */
|
|
5
|
+
segments: readonly DiffSegment[];
|
|
6
|
+
/**
|
|
7
|
+
* Rendered between segments — a space for a word-level diff.
|
|
8
|
+
* @defaultValue `' '`
|
|
9
|
+
*/
|
|
10
|
+
separator?: string | undefined;
|
|
11
|
+
/** A visually hidden word before each inserted run. */
|
|
12
|
+
insertLabel?: string | undefined;
|
|
13
|
+
/** A visually hidden word before each deleted run. */
|
|
14
|
+
deleteLabel?: string | undefined;
|
|
15
|
+
}
|
|
16
|
+
/** A word-level diff rendered inline: inserted runs in `<ins>`, deleted runs in `<del>`, unchanged runs plain. */
|
|
17
|
+
declare const DiffText: import("svelte").Component<Props, {}, "">;
|
|
18
|
+
type DiffText = ReturnType<typeof DiffText>;
|
|
19
|
+
export default DiffText;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A list in one of four shapes — `compact` links, `stacked` rows, a `grid` or `cards` — with an optional feed mode for windowed streams.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
ItemList — the list every index page and detail section renders, in the four
|
|
6
|
+
shapes those pages actually use: a `compact` run of links, `stacked` rows
|
|
7
|
+
divided by rules, a responsive `grid`, or a grid of `cards`.
|
|
8
|
+
|
|
9
|
+
The row body is the caller's, through the `item` snippet, because row shape
|
|
10
|
+
varies per resource type; what this owns is the container, the keying and
|
|
11
|
+
the empty state — so an empty list cannot be forgotten in one page out of
|
|
12
|
+
twenty.
|
|
13
|
+
|
|
14
|
+
ARIA contract, two modes:
|
|
15
|
+
|
|
16
|
+
- Default: a plain `<ul>` of `<li>`s. The list structure is the semantics —
|
|
17
|
+
a screen reader announces "list, 12 items" — and nothing is added to it.
|
|
18
|
+
- `feed`: the ARIA feed pattern, for a stream whose items load as the
|
|
19
|
+
reader scrolls. The container takes `role="feed"`, an accessible name from
|
|
20
|
+
`label`, and `aria-busy` while more is loading; each item is an `<article>`
|
|
21
|
+
carrying `aria-posinset` / `aria-setsize`, so "article 7 of 40" is
|
|
22
|
+
announced even though only 20 are in the DOM, and `tabindex="-1"` so the
|
|
23
|
+
reader's Page Down lands somewhere.
|
|
24
|
+
|
|
25
|
+
Feed mode renders `<div role="feed">` with `<article>` children rather
|
|
26
|
+
than a list, deliberately: `feed` is not a role HTML permits on `<ul>`,
|
|
27
|
+
and forcing `role="article"` onto each `<li>` would throw away the list
|
|
28
|
+
semantics to get there. A feed is not a list, and the markup says so.
|
|
29
|
+
-->
|
|
30
|
+
<script lang="ts" generics="T">let { items, variant = "compact", getKey, item, empty, emptyMessage = "Nothing here yet.", feed = false, label, busy = false, class: className, ...rest } = $props();
|
|
31
|
+
// Literal lookup tables: Tailwind only generates the classes it can read
|
|
32
|
+
// verbatim in the source, so these can never become template strings.
|
|
33
|
+
const containerClass = {
|
|
34
|
+
compact: "space-y-1",
|
|
35
|
+
stacked: "divide-base-300 divide-y",
|
|
36
|
+
grid: "grid grid-cols-1 gap-3 sm:grid-cols-2",
|
|
37
|
+
cards: "grid grid-cols-1 gap-4 sm:grid-cols-2"
|
|
38
|
+
};
|
|
39
|
+
const itemClass = {
|
|
40
|
+
compact: "",
|
|
41
|
+
stacked: "py-3",
|
|
42
|
+
grid: "",
|
|
43
|
+
cards: "card card-border bg-base-100 p-4 shadow-sm"
|
|
44
|
+
};
|
|
45
|
+
const setSize = $derived(items.length);
|
|
46
|
+
export {};
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
{#if items.length === 0}
|
|
50
|
+
{#if empty}
|
|
51
|
+
{@render empty()}
|
|
52
|
+
{:else}
|
|
53
|
+
<p class="text-base-content/70 text-sm leading-6">{emptyMessage}</p>
|
|
54
|
+
{/if}
|
|
55
|
+
{:else if feed}
|
|
56
|
+
<div
|
|
57
|
+
{...rest}
|
|
58
|
+
role="feed"
|
|
59
|
+
aria-label={label}
|
|
60
|
+
aria-busy={busy}
|
|
61
|
+
class={[containerClass[variant], className]}
|
|
62
|
+
>
|
|
63
|
+
{#each items as entry, index (getKey(entry, index))}
|
|
64
|
+
<article
|
|
65
|
+
aria-posinset={index + 1}
|
|
66
|
+
aria-setsize={setSize}
|
|
67
|
+
tabindex="-1"
|
|
68
|
+
class={itemClass[variant]}
|
|
69
|
+
>
|
|
70
|
+
{@render item(entry, index)}
|
|
71
|
+
</article>
|
|
72
|
+
{/each}
|
|
73
|
+
</div>
|
|
74
|
+
{:else}
|
|
75
|
+
<ul {...rest} aria-label={label} class={[containerClass[variant], className]}>
|
|
76
|
+
{#each items as entry, index (getKey(entry, index))}
|
|
77
|
+
<li class={itemClass[variant]}>{@render item(entry, index)}</li>
|
|
78
|
+
{/each}
|
|
79
|
+
</ul>
|
|
80
|
+
{/if}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
declare function $$render<T>(): {
|
|
4
|
+
props: Omit<HTMLAttributes<HTMLElement>, "children"> & {
|
|
5
|
+
/** The items, each rendered by the `item` snippet. */
|
|
6
|
+
items: readonly T[];
|
|
7
|
+
/**
|
|
8
|
+
* The layout.
|
|
9
|
+
* @defaultValue `'compact'`
|
|
10
|
+
*/
|
|
11
|
+
variant?: ("grid" | "compact" | "stacked" | "cards") | undefined;
|
|
12
|
+
/** Stable identity per item — the `{#each}` key. */
|
|
13
|
+
getKey: (item: T, index: number) => string;
|
|
14
|
+
/** One row's body. */
|
|
15
|
+
item: Snippet<[T, number]>;
|
|
16
|
+
/** Rendered in place of the list when there is nothing in it. */
|
|
17
|
+
empty?: Snippet<[]> | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* The line shown when there is nothing and no `empty` snippet.
|
|
20
|
+
* @defaultValue `'Nothing here yet.'`
|
|
21
|
+
*/
|
|
22
|
+
emptyMessage?: string | undefined;
|
|
23
|
+
/** Render as an ARIA feed. */
|
|
24
|
+
feed?: boolean | undefined;
|
|
25
|
+
/** The feed's accessible name. Required in `feed` mode to name the region. */
|
|
26
|
+
label?: string | undefined;
|
|
27
|
+
/** More items are loading — `aria-busy` on the feed. */
|
|
28
|
+
busy?: boolean | undefined;
|
|
29
|
+
};
|
|
30
|
+
exports: {};
|
|
31
|
+
bindings: "";
|
|
32
|
+
slots: {};
|
|
33
|
+
events: {};
|
|
34
|
+
};
|
|
35
|
+
declare class __sveltets_Render<T> {
|
|
36
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
37
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
38
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
39
|
+
bindings(): "";
|
|
40
|
+
exports(): {};
|
|
41
|
+
}
|
|
42
|
+
interface $$IsomorphicComponent {
|
|
43
|
+
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']>> & {
|
|
44
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
45
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
46
|
+
<T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
47
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
48
|
+
}
|
|
49
|
+
/** A list in one of four shapes — `compact` links, `stacked` rows, a `grid` or `cards` — with an optional feed mode for windowed streams. */
|
|
50
|
+
declare const ItemList: $$IsomorphicComponent;
|
|
51
|
+
type ItemList<T> = InstanceType<typeof ItemList<T>>;
|
|
52
|
+
export default ItemList;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The row body most lists want: a linked title, a line of context under it, and short badges.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
LinkListItem — the row body most lists want: a linked title, a line of
|
|
6
|
+
context under it, and short markers.
|
|
7
|
+
|
|
8
|
+
It renders the body only, never the `<li>` or the `<article>` around it,
|
|
9
|
+
because the container is `ItemList`'s decision (a list item in one mode, a
|
|
10
|
+
feed article in the other) and a component that rendered both would have to
|
|
11
|
+
know which.
|
|
12
|
+
|
|
13
|
+
ARIA contract: the title is a real link, resolved through the components
|
|
14
|
+
context, and it is the row's only interactive element — the subtitle and
|
|
15
|
+
the badges are text beside it, not a second target. `headingLevel` promotes
|
|
16
|
+
the title to a real heading for a list of sections a reader navigates by
|
|
17
|
+
headings; by default it is not one, because twenty `<h3>`s in a filter
|
|
18
|
+
result is worse for navigation than none.
|
|
19
|
+
-->
|
|
20
|
+
<script lang="ts">import Badge from "../ui/Badge.svelte";
|
|
21
|
+
import Link from "../ui/Link.svelte";
|
|
22
|
+
let { href, title, subtitle, badges, headingLevel, meta, class: className, ...rest } = $props();
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<div {...rest} class={['flex flex-col gap-1', className]}>
|
|
26
|
+
{#if headingLevel === undefined}
|
|
27
|
+
<Link {href} variant="muted" class="font-medium">{title}</Link>
|
|
28
|
+
{:else}
|
|
29
|
+
<svelte:element this={`h${headingLevel}`} class="text-base font-medium">
|
|
30
|
+
<Link {href} variant="muted">{title}</Link>
|
|
31
|
+
</svelte:element>
|
|
32
|
+
{/if}
|
|
33
|
+
{#if subtitle !== undefined}
|
|
34
|
+
<p class="text-base-content/70 text-sm">{subtitle}</p>
|
|
35
|
+
{/if}
|
|
36
|
+
{#if meta}
|
|
37
|
+
<div class="text-base-content/60 text-sm">{@render meta()}</div>
|
|
38
|
+
{/if}
|
|
39
|
+
{#if badges !== undefined && badges.length > 0}
|
|
40
|
+
<div class="flex flex-wrap gap-1">
|
|
41
|
+
{#each badges as badge (badge)}
|
|
42
|
+
<Badge variant="outline" size="sm">{badge}</Badge>
|
|
43
|
+
{/each}
|
|
44
|
+
</div>
|
|
45
|
+
{/if}
|
|
46
|
+
</div>
|