@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,15 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props extends HTMLAttributes<HTMLElement> {
|
|
4
|
+
/**
|
|
5
|
+
* `main`, or `section` when a `<main>` is already open.
|
|
6
|
+
* @defaultValue `'main'`
|
|
7
|
+
*/
|
|
8
|
+
as?: 'main' | 'section' | undefined;
|
|
9
|
+
/** The page content, inside the landmark and the content column. */
|
|
10
|
+
children: Snippet<[]>;
|
|
11
|
+
}
|
|
12
|
+
/** The page’s content column and the `<main>` landmark. */
|
|
13
|
+
declare const Main: import("svelte").Component<Props, {}, "">;
|
|
14
|
+
type Main = ReturnType<typeof Main>;
|
|
15
|
+
export default Main;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The site banner: brand, primary links and account controls, with a disclosure for what does not fit on a narrow viewport.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Navbar — the site's banner: the brand, the primary links, the account
|
|
6
|
+
controls, and on a narrow viewport the disclosure that holds whatever did
|
|
7
|
+
not fit.
|
|
8
|
+
|
|
9
|
+
The three regions are snippets (`start` / `center` / `end`) because the
|
|
10
|
+
content is the app's — its brand mark, its search form, its `DropdownMenu`
|
|
11
|
+
account menu. What this owns is the structure: the banner
|
|
12
|
+
landmark, the named navigation inside it, the responsive bar, and the
|
|
13
|
+
toggle.
|
|
14
|
+
|
|
15
|
+
The toggle is bits-ui's `Collapsible`, not a hand-rolled button and a
|
|
16
|
+
`hidden` div (which is what three of the four apps had) and not a
|
|
17
|
+
`<details>`. `<details>` would be tempting — it is the native disclosure —
|
|
18
|
+
but its ARIA is implicit: the browser maps the open state internally and
|
|
19
|
+
exposes no `aria-controls`, so the toggle cannot say WHICH region it opens,
|
|
20
|
+
and a `<summary>` cannot be styled as a `btn` without fighting the marker.
|
|
21
|
+
`Collapsible` gives the pairing this needs and nothing else: a real
|
|
22
|
+
`<button type="button">` carrying `aria-expanded` and `aria-controls`
|
|
23
|
+
pointing at the panel's id, and the panel kept in the DOM with `hidden` when
|
|
24
|
+
closed so the reference always resolves.
|
|
25
|
+
|
|
26
|
+
ARIA contract: `<header>` at the top of the document is the `banner`
|
|
27
|
+
landmark; the `<nav aria-label>` inside it is the named navigation. The
|
|
28
|
+
toggle is an icon button with a real accessible name (`menuLabel`) — its
|
|
29
|
+
glyph is `aria-hidden`, so the name never changes as the state does; the
|
|
30
|
+
state is `aria-expanded`'s job, not the label's. `menuOpen` is bindable, so
|
|
31
|
+
an app can close the panel after a route change.
|
|
32
|
+
-->
|
|
33
|
+
<script lang="ts">import { Collapsible } from "bits-ui";
|
|
34
|
+
import { Menu as MenuIcon } from "@lucide/svelte";
|
|
35
|
+
import VisuallyHidden from "../ui/VisuallyHidden.svelte";
|
|
36
|
+
let { label = "Primary", menuLabel = "Menu", menuOpen = $bindable(false), start, center, end, menu, class: className, ...rest } = $props();
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<Collapsible.Root bind:open={menuOpen}>
|
|
40
|
+
{#snippet child({ props })}
|
|
41
|
+
<header {...rest} {...props} class={['bg-base-200 border-base-300 border-b', className]}>
|
|
42
|
+
<nav aria-label={label} class="navbar mx-auto max-w-7xl px-4 sm:px-6">
|
|
43
|
+
<div class="navbar-start min-w-0">{@render start()}</div>
|
|
44
|
+
{#if center}
|
|
45
|
+
<div class="navbar-center hidden lg:flex">{@render center()}</div>
|
|
46
|
+
{/if}
|
|
47
|
+
<div class="navbar-end gap-2">
|
|
48
|
+
{#if end}{@render end()}{/if}
|
|
49
|
+
{#if menu}
|
|
50
|
+
<Collapsible.Trigger>
|
|
51
|
+
{#snippet child({ props: triggerProps })}
|
|
52
|
+
<button {...triggerProps} class="btn btn-ghost btn-square lg:hidden">
|
|
53
|
+
<MenuIcon class="size-5" aria-hidden="true" />
|
|
54
|
+
<VisuallyHidden>{menuLabel}</VisuallyHidden>
|
|
55
|
+
</button>
|
|
56
|
+
{/snippet}
|
|
57
|
+
</Collapsible.Trigger>
|
|
58
|
+
{/if}
|
|
59
|
+
</div>
|
|
60
|
+
</nav>
|
|
61
|
+
{#if menu}
|
|
62
|
+
<Collapsible.Content class="border-base-300 border-t px-4 py-3 lg:hidden">
|
|
63
|
+
{@render menu()}
|
|
64
|
+
</Collapsible.Content>
|
|
65
|
+
{/if}
|
|
66
|
+
</header>
|
|
67
|
+
{/snippet}
|
|
68
|
+
</Collapsible.Root>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props extends HTMLAttributes<HTMLElement> {
|
|
4
|
+
/**
|
|
5
|
+
* Accessible name of the `<nav>` landmark.
|
|
6
|
+
* @defaultValue `'Primary'`
|
|
7
|
+
*/
|
|
8
|
+
label?: string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Accessible name of the responsive menu toggle.
|
|
11
|
+
* @defaultValue `'Menu'`
|
|
12
|
+
*/
|
|
13
|
+
menuLabel?: string | undefined;
|
|
14
|
+
/** Whether the responsive panel is open. Bindable. */
|
|
15
|
+
menuOpen?: boolean | undefined;
|
|
16
|
+
/** Leading region — the brand link. */
|
|
17
|
+
start: Snippet<[]>;
|
|
18
|
+
/** Middle region — the primary links. Hidden below `lg`. */
|
|
19
|
+
center?: Snippet<[]> | undefined;
|
|
20
|
+
/** Trailing region — search, theme, account. */
|
|
21
|
+
end?: Snippet<[]> | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* The panel the toggle opens. Given one, the toggle appears below `lg`;
|
|
24
|
+
* without one there is nothing to disclose and no button is rendered.
|
|
25
|
+
*/
|
|
26
|
+
menu?: Snippet<[]> | undefined;
|
|
27
|
+
}
|
|
28
|
+
/** The site banner: brand, primary links and account controls, with a disclosure for what does not fit on a narrow viewport. */
|
|
29
|
+
declare const Navbar: import("svelte").Component<Props, {}, "menuOpen">;
|
|
30
|
+
type Navbar = ReturnType<typeof Navbar>;
|
|
31
|
+
export default Navbar;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The block at the top of a page: its heading, supporting facts and actions.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
PageHeader — the block at the top of a page: what the page is about, and
|
|
6
|
+
what you can do to it.
|
|
7
|
+
|
|
8
|
+
`title` takes a string OR a snippet because a page title is sometimes
|
|
9
|
+
marked up — a species name in italics, a title with a `<Badge>` after it —
|
|
10
|
+
and an app should not have to choose between the component and its own
|
|
11
|
+
typography.
|
|
12
|
+
|
|
13
|
+
ARIA contract: `title` is a real heading, at `headingLevel` (an `<h1>` by
|
|
14
|
+
default, because this is the page's heading and a page has one). The level
|
|
15
|
+
is a prop and not a consequence of the type scale: the outline is document
|
|
16
|
+
structure, the scale is decoration, and `class` moves the second without
|
|
17
|
+
touching the first. `actions` is a `role="group"` named by `actionsLabel`,
|
|
18
|
+
so the cluster announces itself as one thing ("Page actions, group") rather
|
|
19
|
+
than as loose buttons floating beside a heading. `icon` is decorative and
|
|
20
|
+
hidden — it repeats what the title already says.
|
|
21
|
+
|
|
22
|
+
The `<header>` element is a `banner` landmark only when it is NOT inside
|
|
23
|
+
`<main>`, `<article>`, `<aside>`, `<nav>` or `<section>`. A page header is
|
|
24
|
+
inside `Main`, so it is not a banner, which is correct: the banner is the
|
|
25
|
+
site chrome (`Navbar`), of which there is one per page.
|
|
26
|
+
-->
|
|
27
|
+
<script lang="ts">let { title, subtitle, headingLevel = 1, actionsLabel = "Page actions", eyebrow, icon, meta, actions, children, class: className, ...rest } = $props();
|
|
28
|
+
// The page title's scale is the page's, not the outline's — an `<h2>` used
|
|
29
|
+
// as a page heading (a panel, a dialog body) still reads as the title.
|
|
30
|
+
const titleClasses = "text-3xl font-semibold tracking-tight text-balance sm:text-4xl";
|
|
31
|
+
export {};
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<header {...rest} class={['space-y-3', className]}>
|
|
35
|
+
{#if eyebrow}
|
|
36
|
+
<div class="text-base-content/70 text-sm">{@render eyebrow()}</div>
|
|
37
|
+
{/if}
|
|
38
|
+
|
|
39
|
+
<div class="flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
|
|
40
|
+
<div class="flex min-w-0 flex-1 items-start gap-x-5">
|
|
41
|
+
{#if icon}
|
|
42
|
+
<div class="avatar shrink-0" aria-hidden="true">
|
|
43
|
+
<div class="bg-base-200 size-16 rounded-full">{@render icon()}</div>
|
|
44
|
+
</div>
|
|
45
|
+
{/if}
|
|
46
|
+
<div class="min-w-0 flex-1 space-y-1">
|
|
47
|
+
<svelte:element this={`h${headingLevel}`} class={titleClasses}>
|
|
48
|
+
{#if typeof title === 'string'}
|
|
49
|
+
{title}
|
|
50
|
+
{:else}
|
|
51
|
+
{@render title()}
|
|
52
|
+
{/if}
|
|
53
|
+
</svelte:element>
|
|
54
|
+
{#if subtitle !== undefined}
|
|
55
|
+
<p class="text-base-content/70 text-lg leading-7">{subtitle}</p>
|
|
56
|
+
{/if}
|
|
57
|
+
{#if meta}
|
|
58
|
+
<div
|
|
59
|
+
class="text-base-content/70 flex flex-col gap-2 pt-1 text-sm leading-6 sm:flex-row sm:flex-wrap sm:gap-x-6"
|
|
60
|
+
>
|
|
61
|
+
{@render meta()}
|
|
62
|
+
</div>
|
|
63
|
+
{/if}
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
{#if actions}
|
|
68
|
+
<div role="group" aria-label={actionsLabel} class="flex shrink-0 flex-wrap gap-2">
|
|
69
|
+
{@render actions()}
|
|
70
|
+
</div>
|
|
71
|
+
{/if}
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
{#if children}
|
|
75
|
+
<div>{@render children()}</div>
|
|
76
|
+
{/if}
|
|
77
|
+
</header>
|
|
@@ -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
|
+
interface Props extends Omit<HTMLAttributes<HTMLElement>, 'title' | 'children'> {
|
|
5
|
+
/** The page's heading — its own text, or a snippet for richer markup. */
|
|
6
|
+
title: string | Snippet<[]>;
|
|
7
|
+
/** Supporting line under the heading. */
|
|
8
|
+
subtitle?: string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* The heading level, so the page outline stays intact.
|
|
11
|
+
* @defaultValue `1`
|
|
12
|
+
*/
|
|
13
|
+
headingLevel?: HeadingLevel | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Accessible name of the `actions` group.
|
|
16
|
+
* @defaultValue `'Page actions'`
|
|
17
|
+
*/
|
|
18
|
+
actionsLabel?: string | undefined;
|
|
19
|
+
/** Rendered above the heading — breadcrumbs, an eyebrow label, a badge. */
|
|
20
|
+
eyebrow?: Snippet<[]> | undefined;
|
|
21
|
+
/** A leading avatar or emblem, in a round frame. Decorative. */
|
|
22
|
+
icon?: Snippet<[]> | undefined;
|
|
23
|
+
/** Small facts under the heading — dates, counts, status. */
|
|
24
|
+
meta?: Snippet<[]> | undefined;
|
|
25
|
+
/** Buttons and links, aligned to the end of the heading row. */
|
|
26
|
+
actions?: Snippet<[]> | undefined;
|
|
27
|
+
/** Free content under the whole header block — a tab strip, a filter row. */
|
|
28
|
+
children?: Snippet<[]> | undefined;
|
|
29
|
+
}
|
|
30
|
+
/** The block at the top of a page: its heading, supporting facts and actions. */
|
|
31
|
+
declare const PageHeader: import("svelte").Component<Props, {}, "">;
|
|
32
|
+
type PageHeader = ReturnType<typeof PageHeader>;
|
|
33
|
+
export default PageHeader;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A titled block of a page: a heading, an optional count, optional actions, and either the rows or an empty state.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Section — a titled block of a page: a heading, an optional count beside it,
|
|
6
|
+
optional actions opposite, and either the rows or an honest empty state.
|
|
7
|
+
|
|
8
|
+
Every detail page is a stack of these —
|
|
9
|
+
`InboundSection` and `DetailSection` — that differed only in which optional
|
|
10
|
+
parts they carried. The eight lines were copied per section in the apps,
|
|
11
|
+
and eight copies is eight places to forget the empty state, which renders as
|
|
12
|
+
a section that looks broken rather than one that is honestly empty.
|
|
13
|
+
|
|
14
|
+
`count` is deliberately separate from the rows: a section shows a preview
|
|
15
|
+
(the first fifty) beside the real unpaged total, so the two numbers differ
|
|
16
|
+
and the heading has to say the second one. It is formatted through `Intl`,
|
|
17
|
+
so a five-figure count reads as `12,480` in the reader's locale.
|
|
18
|
+
|
|
19
|
+
ARIA contract: a `<section aria-labelledby>` pointing at its own heading, so
|
|
20
|
+
it is a named `region` — a landmark a reader can jump between, which is the
|
|
21
|
+
whole reason a long detail page is cut into sections. The heading is real
|
|
22
|
+
and at `headingLevel`, defaulting to `<h2>` (one level under the page's
|
|
23
|
+
`<h1>`). `headingId` defaults to a slug of `title`, which makes the section
|
|
24
|
+
addressable by URL fragment and is stable across server and client render.
|
|
25
|
+
-->
|
|
26
|
+
<script lang="ts">import { getComponentsContext } from "../context.svelte.js";
|
|
27
|
+
import { slugify } from "../ui/slug.js";
|
|
28
|
+
let { title, headingLevel = 2, headingId, count, description, empty = false, emptyMessage = "Nothing here yet.", locales, actions, emptyState, children, class: className, ...rest } = $props();
|
|
29
|
+
const context = getComponentsContext();
|
|
30
|
+
const fallbackId = $props.id();
|
|
31
|
+
// A title of nothing but punctuation slugs to `''`, which is not an id —
|
|
32
|
+
// fall back to a generated one rather than emit `aria-labelledby=""`.
|
|
33
|
+
const slugged = $derived(slugify(title));
|
|
34
|
+
const resolvedHeadingId = $derived(headingId ?? (slugged === "" ? fallbackId : slugged));
|
|
35
|
+
// The PERF-CPU-003 shape: the formatter is built in one `$derived` and only
|
|
36
|
+
// `.format()` runs in the next, so re-rendering a count does not re-resolve
|
|
37
|
+
// the locale data.
|
|
38
|
+
const formatter = $derived(new Intl.NumberFormat(locales ?? context.locale()));
|
|
39
|
+
const formattedCount = $derived(count === undefined ? undefined : formatter.format(count));
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<section {...rest} aria-labelledby={resolvedHeadingId} class={['space-y-3', className]}>
|
|
43
|
+
<div class="flex flex-wrap items-baseline justify-between gap-x-4 gap-y-1">
|
|
44
|
+
<svelte:element
|
|
45
|
+
this={`h${headingLevel}`}
|
|
46
|
+
id={resolvedHeadingId}
|
|
47
|
+
class="scroll-mt-16 text-xl font-semibold sm:text-2xl"
|
|
48
|
+
>
|
|
49
|
+
{title}
|
|
50
|
+
{#if formattedCount !== undefined}
|
|
51
|
+
<span class="text-base-content/60 text-base font-normal">({formattedCount})</span>
|
|
52
|
+
{/if}
|
|
53
|
+
</svelte:element>
|
|
54
|
+
{#if actions}
|
|
55
|
+
<div class="flex shrink-0 flex-wrap gap-2">{@render actions()}</div>
|
|
56
|
+
{/if}
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
{#if description !== undefined}
|
|
60
|
+
<p class="text-base-content/70 text-sm leading-6">{description}</p>
|
|
61
|
+
{/if}
|
|
62
|
+
|
|
63
|
+
{#if empty}
|
|
64
|
+
{#if emptyState}
|
|
65
|
+
{@render emptyState()}
|
|
66
|
+
{:else}
|
|
67
|
+
<p class="text-base-content/60">{emptyMessage}</p>
|
|
68
|
+
{/if}
|
|
69
|
+
{:else}
|
|
70
|
+
{@render children()}
|
|
71
|
+
{/if}
|
|
72
|
+
</section>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { HeadingLevel } from '../ui/tones.ts';
|
|
4
|
+
interface Props extends HTMLAttributes<HTMLElement> {
|
|
5
|
+
/** The section's heading. */
|
|
6
|
+
title: string;
|
|
7
|
+
/**
|
|
8
|
+
* The heading level, so the page outline stays intact.
|
|
9
|
+
* @defaultValue `2`
|
|
10
|
+
*/
|
|
11
|
+
headingLevel?: HeadingLevel | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Explicit heading id. Defaults to a slug of `title`, so the section is
|
|
14
|
+
* addressable; pass one when two sections on a page share a title.
|
|
15
|
+
*/
|
|
16
|
+
headingId?: string | undefined;
|
|
17
|
+
/** The unpaged total, rendered beside the heading. */
|
|
18
|
+
count?: number | undefined;
|
|
19
|
+
/** A line under the heading saying what the section contains. */
|
|
20
|
+
description?: string | undefined;
|
|
21
|
+
/** Whether there is anything to show. Drives the empty state. */
|
|
22
|
+
empty?: boolean | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* The default empty state's text.
|
|
25
|
+
* @defaultValue `'Nothing here yet.'`
|
|
26
|
+
*/
|
|
27
|
+
emptyMessage?: string | undefined;
|
|
28
|
+
/** `Intl` locales for `count`; falls back to the context's. */
|
|
29
|
+
locales?: string | readonly string[] | undefined;
|
|
30
|
+
/** A "see all" link or an "add" button, opposite the heading. */
|
|
31
|
+
actions?: Snippet<[]> | undefined;
|
|
32
|
+
/** Replaces the default empty paragraph — usually an `EmptyState`. */
|
|
33
|
+
emptyState?: Snippet<[]> | undefined;
|
|
34
|
+
/** The section's rows; replaced by the empty state when `empty`. */
|
|
35
|
+
children: Snippet<[]>;
|
|
36
|
+
}
|
|
37
|
+
/** A titled block of a page: a heading, an optional count, optional actions, and either the rows or an empty state. */
|
|
38
|
+
declare const Section: import("svelte").Component<Props, {}, "">;
|
|
39
|
+
type Section = ReturnType<typeof Section>;
|
|
40
|
+
export default Section;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The app shell’s navigation column: a brand mark, the primary links and an account block.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Sidebar — the app shell's standing navigation column: a brand mark at the
|
|
6
|
+
top, the primary links in the middle, an account block at the bottom.
|
|
7
|
+
|
|
8
|
+
A thin composition and nothing more. The links themselves are `MenuItem`s
|
|
9
|
+
inside a `Menu`, which already owns the whole navigation
|
|
10
|
+
contract — the `<nav aria-label>` landmark, the `<ul class="menu">`, and
|
|
11
|
+
`aria-current="page"` on the item the reader is on. This adds only what a
|
|
12
|
+
sidebar has and a menu does not.
|
|
13
|
+
|
|
14
|
+
What it deliberately does NOT do is wrap the column in an `<aside>`, which
|
|
15
|
+
is what that original did. `<aside>` is the `complementary` landmark — "content
|
|
16
|
+
related to the main content, meaningful on its own" — and a site's primary
|
|
17
|
+
navigation is neither. Wrapping it makes the app's most important landmark
|
|
18
|
+
announce itself as an afterthought, and puts a second landmark around the
|
|
19
|
+
`navigation` one, which a reader then has to step through twice.
|
|
20
|
+
|
|
21
|
+
ARIA contract: the navigation landmark is `Menu`'s. When `title` is shown,
|
|
22
|
+
it is also the landmark's accessible name by default, so the name a reader
|
|
23
|
+
hears is the text a reader sees. `brand` and `footer` are plain regions: the
|
|
24
|
+
brand is a link, the footer block is usually a second short `Menu`.
|
|
25
|
+
-->
|
|
26
|
+
<script lang="ts">import Menu from "../ui/Menu.svelte";
|
|
27
|
+
let { label, title, headingLevel = 2, brand, footer, children, class: className, ...rest } = $props();
|
|
28
|
+
const navLabel = $derived(label ?? title ?? "Primary");
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<div
|
|
32
|
+
{...rest}
|
|
33
|
+
class={['bg-base-100 border-base-300 flex min-h-full w-72 flex-col border-r', className]}
|
|
34
|
+
>
|
|
35
|
+
{#if brand}
|
|
36
|
+
<div class="flex h-16 shrink-0 items-center px-6">{@render brand()}</div>
|
|
37
|
+
{/if}
|
|
38
|
+
|
|
39
|
+
<div class="min-h-0 flex-1 space-y-2 px-4 py-2">
|
|
40
|
+
{#if title !== undefined}
|
|
41
|
+
<svelte:element
|
|
42
|
+
this={`h${headingLevel}`}
|
|
43
|
+
class="text-base-content/60 px-1 text-xs font-semibold tracking-wide uppercase"
|
|
44
|
+
>
|
|
45
|
+
{title}
|
|
46
|
+
</svelte:element>
|
|
47
|
+
{/if}
|
|
48
|
+
<Menu label={navLabel}>{@render children()}</Menu>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
{#if footer}
|
|
52
|
+
<div class="border-base-300 shrink-0 border-t px-4 py-4">{@render footer()}</div>
|
|
53
|
+
{/if}
|
|
54
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { HeadingLevel } from '../ui/tones.ts';
|
|
4
|
+
interface Props extends HTMLAttributes<HTMLElement> {
|
|
5
|
+
/**
|
|
6
|
+
* Accessible name of the navigation landmark. Defaults to `title` when
|
|
7
|
+
* one is shown, and to `Primary` when it is not.
|
|
8
|
+
*/
|
|
9
|
+
label?: string | undefined;
|
|
10
|
+
/** A visible heading over the links ("Browse", "Your account"). */
|
|
11
|
+
title?: string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* The heading level, so the page outline stays intact.
|
|
14
|
+
* @defaultValue `2`
|
|
15
|
+
*/
|
|
16
|
+
headingLevel?: HeadingLevel | undefined;
|
|
17
|
+
/** The brand mark, above the links. */
|
|
18
|
+
brand?: Snippet<[]> | undefined;
|
|
19
|
+
/** A block pinned under the links — the signed-in account menu. */
|
|
20
|
+
footer?: Snippet<[]> | undefined;
|
|
21
|
+
/** The `MenuItem`s. */
|
|
22
|
+
children: Snippet<[]>;
|
|
23
|
+
}
|
|
24
|
+
/** The app shell’s navigation column: a brand mark, the primary links and an account block. */
|
|
25
|
+
declare const Sidebar: import("svelte").Component<Props, {}, "">;
|
|
26
|
+
type Sidebar = ReturnType<typeof Sidebar>;
|
|
27
|
+
export default Sidebar;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
Flexible space inside a `VStack` / `HStack`: pushes what follows to the far end.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Spacer — SwiftUI's `Spacer()`, Compose's `Spacer(Modifier.weight(1f))`: an
|
|
6
|
+
empty `flex-1` element. It carries nothing, so it is `aria-hidden`.
|
|
7
|
+
-->
|
|
8
|
+
<script lang="ts">let { class: className, ...rest } = $props();
|
|
9
|
+
export {};
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<div {...rest} aria-hidden="true" class={['flex-1', className]}></div>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'>;
|
|
3
|
+
/** Flexible space inside a `VStack` / `HStack`: pushes what follows to the far end. */
|
|
4
|
+
declare const Spacer: import("svelte").Component<Props, {}, "">;
|
|
5
|
+
type Spacer = ReturnType<typeof Spacer>;
|
|
6
|
+
export default Spacer;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A tab strip that is either a tab widget over panels (`mode="panels"`) or navigation between sibling routes (`mode="links"`).
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Tabs — one strip, two things.
|
|
6
|
+
|
|
7
|
+
`mode="panels"` is a tab WIDGET: bits-ui's `Tabs`, which owns the
|
|
8
|
+
`tablist`/`tab`/`tabpanel` roles, the roving tabindex (one Tab stop for the
|
|
9
|
+
whole strip), Arrow/Home/End movement between tabs, and the
|
|
10
|
+
`aria-controls`/`aria-labelledby` pairing between each tab and its panel.
|
|
11
|
+
None of that is worth hand-rolling and all of it is easy to get subtly
|
|
12
|
+
wrong.
|
|
13
|
+
|
|
14
|
+
`mode="links"` is NAVIGATION between sibling routes that happens to look
|
|
15
|
+
like tabs (First preferences / Two-candidate preferred / Polling places).
|
|
16
|
+
It must NOT be a tab widget: these are separate documents, each with its own
|
|
17
|
+
URL, and a `role="tab"` that navigates lies to a reader about what pressing
|
|
18
|
+
it does. So it is a labelled `<nav>` of ordinary anchors, every one of them
|
|
19
|
+
a Tab stop, with `aria-current="page"` on the one you are on — chosen by
|
|
20
|
+
`value` when the caller tracks it, and otherwise by the components context's
|
|
21
|
+
own current-page check.
|
|
22
|
+
|
|
23
|
+
ARIA contract: panels mode is bits-ui's, unmodified — `aria-selected` on the
|
|
24
|
+
tabs, `aria-controls` to the panel, arrows and Home/End moving selection.
|
|
25
|
+
Links mode is `<nav aria-label>` + `aria-current="page"`. A disabled item in
|
|
26
|
+
links mode is not a link at all (there is nothing to navigate to) but stays
|
|
27
|
+
in the strip as `aria-disabled` text, so the set of sections a reader can
|
|
28
|
+
see does not change as their permissions do.
|
|
29
|
+
-->
|
|
30
|
+
<script lang="ts">import { Tabs as BitsTabs } from "bits-ui";
|
|
31
|
+
import { getComponentsContext } from "../context.svelte.js";
|
|
32
|
+
import { tabsSize, tabsVariant } from "./types.js";
|
|
33
|
+
let { items, mode = "panels", value = $bindable(""), label = "Sections", variant = "border", size = "md", panel, class: className } = $props();
|
|
34
|
+
const context = getComponentsContext();
|
|
35
|
+
const stripClasses = $derived([
|
|
36
|
+
"tabs",
|
|
37
|
+
tabsVariant[variant],
|
|
38
|
+
tabsSize[size]
|
|
39
|
+
]);
|
|
40
|
+
// A tab widget with nothing selected shows nothing, so panels need a
|
|
41
|
+
// selection from the start; the first ENABLED item, since a disabled one
|
|
42
|
+
// cannot be navigated back to.
|
|
43
|
+
const selected = $derived(value !== "" ? value : items.find((item) => item.disabled !== true)?.value ?? "");
|
|
44
|
+
const isCurrentLink = (item) => value !== "" ? value === item.value : item.href !== undefined && context.isCurrent(context.href(item.href));
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
{#if mode === 'links'}
|
|
48
|
+
<nav aria-label={label} class={[...stripClasses, className]}>
|
|
49
|
+
{#each items as item (item.value)}
|
|
50
|
+
{#if item.disabled === true}
|
|
51
|
+
<span class="tab tab-disabled" aria-disabled="true">{item.label}</span>
|
|
52
|
+
{:else}
|
|
53
|
+
{@const current = isCurrentLink(item)}
|
|
54
|
+
<a
|
|
55
|
+
href={context.href(item.href ?? '')}
|
|
56
|
+
class={['tab', current && 'tab-active']}
|
|
57
|
+
aria-current={current ? 'page' : undefined}
|
|
58
|
+
>
|
|
59
|
+
{item.label}
|
|
60
|
+
</a>
|
|
61
|
+
{/if}
|
|
62
|
+
{/each}
|
|
63
|
+
</nav>
|
|
64
|
+
{:else}
|
|
65
|
+
<!-- A function binding rather than `bind:value`: the value this renders at
|
|
66
|
+
is the DEFAULTED one, while what a write puts back is the caller's. -->
|
|
67
|
+
<BitsTabs.Root bind:value={() => selected, (next) => (value = next)} class={className}>
|
|
68
|
+
<BitsTabs.List class={stripClasses} aria-label={label}>
|
|
69
|
+
{#each items as item (item.value)}
|
|
70
|
+
<BitsTabs.Trigger
|
|
71
|
+
value={item.value}
|
|
72
|
+
disabled={item.disabled === true}
|
|
73
|
+
class={['tab', selected === item.value && 'tab-active']}
|
|
74
|
+
>
|
|
75
|
+
{item.label}
|
|
76
|
+
</BitsTabs.Trigger>
|
|
77
|
+
{/each}
|
|
78
|
+
</BitsTabs.List>
|
|
79
|
+
{#if panel}
|
|
80
|
+
{#each items as item (item.value)}
|
|
81
|
+
<BitsTabs.Content value={item.value} class="py-4">{@render panel(item)}</BitsTabs.Content>
|
|
82
|
+
{/each}
|
|
83
|
+
{/if}
|
|
84
|
+
</BitsTabs.Root>
|
|
85
|
+
{/if}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { Size } from '../ui/tones.ts';
|
|
3
|
+
import { type TabItem, type TabsMode, type TabsVariant } from './types.ts';
|
|
4
|
+
interface Props {
|
|
5
|
+
/** The tabs, in order: `value` and `label`, plus `href` in `links` mode. */
|
|
6
|
+
items: readonly TabItem[];
|
|
7
|
+
/**
|
|
8
|
+
* `panels` for a tab widget; `links` for navigation between routes.
|
|
9
|
+
* @defaultValue `'panels'`
|
|
10
|
+
*/
|
|
11
|
+
mode?: TabsMode | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* The selected value (panels) or the current one (links); `''` means
|
|
14
|
+
* unset — panels then select the first enabled item and links fall back to
|
|
15
|
+
* the context's current-page check. Bindable.
|
|
16
|
+
* @defaultValue `''`
|
|
17
|
+
*/
|
|
18
|
+
value?: string | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Accessible name of the tab list / the navigation landmark.
|
|
21
|
+
* @defaultValue `'Sections'`
|
|
22
|
+
*/
|
|
23
|
+
label?: string | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* daisyUI tab style.
|
|
26
|
+
* @defaultValue `'border'`
|
|
27
|
+
*/
|
|
28
|
+
variant?: TabsVariant | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* daisyUI size step.
|
|
31
|
+
* @defaultValue `'md'`
|
|
32
|
+
*/
|
|
33
|
+
size?: Size | undefined;
|
|
34
|
+
/** One panel's content, in `panels` mode. Without it, no panels render. */
|
|
35
|
+
panel?: Snippet<[TabItem]> | undefined;
|
|
36
|
+
/** Extra classes, merged last. */
|
|
37
|
+
class?: string | undefined;
|
|
38
|
+
}
|
|
39
|
+
/** A tab strip that is either a tab widget over panels (`mode="panels"`) or navigation between sibling routes (`mode="links"`). */
|
|
40
|
+
declare const Tabs: import("svelte").Component<Props, {}, "value">;
|
|
41
|
+
type Tabs = ReturnType<typeof Tabs>;
|
|
42
|
+
export default Tabs;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A vertical stack: children one above the next, on the spacing scale.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
VStack — children in a column with a token gap (SwiftUI `VStack`, Compose `Column`). Tokens for gap and alignment come from `space.ts`, the
|
|
6
|
+
library's spacing scale. See `Flow` for the list and divider rules.
|
|
7
|
+
-->
|
|
8
|
+
<script lang="ts">import Flow from "./Flow.svelte";
|
|
9
|
+
let props = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<Flow direction="vertical" {...props} />
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { FlowAlign, FlowElement, FlowJustify, Gap } from './space.ts';
|
|
4
|
+
interface Props extends HTMLAttributes<HTMLElement> {
|
|
5
|
+
/**
|
|
6
|
+
* Space between children.
|
|
7
|
+
* @defaultValue `'md'`
|
|
8
|
+
*/
|
|
9
|
+
gap?: Gap | undefined;
|
|
10
|
+
/** Cross-axis alignment. */
|
|
11
|
+
align?: FlowAlign | undefined;
|
|
12
|
+
/** Main-axis distribution. */
|
|
13
|
+
justify?: FlowJustify | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* A decorative rule between children (never around them).
|
|
16
|
+
* @defaultValue `false`
|
|
17
|
+
*/
|
|
18
|
+
divider?: boolean | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* The element. With `'ul'` / `'ol'`, children must be `<li>`s.
|
|
21
|
+
* @defaultValue `'div'`
|
|
22
|
+
*/
|
|
23
|
+
as?: FlowElement | undefined;
|
|
24
|
+
children: Snippet<[]>;
|
|
25
|
+
}
|
|
26
|
+
/** A vertical stack: children one above the next, on the spacing scale. */
|
|
27
|
+
declare const VStack: import("svelte").Component<Props, {}, "">;
|
|
28
|
+
type VStack = ReturnType<typeof VStack>;
|
|
29
|
+
export default VStack;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* layout — page chrome: the landmarks a page is assembled from, and the
|
|
3
|
+
* blocks that sit inside them.
|
|
4
|
+
*
|
|
5
|
+
* The family is structure, never copy. Every one of these takes the app's
|
|
6
|
+
* content as snippets and owns only the element that carries the semantics —
|
|
7
|
+
* the `<main>` a reader jumps to, the named `<nav>`s, the `banner` and
|
|
8
|
+
* `contentinfo` at the two ends of the page, the `<section aria-labelledby>`
|
|
9
|
+
* a long page is cut into. Import from the package barrel rather than from
|
|
10
|
+
* here.
|
|
11
|
+
*
|
|
12
|
+
* Optional props are declared `T | undefined` for the reason `ui/`'s are: the
|
|
13
|
+
* workspace compiles with `exactOptionalPropertyTypes`, under which `prop?: T`
|
|
14
|
+
* rejects an explicitly passed `undefined` and a caller cannot forward its own
|
|
15
|
+
* optional prop straight through.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
export { default as AppShell } from './AppShell.svelte';
|
|
20
|
+
export { default as Breadcrumbs } from './Breadcrumbs.svelte';
|
|
21
|
+
export { default as Cluster } from './Cluster.svelte';
|
|
22
|
+
export { default as DetailLayout } from './DetailLayout.svelte';
|
|
23
|
+
export { default as FilterBar } from './FilterBar.svelte';
|
|
24
|
+
export { default as Fits } from './Fits.svelte';
|
|
25
|
+
export { default as Footer } from './Footer.svelte';
|
|
26
|
+
export { default as Grid } from './Grid.svelte';
|
|
27
|
+
export { default as HStack } from './HStack.svelte';
|
|
28
|
+
export { default as Hero } from './Hero.svelte';
|
|
29
|
+
export { default as Main } from './Main.svelte';
|
|
30
|
+
export { default as Navbar } from './Navbar.svelte';
|
|
31
|
+
export { default as PageHeader } from './PageHeader.svelte';
|
|
32
|
+
export { default as Section } from './Section.svelte';
|
|
33
|
+
export { default as Sidebar } from './Sidebar.svelte';
|
|
34
|
+
export { default as Spacer } from './Spacer.svelte';
|
|
35
|
+
export { default as Tabs } from './Tabs.svelte';
|
|
36
|
+
export { default as VStack } from './VStack.svelte';
|
|
37
|
+
export * from './space.ts';
|
|
38
|
+
export * from './types.ts';
|