@svgrid/grid 1.2.34 → 2.0.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/README.md +6 -5
- package/dist/FlexRender.svelte +96 -96
- package/dist/GridFooter.svelte +178 -178
- 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 +2376 -2343
- package/dist/SvGrid.svelte +2764 -2651
- 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 +666 -665
- 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 +16022 -8235
- package/dist/cdn/svgrid.svelte-external.js +14543 -6765
- 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 +85 -85
- package/src/FlexRender.svelte +96 -96
- package/src/GridFooter.svelte +178 -178
- 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 +2553 -2494
- package/src/SvGrid.css +2376 -2343
- package/src/SvGrid.svelte +2764 -2651
- package/src/SvGrid.types.ts +944 -570
- package/src/SvGridBoard.svelte +2281 -0
- package/src/SvGridDropdown.svelte +666 -665
- 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.contract.test.ts +49 -49
- package/src/a11y.test.ts +59 -59
- package/src/a11y.ts +61 -59
- package/src/avatar.test.ts +32 -0
- package/src/avatar.ts +21 -0
- package/src/board.test.ts +927 -0
- package/src/build-api.ts +798 -798
- 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/cell-formatting.ts +169 -169
- package/src/cell-render.ts +469 -469
- package/src/collaboration.test.ts +104 -104
- package/src/collaboration.ts +167 -167
- package/src/columns.ts +3 -2
- package/src/core.performance.test.ts +30 -30
- package/src/core.ts +1111 -1101
- 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/createGrid.svelte.ts +42 -42
- package/src/createGrid.test.ts +10 -10
- package/src/createGridState.svelte.ts +17 -17
- 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/editing.test.ts +859 -859
- package/src/editing.ts +675 -675
- 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/export-data-api.test.ts +126 -126
- package/src/export-format.test.ts +107 -107
- package/src/export-format.ts +598 -598
- package/src/flex-render.ts +3 -3
- 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 +463 -318
- package/src/keyboard-handlers.ts +20 -0
- package/src/keyboard.test.ts +59 -59
- package/src/keyboard.ts +97 -97
- package/src/list-option.ts +74 -0
- package/src/list-power.test.ts +71 -0
- package/src/menus.ts +582 -582
- package/src/merge-objects.ts +48 -48
- 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/render-component.ts +28 -28
- package/src/selection.test.ts +754 -754
- package/src/selection.ts +600 -600
- package/src/server-data-source.test.ts +289 -289
- package/src/server-data-source.ts +413 -311
- package/src/server-group-model.test.ts +294 -0
- package/src/server-group-model.ts +370 -0
- package/src/sparkline.test.ts +68 -68
- package/src/sparkline.ts +169 -169
- package/src/spreadsheet.test.ts +489 -489
- package/src/spreadsheet.ts +304 -304
- package/src/static-functions.ts +11 -11
- package/src/subscribe.ts +38 -38
- package/src/svgrid-wrapper.types.ts +439 -439
- package/src/svgrid.behavior.test.ts +706 -706
- package/src/svgrid.features.test.ts +157 -157
- package/src/svgrid.new-features.wrapper.test.ts +251 -251
- package/src/svgrid.responsive.test.ts +72 -0
- package/src/svgrid.wrapper.test.ts +40 -40
- 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/src/virtualization/column-virtualizer.test.ts +27 -27
- package/src/virtualization/column-virtualizer.ts +30 -30
- package/src/virtualization/svelte-virtualizer.svelte.ts +26 -26
- package/src/virtualization/types.ts +30 -30
- package/src/virtualization/virtualizer.test.ts +47 -47
- package/src/virtualization/virtualizer.ts +296 -296
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createPopoverSelect - the shared HEADLESS engine behind the kit's dropdown
|
|
3
|
+
* selects (SvMultiSelect, SvTreeSelect, SvGridSelect and any future one). It
|
|
4
|
+
* owns the parts every anchored-panel select repeats: open/close state, the
|
|
5
|
+
* `anchoredRect` positioning (reposition on scroll/resize), outside/Escape
|
|
6
|
+
* dismissal via the shared layer stack, a roving `active` index over the visible
|
|
7
|
+
* items, the WAI-ARIA combobox wiring (`aria-expanded` / `aria-controls` /
|
|
8
|
+
* `aria-activedescendant` + stable option ids), and focus management (focus
|
|
9
|
+
* moves into the panel on open, back to the trigger on close).
|
|
10
|
+
*
|
|
11
|
+
* The component owns its own `bind:this` refs and item rendering; it passes the
|
|
12
|
+
* refs in as getters and spreads the returned prop-getters onto its trigger,
|
|
13
|
+
* panel and items. Runes-based, like `createListbox`.
|
|
14
|
+
*/
|
|
15
|
+
import { anchoredRect } from './popover';
|
|
16
|
+
import { createDismissableLayer } from './a11y/dismissable';
|
|
17
|
+
let uidSeq = 0;
|
|
18
|
+
export function createPopoverSelect(config) {
|
|
19
|
+
const id = `${config.idPrefix ?? 'sv-pop'}-${uidSeq++}`;
|
|
20
|
+
const panelId = `${id}-panel`;
|
|
21
|
+
const optionId = (i) => `${id}-opt-${i}`;
|
|
22
|
+
let open = $state(false);
|
|
23
|
+
let active = $state(0);
|
|
24
|
+
let rect = $state({ top: 0, left: 0, width: 0, openUpward: false });
|
|
25
|
+
const count = () => config.itemCount();
|
|
26
|
+
const isDisabled = (i) => config.disabled?.(i) ?? false;
|
|
27
|
+
function enabledIndices() {
|
|
28
|
+
const out = [];
|
|
29
|
+
const n = count();
|
|
30
|
+
for (let i = 0; i < n; i++)
|
|
31
|
+
if (!isDisabled(i))
|
|
32
|
+
out.push(i);
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
function clampActive(i) {
|
|
36
|
+
const n = count();
|
|
37
|
+
return n <= 0 ? 0 : Math.max(0, Math.min(i, n - 1));
|
|
38
|
+
}
|
|
39
|
+
function setOpen(v) {
|
|
40
|
+
if (v === open)
|
|
41
|
+
return;
|
|
42
|
+
open = v;
|
|
43
|
+
config.onOpenChange?.(v);
|
|
44
|
+
}
|
|
45
|
+
function openPanel() {
|
|
46
|
+
active = clampActive(config.initialActive?.() ?? 0);
|
|
47
|
+
setOpen(true);
|
|
48
|
+
}
|
|
49
|
+
function closePanel() {
|
|
50
|
+
setOpen(false);
|
|
51
|
+
config.getTrigger()?.focus();
|
|
52
|
+
}
|
|
53
|
+
function toggle() {
|
|
54
|
+
open ? setOpen(false) : openPanel();
|
|
55
|
+
}
|
|
56
|
+
function move(delta) {
|
|
57
|
+
const list = enabledIndices();
|
|
58
|
+
if (!list.length)
|
|
59
|
+
return;
|
|
60
|
+
const pos = list.indexOf(active);
|
|
61
|
+
active = list[(pos + delta + list.length) % list.length] ?? list[0];
|
|
62
|
+
}
|
|
63
|
+
function first() { active = enabledIndices()[0] ?? 0; }
|
|
64
|
+
function last() { active = enabledIndices().at(-1) ?? 0; }
|
|
65
|
+
function selectActive() {
|
|
66
|
+
if (count() === 0 || isDisabled(active))
|
|
67
|
+
return;
|
|
68
|
+
config.onSelect(active);
|
|
69
|
+
if (config.closeOnSelect?.() ?? true)
|
|
70
|
+
closePanel();
|
|
71
|
+
}
|
|
72
|
+
function updatePos() {
|
|
73
|
+
const t = config.getTrigger();
|
|
74
|
+
if (!t)
|
|
75
|
+
return;
|
|
76
|
+
rect = anchoredRect(t.getBoundingClientRect(), {
|
|
77
|
+
estimatedHeight: config.estimatedHeight?.() ?? 280,
|
|
78
|
+
minWidth: config.minWidth?.() ?? 200,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// While open: position, focus into the panel, reposition on scroll/resize, and
|
|
82
|
+
// register a dismissable layer (Escape / outside-click, top-of-stack first).
|
|
83
|
+
$effect(() => {
|
|
84
|
+
if (!open)
|
|
85
|
+
return;
|
|
86
|
+
updatePos();
|
|
87
|
+
const initial = config.getInitialFocus?.() ?? config.getPanel();
|
|
88
|
+
queueMicrotask(() => initial?.focus());
|
|
89
|
+
const rp = () => updatePos();
|
|
90
|
+
window.addEventListener('scroll', rp, true);
|
|
91
|
+
window.addEventListener('resize', rp);
|
|
92
|
+
const layer = createDismissableLayer({
|
|
93
|
+
element: () => [config.getTrigger(), config.getPanel()],
|
|
94
|
+
onDismiss: () => setOpen(false),
|
|
95
|
+
});
|
|
96
|
+
layer.activate();
|
|
97
|
+
return () => {
|
|
98
|
+
window.removeEventListener('scroll', rp, true);
|
|
99
|
+
window.removeEventListener('resize', rp);
|
|
100
|
+
layer.release();
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
function onTriggerKeydown(e) {
|
|
104
|
+
if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {
|
|
105
|
+
e.preventDefault();
|
|
106
|
+
openPanel();
|
|
107
|
+
}
|
|
108
|
+
else if (e.key === 'ArrowUp') {
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
openPanel();
|
|
111
|
+
last();
|
|
112
|
+
}
|
|
113
|
+
else if (e.key === 'Escape') {
|
|
114
|
+
setOpen(false);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function onPanelKeydown(e) {
|
|
118
|
+
if (config.onExtraKey?.(e, active))
|
|
119
|
+
return;
|
|
120
|
+
switch (e.key) {
|
|
121
|
+
case 'ArrowDown':
|
|
122
|
+
e.preventDefault();
|
|
123
|
+
move(1);
|
|
124
|
+
break;
|
|
125
|
+
case 'ArrowUp':
|
|
126
|
+
e.preventDefault();
|
|
127
|
+
move(-1);
|
|
128
|
+
break;
|
|
129
|
+
case 'Home':
|
|
130
|
+
e.preventDefault();
|
|
131
|
+
first();
|
|
132
|
+
break;
|
|
133
|
+
case 'End':
|
|
134
|
+
e.preventDefault();
|
|
135
|
+
last();
|
|
136
|
+
break;
|
|
137
|
+
case 'Enter':
|
|
138
|
+
e.preventDefault();
|
|
139
|
+
selectActive();
|
|
140
|
+
break;
|
|
141
|
+
case 'Escape':
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
closePanel();
|
|
144
|
+
break;
|
|
145
|
+
case 'Tab':
|
|
146
|
+
setOpen(false);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/** The current active-descendant id (for the focused element), or undefined. */
|
|
151
|
+
const activeDescendant = () => (open && count() > 0 ? optionId(active) : undefined);
|
|
152
|
+
return {
|
|
153
|
+
get open() { return open; },
|
|
154
|
+
set open(v) { setOpen(v); },
|
|
155
|
+
get active() { return active; },
|
|
156
|
+
set active(i) { active = clampActive(i); },
|
|
157
|
+
get rect() { return rect; },
|
|
158
|
+
/** Stable id of the panel element (for aria-controls / labelling). */
|
|
159
|
+
panelId,
|
|
160
|
+
/** Stable id of the option at `i` (for aria-activedescendant + item id). */
|
|
161
|
+
optionId,
|
|
162
|
+
activeDescendant,
|
|
163
|
+
openPanel,
|
|
164
|
+
closePanel,
|
|
165
|
+
toggle,
|
|
166
|
+
move,
|
|
167
|
+
first,
|
|
168
|
+
last,
|
|
169
|
+
selectActive,
|
|
170
|
+
updatePos,
|
|
171
|
+
onPanelKeydown,
|
|
172
|
+
/** True when item `i` is the roving-active one. */
|
|
173
|
+
isActive: (i) => i === active,
|
|
174
|
+
/** Spread onto the trigger button. */
|
|
175
|
+
triggerProps: () => ({
|
|
176
|
+
'aria-haspopup': 'listbox',
|
|
177
|
+
'aria-expanded': open,
|
|
178
|
+
'aria-controls': open ? panelId : undefined,
|
|
179
|
+
onkeydown: onTriggerKeydown,
|
|
180
|
+
}),
|
|
181
|
+
/** Attributes for the element that OWNS focus + activedescendant (the panel,
|
|
182
|
+
* or a search input). Pass the ARIA role the panel should expose. */
|
|
183
|
+
focusOwnerProps: (role = 'listbox') => ({
|
|
184
|
+
role,
|
|
185
|
+
'aria-activedescendant': activeDescendant(),
|
|
186
|
+
onkeydown: onPanelKeydown,
|
|
187
|
+
}),
|
|
188
|
+
/** Spread onto the item element at `i`. */
|
|
189
|
+
itemProps: (i) => ({
|
|
190
|
+
id: optionId(i),
|
|
191
|
+
'data-active': i === active ? '' : undefined,
|
|
192
|
+
onpointermove: () => { if (!isDisabled(i))
|
|
193
|
+
active = i; },
|
|
194
|
+
}),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
@@ -31,6 +31,11 @@ export type RadioGroupConfig = {
|
|
|
31
31
|
onChange?: (value: string | number) => void;
|
|
32
32
|
disabled?: () => boolean;
|
|
33
33
|
ariaLabel?: () => string | undefined;
|
|
34
|
+
id?: () => string | undefined;
|
|
35
|
+
invalid?: () => boolean;
|
|
36
|
+
required?: () => boolean;
|
|
37
|
+
error?: () => string | undefined;
|
|
38
|
+
hint?: () => string | undefined;
|
|
34
39
|
};
|
|
35
40
|
export type RadioProps = {
|
|
36
41
|
type: 'button';
|
|
@@ -44,7 +49,11 @@ export type RadioProps = {
|
|
|
44
49
|
};
|
|
45
50
|
export type RadioGroupProps = {
|
|
46
51
|
role: 'radiogroup';
|
|
52
|
+
id: string | undefined;
|
|
47
53
|
'aria-label': string | undefined;
|
|
54
|
+
'aria-invalid': 'true' | undefined;
|
|
55
|
+
'aria-required': 'true' | undefined;
|
|
56
|
+
'aria-describedby': string | undefined;
|
|
48
57
|
'aria-disabled': boolean;
|
|
49
58
|
onkeydown: (e: KeyboardEvent) => void;
|
|
50
59
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { editorAria } from './editor-contract';
|
|
1
2
|
export function createRadioGroup(config) {
|
|
2
3
|
const opts = () => config.options();
|
|
3
4
|
const disabled = () => config.disabled?.() ?? false;
|
|
@@ -43,6 +44,14 @@ export function createRadioGroup(config) {
|
|
|
43
44
|
pickIndex(target);
|
|
44
45
|
container.querySelectorAll('[role="radio"]')[target]?.focus();
|
|
45
46
|
}
|
|
47
|
+
const ariaState = () => ({
|
|
48
|
+
id: config.id?.(),
|
|
49
|
+
invalid: config.invalid?.(),
|
|
50
|
+
required: config.required?.(),
|
|
51
|
+
error: config.error?.(),
|
|
52
|
+
hint: config.hint?.(),
|
|
53
|
+
ariaLabel: config.ariaLabel?.(),
|
|
54
|
+
});
|
|
46
55
|
return {
|
|
47
56
|
get value() { return config.value(); },
|
|
48
57
|
get disabled() { return disabled(); },
|
|
@@ -51,8 +60,9 @@ export function createRadioGroup(config) {
|
|
|
51
60
|
onKeydown,
|
|
52
61
|
groupProps: () => ({
|
|
53
62
|
role: 'radiogroup',
|
|
54
|
-
|
|
63
|
+
id: config.id?.(),
|
|
55
64
|
'aria-disabled': disabled(),
|
|
65
|
+
...editorAria(ariaState()),
|
|
56
66
|
onkeydown: onKeydown,
|
|
57
67
|
}),
|
|
58
68
|
radioProps: (option) => {
|
|
@@ -27,11 +27,22 @@ export type RatingConfig = {
|
|
|
27
27
|
readonly?: () => boolean;
|
|
28
28
|
disabled?: () => boolean;
|
|
29
29
|
ariaLabel?: () => string | undefined;
|
|
30
|
+
/** Accessible label for a star given its 1-based position (localizable). */
|
|
31
|
+
starLabel?: (position: number) => string | undefined;
|
|
32
|
+
id?: () => string | undefined;
|
|
33
|
+
invalid?: () => boolean;
|
|
34
|
+
required?: () => boolean;
|
|
35
|
+
error?: () => string | undefined;
|
|
36
|
+
hint?: () => string | undefined;
|
|
30
37
|
};
|
|
31
38
|
export type RatingRootProps = {
|
|
32
39
|
role: 'slider';
|
|
40
|
+
id: string | undefined;
|
|
33
41
|
tabindex: number;
|
|
34
42
|
'aria-label': string;
|
|
43
|
+
'aria-invalid': 'true' | undefined;
|
|
44
|
+
'aria-required': 'true' | undefined;
|
|
45
|
+
'aria-describedby': string | undefined;
|
|
35
46
|
'aria-valuenow': number;
|
|
36
47
|
'aria-valuemin': number;
|
|
37
48
|
'aria-valuemax': number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { editorAria } from './editor-contract';
|
|
1
2
|
export function createRating(config) {
|
|
2
3
|
const max = () => config.max?.() ?? 5;
|
|
3
4
|
const allowHalf = () => config.allowHalf?.() ?? false;
|
|
@@ -50,6 +51,14 @@ export function createRating(config) {
|
|
|
50
51
|
config.onChange?.(max());
|
|
51
52
|
}
|
|
52
53
|
}
|
|
54
|
+
const ariaState = () => ({
|
|
55
|
+
id: config.id?.(),
|
|
56
|
+
invalid: config.invalid?.(),
|
|
57
|
+
required: config.required?.(),
|
|
58
|
+
error: config.error?.(),
|
|
59
|
+
hint: config.hint?.(),
|
|
60
|
+
ariaLabel: config.ariaLabel?.(),
|
|
61
|
+
});
|
|
53
62
|
return {
|
|
54
63
|
get value() { return config.value(); },
|
|
55
64
|
get preview() { return preview; },
|
|
@@ -61,7 +70,9 @@ export function createRating(config) {
|
|
|
61
70
|
onKeydown,
|
|
62
71
|
rootProps: () => ({
|
|
63
72
|
role: 'slider',
|
|
73
|
+
id: config.id?.(),
|
|
64
74
|
tabindex: interactive() ? 0 : -1,
|
|
75
|
+
...editorAria(ariaState()),
|
|
65
76
|
'aria-label': config.ariaLabel?.() ?? 'Rating',
|
|
66
77
|
'aria-valuenow': config.value(),
|
|
67
78
|
'aria-valuemin': 0,
|
|
@@ -74,7 +85,7 @@ export function createRating(config) {
|
|
|
74
85
|
type: 'button',
|
|
75
86
|
tabindex: -1,
|
|
76
87
|
disabled: !interactive(),
|
|
77
|
-
'aria-label': `${index + 1} star${index ? 's' : ''}`,
|
|
88
|
+
'aria-label': config.starLabel?.(index + 1) ?? `${index + 1} star${index ? 's' : ''}`,
|
|
78
89
|
'data-fill': fillOf(index),
|
|
79
90
|
onpointermove: (e) => { if (interactive())
|
|
80
91
|
hover = valueAt(e, index); },
|
|
@@ -37,6 +37,8 @@ export type SliderConfig = {
|
|
|
37
37
|
orientation?: () => SliderOrientation;
|
|
38
38
|
disabled?: () => boolean;
|
|
39
39
|
ariaLabel?: () => string | undefined;
|
|
40
|
+
/** Right-to-left: mirrors horizontal pointer + Left/Right key direction. */
|
|
41
|
+
rtl?: () => boolean;
|
|
40
42
|
};
|
|
41
43
|
export declare function createSlider(config: SliderConfig): {
|
|
42
44
|
readonly value: SliderValue;
|
|
@@ -5,6 +5,7 @@ export function createSlider(config) {
|
|
|
5
5
|
const range = () => config.range?.() ?? false;
|
|
6
6
|
const isVert = () => (config.orientation?.() ?? 'horizontal') === 'vertical';
|
|
7
7
|
const disabled = () => config.disabled?.() ?? false;
|
|
8
|
+
const rtl = () => config.rtl?.() ?? false;
|
|
8
9
|
const lo = $derived(range() ? config.value()[0] : min());
|
|
9
10
|
const hi = $derived(range() ? config.value()[1] : config.value());
|
|
10
11
|
function clampStep(v) {
|
|
@@ -16,9 +17,10 @@ export function createSlider(config) {
|
|
|
16
17
|
let dragging = $state(null);
|
|
17
18
|
/** Turn a pointer position (client coords) + measured track rect into a value. */
|
|
18
19
|
function valueFromPointer(pos, rect) {
|
|
20
|
+
const horiz = (pos.x - rect.left) / rect.width;
|
|
19
21
|
const frac = isVert()
|
|
20
22
|
? 1 - (pos.y - rect.top) / rect.height
|
|
21
|
-
: (
|
|
23
|
+
: rtl() ? 1 - horiz : horiz;
|
|
22
24
|
return clampStep(min() + Math.min(1, Math.max(0, frac)) * (max() - min()));
|
|
23
25
|
}
|
|
24
26
|
const emitSingle = (v) => config.onChange?.(v);
|
|
@@ -64,11 +66,20 @@ export function createSlider(config) {
|
|
|
64
66
|
if (disabled())
|
|
65
67
|
return;
|
|
66
68
|
const cur = which === 'lo' ? lo : hi;
|
|
69
|
+
// Under horizontal RTL, Left increases and Right decreases (Up/Down keep
|
|
70
|
+
// their natural up=more direction regardless of text direction).
|
|
71
|
+
const rtlH = rtl() && !isVert();
|
|
72
|
+
const inc = clampStep(cur + stepSize());
|
|
73
|
+
const dec = clampStep(cur - stepSize());
|
|
67
74
|
let next = cur;
|
|
68
|
-
if (e.key === '
|
|
69
|
-
next =
|
|
70
|
-
else if (e.key === '
|
|
71
|
-
next =
|
|
75
|
+
if (e.key === 'ArrowUp')
|
|
76
|
+
next = inc;
|
|
77
|
+
else if (e.key === 'ArrowDown')
|
|
78
|
+
next = dec;
|
|
79
|
+
else if (e.key === 'ArrowRight')
|
|
80
|
+
next = rtlH ? dec : inc;
|
|
81
|
+
else if (e.key === 'ArrowLeft')
|
|
82
|
+
next = rtlH ? inc : dec;
|
|
72
83
|
else if (e.key === 'Home')
|
|
73
84
|
next = min();
|
|
74
85
|
else if (e.key === 'End')
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createSplitter - the HEADLESS core behind <SvSplitter>: a two-pane resizable
|
|
3
|
+
* split with a draggable separator (WAI-ARIA `separator`), keyboard resize and
|
|
4
|
+
* clamping, exposed as **prop-getters** you spread onto YOUR OWN markup. The core
|
|
5
|
+
* never touches the DOM - the renderer measures the container rect and passes the
|
|
6
|
+
* pointer position + rect IN via `setFromPointer` (same split as createSlider).
|
|
7
|
+
* Parity: Smart `smart-splitter`.
|
|
8
|
+
*
|
|
9
|
+
* ```svelte
|
|
10
|
+
* <script lang="ts">
|
|
11
|
+
* import { createSplitter } from '@svgrid/grid'
|
|
12
|
+
* let frac = $state(0.5)
|
|
13
|
+
* const sp = createSplitter({ fraction: () => frac, onChange: (f) => (frac = f) })
|
|
14
|
+
* </script>
|
|
15
|
+
* <div class="row" bind:this={row}>
|
|
16
|
+
* <div style:flex-basis={sp.percent + '%'}>A</div>
|
|
17
|
+
* <div {...sp.separatorProps()} onpointerdown={...}></div>
|
|
18
|
+
* <div style:flex="1">B</div>
|
|
19
|
+
* </div>
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export type SplitterOrientation = 'horizontal' | 'vertical';
|
|
23
|
+
export type SplitterPoint = {
|
|
24
|
+
x: number;
|
|
25
|
+
y: number;
|
|
26
|
+
};
|
|
27
|
+
/** Reactive inputs are passed as getters so the core tracks live prop changes. */
|
|
28
|
+
export type SplitterConfig = {
|
|
29
|
+
/** Size of the FIRST pane as a fraction of the container (0..1). */
|
|
30
|
+
fraction: () => number;
|
|
31
|
+
onChange?: (fraction: number) => void;
|
|
32
|
+
/** Split direction: `horizontal` = a vertical gutter between left/right panes. */
|
|
33
|
+
orientation?: () => SplitterOrientation;
|
|
34
|
+
/** Min / max fraction for the first pane (0..1). */
|
|
35
|
+
min?: () => number;
|
|
36
|
+
max?: () => number;
|
|
37
|
+
/** Keyboard step as a fraction (default 0.02 = 2%). */
|
|
38
|
+
step?: () => number;
|
|
39
|
+
disabled?: () => boolean;
|
|
40
|
+
dir?: () => 'ltr' | 'rtl' | 'auto' | undefined;
|
|
41
|
+
ariaLabel?: () => string | undefined;
|
|
42
|
+
};
|
|
43
|
+
export declare function createSplitter(config: SplitterConfig): {
|
|
44
|
+
/** Clamped fraction (0..1) of the first pane. */
|
|
45
|
+
readonly fraction: number;
|
|
46
|
+
/** Clamped size of the first pane as a percentage (0..100). */
|
|
47
|
+
readonly percent: number;
|
|
48
|
+
/** Whether the separator is being dragged. */
|
|
49
|
+
readonly dragging: boolean;
|
|
50
|
+
pointerDown: () => void;
|
|
51
|
+
setFromPointer: (pos: SplitterPoint, rect: DOMRect) => void;
|
|
52
|
+
endDrag: () => void;
|
|
53
|
+
nudge: (delta: number) => void;
|
|
54
|
+
/** Spread onto the draggable separator element. */
|
|
55
|
+
separatorProps: () => {
|
|
56
|
+
role: "separator";
|
|
57
|
+
tabindex: number;
|
|
58
|
+
'aria-orientation': "horizontal" | "vertical";
|
|
59
|
+
'aria-valuemin': number;
|
|
60
|
+
'aria-valuemax': number;
|
|
61
|
+
'aria-valuenow': number;
|
|
62
|
+
'aria-label': string;
|
|
63
|
+
'aria-disabled': true | undefined;
|
|
64
|
+
onkeydown: (e: KeyboardEvent) => void;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
export type Splitter = ReturnType<typeof createSplitter>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export function createSplitter(config) {
|
|
2
|
+
const isVert = () => (config.orientation?.() ?? 'horizontal') === 'vertical';
|
|
3
|
+
const min = () => config.min?.() ?? 0.1;
|
|
4
|
+
const max = () => config.max?.() ?? 0.9;
|
|
5
|
+
const step = () => config.step?.() ?? 0.02;
|
|
6
|
+
const disabled = () => config.disabled?.() ?? false;
|
|
7
|
+
const rtl = () => config.dir?.() === 'rtl';
|
|
8
|
+
const clamp = (f) => Math.min(max(), Math.max(min(), f));
|
|
9
|
+
const fraction = $derived(clamp(config.fraction()));
|
|
10
|
+
const percent = $derived(Math.round(fraction * 1000) / 10);
|
|
11
|
+
let dragging = $state(false);
|
|
12
|
+
function fromPointer(pos, rect) {
|
|
13
|
+
const raw = isVert()
|
|
14
|
+
? (pos.y - rect.top) / rect.height
|
|
15
|
+
: (pos.x - rect.left) / rect.width;
|
|
16
|
+
// Horizontal RTL: the first pane sits on the right, so invert.
|
|
17
|
+
const f = !isVert() && rtl() ? 1 - raw : raw;
|
|
18
|
+
return clamp(f);
|
|
19
|
+
}
|
|
20
|
+
function pointerDown() { if (!disabled())
|
|
21
|
+
dragging = true; }
|
|
22
|
+
function setFromPointer(pos, rect) {
|
|
23
|
+
if (!dragging || disabled())
|
|
24
|
+
return;
|
|
25
|
+
config.onChange?.(fromPointer(pos, rect));
|
|
26
|
+
}
|
|
27
|
+
function endDrag() { dragging = false; }
|
|
28
|
+
function nudge(delta) {
|
|
29
|
+
if (disabled())
|
|
30
|
+
return;
|
|
31
|
+
config.onChange?.(clamp(fraction + delta));
|
|
32
|
+
}
|
|
33
|
+
function onKeydown(e) {
|
|
34
|
+
if (disabled())
|
|
35
|
+
return;
|
|
36
|
+
const horiz = !isVert();
|
|
37
|
+
const rtlH = horiz && rtl();
|
|
38
|
+
const inc = () => nudge(step());
|
|
39
|
+
const dec = () => nudge(-step());
|
|
40
|
+
switch (e.key) {
|
|
41
|
+
case 'ArrowRight':
|
|
42
|
+
if (horiz) {
|
|
43
|
+
e.preventDefault();
|
|
44
|
+
rtlH ? dec() : inc();
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
case 'ArrowLeft':
|
|
48
|
+
if (horiz) {
|
|
49
|
+
e.preventDefault();
|
|
50
|
+
rtlH ? inc() : dec();
|
|
51
|
+
}
|
|
52
|
+
break;
|
|
53
|
+
case 'ArrowDown':
|
|
54
|
+
if (!horiz) {
|
|
55
|
+
e.preventDefault();
|
|
56
|
+
inc();
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
case 'ArrowUp':
|
|
60
|
+
if (!horiz) {
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
dec();
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
case 'Home':
|
|
66
|
+
e.preventDefault();
|
|
67
|
+
config.onChange?.(min());
|
|
68
|
+
break;
|
|
69
|
+
case 'End':
|
|
70
|
+
e.preventDefault();
|
|
71
|
+
config.onChange?.(max());
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
/** Clamped fraction (0..1) of the first pane. */
|
|
77
|
+
get fraction() { return fraction; },
|
|
78
|
+
/** Clamped size of the first pane as a percentage (0..100). */
|
|
79
|
+
get percent() { return percent; },
|
|
80
|
+
/** Whether the separator is being dragged. */
|
|
81
|
+
get dragging() { return dragging; },
|
|
82
|
+
pointerDown,
|
|
83
|
+
setFromPointer,
|
|
84
|
+
endDrag,
|
|
85
|
+
nudge,
|
|
86
|
+
/** Spread onto the draggable separator element. */
|
|
87
|
+
separatorProps: () => ({
|
|
88
|
+
role: 'separator',
|
|
89
|
+
tabindex: disabled() ? -1 : 0,
|
|
90
|
+
'aria-orientation': (isVert() ? 'horizontal' : 'vertical'),
|
|
91
|
+
'aria-valuemin': Math.round(min() * 100),
|
|
92
|
+
'aria-valuemax': Math.round(max() * 100),
|
|
93
|
+
'aria-valuenow': Math.round(fraction * 100),
|
|
94
|
+
'aria-label': config.ariaLabel?.() ?? 'Resize panes',
|
|
95
|
+
'aria-disabled': disabled() || undefined,
|
|
96
|
+
onkeydown: onKeydown,
|
|
97
|
+
}),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
@@ -1,29 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* createSwitch - the HEADLESS core behind <SvSwitchButton>: a controlled on/off
|
|
3
|
-
* switch (ARIA `switch`) with full keyboard (Space/Enter toggle, ArrowRight on,
|
|
4
|
-
* ArrowLeft off), exposed as **prop-getters** you spread onto YOUR OWN markup.
|
|
5
|
-
*
|
|
6
|
-
* ```svelte
|
|
7
|
-
* <script lang="ts">
|
|
8
|
-
* import { createSwitch } from '@svgrid/grid'
|
|
9
|
-
* let on = $state(false)
|
|
10
|
-
* const sw = createSwitch({ checked: () => on, onChange: (v) => (on = v) })
|
|
11
|
-
* </script>
|
|
12
|
-
* <button {...sw.switchProps()}><span class="thumb"></span></button>
|
|
13
|
-
* ```
|
|
14
|
-
*
|
|
15
|
-
* The styled <SvSwitchButton> is just one renderer over this core.
|
|
16
|
-
*/
|
|
17
1
|
export type SwitchConfig = {
|
|
18
2
|
checked: () => boolean;
|
|
19
3
|
onChange?: (checked: boolean) => void;
|
|
20
4
|
disabled?: () => boolean;
|
|
5
|
+
id?: () => string | undefined;
|
|
6
|
+
invalid?: () => boolean;
|
|
7
|
+
required?: () => boolean;
|
|
8
|
+
error?: () => string | undefined;
|
|
9
|
+
hint?: () => string | undefined;
|
|
21
10
|
ariaLabel?: () => string | undefined;
|
|
22
11
|
};
|
|
23
12
|
export type SwitchProps = {
|
|
24
13
|
type: 'button';
|
|
25
14
|
role: 'switch';
|
|
15
|
+
id: string | undefined;
|
|
26
16
|
'aria-checked': boolean;
|
|
17
|
+
'aria-invalid': 'true' | undefined;
|
|
18
|
+
'aria-required': 'true' | undefined;
|
|
19
|
+
'aria-describedby': string | undefined;
|
|
27
20
|
'aria-label': string | undefined;
|
|
28
21
|
disabled: boolean;
|
|
29
22
|
'data-checked': '' | undefined;
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createSwitch - the HEADLESS core behind <SvSwitchButton>: a controlled on/off
|
|
3
|
+
* switch (ARIA `switch`) with full keyboard (Space/Enter toggle, ArrowRight on,
|
|
4
|
+
* ArrowLeft off), exposed as **prop-getters** you spread onto YOUR OWN markup.
|
|
5
|
+
*
|
|
6
|
+
* ```svelte
|
|
7
|
+
* <script lang="ts">
|
|
8
|
+
* import { createSwitch } from '@svgrid/grid'
|
|
9
|
+
* let on = $state(false)
|
|
10
|
+
* const sw = createSwitch({ checked: () => on, onChange: (v) => (on = v) })
|
|
11
|
+
* </script>
|
|
12
|
+
* <button {...sw.switchProps()}><span class="thumb"></span></button>
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* The styled <SvSwitchButton> is just one renderer over this core.
|
|
16
|
+
*/
|
|
17
|
+
import { editorAria } from './editor-contract';
|
|
1
18
|
export function createSwitch(config) {
|
|
2
19
|
const checked = () => config.checked();
|
|
3
20
|
const disabled = () => config.disabled?.() ?? false;
|
|
@@ -22,6 +39,15 @@ export function createSwitch(config) {
|
|
|
22
39
|
config.onChange?.(false);
|
|
23
40
|
}
|
|
24
41
|
}
|
|
42
|
+
// The validation/label ARIA is derived from the editor contract state.
|
|
43
|
+
const ariaState = () => ({
|
|
44
|
+
id: config.id?.(),
|
|
45
|
+
invalid: config.invalid?.(),
|
|
46
|
+
required: config.required?.(),
|
|
47
|
+
error: config.error?.(),
|
|
48
|
+
hint: config.hint?.(),
|
|
49
|
+
ariaLabel: config.ariaLabel?.(),
|
|
50
|
+
});
|
|
25
51
|
return {
|
|
26
52
|
get checked() { return checked(); },
|
|
27
53
|
get disabled() { return disabled(); },
|
|
@@ -30,10 +56,11 @@ export function createSwitch(config) {
|
|
|
30
56
|
switchProps: () => ({
|
|
31
57
|
type: 'button',
|
|
32
58
|
role: 'switch',
|
|
59
|
+
id: config.id?.(),
|
|
33
60
|
'aria-checked': checked(),
|
|
34
|
-
'aria-label': config.ariaLabel?.(),
|
|
35
61
|
disabled: disabled(),
|
|
36
62
|
'data-checked': checked() ? '' : undefined,
|
|
63
|
+
...editorAria(ariaState()),
|
|
37
64
|
onclick: toggle,
|
|
38
65
|
onkeydown: onKeydown,
|
|
39
66
|
}),
|
|
@@ -23,10 +23,12 @@
|
|
|
23
23
|
* a render concern, so the component watches `focusTick`/`focusId` and calls
|
|
24
24
|
* `.focus()` itself; the core only decides *which* tab should take focus.
|
|
25
25
|
*/
|
|
26
|
+
import type { EditorDir } from './editor-contract';
|
|
26
27
|
export type TabItem = {
|
|
27
28
|
id: string;
|
|
28
29
|
label: string;
|
|
29
30
|
disabled?: boolean;
|
|
31
|
+
closable?: boolean;
|
|
30
32
|
};
|
|
31
33
|
export type TabsOrientation = 'horizontal' | 'vertical';
|
|
32
34
|
export type TabsActivation = 'automatic' | 'manual';
|
|
@@ -35,8 +37,12 @@ export type TabsConfig = {
|
|
|
35
37
|
tabs: () => ReadonlyArray<TabItem>;
|
|
36
38
|
value: () => string | undefined;
|
|
37
39
|
onChange?: (id: string) => void;
|
|
40
|
+
/** Fired when a closable tab is closed (Delete key, or the renderer's x). */
|
|
41
|
+
onClose?: (id: string) => void;
|
|
38
42
|
orientation?: () => TabsOrientation;
|
|
39
43
|
activation?: () => TabsActivation;
|
|
44
|
+
/** Text direction; under `'rtl'` horizontal Left/Right arrows flip. */
|
|
45
|
+
dir?: () => EditorDir | undefined;
|
|
40
46
|
ariaLabel?: () => string | undefined;
|
|
41
47
|
};
|
|
42
48
|
export declare function createTabs(config: TabsConfig): {
|
|
@@ -48,6 +54,7 @@ export declare function createTabs(config: TabsConfig): {
|
|
|
48
54
|
readonly focusTick: number;
|
|
49
55
|
isActive: (tid: string) => boolean;
|
|
50
56
|
select: (tid: string) => void;
|
|
57
|
+
close: (tid: string) => void;
|
|
51
58
|
onKeydown: (e: KeyboardEvent) => void;
|
|
52
59
|
/** Spread onto the tablist container element. */
|
|
53
60
|
tablistProps: () => {
|