@svgrid/grid 1.2.34 → 2.0.1
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/README.md +6 -5
- package/dist/SvAccordion.svelte +109 -0
- package/dist/SvAccordion.svelte.d.ts +28 -0
- package/dist/SvAlert.svelte +92 -0
- package/dist/SvAlert.svelte.d.ts +27 -0
- package/dist/SvAutoComplete.svelte +47 -18
- package/dist/SvAutoComplete.svelte.d.ts +2 -5
- package/dist/SvAvatar.svelte +75 -0
- package/dist/SvAvatar.svelte.d.ts +14 -0
- package/dist/SvAvatarGroup.svelte +48 -0
- package/dist/SvAvatarGroup.svelte.d.ts +16 -0
- package/dist/SvBadge.svelte +54 -0
- package/dist/SvBadge.svelte.d.ts +23 -0
- package/dist/SvBreadcrumb.svelte +88 -0
- package/dist/SvBreadcrumb.svelte.d.ts +23 -0
- package/dist/SvButtonGroup.svelte +121 -0
- package/dist/SvButtonGroup.svelte.d.ts +16 -0
- package/dist/SvCalendar.svelte +72 -9
- package/dist/SvCalendar.svelte.d.ts +34 -1
- package/dist/SvCard.svelte +71 -0
- package/dist/SvCard.svelte.d.ts +28 -0
- package/dist/SvCarousel.svelte +134 -0
- package/dist/SvCarousel.svelte.d.ts +28 -0
- package/dist/SvCheckBox.svelte +36 -21
- package/dist/SvCheckBox.svelte.d.ts +2 -5
- package/dist/SvChip.svelte +88 -0
- package/dist/SvChip.svelte.d.ts +31 -0
- package/dist/SvCircularProgress.svelte +109 -0
- package/dist/SvCircularProgress.svelte.d.ts +31 -0
- package/dist/SvColorInput.svelte +54 -27
- package/dist/SvColorInput.svelte.d.ts +10 -6
- package/dist/SvComboBox.svelte +119 -33
- package/dist/SvComboBox.svelte.d.ts +18 -6
- package/dist/SvCommand.svelte +197 -0
- package/dist/SvCommand.svelte.d.ts +26 -0
- package/dist/SvContextMenu.svelte +96 -0
- package/dist/SvContextMenu.svelte.d.ts +25 -0
- package/dist/SvCountryInput.svelte +56 -21
- package/dist/SvCountryInput.svelte.d.ts +9 -5
- package/dist/SvDateRangeInput.svelte +256 -0
- package/dist/SvDateRangeInput.svelte.d.ts +37 -0
- package/dist/SvDateTimePicker.svelte +57 -20
- package/dist/SvDateTimePicker.svelte.d.ts +12 -4
- package/dist/SvDivider.svelte +61 -0
- package/dist/SvDivider.svelte.d.ts +22 -0
- package/dist/SvDrawer.svelte +226 -0
- package/dist/SvDrawer.svelte.d.ts +43 -0
- package/dist/SvDropDownList.svelte +114 -35
- package/dist/SvDropDownList.svelte.d.ts +7 -6
- package/dist/SvDurationInput.svelte +108 -0
- package/dist/SvDurationInput.svelte.d.ts +15 -0
- package/dist/SvEmptyState.svelte +59 -0
- package/dist/SvEmptyState.svelte.d.ts +25 -0
- package/dist/SvField.svelte +85 -0
- package/dist/SvField.svelte.d.ts +30 -0
- package/dist/SvFileUpload.svelte +169 -0
- package/dist/SvFileUpload.svelte.d.ts +24 -0
- package/dist/SvForm.svelte +7 -1
- package/dist/SvForm.svelte.d.ts +3 -0
- package/dist/SvGauge.svelte +7 -1
- package/dist/SvGauge.svelte.d.ts +11 -0
- package/dist/SvGrid.controller.svelte.d.ts +6 -0
- package/dist/SvGrid.controller.svelte.js +64 -9
- package/dist/SvGrid.css +33 -0
- package/dist/SvGrid.svelte +116 -3
- package/dist/SvGrid.types.d.ts +366 -0
- package/dist/SvGridBoard.svelte +2281 -0
- package/dist/SvGridBoard.svelte.d.ts +31 -0
- package/dist/SvGridDropdown.svelte +2 -1
- package/dist/SvGridSelect.svelte +255 -0
- package/dist/SvGridSelect.svelte.d.ts +32 -0
- package/dist/SvGroupCell.svelte +109 -0
- package/dist/SvGroupCell.svelte.d.ts +41 -0
- package/dist/SvListBox.svelte +123 -36
- package/dist/SvListBox.svelte.d.ts +12 -8
- package/dist/SvMaskedInput.svelte +53 -13
- package/dist/SvMaskedInput.svelte.d.ts +16 -6
- package/dist/SvMenu.svelte +101 -0
- package/dist/SvMenu.svelte.d.ts +26 -0
- package/dist/SvMenuList.svelte +143 -0
- package/dist/SvMenuList.svelte.d.ts +24 -0
- package/dist/SvModal.svelte +220 -0
- package/dist/SvModal.svelte.d.ts +31 -0
- package/dist/SvMultiSelect.svelte +277 -0
- package/dist/SvMultiSelect.svelte.d.ts +31 -0
- package/dist/SvNavPane.svelte +314 -0
- package/dist/SvNavPane.svelte.d.ts +59 -0
- package/dist/SvNumberInput.svelte +23 -9
- package/dist/SvNumberInput.svelte.d.ts +2 -0
- package/dist/SvOtpInput.svelte +157 -0
- package/dist/SvOtpInput.svelte.d.ts +16 -0
- package/dist/SvPagination.svelte +100 -0
- package/dist/SvPagination.svelte.d.ts +16 -0
- package/dist/SvPasswordInput.svelte +42 -12
- package/dist/SvPasswordInput.svelte.d.ts +13 -6
- package/dist/SvPhoneInput.svelte +43 -11
- package/dist/SvPhoneInput.svelte.d.ts +10 -11
- package/dist/SvPopover.svelte +127 -0
- package/dist/SvPopover.svelte.d.ts +35 -0
- package/dist/SvProgress.svelte +116 -0
- package/dist/SvProgress.svelte.d.ts +32 -0
- package/dist/SvRadioGroup.svelte +40 -22
- package/dist/SvRadioGroup.svelte.d.ts +2 -10
- package/dist/SvRating.svelte +51 -30
- package/dist/SvRating.svelte.d.ts +10 -7
- package/dist/SvRichText.svelte +192 -0
- package/dist/SvRichText.svelte.d.ts +16 -0
- package/dist/SvRowGroupPanel.svelte +147 -0
- package/dist/SvRowGroupPanel.svelte.d.ts +17 -0
- package/dist/SvScrollArea.svelte +50 -0
- package/dist/SvScrollArea.svelte.d.ts +22 -0
- package/dist/SvSkeleton.svelte +76 -0
- package/dist/SvSkeleton.svelte.d.ts +25 -0
- package/dist/SvSlider.svelte +41 -9
- package/dist/SvSlider.svelte.d.ts +4 -4
- package/dist/SvSparkline.svelte +77 -0
- package/dist/SvSparkline.svelte.d.ts +28 -0
- package/dist/SvSplitter.svelte +138 -0
- package/dist/SvSplitter.svelte.d.ts +32 -0
- package/dist/SvStat.svelte +86 -0
- package/dist/SvStat.svelte.d.ts +30 -0
- package/dist/SvStepper.svelte +91 -0
- package/dist/SvStepper.svelte.d.ts +24 -0
- package/dist/SvSwitchButton.svelte +39 -24
- package/dist/SvSwitchButton.svelte.d.ts +2 -5
- package/dist/SvTabs.svelte +147 -28
- package/dist/SvTabs.svelte.d.ts +16 -4
- package/dist/SvTagsInput.svelte +59 -22
- package/dist/SvTagsInput.svelte.d.ts +9 -4
- package/dist/SvTextArea.svelte +113 -0
- package/dist/SvTextArea.svelte.d.ts +18 -0
- package/dist/SvTextInput.svelte +115 -0
- package/dist/SvTextInput.svelte.d.ts +20 -0
- package/dist/SvTimePicker.svelte +19 -5
- package/dist/SvTimePicker.svelte.d.ts +12 -0
- package/dist/SvTimeline.svelte +75 -0
- package/dist/SvTimeline.svelte.d.ts +24 -0
- package/dist/SvToaster.svelte +124 -0
- package/dist/SvToaster.svelte.d.ts +10 -0
- package/dist/SvToggleButton.svelte +37 -12
- package/dist/SvToggleButton.svelte.d.ts +2 -4
- package/dist/SvTooltip.svelte +113 -0
- package/dist/SvTooltip.svelte.d.ts +22 -0
- package/dist/SvTour.svelte +151 -0
- package/dist/SvTour.svelte.d.ts +25 -0
- package/dist/SvTree.svelte +286 -44
- package/dist/SvTree.svelte.d.ts +26 -9
- package/dist/SvTreeSelect.svelte +222 -0
- package/dist/SvTreeSelect.svelte.d.ts +24 -0
- package/dist/a11y/dismissable.d.ts +32 -0
- package/dist/a11y/dismissable.js +54 -0
- package/dist/a11y/focus-trap.d.ts +39 -0
- package/dist/a11y/focus-trap.js +142 -0
- package/dist/a11y/live-region.d.ts +8 -0
- package/dist/a11y/live-region.js +60 -0
- package/dist/a11y/scroll-lock.d.ts +4 -0
- package/dist/a11y/scroll-lock.js +41 -0
- package/dist/a11y.d.ts +3 -1
- package/dist/a11y.js +1 -1
- package/dist/avatar.d.ts +10 -0
- package/dist/avatar.js +22 -0
- package/dist/builtin-editors.d.ts +5 -0
- package/dist/builtin-editors.js +55 -0
- package/dist/cdn/svgrid.js +16021 -8234
- package/dist/cdn/svgrid.svelte-external.js +14542 -6764
- package/dist/columns.js +3 -2
- package/dist/core.d.ts +7 -1
- package/dist/countries.d.ts +12 -0
- package/dist/countries.js +24 -0
- package/dist/createAccordion.svelte.d.ts +71 -0
- package/dist/createAccordion.svelte.js +99 -0
- package/dist/createAutocomplete.svelte.d.ts +13 -4
- package/dist/createAutocomplete.svelte.js +11 -1
- package/dist/createButtonGroup.svelte.d.ts +62 -0
- package/dist/createButtonGroup.svelte.js +154 -0
- package/dist/createCalendar.svelte.d.ts +5 -0
- package/dist/createCalendar.svelte.js +2 -0
- package/dist/createCheckbox.svelte.d.ts +9 -17
- package/dist/createCheckbox.svelte.js +28 -1
- package/dist/createColorInput.svelte.d.ts +12 -22
- package/dist/createColorInput.svelte.js +13 -0
- package/dist/createCombobox.svelte.d.ts +16 -5
- package/dist/createCombobox.svelte.js +13 -2
- package/dist/createCountryInput.svelte.d.ts +14 -3
- package/dist/createCountryInput.svelte.js +12 -2
- package/dist/createDateTimePicker.svelte.d.ts +17 -2
- package/dist/createDateTimePicker.svelte.js +12 -2
- package/dist/createDropdownList.svelte.d.ts +14 -5
- package/dist/createDropdownList.svelte.js +50 -1
- package/dist/createFileUpload.svelte.d.ts +68 -0
- package/dist/createFileUpload.svelte.js +122 -0
- package/dist/createListbox.svelte.d.ts +10 -1
- package/dist/createListbox.svelte.js +48 -1
- package/dist/createMaskedInput.svelte.d.ts +11 -2
- package/dist/createMaskedInput.svelte.js +11 -1
- package/dist/createNumberInput.svelte.d.ts +1 -0
- package/dist/createNumberInput.svelte.js +1 -0
- package/dist/createPasswordInput.svelte.d.ts +19 -21
- package/dist/createPasswordInput.svelte.js +16 -4
- package/dist/createPhoneInput.svelte.d.ts +26 -7
- package/dist/createPhoneInput.svelte.js +24 -3
- package/dist/createPopoverSelect.svelte.d.ts +86 -0
- package/dist/createPopoverSelect.svelte.js +196 -0
- package/dist/createRadioGroup.svelte.d.ts +9 -0
- package/dist/createRadioGroup.svelte.js +11 -1
- package/dist/createRating.svelte.d.ts +11 -0
- package/dist/createRating.svelte.js +12 -1
- package/dist/createSlider.svelte.d.ts +2 -0
- package/dist/createSlider.svelte.js +16 -5
- package/dist/createSplitter.svelte.d.ts +67 -0
- package/dist/createSplitter.svelte.js +99 -0
- package/dist/createSwitch.svelte.d.ts +9 -16
- package/dist/createSwitch.svelte.js +28 -1
- package/dist/createTabs.svelte.d.ts +7 -0
- package/dist/createTabs.svelte.js +17 -2
- package/dist/createTagsInput.svelte.d.ts +13 -1
- package/dist/createTagsInput.svelte.js +12 -3
- package/dist/createToggle.svelte.d.ts +9 -0
- package/dist/createToggle.svelte.js +12 -1
- package/dist/createTree.svelte.d.ts +19 -0
- package/dist/createTree.svelte.js +108 -15
- package/dist/debounce.d.ts +11 -0
- package/dist/debounce.js +30 -0
- package/dist/duration.d.ts +15 -0
- package/dist/duration.js +51 -0
- package/dist/editor-contract.d.ts +62 -7
- package/dist/editor-contract.js +45 -5
- package/dist/editor-registry.d.ts +67 -0
- package/dist/editor-registry.js +38 -0
- package/dist/editors/cell-editors.d.ts +1 -1
- package/dist/editors/cell-editors.js +5 -0
- package/dist/fuzzy.d.ts +3 -0
- package/dist/fuzzy.js +41 -0
- package/dist/grid-select.d.ts +9 -0
- package/dist/grid-select.js +8 -0
- package/dist/index.d.ts +79 -6
- package/dist/index.js +78 -4
- package/dist/keyboard-handlers.js +19 -0
- package/dist/list-option.d.ts +36 -0
- package/dist/list-option.js +68 -0
- package/dist/otp.d.ts +16 -0
- package/dist/otp.js +26 -0
- package/dist/paginate.d.ts +20 -0
- package/dist/paginate.js +40 -0
- package/dist/popover.d.ts +15 -1
- package/dist/popover.js +29 -3
- package/dist/recurrence.d.ts +36 -0
- package/dist/recurrence.js +90 -0
- package/dist/server-data-source.d.ts +89 -0
- package/dist/server-data-source.js +4 -0
- package/dist/server-group-model.d.ts +98 -0
- package/dist/server-group-model.js +263 -0
- package/dist/toast-store.svelte.d.ts +41 -0
- package/dist/toast-store.svelte.js +113 -0
- package/dist/tree-select.d.ts +19 -0
- package/dist/tree-select.js +40 -0
- package/dist/ui-app.types.d.ts +80 -0
- package/dist/ui-app.types.js +7 -0
- package/dist/validators.d.ts +43 -0
- package/dist/validators.js +53 -0
- package/dist/virtual.d.ts +35 -0
- package/dist/virtual.js +34 -0
- package/package.json +1 -1
- package/src/SvAccordion.svelte +109 -0
- package/src/SvAccordion.test.ts +66 -0
- package/src/SvAlert.svelte +92 -0
- package/src/SvAutoComplete.svelte +47 -18
- package/src/SvAvatar.svelte +75 -0
- package/src/SvAvatarGroup.svelte +48 -0
- package/src/SvBadge.svelte +54 -0
- package/src/SvBreadcrumb.svelte +88 -0
- package/src/SvButtonGroup.svelte +121 -0
- package/src/SvButtonGroup.test.ts +72 -0
- package/src/SvCalendar.svelte +72 -9
- package/src/SvCard.svelte +71 -0
- package/src/SvCarousel.svelte +134 -0
- package/src/SvCheckBox.svelte +36 -21
- package/src/SvChip.svelte +88 -0
- package/src/SvCircularProgress.svelte +109 -0
- package/src/SvColorInput.svelte +54 -27
- package/src/SvComboBox.svelte +119 -33
- package/src/SvCommand.svelte +197 -0
- package/src/SvContextMenu.svelte +96 -0
- package/src/SvCountryInput.svelte +56 -21
- package/src/SvDateRangeInput.svelte +256 -0
- package/src/SvDateRangeInput.test.ts +80 -0
- package/src/SvDateTimePicker.svelte +57 -20
- package/src/SvDivider.svelte +61 -0
- package/src/SvDrawer.svelte +226 -0
- package/src/SvDrawer.test.ts +125 -0
- package/src/SvDropDownList.svelte +114 -35
- package/src/SvDurationInput.svelte +108 -0
- package/src/SvEmptyState.svelte +59 -0
- package/src/SvField.svelte +85 -0
- package/src/SvFileUpload.svelte +169 -0
- package/src/SvFileUpload.test.ts +59 -0
- package/src/SvForm.svelte +7 -1
- package/src/SvGauge.svelte +7 -1
- package/src/SvGrid.controller.svelte.ts +68 -9
- package/src/SvGrid.css +33 -0
- package/src/SvGrid.svelte +116 -3
- package/src/SvGrid.types.ts +374 -0
- package/src/SvGridBoard.svelte +2281 -0
- package/src/SvGridDropdown.svelte +2 -1
- package/src/SvGridSelect.svelte +255 -0
- package/src/SvGridSelect.test.ts +100 -0
- package/src/SvGroupCell.svelte +109 -0
- package/src/SvListBox.svelte +123 -36
- package/src/SvMaskedInput.svelte +53 -13
- package/src/SvMenu.svelte +101 -0
- package/src/SvMenu.test.ts +73 -0
- package/src/SvMenuList.svelte +143 -0
- package/src/SvModal.svelte +220 -0
- package/src/SvMultiSelect.svelte +277 -0
- package/src/SvMultiSelect.test.ts +167 -0
- package/src/SvNavPane.svelte +314 -0
- package/src/SvNavPane.test.ts +70 -0
- package/src/SvNumberInput.svelte +23 -9
- package/src/SvOtpInput.svelte +157 -0
- package/src/SvPagination.svelte +100 -0
- package/src/SvPasswordInput.svelte +42 -12
- package/src/SvPhoneInput.svelte +43 -11
- package/src/SvPopover.svelte +127 -0
- package/src/SvProgress.svelte +116 -0
- package/src/SvRadioGroup.svelte +40 -22
- package/src/SvRating.svelte +51 -30
- package/src/SvRichText.svelte +192 -0
- package/src/SvRowGroupPanel.svelte +147 -0
- package/src/SvScrollArea.svelte +50 -0
- package/src/SvSkeleton.svelte +76 -0
- package/src/SvSlider.svelte +41 -9
- package/src/SvSparkline.svelte +77 -0
- package/src/SvSplitter.svelte +138 -0
- package/src/SvSplitter.test.ts +55 -0
- package/src/SvStat.svelte +86 -0
- package/src/SvStepper.svelte +91 -0
- package/src/SvSwitchButton.svelte +39 -24
- package/src/SvTabs.svelte +147 -28
- package/src/SvTagsInput.svelte +59 -22
- package/src/SvTextArea.svelte +113 -0
- package/src/SvTextInput.svelte +115 -0
- package/src/SvTimePicker.svelte +19 -5
- package/src/SvTimeline.svelte +75 -0
- package/src/SvToaster.svelte +124 -0
- package/src/SvToaster.test.ts +63 -0
- package/src/SvToggleButton.svelte +37 -12
- package/src/SvTooltip.svelte +113 -0
- package/src/SvTour.svelte +151 -0
- package/src/SvTree.svelte +286 -44
- package/src/SvTreeSelect.svelte +222 -0
- package/src/SvTreeSelect.test.ts +87 -0
- package/src/a11y/dismissable.test.ts +95 -0
- package/src/a11y/dismissable.ts +94 -0
- package/src/a11y/focus-trap.test.ts +110 -0
- package/src/a11y/focus-trap.ts +134 -0
- package/src/a11y/live-region.test.ts +40 -0
- package/src/a11y/live-region.ts +65 -0
- package/src/a11y/scroll-lock.test.ts +38 -0
- package/src/a11y/scroll-lock.ts +41 -0
- package/src/a11y.ts +3 -1
- package/src/avatar.test.ts +32 -0
- package/src/avatar.ts +21 -0
- package/src/board.test.ts +927 -0
- package/src/builtin-editors.grid.test.ts +85 -0
- package/src/builtin-editors.test.ts +58 -0
- package/src/builtin-editors.ts +56 -0
- package/src/columns.ts +3 -2
- package/src/core.ts +10 -0
- package/src/countries.ts +25 -0
- package/src/createAccordion.svelte.ts +126 -0
- package/src/createAutocomplete.svelte.ts +18 -1
- package/src/createButtonGroup.svelte.ts +166 -0
- package/src/createCalendar.svelte.ts +6 -0
- package/src/createCheckbox.svelte.ts +23 -1
- package/src/createColorInput.svelte.ts +20 -0
- package/src/createCombobox.svelte.ts +22 -2
- package/src/createCountryInput.svelte.ts +21 -2
- package/src/createDateTimePicker.svelte.ts +23 -2
- package/src/createDropdownList.svelte.ts +31 -2
- package/src/createFileUpload.svelte.ts +144 -0
- package/src/createListbox.svelte.ts +35 -3
- package/src/createMaskedInput.svelte.ts +18 -1
- package/src/createNumberInput.svelte.ts +2 -0
- package/src/createPasswordInput.svelte.ts +31 -5
- package/src/createPhoneInput.svelte.ts +38 -4
- package/src/createPopoverSelect.svelte.ts +208 -0
- package/src/createRadioGroup.svelte.ts +23 -1
- package/src/createRating.svelte.ts +26 -1
- package/src/createSlider.svelte.ts +14 -3
- package/src/createSplitter.svelte.ts +119 -0
- package/src/createSwitch.svelte.ts +26 -3
- package/src/createTabs.svelte.ts +20 -3
- package/src/createTagsInput.svelte.ts +24 -3
- package/src/createToggle.svelte.ts +25 -2
- package/src/createTree.svelte.ts +104 -14
- package/src/debounce.test.ts +50 -0
- package/src/debounce.ts +41 -0
- package/src/duration.test.ts +41 -0
- package/src/duration.ts +51 -0
- package/src/editor-contract.ts +87 -8
- package/src/editor-registry.grid.test.ts +98 -0
- package/src/editor-registry.test.ts +86 -0
- package/src/editor-registry.ts +106 -0
- package/src/editors/cell-editors.ts +10 -1
- package/src/fuzzy.test.ts +40 -0
- package/src/fuzzy.ts +39 -0
- package/src/grid-select.test.ts +28 -0
- package/src/grid-select.ts +20 -0
- package/src/index.ts +150 -5
- package/src/keyboard-handlers.ts +20 -0
- package/src/list-option.ts +74 -0
- package/src/list-power.test.ts +71 -0
- package/src/otp.test.ts +28 -0
- package/src/otp.ts +28 -0
- package/src/overlays.test.ts +85 -0
- package/src/paginate.test.ts +41 -0
- package/src/paginate.ts +61 -0
- package/src/phone-valid.test.ts +26 -0
- package/src/popover.ts +31 -3
- package/src/progress.test.ts +55 -0
- package/src/recurrence.test.ts +91 -0
- package/src/recurrence.ts +111 -0
- package/src/server-data-source.ts +102 -0
- package/src/server-group-model.test.ts +294 -0
- package/src/server-group-model.ts +370 -0
- package/src/svgrid.responsive.test.ts +72 -0
- package/src/toast-store.svelte.ts +148 -0
- package/src/toast-store.test.ts +86 -0
- package/src/tree-edit.test.ts +49 -0
- package/src/tree-filter.test.ts +56 -0
- package/src/tree-select.test.ts +48 -0
- package/src/tree-select.ts +62 -0
- package/src/ui-app.test.ts +130 -0
- package/src/ui-app.types.ts +88 -0
- package/src/ui-display.test.ts +79 -0
- package/src/ui-inputs.test.ts +1 -1
- package/src/ui-status.test.ts +141 -0
- package/src/ui-tier1.test.ts +142 -0
- package/src/ui-tier2.test.ts +124 -0
- package/src/ui-tier3.test.ts +139 -0
- package/src/validators.test.ts +58 -0
- package/src/validators.ts +105 -0
- package/src/virtual.test.ts +72 -0
- package/src/virtual.ts +67 -0
package/dist/SvTagsInput.svelte
CHANGED
|
@@ -7,21 +7,47 @@
|
|
|
7
7
|
* One styled renderer over the headless `createTagsInput` core (draft +
|
|
8
8
|
* add/remove + keyboard).
|
|
9
9
|
*/
|
|
10
|
+
import SvField from './SvField.svelte'
|
|
11
|
+
import { nextEditorId, resolveMessages, type SvEditorProps } from './editor-contract'
|
|
10
12
|
import { createTagsInput } from './createTagsInput.svelte'
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
/** User-facing strings (localizable via `messages`). */
|
|
15
|
+
type TagsMessages = { add: string; remove: string }
|
|
16
|
+
const DEFAULT_MESSAGES: TagsMessages = { add: 'Add tag', remove: 'Remove' }
|
|
17
|
+
|
|
18
|
+
type Props = SvEditorProps & {
|
|
13
19
|
value?: string[]
|
|
14
20
|
onChange?: (tags: string[]) => void
|
|
15
21
|
placeholder?: string
|
|
16
|
-
disabled?: boolean
|
|
17
22
|
/** Reject duplicate tags. Default true. */
|
|
18
23
|
unique?: boolean
|
|
19
24
|
max?: number
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
/** Override the built-in strings (draft + remove aria-labels). */
|
|
26
|
+
messages?: Partial<TagsMessages>
|
|
22
27
|
}
|
|
23
28
|
|
|
24
|
-
let {
|
|
29
|
+
let {
|
|
30
|
+
value = [],
|
|
31
|
+
onChange,
|
|
32
|
+
placeholder = 'Add tag…',
|
|
33
|
+
disabled = false,
|
|
34
|
+
unique = true,
|
|
35
|
+
max = Infinity,
|
|
36
|
+
name,
|
|
37
|
+
ariaLabel,
|
|
38
|
+
invalid = false,
|
|
39
|
+
required = false,
|
|
40
|
+
error,
|
|
41
|
+
label,
|
|
42
|
+
hint,
|
|
43
|
+
dir,
|
|
44
|
+
id,
|
|
45
|
+
messages,
|
|
46
|
+
}: Props = $props()
|
|
47
|
+
|
|
48
|
+
const autoId = nextEditorId('sv-tags')
|
|
49
|
+
const uid = $derived(id ?? autoId)
|
|
50
|
+
const M = $derived(resolveMessages(DEFAULT_MESSAGES, messages))
|
|
25
51
|
|
|
26
52
|
const ti = createTagsInput({
|
|
27
53
|
value: () => value,
|
|
@@ -30,25 +56,34 @@
|
|
|
30
56
|
unique: () => unique,
|
|
31
57
|
max: () => max,
|
|
32
58
|
ariaLabel: () => ariaLabel,
|
|
59
|
+
addLabel: () => M.add,
|
|
60
|
+
removeLabel: () => M.remove,
|
|
61
|
+
id: () => uid,
|
|
62
|
+
invalid: () => invalid,
|
|
63
|
+
required: () => required,
|
|
64
|
+
error: () => error,
|
|
65
|
+
hint: () => hint,
|
|
33
66
|
})
|
|
34
67
|
</script>
|
|
35
68
|
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<span class="sv-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
69
|
+
<SvField id={uid} {label} {hint} {error} {required} {dir}>
|
|
70
|
+
<div class="sv-tags" class:is-disabled={disabled} class:is-invalid={invalid} {...ti.rootProps()}>
|
|
71
|
+
{#each value as tag, i (tag + i)}
|
|
72
|
+
<span class="sv-tags__chip" {...ti.tagProps(i)}>
|
|
73
|
+
<span class="sv-tags__label">{tag}</span>
|
|
74
|
+
{#if !disabled}
|
|
75
|
+
<button class="sv-tags__x" {...ti.removeProps(i)}>×</button>
|
|
76
|
+
{/if}
|
|
77
|
+
</span>
|
|
78
|
+
{/each}
|
|
79
|
+
<input
|
|
80
|
+
class="sv-tags__input"
|
|
81
|
+
placeholder={value.length ? '' : placeholder}
|
|
82
|
+
{...ti.inputProps()}
|
|
83
|
+
/>
|
|
84
|
+
{#if name}<input type="hidden" {name} value={value.join(',')} />{/if}
|
|
85
|
+
</div>
|
|
86
|
+
</SvField>
|
|
52
87
|
|
|
53
88
|
<style>
|
|
54
89
|
.sv-tags {
|
|
@@ -58,9 +93,11 @@
|
|
|
58
93
|
border: 1px solid var(--sg-input-border, var(--sg-border, #cbd5e1)); border-radius: var(--sg-radius, 8px);
|
|
59
94
|
}
|
|
60
95
|
.sv-tags:focus-within { border-color: var(--_accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--_accent) 22%, transparent); }
|
|
96
|
+
.sv-tags.is-invalid { border-color: var(--sg-danger, #dc2626); }
|
|
97
|
+
.sv-tags.is-invalid:focus-within { box-shadow: 0 0 0 2px color-mix(in srgb, var(--sg-danger, #dc2626) 22%, transparent); }
|
|
61
98
|
.sv-tags.is-disabled { opacity: 0.6; }
|
|
62
99
|
.sv-tags__chip {
|
|
63
|
-
display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0
|
|
100
|
+
display: inline-flex; align-items: center; gap: 4px; height: 22px; padding-block: 0; padding-inline: 8px 4px;
|
|
64
101
|
background: color-mix(in srgb, var(--_accent) 14%, transparent); color: var(--_accent);
|
|
65
102
|
border-radius: 5px; font-size: 12px; font-weight: 600;
|
|
66
103
|
}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
type
|
|
1
|
+
import { type SvEditorProps } from './editor-contract';
|
|
2
|
+
/** User-facing strings (localizable via `messages`). */
|
|
3
|
+
type TagsMessages = {
|
|
4
|
+
add: string;
|
|
5
|
+
remove: string;
|
|
6
|
+
};
|
|
7
|
+
type Props = SvEditorProps & {
|
|
2
8
|
value?: string[];
|
|
3
9
|
onChange?: (tags: string[]) => void;
|
|
4
10
|
placeholder?: string;
|
|
5
|
-
disabled?: boolean;
|
|
6
11
|
/** Reject duplicate tags. Default true. */
|
|
7
12
|
unique?: boolean;
|
|
8
13
|
max?: number;
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
/** Override the built-in strings (draft + remove aria-labels). */
|
|
15
|
+
messages?: Partial<TagsMessages>;
|
|
11
16
|
};
|
|
12
17
|
declare const SvTagsInput: import("svelte").Component<Props, {}, "">;
|
|
13
18
|
type SvTagsInput = ReturnType<typeof SvTagsInput>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SvTextArea - a multi-line text editor on the shared editor contract, with an
|
|
4
|
+
* optional auto-grow (the box height follows the content) and a character
|
|
5
|
+
* counter. Parity: Smart multiline input. As a grid cell editor: Escape
|
|
6
|
+
* cancels; Ctrl/Cmd+Enter commits (a bare Enter inserts a newline).
|
|
7
|
+
*/
|
|
8
|
+
import SvField from './SvField.svelte'
|
|
9
|
+
import { editorAria, nextEditorId, type SvEditorProps } from './editor-contract'
|
|
10
|
+
|
|
11
|
+
type Props = SvEditorProps & {
|
|
12
|
+
value?: string
|
|
13
|
+
onChange?: (value: string) => void
|
|
14
|
+
onCommit?: (value: string) => void
|
|
15
|
+
onCancel?: () => void
|
|
16
|
+
placeholder?: string
|
|
17
|
+
rows?: number
|
|
18
|
+
maxlength?: number
|
|
19
|
+
/** Grow the box to fit content instead of scrolling. */
|
|
20
|
+
autoGrow?: boolean
|
|
21
|
+
/** Show a "n / max" character counter (needs `maxlength`). */
|
|
22
|
+
showCount?: boolean
|
|
23
|
+
autofocus?: boolean
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let {
|
|
27
|
+
value = $bindable(''),
|
|
28
|
+
onChange,
|
|
29
|
+
onCommit,
|
|
30
|
+
onCancel,
|
|
31
|
+
placeholder,
|
|
32
|
+
disabled = false,
|
|
33
|
+
readonly = false,
|
|
34
|
+
rows = 3,
|
|
35
|
+
maxlength,
|
|
36
|
+
autoGrow = false,
|
|
37
|
+
showCount = false,
|
|
38
|
+
name,
|
|
39
|
+
size = 'md',
|
|
40
|
+
ariaLabel,
|
|
41
|
+
invalid = false,
|
|
42
|
+
required = false,
|
|
43
|
+
error,
|
|
44
|
+
label,
|
|
45
|
+
hint,
|
|
46
|
+
dir,
|
|
47
|
+
id,
|
|
48
|
+
autofocus = false,
|
|
49
|
+
}: Props = $props()
|
|
50
|
+
|
|
51
|
+
const autoId = nextEditorId('sv-textarea')
|
|
52
|
+
const uid = $derived(id ?? autoId)
|
|
53
|
+
|
|
54
|
+
function grow(node: HTMLTextAreaElement) {
|
|
55
|
+
if (!autoGrow) return
|
|
56
|
+
const resize = () => { node.style.height = 'auto'; node.style.height = `${node.scrollHeight}px` }
|
|
57
|
+
resize()
|
|
58
|
+
node.addEventListener('input', resize)
|
|
59
|
+
return { destroy: () => node.removeEventListener('input', resize) }
|
|
60
|
+
}
|
|
61
|
+
function mountFocus(node: HTMLTextAreaElement) {
|
|
62
|
+
if (autofocus) { node.focus(); node.select() }
|
|
63
|
+
}
|
|
64
|
+
function onInput(e: Event) {
|
|
65
|
+
const v = (e.currentTarget as HTMLTextAreaElement).value
|
|
66
|
+
value = v // enables bind:value
|
|
67
|
+
onChange?.(v)
|
|
68
|
+
}
|
|
69
|
+
function onKeydown(e: KeyboardEvent) {
|
|
70
|
+
if (e.key === 'Escape') onCancel?.()
|
|
71
|
+
else if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { e.preventDefault(); onCommit?.(value) }
|
|
72
|
+
}
|
|
73
|
+
</script>
|
|
74
|
+
|
|
75
|
+
<SvField id={uid} {label} {hint} {error} {required} {dir}>
|
|
76
|
+
<div class="sv-ta sv-ta--{size}" class:is-disabled={disabled}>
|
|
77
|
+
<textarea
|
|
78
|
+
use:grow
|
|
79
|
+
use:mountFocus
|
|
80
|
+
class="sv-ta__input"
|
|
81
|
+
class:is-invalid={invalid}
|
|
82
|
+
{value}
|
|
83
|
+
{placeholder}
|
|
84
|
+
{disabled}
|
|
85
|
+
{readonly}
|
|
86
|
+
{rows}
|
|
87
|
+
{maxlength}
|
|
88
|
+
oninput={onInput}
|
|
89
|
+
onkeydown={onKeydown}
|
|
90
|
+
{...editorAria({ id: uid, invalid, required, error, hint, ariaLabel })}
|
|
91
|
+
></textarea>
|
|
92
|
+
{#if showCount && maxlength}
|
|
93
|
+
<span class="sv-ta__count" aria-hidden="true">{value.length} / {maxlength}</span>
|
|
94
|
+
{/if}
|
|
95
|
+
{#if name}<input type="hidden" {name} value={value} />{/if}
|
|
96
|
+
</div>
|
|
97
|
+
</SvField>
|
|
98
|
+
|
|
99
|
+
<style>
|
|
100
|
+
.sv-ta { --_accent: var(--sg-accent, #2563eb); display: inline-flex; flex-direction: column; gap: 3px; width: 260px; }
|
|
101
|
+
.sv-ta.is-disabled { opacity: 0.6; }
|
|
102
|
+
.sv-ta__input {
|
|
103
|
+
width: 100%; box-sizing: border-box; resize: vertical; font: inherit; padding: 8px 10px;
|
|
104
|
+
background: var(--sg-input-bg, #fff); color: var(--sg-fg, #0f172a);
|
|
105
|
+
border: 1px solid var(--sg-input-border, var(--sg-border, #cbd5e1)); border-radius: var(--sg-radius, 8px); outline: none;
|
|
106
|
+
}
|
|
107
|
+
.sv-ta--sm .sv-ta__input { font-size: 12px; }
|
|
108
|
+
.sv-ta--md .sv-ta__input { font-size: 13px; }
|
|
109
|
+
.sv-ta--lg .sv-ta__input { font-size: 15px; }
|
|
110
|
+
.sv-ta__input:focus { border-color: var(--_accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--_accent) 22%, transparent); }
|
|
111
|
+
.sv-ta__input.is-invalid { border-color: var(--sg-danger, #dc2626); }
|
|
112
|
+
.sv-ta__count { align-self: flex-end; font-size: 11px; color: var(--sg-muted, #64748b); }
|
|
113
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type SvEditorProps } from './editor-contract';
|
|
2
|
+
type Props = SvEditorProps & {
|
|
3
|
+
value?: string;
|
|
4
|
+
onChange?: (value: string) => void;
|
|
5
|
+
onCommit?: (value: string) => void;
|
|
6
|
+
onCancel?: () => void;
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
rows?: number;
|
|
9
|
+
maxlength?: number;
|
|
10
|
+
/** Grow the box to fit content instead of scrolling. */
|
|
11
|
+
autoGrow?: boolean;
|
|
12
|
+
/** Show a "n / max" character counter (needs `maxlength`). */
|
|
13
|
+
showCount?: boolean;
|
|
14
|
+
autofocus?: boolean;
|
|
15
|
+
};
|
|
16
|
+
declare const SvTextArea: import("svelte").Component<Props, {}, "value">;
|
|
17
|
+
type SvTextArea = ReturnType<typeof SvTextArea>;
|
|
18
|
+
export default SvTextArea;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SvTextInput - the base single-line text editor on the shared editor contract
|
|
4
|
+
* (label / hint / error / RTL / a11y via SvField). Handles `text`, `email`,
|
|
5
|
+
* `url`, `tel` and `search`. As a grid cell editor it honours the interaction
|
|
6
|
+
* contract: Enter commits, Escape cancels. Parity: Smart `smart-input`.
|
|
7
|
+
*/
|
|
8
|
+
import SvField from './SvField.svelte'
|
|
9
|
+
import { editorAria, nextEditorId, type SvEditorProps } from './editor-contract'
|
|
10
|
+
|
|
11
|
+
type Props = SvEditorProps & {
|
|
12
|
+
value?: string
|
|
13
|
+
onChange?: (value: string) => void
|
|
14
|
+
/** Commit + stop editing (Enter, or supplied by the grid in a cell). */
|
|
15
|
+
onCommit?: (value: string) => void
|
|
16
|
+
/** Cancel editing (Escape). */
|
|
17
|
+
onCancel?: () => void
|
|
18
|
+
placeholder?: string
|
|
19
|
+
type?: 'text' | 'email' | 'url' | 'tel' | 'search'
|
|
20
|
+
maxlength?: number
|
|
21
|
+
/** Show an inline clear (x) button when non-empty. */
|
|
22
|
+
clearable?: boolean
|
|
23
|
+
autocomplete?: AutoFill
|
|
24
|
+
/** Autofocus + select on mount (used when mounted as a cell editor). */
|
|
25
|
+
autofocus?: boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let {
|
|
29
|
+
value = $bindable(''),
|
|
30
|
+
onChange,
|
|
31
|
+
onCommit,
|
|
32
|
+
onCancel,
|
|
33
|
+
placeholder,
|
|
34
|
+
disabled = false,
|
|
35
|
+
readonly = false,
|
|
36
|
+
type = 'text',
|
|
37
|
+
maxlength,
|
|
38
|
+
clearable = false,
|
|
39
|
+
name,
|
|
40
|
+
size = 'md',
|
|
41
|
+
ariaLabel,
|
|
42
|
+
invalid = false,
|
|
43
|
+
required = false,
|
|
44
|
+
error,
|
|
45
|
+
label,
|
|
46
|
+
hint,
|
|
47
|
+
dir,
|
|
48
|
+
id,
|
|
49
|
+
autocomplete,
|
|
50
|
+
autofocus = false,
|
|
51
|
+
}: Props = $props()
|
|
52
|
+
|
|
53
|
+
const autoId = nextEditorId('sv-text')
|
|
54
|
+
const uid = $derived(id ?? autoId)
|
|
55
|
+
|
|
56
|
+
// Write `value` (so `bind:value` works) AND fire `onChange` (callback users).
|
|
57
|
+
function set(v: string) {
|
|
58
|
+
value = v
|
|
59
|
+
onChange?.(v)
|
|
60
|
+
}
|
|
61
|
+
function onInput(e: Event) {
|
|
62
|
+
set((e.currentTarget as HTMLInputElement).value)
|
|
63
|
+
}
|
|
64
|
+
function onKeydown(e: KeyboardEvent) {
|
|
65
|
+
if (e.key === 'Enter') onCommit?.(value)
|
|
66
|
+
else if (e.key === 'Escape') onCancel?.()
|
|
67
|
+
}
|
|
68
|
+
function mountFocus(node: HTMLInputElement) {
|
|
69
|
+
if (autofocus) { node.focus(); node.select() }
|
|
70
|
+
}
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
<SvField id={uid} {label} {hint} {error} {required} {dir}>
|
|
74
|
+
<div class="sv-text sv-text--{size}" class:is-disabled={disabled}>
|
|
75
|
+
<div class="sv-text__field" class:is-invalid={invalid}>
|
|
76
|
+
<input
|
|
77
|
+
use:mountFocus
|
|
78
|
+
class="sv-text__input"
|
|
79
|
+
{type}
|
|
80
|
+
{value}
|
|
81
|
+
{placeholder}
|
|
82
|
+
{disabled}
|
|
83
|
+
{readonly}
|
|
84
|
+
{maxlength}
|
|
85
|
+
{autocomplete}
|
|
86
|
+
oninput={onInput}
|
|
87
|
+
onkeydown={onKeydown}
|
|
88
|
+
{...editorAria({ id: uid, invalid, required, error, hint, ariaLabel })}
|
|
89
|
+
/>
|
|
90
|
+
{#if clearable && value && !disabled && !readonly}
|
|
91
|
+
<button class="sv-text__clear" type="button" tabindex="-1" aria-label="Clear" onclick={() => set('')}>×</button>
|
|
92
|
+
{/if}
|
|
93
|
+
</div>
|
|
94
|
+
{#if name}<input type="hidden" {name} value={value} />{/if}
|
|
95
|
+
</div>
|
|
96
|
+
</SvField>
|
|
97
|
+
|
|
98
|
+
<style>
|
|
99
|
+
.sv-text { --_accent: var(--sg-accent, #2563eb); display: inline-flex; flex-direction: column; width: 220px; }
|
|
100
|
+
.sv-text.is-disabled { opacity: 0.6; }
|
|
101
|
+
.sv-text__field {
|
|
102
|
+
display: flex; align-items: center;
|
|
103
|
+
background: var(--sg-input-bg, #fff); color: var(--sg-fg, #0f172a);
|
|
104
|
+
border: 1px solid var(--sg-input-border, var(--sg-border, #cbd5e1)); border-radius: var(--sg-radius, 8px);
|
|
105
|
+
}
|
|
106
|
+
.sv-text__field:focus-within { border-color: var(--_accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--_accent) 22%, transparent); }
|
|
107
|
+
.sv-text__field.is-invalid { border-color: var(--sg-danger, #dc2626); }
|
|
108
|
+
.sv-text__field.is-invalid:focus-within { box-shadow: 0 0 0 2px color-mix(in srgb, var(--sg-danger, #dc2626) 22%, transparent); }
|
|
109
|
+
.sv-text__input { flex: 1; min-width: 0; border: 0; background: none; outline: none; color: inherit; font: inherit; padding: 0 10px; }
|
|
110
|
+
.sv-text--sm .sv-text__field { height: 28px; font-size: 12px; }
|
|
111
|
+
.sv-text--md .sv-text__field { height: 34px; font-size: 13px; }
|
|
112
|
+
.sv-text--lg .sv-text__field { height: 40px; font-size: 15px; }
|
|
113
|
+
.sv-text__clear { display: grid; place-items: center; width: 28px; align-self: stretch; background: none; border: 0; color: var(--sg-muted, #64748b); cursor: pointer; font-size: 17px; line-height: 1; }
|
|
114
|
+
.sv-text__clear:hover { color: var(--sg-fg, #0f172a); }
|
|
115
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type SvEditorProps } from './editor-contract';
|
|
2
|
+
type Props = SvEditorProps & {
|
|
3
|
+
value?: string;
|
|
4
|
+
onChange?: (value: string) => void;
|
|
5
|
+
/** Commit + stop editing (Enter, or supplied by the grid in a cell). */
|
|
6
|
+
onCommit?: (value: string) => void;
|
|
7
|
+
/** Cancel editing (Escape). */
|
|
8
|
+
onCancel?: () => void;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
type?: 'text' | 'email' | 'url' | 'tel' | 'search';
|
|
11
|
+
maxlength?: number;
|
|
12
|
+
/** Show an inline clear (x) button when non-empty. */
|
|
13
|
+
clearable?: boolean;
|
|
14
|
+
autocomplete?: AutoFill;
|
|
15
|
+
/** Autofocus + select on mount (used when mounted as a cell editor). */
|
|
16
|
+
autofocus?: boolean;
|
|
17
|
+
};
|
|
18
|
+
declare const SvTextInput: import("svelte").Component<Props, {}, "value">;
|
|
19
|
+
type SvTextInput = ReturnType<typeof SvTextInput>;
|
|
20
|
+
export default SvTextInput;
|
package/dist/SvTimePicker.svelte
CHANGED
|
@@ -11,8 +11,13 @@
|
|
|
11
11
|
* and ARIA; this component keeps the DOM-bound pointer capture + hit-testing.
|
|
12
12
|
* All visuals come from `--sg-*` tokens so every theme applies for free.
|
|
13
13
|
*/
|
|
14
|
+
import { resolveMessages, type EditorDir } from './editor-contract'
|
|
14
15
|
import { createTimePicker, type TimeValue, type TimeFormat, type TimeSelection } from './createTimePicker.svelte'
|
|
15
16
|
|
|
17
|
+
/** User-facing strings (localizable via `messages`). */
|
|
18
|
+
type TimeMessages = { label: string; am: string; pm: string; now: string }
|
|
19
|
+
const DEFAULT_MESSAGES: TimeMessages = { label: 'Time picker', am: 'AM', pm: 'PM', now: 'Now' }
|
|
20
|
+
|
|
16
21
|
type Props = {
|
|
17
22
|
/** Date, "HH:MM[:SS]" string, or epoch ms. */
|
|
18
23
|
value?: TimeValue
|
|
@@ -29,6 +34,10 @@
|
|
|
29
34
|
name?: string
|
|
30
35
|
/** Which dial opens first. */
|
|
31
36
|
selection?: TimeSelection
|
|
37
|
+
/** Text direction (rtl mirrors layout; auto/undefined inherits). */
|
|
38
|
+
dir?: EditorDir
|
|
39
|
+
/** Override the built-in strings (group label + AM/PM/Now). */
|
|
40
|
+
messages?: Partial<TimeMessages>
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
let {
|
|
@@ -42,8 +51,13 @@
|
|
|
42
51
|
readonly = false,
|
|
43
52
|
name,
|
|
44
53
|
selection = 'hour',
|
|
54
|
+
dir,
|
|
55
|
+
messages,
|
|
45
56
|
}: Props = $props()
|
|
46
57
|
|
|
58
|
+
const M = $derived(resolveMessages(DEFAULT_MESSAGES, messages))
|
|
59
|
+
const resolvedDir = $derived(dir === 'ltr' || dir === 'rtl' ? dir : undefined)
|
|
60
|
+
|
|
47
61
|
// The headless core owns all state, geometry, keyboard + ARIA. Reactive inputs
|
|
48
62
|
// are getters; callbacks are closures.
|
|
49
63
|
const tp = createTimePicker({
|
|
@@ -93,7 +107,7 @@
|
|
|
93
107
|
}
|
|
94
108
|
</script>
|
|
95
109
|
|
|
96
|
-
<div class="sv-tp" class:sv-tp--disabled={disabled} role="group" aria-label=
|
|
110
|
+
<div class="sv-tp" class:sv-tp--disabled={disabled} role="group" aria-label={M.label} dir={resolvedDir}>
|
|
97
111
|
<div class="sv-tp__head">
|
|
98
112
|
<button class="sv-tp__seg" class:is-active={tp.selection === 'hour'} {...tp.segProps('hour')}>
|
|
99
113
|
{String(tp.displayHour).padStart(2, '0')}
|
|
@@ -104,8 +118,8 @@
|
|
|
104
118
|
</button>
|
|
105
119
|
{#if tp.is12}
|
|
106
120
|
<div class="sv-tp__ampm">
|
|
107
|
-
<button class:is-active={!tp.isPm} {...tp.ampmProps(false)}>
|
|
108
|
-
<button class:is-active={tp.isPm} {...tp.ampmProps(true)}>
|
|
121
|
+
<button class:is-active={!tp.isPm} {...tp.ampmProps(false)}>{M.am}</button>
|
|
122
|
+
<button class:is-active={tp.isPm} {...tp.ampmProps(true)}>{M.pm}</button>
|
|
109
123
|
</div>
|
|
110
124
|
{/if}
|
|
111
125
|
</div>
|
|
@@ -139,7 +153,7 @@
|
|
|
139
153
|
|
|
140
154
|
{#if footer}
|
|
141
155
|
<div class="sv-tp__footer">
|
|
142
|
-
<button class="sv-tp__now" {...tp.nowProps()}>
|
|
156
|
+
<button class="sv-tp__now" {...tp.nowProps()}>{M.now}</button>
|
|
143
157
|
</div>
|
|
144
158
|
{/if}
|
|
145
159
|
|
|
@@ -171,7 +185,7 @@
|
|
|
171
185
|
}
|
|
172
186
|
.sv-tp__seg.is-active { color: var(--_accent); background: color-mix(in srgb, var(--_accent) 12%, transparent); }
|
|
173
187
|
.sv-tp__colon { font-size: 28px; font-weight: 700; color: var(--_muted); }
|
|
174
|
-
.sv-tp__ampm { display: flex; flex-direction: column; margin-
|
|
188
|
+
.sv-tp__ampm { display: flex; flex-direction: column; margin-inline-start: 8px; gap: 2px; }
|
|
175
189
|
.sv-tp__ampm button {
|
|
176
190
|
font-size: 11px; font-weight: 700; padding: 3px 8px;
|
|
177
191
|
background: none; border: 1px solid var(--_border); border-radius: 6px; color: var(--_muted); cursor: pointer;
|
|
@@ -7,7 +7,15 @@ export type { TimeValue } from './createTimePicker.svelte';
|
|
|
7
7
|
* and ARIA; this component keeps the DOM-bound pointer capture + hit-testing.
|
|
8
8
|
* All visuals come from `--sg-*` tokens so every theme applies for free.
|
|
9
9
|
*/
|
|
10
|
+
import { type EditorDir } from './editor-contract';
|
|
10
11
|
import { type TimeValue, type TimeFormat, type TimeSelection } from './createTimePicker.svelte';
|
|
12
|
+
/** User-facing strings (localizable via `messages`). */
|
|
13
|
+
type TimeMessages = {
|
|
14
|
+
label: string;
|
|
15
|
+
am: string;
|
|
16
|
+
pm: string;
|
|
17
|
+
now: string;
|
|
18
|
+
};
|
|
11
19
|
type Props = {
|
|
12
20
|
/** Date, "HH:MM[:SS]" string, or epoch ms. */
|
|
13
21
|
value?: TimeValue;
|
|
@@ -24,6 +32,10 @@ type Props = {
|
|
|
24
32
|
name?: string;
|
|
25
33
|
/** Which dial opens first. */
|
|
26
34
|
selection?: TimeSelection;
|
|
35
|
+
/** Text direction (rtl mirrors layout; auto/undefined inherits). */
|
|
36
|
+
dir?: EditorDir;
|
|
37
|
+
/** Override the built-in strings (group label + AM/PM/Now). */
|
|
38
|
+
messages?: Partial<TimeMessages>;
|
|
27
39
|
};
|
|
28
40
|
declare const SvTimePicker: import("svelte").Component<Props, {}, "">;
|
|
29
41
|
type SvTimePicker = ReturnType<typeof SvTimePicker>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export type { TimelineItem } from './ui-app.types'
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
/**
|
|
7
|
+
* SvTimeline - a vertical activity / history feed: a connecting line with a
|
|
8
|
+
* marker (colour + optional glyph) per entry, and a title / time / description.
|
|
9
|
+
* Data-driven via `items`, with an optional `item` snippet for custom content.
|
|
10
|
+
* Theme-driven. Parity: Smart timeline.
|
|
11
|
+
*
|
|
12
|
+
* ```svelte
|
|
13
|
+
* <SvTimeline items={[
|
|
14
|
+
* { title: 'Order placed', time: '09:12', color: '#16a34a' },
|
|
15
|
+
* { title: 'Shipped', time: '14:40', description: 'Left the warehouse' },
|
|
16
|
+
* ]} />
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
import type { Snippet } from 'svelte'
|
|
20
|
+
import type { TimelineItem } from './ui-app.types'
|
|
21
|
+
|
|
22
|
+
type Props = {
|
|
23
|
+
items: ReadonlyArray<TimelineItem>
|
|
24
|
+
/** Render custom content per entry (receives the item). */
|
|
25
|
+
item?: Snippet<[TimelineItem]>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let { items, item }: Props = $props()
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<ol class="sv-timeline">
|
|
32
|
+
{#each items as it, i (it.id ?? i)}
|
|
33
|
+
<li class="sv-timeline__item">
|
|
34
|
+
<div class="sv-timeline__rail">
|
|
35
|
+
<span class="sv-timeline__marker" style:--c={it.color}>
|
|
36
|
+
{#if it.icon}<span class="sv-timeline__glyph">{it.icon}</span>{/if}
|
|
37
|
+
</span>
|
|
38
|
+
</div>
|
|
39
|
+
<div class="sv-timeline__content">
|
|
40
|
+
{#if item}
|
|
41
|
+
{@render item(it)}
|
|
42
|
+
{:else}
|
|
43
|
+
<div class="sv-timeline__row">
|
|
44
|
+
<span class="sv-timeline__title">{it.title}</span>
|
|
45
|
+
{#if it.time}<span class="sv-timeline__time">{it.time}</span>{/if}
|
|
46
|
+
</div>
|
|
47
|
+
{#if it.description}<p class="sv-timeline__desc">{it.description}</p>{/if}
|
|
48
|
+
{/if}
|
|
49
|
+
</div>
|
|
50
|
+
</li>
|
|
51
|
+
{/each}
|
|
52
|
+
</ol>
|
|
53
|
+
|
|
54
|
+
<style>
|
|
55
|
+
.sv-timeline { list-style: none; margin: 0; padding: 0; color: var(--sg-fg, #0f172a); }
|
|
56
|
+
.sv-timeline__item { display: grid; grid-template-columns: 22px 1fr; gap: 10px; }
|
|
57
|
+
.sv-timeline__rail { display: flex; flex-direction: column; align-items: center; }
|
|
58
|
+
.sv-timeline__marker {
|
|
59
|
+
--c: var(--sg-accent, #2563eb);
|
|
60
|
+
flex: none; width: 14px; height: 14px; margin-top: 2px; border-radius: 50%;
|
|
61
|
+
display: grid; place-items: center; font-size: 8px; color: var(--sg-on-accent, #fff);
|
|
62
|
+
background: var(--c); box-shadow: 0 0 0 3px color-mix(in srgb, var(--c) 18%, transparent);
|
|
63
|
+
}
|
|
64
|
+
.sv-timeline__glyph { line-height: 1; }
|
|
65
|
+
/* The connecting line: grows to fill the rail between markers. */
|
|
66
|
+
.sv-timeline__item:not(:last-child) .sv-timeline__rail::after {
|
|
67
|
+
content: ''; flex: 1; width: 2px; margin: 3px 0 -2px; background: var(--sg-border, #e2e8f0); border-radius: 1px;
|
|
68
|
+
}
|
|
69
|
+
.sv-timeline__content { padding-bottom: 16px; min-width: 0; }
|
|
70
|
+
.sv-timeline__item:last-child .sv-timeline__content { padding-bottom: 0; }
|
|
71
|
+
.sv-timeline__row { display: flex; align-items: baseline; gap: 10px; }
|
|
72
|
+
.sv-timeline__title { font-size: 13.5px; font-weight: 600; }
|
|
73
|
+
.sv-timeline__time { margin-inline-start: auto; flex: none; font-size: 11.5px; color: var(--sg-muted, #94a3b8); font-variant-numeric: tabular-nums; }
|
|
74
|
+
.sv-timeline__desc { margin: 2px 0 0; font-size: 12.5px; color: var(--sg-muted, #64748b); line-height: 1.5; }
|
|
75
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type { TimelineItem } from './ui-app.types';
|
|
2
|
+
/**
|
|
3
|
+
* SvTimeline - a vertical activity / history feed: a connecting line with a
|
|
4
|
+
* marker (colour + optional glyph) per entry, and a title / time / description.
|
|
5
|
+
* Data-driven via `items`, with an optional `item` snippet for custom content.
|
|
6
|
+
* Theme-driven. Parity: Smart timeline.
|
|
7
|
+
*
|
|
8
|
+
* ```svelte
|
|
9
|
+
* <SvTimeline items={[
|
|
10
|
+
* { title: 'Order placed', time: '09:12', color: '#16a34a' },
|
|
11
|
+
* { title: 'Shipped', time: '14:40', description: 'Left the warehouse' },
|
|
12
|
+
* ]} />
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
import type { Snippet } from 'svelte';
|
|
16
|
+
import type { TimelineItem } from './ui-app.types';
|
|
17
|
+
type Props = {
|
|
18
|
+
items: ReadonlyArray<TimelineItem>;
|
|
19
|
+
/** Render custom content per entry (receives the item). */
|
|
20
|
+
item?: Snippet<[TimelineItem]>;
|
|
21
|
+
};
|
|
22
|
+
declare const SvTimeline: import("svelte").Component<Props, {}, "">;
|
|
23
|
+
type SvTimeline = ReturnType<typeof SvTimeline>;
|
|
24
|
+
export default SvTimeline;
|