@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
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accessible Svelte 5 UI primitives.
|
|
3
|
+
*
|
|
4
|
+
* Everything exported here is app-agnostic: it takes props and snippets,
|
|
5
|
+
* spreads the native attributes of the element it renders, reads no global
|
|
6
|
+
* state, and gets every user-facing string from a prop with an English
|
|
7
|
+
* default. Styling is daisyUI semantic classes over the tokens in
|
|
8
|
+
* `./theme.css`, which ships beside this barrel as the package's
|
|
9
|
+
* `./theme.css` export. The one injected dependency is
|
|
10
|
+
* {@link ComponentsContext}: locale, href resolution, navigation and the
|
|
11
|
+
* current-page check.
|
|
12
|
+
*
|
|
13
|
+
* The heavier families — `citations`, `canvas`, `charts`, `tips`, `seo` —
|
|
14
|
+
* are separate entry points (`@thomasfosterau/components/<family>`), as is
|
|
15
|
+
* `EntityForm` (`@thomasfosterau/components/entity-form`, which needs the
|
|
16
|
+
* optional peer `@thomasfosterau/effect-forms-svelte`); none is re-exported
|
|
17
|
+
* here. `hotkeys` is both: re-exported here and its own
|
|
18
|
+
* `@thomasfosterau/components/hotkeys` entry, for a lazily loaded help dialog. The maps family lives one package over, in
|
|
19
|
+
* `@thomasfosterau/components-mapbox`: its behaviour needs a specific
|
|
20
|
+
* third-party engine (`mapbox-gl`), and a component that needs one lives in
|
|
21
|
+
* its own package so this one stays free of it.
|
|
22
|
+
*
|
|
23
|
+
* @module @thomasfosterau/components
|
|
24
|
+
*/
|
|
25
|
+
export * from './context.svelte.ts';
|
|
26
|
+
export * from './ui/index.ts';
|
|
27
|
+
export * from './feedback/index.ts';
|
|
28
|
+
export * from './layout/index.ts';
|
|
29
|
+
export * from './fields/index.ts';
|
|
30
|
+
export * from './forms/index.ts';
|
|
31
|
+
export * from './data/index.ts';
|
|
32
|
+
export * from './infobox/index.ts';
|
|
33
|
+
export * from './formatting/index.ts';
|
|
34
|
+
export * from './links/index.ts';
|
|
35
|
+
export * from './media/index.ts';
|
|
36
|
+
export * from './hotkeys/index.ts';
|
|
37
|
+
export * from './search/index.ts';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accessible Svelte 5 UI primitives.
|
|
3
|
+
*
|
|
4
|
+
* Everything exported here is app-agnostic: it takes props and snippets,
|
|
5
|
+
* spreads the native attributes of the element it renders, reads no global
|
|
6
|
+
* state, and gets every user-facing string from a prop with an English
|
|
7
|
+
* default. Styling is daisyUI semantic classes over the tokens in
|
|
8
|
+
* `./theme.css`, which ships beside this barrel as the package's
|
|
9
|
+
* `./theme.css` export. The one injected dependency is
|
|
10
|
+
* {@link ComponentsContext}: locale, href resolution, navigation and the
|
|
11
|
+
* current-page check.
|
|
12
|
+
*
|
|
13
|
+
* The heavier families — `citations`, `canvas`, `charts`, `tips`, `seo` —
|
|
14
|
+
* are separate entry points (`@thomasfosterau/components/<family>`), as is
|
|
15
|
+
* `EntityForm` (`@thomasfosterau/components/entity-form`, which needs the
|
|
16
|
+
* optional peer `@thomasfosterau/effect-forms-svelte`); none is re-exported
|
|
17
|
+
* here. `hotkeys` is both: re-exported here and its own
|
|
18
|
+
* `@thomasfosterau/components/hotkeys` entry, for a lazily loaded help dialog. The maps family lives one package over, in
|
|
19
|
+
* `@thomasfosterau/components-mapbox`: its behaviour needs a specific
|
|
20
|
+
* third-party engine (`mapbox-gl`), and a component that needs one lives in
|
|
21
|
+
* its own package so this one stays free of it.
|
|
22
|
+
*
|
|
23
|
+
* @module @thomasfosterau/components
|
|
24
|
+
*/
|
|
25
|
+
export * from "./context.svelte.js";
|
|
26
|
+
export * from "./ui/index.js";
|
|
27
|
+
export * from "./feedback/index.js";
|
|
28
|
+
export * from "./layout/index.js";
|
|
29
|
+
export * from "./fields/index.js";
|
|
30
|
+
export * from "./forms/index.js";
|
|
31
|
+
export * from "./data/index.js";
|
|
32
|
+
export * from "./infobox/index.js";
|
|
33
|
+
export * from "./formatting/index.js";
|
|
34
|
+
export * from "./links/index.js";
|
|
35
|
+
export * from "./media/index.js";
|
|
36
|
+
export * from "./hotkeys/index.js";
|
|
37
|
+
export * from "./search/index.js";
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The summary rail beside an entity page’s prose: an optional header and image above a body of labelled facts.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Infobox — the summary rail beside an entity page's prose: an optional
|
|
6
|
+
header, an optional image, and a body of labelled facts.
|
|
7
|
+
|
|
8
|
+
Two ways to fill it, both live at once. The composable path — `children`
|
|
9
|
+
taking `InfoboxSection`/`InfoboxRow` (or anything else):
|
|
10
|
+
a page builds bespoke markup, one piece of markup per concern, and a fix
|
|
11
|
+
to row layout lands once because there is only one row layout. `rows` renders through the SAME `InfoboxSection`/
|
|
12
|
+
`InfoboxRow`/`InfoboxImage` primitives `children` would use — never a
|
|
13
|
+
second copy of the markup — so both paths stay in lock step. Both are
|
|
14
|
+
accepted together: `rows` first, then `children` below them.
|
|
15
|
+
|
|
16
|
+
`float`: floats the box to the right of the article's prose; instead give it its own grid column in the
|
|
17
|
+
page layout and never float it. Off by default, since a grid-column aside
|
|
18
|
+
is the more common shape here, and opt-in per page with `float`.
|
|
19
|
+
|
|
20
|
+
ARIA contract: `aria-label={title ?? label}` names the region — a real
|
|
21
|
+
`title` is more specific than the generic default, so it wins.
|
|
22
|
+
`data-testid="infobox"` is kept for e2e parity with the source apps.
|
|
23
|
+
-->
|
|
24
|
+
<script lang="ts">import Link from "../ui/Link.svelte";
|
|
25
|
+
import InfoboxHeader from "./InfoboxHeader.svelte";
|
|
26
|
+
import InfoboxImage from "./InfoboxImage.svelte";
|
|
27
|
+
import InfoboxRow from "./InfoboxRow.svelte";
|
|
28
|
+
import InfoboxSection from "./InfoboxSection.svelte";
|
|
29
|
+
import { infoboxRowIsPresent } from "./types.js";
|
|
30
|
+
let { title, subtitle, headingLevel, label = "Key facts", image, rows, float = false, children, class: className, ...rest } = $props();
|
|
31
|
+
const presentRows = $derived((rows ?? []).filter(infoboxRowIsPresent));
|
|
32
|
+
const imageRows = $derived(presentRows.filter((row) => row.kind === "image"));
|
|
33
|
+
const bodyRows = $derived(presentRows.filter((row) => row.kind !== "image"));
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<aside
|
|
37
|
+
{...rest}
|
|
38
|
+
data-testid="infobox"
|
|
39
|
+
aria-label={title ?? label}
|
|
40
|
+
class={[
|
|
41
|
+
'card card-border bg-base-100 shadow-sm',
|
|
42
|
+
float && 'float-right mb-4 ml-4 w-full sm:w-80',
|
|
43
|
+
className,
|
|
44
|
+
]}
|
|
45
|
+
>
|
|
46
|
+
{#if title !== undefined}
|
|
47
|
+
<InfoboxHeader {title} {subtitle} {headingLevel} />
|
|
48
|
+
{/if}
|
|
49
|
+
{#if image !== undefined}
|
|
50
|
+
<InfoboxImage {...image} />
|
|
51
|
+
{/if}
|
|
52
|
+
{#each imageRows as row (row.src)}
|
|
53
|
+
<InfoboxImage {...row} />
|
|
54
|
+
{/each}
|
|
55
|
+
{#if bodyRows.length > 0}
|
|
56
|
+
<InfoboxSection>
|
|
57
|
+
{#each bodyRows as row (row.label)}
|
|
58
|
+
{#if row.kind === 'fact'}
|
|
59
|
+
<InfoboxRow label={row.label} value={row.value} />
|
|
60
|
+
{:else if row.kind === 'link'}
|
|
61
|
+
<InfoboxRow label={row.label} value={row.text} href={row.href} external={row.external} />
|
|
62
|
+
{:else if row.kind === 'links'}
|
|
63
|
+
<InfoboxRow label={row.label}>
|
|
64
|
+
<ul class="flex flex-col gap-1">
|
|
65
|
+
{#each row.links ?? [] as link (link.href)}
|
|
66
|
+
<li><Link href={link.href}>{link.label}</Link></li>
|
|
67
|
+
{/each}
|
|
68
|
+
</ul>
|
|
69
|
+
</InfoboxRow>
|
|
70
|
+
{:else if row.kind === 'custom'}
|
|
71
|
+
<InfoboxRow label={row.label}>
|
|
72
|
+
{@render row.content()}
|
|
73
|
+
</InfoboxRow>
|
|
74
|
+
{/if}
|
|
75
|
+
{/each}
|
|
76
|
+
</InfoboxSection>
|
|
77
|
+
{/if}
|
|
78
|
+
{@render children?.()}
|
|
79
|
+
</aside>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { HeadingLevel } from '../ui/tones.ts';
|
|
4
|
+
import { type InfoboxImageSpec, type InfoboxRowSpec as Row } from './types.ts';
|
|
5
|
+
interface Props extends Omit<HTMLAttributes<HTMLElement>, 'children' | 'title'> {
|
|
6
|
+
/** Heading of the rail; also its accessible name. */
|
|
7
|
+
title?: string | undefined;
|
|
8
|
+
/** A line under the title. */
|
|
9
|
+
subtitle?: string | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* The title's heading level (`InfoboxHeader`'s). Keep the default beside
|
|
12
|
+
* prose; raise it when the box is a section of the page in its own right.
|
|
13
|
+
* @defaultValue `3`
|
|
14
|
+
*/
|
|
15
|
+
headingLevel?: Exclude<HeadingLevel, 1> | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Accessible name for the region when there is no `title`.
|
|
18
|
+
* @defaultValue `'Key facts'`
|
|
19
|
+
*/
|
|
20
|
+
label?: string | undefined;
|
|
21
|
+
/** Renders an `InfoboxImage` above the body. */
|
|
22
|
+
image?: InfoboxImageSpec | undefined;
|
|
23
|
+
/** Rendered through the primitives below, inside one `InfoboxSection`. */
|
|
24
|
+
rows?: readonly Row[] | undefined;
|
|
25
|
+
/** float-right rail; off renders in normal flow (a grid column). */
|
|
26
|
+
float?: boolean | undefined;
|
|
27
|
+
/** Extra composed markup — `InfoboxSection`/`InfoboxRow`, or anything else. Rendered after `rows`. */
|
|
28
|
+
children?: Snippet<[]> | undefined;
|
|
29
|
+
}
|
|
30
|
+
/** The summary rail beside an entity page’s prose: an optional header and image above a body of labelled facts. */
|
|
31
|
+
declare const Infobox: import("svelte").Component<Props, {}, "">;
|
|
32
|
+
type Infobox = ReturnType<typeof Infobox>;
|
|
33
|
+
export default Infobox;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The title block at the top of an `Infobox`.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
InfoboxHeader — the title block at the top of an `Infobox`.
|
|
6
|
+
|
|
7
|
+
An `h3` by default rather than an `h2`: the box sits beside an article's
|
|
8
|
+
prose, and its title names the summary, not a section of the document.
|
|
9
|
+
Promoting it to the level a real section heading would use puts a phantom
|
|
10
|
+
entry in the page's outline between two real ones — the box is
|
|
11
|
+
deliberately outside the outline.
|
|
12
|
+
|
|
13
|
+
`headingLevel` raises (or lowers) it for a page that uses the box as a
|
|
14
|
+
section in its own right, where `h3` would skip a level (`h1` → `h3`) or
|
|
15
|
+
read as a sub-heading of the section before it. Only the tag changes; the
|
|
16
|
+
classes are the same at every level. `1` is excluded: the box never titles
|
|
17
|
+
the page.
|
|
18
|
+
-->
|
|
19
|
+
<script lang="ts">let { title, subtitle, headingLevel = 3, class: className, ...rest } = $props();
|
|
20
|
+
export {};
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<div
|
|
24
|
+
{...rest}
|
|
25
|
+
class={["border-base-300 bg-base-300 border-b px-4 py-3", className]}
|
|
26
|
+
>
|
|
27
|
+
<svelte:element this={`h${headingLevel}`} class="text-center text-lg font-bold select-none">
|
|
28
|
+
{title}
|
|
29
|
+
</svelte:element>
|
|
30
|
+
{#if subtitle !== undefined && subtitle !== ""}
|
|
31
|
+
<p class="text-base-content/60 mt-1 text-center text-sm select-none">
|
|
32
|
+
{subtitle}
|
|
33
|
+
</p>
|
|
34
|
+
{/if}
|
|
35
|
+
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
2
|
+
import type { HeadingLevel } from "../ui/tones.ts";
|
|
3
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
/** The infobox heading text. */
|
|
5
|
+
title: string;
|
|
6
|
+
/** A line under the heading. */
|
|
7
|
+
subtitle?: string | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* The heading's level. Keep the default when the box sits beside prose;
|
|
10
|
+
* raise it to the page's section level when the box is a section itself.
|
|
11
|
+
* @defaultValue `3`
|
|
12
|
+
*/
|
|
13
|
+
headingLevel?: Exclude<HeadingLevel, 1> | undefined;
|
|
14
|
+
}
|
|
15
|
+
/** The title block at the top of an `Infobox`. */
|
|
16
|
+
declare const InfoboxHeader: import("svelte").Component<Props, {}, "">;
|
|
17
|
+
type InfoboxHeader = ReturnType<typeof InfoboxHeader>;
|
|
18
|
+
export default InfoboxHeader;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The picture at the top of an `Infobox`, with its caption.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
InfoboxImage — the picture at the top of an `Infobox`, with its caption.
|
|
6
|
+
|
|
7
|
+
`width`/`height` are passed through so the browser can reserve the box
|
|
8
|
+
before the bytes arrive — the difference between a page that settles and
|
|
9
|
+
one that jumps under the reader's eye — but only reserve that space when
|
|
10
|
+
BOTH are present; the caller supplies them together or not at all.
|
|
11
|
+
|
|
12
|
+
`eager` (default off: an infobox usually sits beside the prose rather than
|
|
13
|
+
above it, so its picture is rarely the first thing painted) sets
|
|
14
|
+
`loading="eager"` and `fetchpriority="high"` together.
|
|
15
|
+
-->
|
|
16
|
+
<script lang="ts">let { src, alt, caption, width, height, eager = false, class: className, ...rest } = $props();
|
|
17
|
+
const loading = $derived(eager ? "eager" : "lazy");
|
|
18
|
+
const fetchpriority = $derived(eager ? "high" : undefined);
|
|
19
|
+
export {};
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<figure class="border-base-300 border-b">
|
|
23
|
+
<img
|
|
24
|
+
{...rest}
|
|
25
|
+
{src}
|
|
26
|
+
{alt}
|
|
27
|
+
{width}
|
|
28
|
+
{height}
|
|
29
|
+
{loading}
|
|
30
|
+
{fetchpriority}
|
|
31
|
+
class={['h-auto w-full', className]}
|
|
32
|
+
/>
|
|
33
|
+
{#if caption !== undefined && caption !== ''}
|
|
34
|
+
<figcaption class="text-base-content/60 px-4 py-2 text-center text-xs italic">
|
|
35
|
+
{caption}
|
|
36
|
+
</figcaption>
|
|
37
|
+
{/if}
|
|
38
|
+
</figure>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { HTMLImgAttributes } from 'svelte/elements';
|
|
2
|
+
interface Props extends Omit<HTMLImgAttributes, 'src' | 'alt' | 'width' | 'height' | 'loading' | 'class'> {
|
|
3
|
+
/** Image URL. */
|
|
4
|
+
src: string;
|
|
5
|
+
/** Alternative text; `''` only where the image is decoration. */
|
|
6
|
+
alt: string;
|
|
7
|
+
/** Rendered as the `<figcaption>`. */
|
|
8
|
+
caption?: string | undefined;
|
|
9
|
+
/** Intrinsic width in pixels; reserves the box. */
|
|
10
|
+
width?: number | undefined;
|
|
11
|
+
/** Intrinsic height in pixels; reserves the box. */
|
|
12
|
+
height?: number | undefined;
|
|
13
|
+
/** Eager-loads at high `fetchpriority` — for the page's LCP candidate. */
|
|
14
|
+
eager?: boolean | undefined;
|
|
15
|
+
/** Extra classes, merged last. */
|
|
16
|
+
class?: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
/** The picture at the top of an `Infobox`, with its caption. */
|
|
19
|
+
declare const InfoboxImage: import("svelte").Component<Props, {}, "">;
|
|
20
|
+
type InfoboxImage = ReturnType<typeof InfoboxImage>;
|
|
21
|
+
export default InfoboxImage;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
One label/value pair inside an `InfoboxSection`.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
InfoboxRow — one label/value pair inside an `InfoboxSection`.
|
|
6
|
+
|
|
7
|
+
Absent by default: a row with neither a `value` nor `children` renders no
|
|
8
|
+
DOM at all, so a page can build a run of rows straight off sparse resource
|
|
9
|
+
attributes without guarding each one — the same "has something to show"
|
|
10
|
+
contract `infoboxRowIsPresent` gives the typed `rows` convenience on
|
|
11
|
+
`Infobox`. `showEmpty` opts back: an em
|
|
12
|
+
dash captioned by `emptyLabel`, which says "asked, and there is no answer"
|
|
13
|
+
rather than "nobody asked" — for a section that always lists the same
|
|
14
|
+
facts, where a gap is itself informative.
|
|
15
|
+
|
|
16
|
+
`href` wraps the row's content in the shared `Link`, so an in-app path
|
|
17
|
+
resolves through the components context exactly like every other link in
|
|
18
|
+
the library; `external` is `Link`'s own external-link contract, passed
|
|
19
|
+
straight through.
|
|
20
|
+
-->
|
|
21
|
+
<script lang="ts">import Link from "../ui/Link.svelte";
|
|
22
|
+
let { label, value, children, href, external, emptyLabel = "unrecorded", showEmpty = false, class: className, ...rest } = $props();
|
|
23
|
+
const hasValue = $derived(value !== undefined && value !== "");
|
|
24
|
+
const present = $derived(children !== undefined || hasValue);
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
{#if present || showEmpty}
|
|
28
|
+
<div
|
|
29
|
+
{...rest}
|
|
30
|
+
class={[
|
|
31
|
+
'hover:bg-base-100 grid grid-cols-3 gap-2 px-4 py-2 transition-colors',
|
|
32
|
+
className,
|
|
33
|
+
]}
|
|
34
|
+
>
|
|
35
|
+
<dt class="text-base-content/70 col-span-1 text-sm font-semibold select-none">{label}</dt>
|
|
36
|
+
<dd class="col-span-2 text-sm">
|
|
37
|
+
{#if present && href !== undefined}
|
|
38
|
+
<Link {href} external={external ?? false}>
|
|
39
|
+
{#if children}{@render children()}{:else}{value}{/if}
|
|
40
|
+
</Link>
|
|
41
|
+
{:else if present && children}
|
|
42
|
+
{@render children()}
|
|
43
|
+
{:else if present}
|
|
44
|
+
{value}
|
|
45
|
+
{:else}
|
|
46
|
+
<span class="text-base-content/40" aria-label={emptyLabel}>—</span>
|
|
47
|
+
{/if}
|
|
48
|
+
</dd>
|
|
49
|
+
</div>
|
|
50
|
+
{/if}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
4
|
+
/** The term, rendered as the `<dt>`. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** Plain text or number; `children` wins where both are supplied. */
|
|
7
|
+
value?: string | number | undefined;
|
|
8
|
+
/** Richer markup — a formatted quantity, a badge, more than one link. */
|
|
9
|
+
children?: Snippet<[]> | undefined;
|
|
10
|
+
/** Wraps the row's content in a `Link` resolved through the components context. */
|
|
11
|
+
href?: string | undefined;
|
|
12
|
+
/** Passed through to `Link` — an off-site destination. */
|
|
13
|
+
external?: boolean | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Stands in for the value, captioned by `aria-label`, when `showEmpty` and the row has nothing.
|
|
16
|
+
* @defaultValue `'unrecorded'`
|
|
17
|
+
*/
|
|
18
|
+
emptyLabel?: string | undefined;
|
|
19
|
+
/** Render the row even when empty, showing `emptyLabel` instead of nothing. */
|
|
20
|
+
showEmpty?: boolean | undefined;
|
|
21
|
+
}
|
|
22
|
+
/** One label/value pair inside an `InfoboxSection`. */
|
|
23
|
+
declare const InfoboxRow: import("svelte").Component<Props, {}, "">;
|
|
24
|
+
type InfoboxRow = ReturnType<typeof InfoboxRow>;
|
|
25
|
+
export default InfoboxRow;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A titled group of `InfoboxRow`s, with dividing rules between them.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
InfoboxSection — a titled group of `InfoboxRow`s, with the dividing rules
|
|
6
|
+
between them.
|
|
7
|
+
|
|
8
|
+
The `<dl>` lives here rather than on each row: a definition list whose
|
|
9
|
+
terms and definitions are split across a dozen sibling lists is not one
|
|
10
|
+
list, and a screen reader reading "list of 1 item" twelve times is the
|
|
11
|
+
audible version of that mistake. Rows contribute the `<dt>`/`<dd>` pairs.
|
|
12
|
+
-->
|
|
13
|
+
<script lang="ts">let { title, children, class: className, ...rest } = $props();
|
|
14
|
+
export {};
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
{#if title !== undefined && title !== ''}
|
|
18
|
+
<div class="border-base-300 bg-base-300 border-b px-4 py-2">
|
|
19
|
+
<h4 class="text-sm font-bold select-none">{title}</h4>
|
|
20
|
+
</div>
|
|
21
|
+
{/if}
|
|
22
|
+
<dl {...rest} class={['divide-base-300 divide-y', className]}>
|
|
23
|
+
{@render children()}
|
|
24
|
+
</dl>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props extends HTMLAttributes<HTMLDListElement> {
|
|
4
|
+
/** Names the group; omitted for an untitled run of rows. */
|
|
5
|
+
title?: string | undefined;
|
|
6
|
+
/** The rows — `InfoboxRow`s, or anything else that belongs in a `<dl>`. */
|
|
7
|
+
children: Snippet<[]>;
|
|
8
|
+
}
|
|
9
|
+
/** A titled group of `InfoboxRow`s, with dividing rules between them. */
|
|
10
|
+
declare const InfoboxSection: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type InfoboxSection = ReturnType<typeof InfoboxSection>;
|
|
12
|
+
export default InfoboxSection;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* infobox — the family that fills an entity page's summary rail, two ways
|
|
3
|
+
* at once.
|
|
4
|
+
*
|
|
5
|
+
* Composed primitives (`InfoboxHeader`, `InfoboxImage`, `InfoboxSection`,
|
|
6
|
+
* `InfoboxRow`) let a page build bespoke markup. A
|
|
7
|
+
* typed `rows` convenience on `Infobox` itself — the `InfoboxRowSpec` union
|
|
8
|
+
* and `infoboxRowIsPresent` — lets a page instead hand over a
|
|
9
|
+
* `$derived<InfoboxRowSpec[]>` built from sparse entity attributes; `rows` renders through the very
|
|
10
|
+
* same primitives, so a fix to row layout lands in one place regardless of
|
|
11
|
+
* which API a caller used to reach it.
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
export { default as Infobox } from './Infobox.svelte';
|
|
16
|
+
export { default as InfoboxHeader } from './InfoboxHeader.svelte';
|
|
17
|
+
export { default as InfoboxImage } from './InfoboxImage.svelte';
|
|
18
|
+
export { default as InfoboxRow } from './InfoboxRow.svelte';
|
|
19
|
+
export { default as InfoboxSection } from './InfoboxSection.svelte';
|
|
20
|
+
export { infoboxRowIsPresent } from './types.ts';
|
|
21
|
+
export type { InfoboxCustomRow, InfoboxFactRow, InfoboxImageRow, InfoboxImageSpec, InfoboxLinkEntry, InfoboxLinkRow, InfoboxLinksRow, InfoboxRowSpec, } from './types.ts';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* infobox — the family that fills an entity page's summary rail, two ways
|
|
3
|
+
* at once.
|
|
4
|
+
*
|
|
5
|
+
* Composed primitives (`InfoboxHeader`, `InfoboxImage`, `InfoboxSection`,
|
|
6
|
+
* `InfoboxRow`) let a page build bespoke markup. A
|
|
7
|
+
* typed `rows` convenience on `Infobox` itself — the `InfoboxRowSpec` union
|
|
8
|
+
* and `infoboxRowIsPresent` — lets a page instead hand over a
|
|
9
|
+
* `$derived<InfoboxRowSpec[]>` built from sparse entity attributes; `rows` renders through the very
|
|
10
|
+
* same primitives, so a fix to row layout lands in one place regardless of
|
|
11
|
+
* which API a caller used to reach it.
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
export { default as Infobox } from './Infobox.svelte';
|
|
16
|
+
export { default as InfoboxHeader } from './InfoboxHeader.svelte';
|
|
17
|
+
export { default as InfoboxImage } from './InfoboxImage.svelte';
|
|
18
|
+
export { default as InfoboxRow } from './InfoboxRow.svelte';
|
|
19
|
+
export { default as InfoboxSection } from './InfoboxSection.svelte';
|
|
20
|
+
export { infoboxRowIsPresent } from "./types.js";
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shapes the `infobox` family passes around: the image spec both
|
|
3
|
+
* `InfoboxImage` and an `image`-kind row accept, the row union `Infobox`'s
|
|
4
|
+
* `rows` convenience renders, and the single "has something to show" rule
|
|
5
|
+
* the component and its tests share.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import type { Snippet } from 'svelte';
|
|
10
|
+
/** The picture at the top of an `Infobox`. */
|
|
11
|
+
export interface InfoboxImageSpec {
|
|
12
|
+
readonly src: string;
|
|
13
|
+
/** Empty for a purely decorative image; a description otherwise. */
|
|
14
|
+
readonly alt: string;
|
|
15
|
+
/** Shown beneath the picture — a photographer, a provenance, a scale. */
|
|
16
|
+
readonly caption?: string | undefined;
|
|
17
|
+
/** Intrinsic dimensions; supplying both is what stops the layout shifting. */
|
|
18
|
+
readonly width?: number | undefined;
|
|
19
|
+
readonly height?: number | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Eager-loads at high `fetchpriority`. Set when this image is the page's
|
|
22
|
+
* LCP candidate — typically an infobox's own identifying picture.
|
|
23
|
+
*/
|
|
24
|
+
readonly eager?: boolean | undefined;
|
|
25
|
+
}
|
|
26
|
+
/** An `Infobox` row holding a single identifying fact (e.g. publication year, ISBN, page count). */
|
|
27
|
+
export interface InfoboxFactRow {
|
|
28
|
+
readonly kind: 'fact';
|
|
29
|
+
readonly label: string;
|
|
30
|
+
/** `undefined` or an empty string skips the row. */
|
|
31
|
+
readonly value: string | number | undefined;
|
|
32
|
+
}
|
|
33
|
+
/** An `Infobox` row holding a single named link, with its own visible text. */
|
|
34
|
+
export interface InfoboxLinkRow {
|
|
35
|
+
readonly kind: 'link';
|
|
36
|
+
readonly label: string;
|
|
37
|
+
readonly text: string;
|
|
38
|
+
/** `undefined` or an empty string skips the row. */
|
|
39
|
+
readonly href: string | undefined;
|
|
40
|
+
/** Passed through to the underlying `Link` — an off-site destination. */
|
|
41
|
+
readonly external?: boolean | undefined;
|
|
42
|
+
}
|
|
43
|
+
/** One entry of an `InfoboxLinksRow`. */
|
|
44
|
+
export interface InfoboxLinkEntry {
|
|
45
|
+
readonly label: string;
|
|
46
|
+
readonly href: string;
|
|
47
|
+
}
|
|
48
|
+
/** An `Infobox` row for a named outbound relationship, rendered as one or more links. */
|
|
49
|
+
export interface InfoboxLinksRow {
|
|
50
|
+
readonly kind: 'links';
|
|
51
|
+
readonly label: string;
|
|
52
|
+
/** `undefined` or an empty list skips the row. */
|
|
53
|
+
readonly links: readonly InfoboxLinkEntry[] | undefined;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* An `Infobox` row for the hero/identifying image. Renders above the `<dl>` as an
|
|
57
|
+
* `InfoboxImage`, not as a `dt`/`dd` pair — the same shape `Infobox`'s own
|
|
58
|
+
* `image` prop takes, offered as a row for the callers who build the whole
|
|
59
|
+
* infobox from one `rows` array.
|
|
60
|
+
*/
|
|
61
|
+
export interface InfoboxImageRow extends InfoboxImageSpec {
|
|
62
|
+
readonly kind: 'image';
|
|
63
|
+
}
|
|
64
|
+
/** An `Infobox` row whose value is arbitrary markup (a badge, a formatted quantity). */
|
|
65
|
+
export interface InfoboxCustomRow {
|
|
66
|
+
readonly kind: 'custom';
|
|
67
|
+
readonly label: string;
|
|
68
|
+
readonly content: Snippet<[]>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Discriminated union of every row kind `Infobox`'s `rows` prop accepts.
|
|
72
|
+
*
|
|
73
|
+
* Named `InfoboxRowSpec` rather than `InfoboxRow` (design.md's own name for
|
|
74
|
+
* it) because the family already has an `InfoboxRow` COMPONENT: Svelte's
|
|
75
|
+
* compiled default export carries a type meaning as well as a value one, so
|
|
76
|
+
* a value export and a type export cannot share that identifier in the same
|
|
77
|
+
* module without a "Duplicate identifier" error. `*Spec` matches
|
|
78
|
+
* `InfoboxImageSpec`, the sibling type this union's `image` member reuses.
|
|
79
|
+
*/
|
|
80
|
+
export type InfoboxRowSpec = InfoboxFactRow | InfoboxLinkRow | InfoboxLinksRow | InfoboxImageRow | InfoboxCustomRow;
|
|
81
|
+
/**
|
|
82
|
+
* Whether a row carries renderable content — the single definition of
|
|
83
|
+
* "empty" `Infobox` and its unit tests share. A `custom` row is always
|
|
84
|
+
* present: its snippet is the caller's decision, not this function's.
|
|
85
|
+
*/
|
|
86
|
+
export declare function infoboxRowIsPresent(row: InfoboxRowSpec): boolean;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shapes the `infobox` family passes around: the image spec both
|
|
3
|
+
* `InfoboxImage` and an `image`-kind row accept, the row union `Infobox`'s
|
|
4
|
+
* `rows` convenience renders, and the single "has something to show" rule
|
|
5
|
+
* the component and its tests share.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Whether a row carries renderable content — the single definition of
|
|
11
|
+
* "empty" `Infobox` and its unit tests share. A `custom` row is always
|
|
12
|
+
* present: its snippet is the caller's decision, not this function's.
|
|
13
|
+
*/
|
|
14
|
+
export function infoboxRowIsPresent(row) {
|
|
15
|
+
switch (row.kind) {
|
|
16
|
+
case 'fact':
|
|
17
|
+
return row.value !== undefined && row.value !== '';
|
|
18
|
+
case 'link':
|
|
19
|
+
return row.href !== undefined && row.href !== '';
|
|
20
|
+
case 'links':
|
|
21
|
+
return row.links !== undefined && row.links.length > 0;
|
|
22
|
+
case 'image':
|
|
23
|
+
return row.src !== '';
|
|
24
|
+
case 'custom':
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The responsive app frame: the sidebar as a standing column from `lg` up, and in a navigation drawer below it.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
AppShell — the frame every app with a `Sidebar` rebuilt by hand. From
|
|
6
|
+
`lg` up the `sidebar` snippet is a plain column beside the content; below
|
|
7
|
+
`lg` it moves into a `Drawer` (`side="start"`) opened from a top bar's
|
|
8
|
+
menu button.
|
|
9
|
+
|
|
10
|
+
The persistent column is never inside a dialog. The sidebar renders in
|
|
11
|
+
two places, but the column is `display: none` below `lg` and the drawer
|
|
12
|
+
only exists while it is open (and only its trigger bar below `lg`), so
|
|
13
|
+
exactly one copy, and one `navigation` landmark, is in the accessibility
|
|
14
|
+
tree at any width.
|
|
15
|
+
|
|
16
|
+
Closing the drawer on navigation is the app's job, because a library
|
|
17
|
+
cannot import `$app/navigation`. Bind `navOpen` and reset it in
|
|
18
|
+
SvelteKit's `afterNavigate(() => (navOpen = false))`, as with
|
|
19
|
+
`Navbar`'s `menuOpen`.
|
|
20
|
+
-->
|
|
21
|
+
<script lang="ts">import { Menu as MenuIcon } from "@lucide/svelte";
|
|
22
|
+
import Drawer from "../feedback/Drawer.svelte";
|
|
23
|
+
import Button from "../ui/Button.svelte";
|
|
24
|
+
import VisuallyHidden from "../ui/VisuallyHidden.svelte";
|
|
25
|
+
let { sidebar, header, children, navOpen = $bindable(false), navLabel = "Menu", navTitle = "Navigation", class: className, ...rest } = $props();
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<div {...rest} class={['min-h-svh lg:flex', className]}>
|
|
29
|
+
<div class="hidden shrink-0 lg:block">{@render sidebar()}</div>
|
|
30
|
+
<div class="min-w-0 flex-1">
|
|
31
|
+
<div class="lg:hidden">
|
|
32
|
+
<Drawer bind:open={navOpen} title={navTitle} hideTitle side="start" size="sm">
|
|
33
|
+
{#snippet trigger({ props })}
|
|
34
|
+
{#if header}
|
|
35
|
+
{@render header({ triggerProps: props })}
|
|
36
|
+
{:else}
|
|
37
|
+
<div class="border-base-300 bg-base-100 flex h-14 items-center border-b px-2">
|
|
38
|
+
<Button {...props} variant="ghost" class="btn-square">
|
|
39
|
+
<MenuIcon class="size-5" aria-hidden="true" />
|
|
40
|
+
<VisuallyHidden>{navLabel}</VisuallyHidden>
|
|
41
|
+
</Button>
|
|
42
|
+
</div>
|
|
43
|
+
{/if}
|
|
44
|
+
{/snippet}
|
|
45
|
+
{@render sidebar()}
|
|
46
|
+
</Drawer>
|
|
47
|
+
</div>
|
|
48
|
+
{@render children()}
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
4
|
+
/** The sidebar, usually a `Sidebar`: a column from `lg` up, the drawer's body below. */
|
|
5
|
+
sidebar: Snippet<[]>;
|
|
6
|
+
/** The top bar below `lg`; spread `triggerProps` onto the menu button. Omitted, a bar with a menu button. */
|
|
7
|
+
header?: Snippet<[{
|
|
8
|
+
triggerProps: Record<string, unknown>;
|
|
9
|
+
}]> | undefined;
|
|
10
|
+
/** The page content. */
|
|
11
|
+
children: Snippet<[]>;
|
|
12
|
+
/** Whether the narrow-viewport drawer is open. Bindable. */
|
|
13
|
+
navOpen?: boolean | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Accessible name of the default menu button.
|
|
16
|
+
* @defaultValue `'Menu'`
|
|
17
|
+
*/
|
|
18
|
+
navLabel?: string | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* The drawer's accessible name.
|
|
21
|
+
* @defaultValue `'Navigation'`
|
|
22
|
+
*/
|
|
23
|
+
navTitle?: string | undefined;
|
|
24
|
+
}
|
|
25
|
+
/** The responsive app frame: the sidebar as a standing column from `lg` up, and in a navigation drawer below it. */
|
|
26
|
+
declare const AppShell: import("svelte").Component<Props, {}, "navOpen">;
|
|
27
|
+
type AppShell = ReturnType<typeof AppShell>;
|
|
28
|
+
export default AppShell;
|