@svgrid/grid 1.2.33 → 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
package/dist/otp.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* otp - pure helpers behind <SvOtpInput>: sanitize/spread a raw string across N
|
|
3
|
+
* segments (used on paste and per-cell input) and detect completion.
|
|
4
|
+
* Framework-free + pure so they are unit-tested directly.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Keep only the characters allowed for `numeric` mode (digits) or any
|
|
8
|
+
* non-whitespace otherwise, then clamp to `length`. Returns the cleaned string
|
|
9
|
+
* (<= length chars).
|
|
10
|
+
*/
|
|
11
|
+
export function sanitizeOtp(raw, length, numeric) {
|
|
12
|
+
const kept = numeric ? raw.replace(/\D/g, '') : raw.replace(/\s/g, '');
|
|
13
|
+
return kept.slice(0, Math.max(0, length));
|
|
14
|
+
}
|
|
15
|
+
/** Split a value into exactly `length` single-char cells (padding with ''). */
|
|
16
|
+
export function otpCells(value, length) {
|
|
17
|
+
const cells = [];
|
|
18
|
+
for (let i = 0; i < length; i++)
|
|
19
|
+
cells[i] = value[i] ?? '';
|
|
20
|
+
return cells;
|
|
21
|
+
}
|
|
22
|
+
/** Whether `value` fills every cell (a joined OTP has no internal gaps, so an
|
|
23
|
+
* exact-length string is complete). */
|
|
24
|
+
export function isOtpComplete(value, length) {
|
|
25
|
+
return value.length === length;
|
|
26
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* paginate - the pure page-range algorithm behind <SvPagination>. Given the
|
|
3
|
+
* current page and total page count, returns the sequence of page numbers and
|
|
4
|
+
* ellipsis markers to render (boundary pages + a window of siblings around the
|
|
5
|
+
* current page, with gaps collapsed to an ellipsis). Framework-free + pure so
|
|
6
|
+
* it is unit-tested on its own.
|
|
7
|
+
*/
|
|
8
|
+
export type PaginationItem = number | 'ellipsis-left' | 'ellipsis-right';
|
|
9
|
+
export type PaginationRangeOptions = {
|
|
10
|
+
/** 1-based current page. */
|
|
11
|
+
page: number;
|
|
12
|
+
/** Total number of pages. */
|
|
13
|
+
pageCount: number;
|
|
14
|
+
/** Pages shown on each side of the current page. Default 1. */
|
|
15
|
+
siblingCount?: number;
|
|
16
|
+
/** Pages pinned at each end. Default 1. */
|
|
17
|
+
boundaryCount?: number;
|
|
18
|
+
};
|
|
19
|
+
/** Build the page/ellipsis sequence (e.g. `[1, 'ellipsis-left', 4, 5, 6, 'ellipsis-right', 20]`). */
|
|
20
|
+
export declare function paginationRange(options: PaginationRangeOptions): PaginationItem[];
|
package/dist/paginate.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const clamp = (n, lo, hi) => Math.min(Math.max(n, lo), hi);
|
|
2
|
+
/** Build the page/ellipsis sequence (e.g. `[1, 'ellipsis-left', 4, 5, 6, 'ellipsis-right', 20]`). */
|
|
3
|
+
export function paginationRange(options) {
|
|
4
|
+
const { pageCount } = options;
|
|
5
|
+
if (pageCount <= 0)
|
|
6
|
+
return [];
|
|
7
|
+
const siblingCount = Math.max(0, options.siblingCount ?? 1);
|
|
8
|
+
const boundaryCount = Math.max(1, options.boundaryCount ?? 1);
|
|
9
|
+
const page = clamp(options.page, 1, pageCount);
|
|
10
|
+
// If ellipsis could hide at most one page, just show every page.
|
|
11
|
+
if (pageCount <= boundaryCount * 2 + siblingCount * 2 + 3) {
|
|
12
|
+
return Array.from({ length: pageCount }, (_, i) => i + 1);
|
|
13
|
+
}
|
|
14
|
+
const pages = new Set();
|
|
15
|
+
// End boundaries (both ends).
|
|
16
|
+
for (let i = 1; i <= boundaryCount && i <= pageCount; i++) {
|
|
17
|
+
pages.add(i);
|
|
18
|
+
pages.add(pageCount - i + 1);
|
|
19
|
+
}
|
|
20
|
+
// Siblings around the current page.
|
|
21
|
+
for (let i = page - siblingCount; i <= page + siblingCount; i++) {
|
|
22
|
+
if (i >= 1 && i <= pageCount)
|
|
23
|
+
pages.add(i);
|
|
24
|
+
}
|
|
25
|
+
const sorted = [...pages].sort((a, b) => a - b);
|
|
26
|
+
const result = [];
|
|
27
|
+
let prev = 0;
|
|
28
|
+
for (const p of sorted) {
|
|
29
|
+
if (p - prev === 2) {
|
|
30
|
+
// Exactly one page in the gap: show it instead of an ellipsis.
|
|
31
|
+
result.push(prev + 1);
|
|
32
|
+
}
|
|
33
|
+
else if (p - prev > 2) {
|
|
34
|
+
result.push(p <= page ? 'ellipsis-left' : 'ellipsis-right');
|
|
35
|
+
}
|
|
36
|
+
result.push(p);
|
|
37
|
+
prev = p;
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
package/dist/popover.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* resolved values and pin them inline. Keep this list in sync with the tokens
|
|
15
15
|
* any popover panel actually consumes.
|
|
16
16
|
*/
|
|
17
|
-
export declare const PANEL_THEME_VARS: readonly ["--sg-accent", "--sg-bg", "--sg-fg", "--sg-
|
|
17
|
+
export declare const PANEL_THEME_VARS: readonly ["--sg-accent", "--sg-on-accent", "--sg-bg", "--sg-fg", "--sg-muted", "--sg-border", "--sg-header-bg", "--sg-header-fg", "--sg-row-hover-bg", "--sg-row-alt-bg", "--sg-selection-bg", "--sg-selection-fg", "--sg-input-bg", "--sg-input-border", "--sg-danger", "--sg-focus-ring", "--sg-radius", "--sg-font", "--sg-invalid-bg", "--sg-invalid-border", "--sg-invalid-fg", "--sg-rating-on", "--sg-rating-empty", "--sg-rating-hover"];
|
|
18
18
|
/**
|
|
19
19
|
* Svelte action: snapshot the resolved theme tokens from the node's current
|
|
20
20
|
* (in-scope) position, then detach it and append to <body> so it can never be
|
|
@@ -23,6 +23,20 @@ export declare const PANEL_THEME_VARS: readonly ["--sg-accent", "--sg-bg", "--sg
|
|
|
23
23
|
export declare function portalToBody(node: HTMLElement, vars?: ReadonlyArray<string>): {
|
|
24
24
|
destroy(): void;
|
|
25
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Svelte action: play a short enter animation when a portalled panel mounts
|
|
28
|
+
* (dropdowns, popovers, dialogs). Slides from the trigger side + fades/scales in.
|
|
29
|
+
* A no-op under `prefers-reduced-motion` and in environments without the Web
|
|
30
|
+
* Animations API (jsdom), so tests and reduced-motion users are unaffected.
|
|
31
|
+
*
|
|
32
|
+
* `use:popIn={{ up: rect.openUpward }}` - pass `up` for panels that flipped above
|
|
33
|
+
* their trigger so the slide direction matches.
|
|
34
|
+
*/
|
|
35
|
+
export declare function popIn(node: HTMLElement, param?: {
|
|
36
|
+
up?: boolean;
|
|
37
|
+
duration?: number;
|
|
38
|
+
scale?: number;
|
|
39
|
+
}): {} | undefined;
|
|
26
40
|
export type AnchoredRect = {
|
|
27
41
|
top: number;
|
|
28
42
|
left: number;
|
package/dist/popover.js
CHANGED
|
@@ -15,9 +15,12 @@
|
|
|
15
15
|
* any popover panel actually consumes.
|
|
16
16
|
*/
|
|
17
17
|
export const PANEL_THEME_VARS = [
|
|
18
|
-
'--sg-accent', '--sg-bg', '--sg-fg', '--sg-
|
|
19
|
-
'--sg-header-bg', '--sg-row-hover-bg', '--sg-
|
|
20
|
-
'--sg-
|
|
18
|
+
'--sg-accent', '--sg-on-accent', '--sg-bg', '--sg-fg', '--sg-muted', '--sg-border',
|
|
19
|
+
'--sg-header-bg', '--sg-header-fg', '--sg-row-hover-bg', '--sg-row-alt-bg',
|
|
20
|
+
'--sg-selection-bg', '--sg-selection-fg', '--sg-input-bg', '--sg-input-border',
|
|
21
|
+
'--sg-danger', '--sg-focus-ring', '--sg-radius', '--sg-font',
|
|
22
|
+
'--sg-invalid-bg', '--sg-invalid-border', '--sg-invalid-fg',
|
|
23
|
+
'--sg-rating-on', '--sg-rating-empty', '--sg-rating-hover',
|
|
21
24
|
];
|
|
22
25
|
/**
|
|
23
26
|
* Svelte action: snapshot the resolved theme tokens from the node's current
|
|
@@ -39,6 +42,29 @@ export function portalToBody(node, vars = PANEL_THEME_VARS) {
|
|
|
39
42
|
},
|
|
40
43
|
};
|
|
41
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Svelte action: play a short enter animation when a portalled panel mounts
|
|
47
|
+
* (dropdowns, popovers, dialogs). Slides from the trigger side + fades/scales in.
|
|
48
|
+
* A no-op under `prefers-reduced-motion` and in environments without the Web
|
|
49
|
+
* Animations API (jsdom), so tests and reduced-motion users are unaffected.
|
|
50
|
+
*
|
|
51
|
+
* `use:popIn={{ up: rect.openUpward }}` - pass `up` for panels that flipped above
|
|
52
|
+
* their trigger so the slide direction matches.
|
|
53
|
+
*/
|
|
54
|
+
export function popIn(node, param = {}) {
|
|
55
|
+
if (typeof node.animate !== 'function')
|
|
56
|
+
return;
|
|
57
|
+
const reduce = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
58
|
+
if (reduce)
|
|
59
|
+
return;
|
|
60
|
+
const dy = param.up ? 6 : -6;
|
|
61
|
+
const s = param.scale ?? 0.97;
|
|
62
|
+
node.animate([
|
|
63
|
+
{ opacity: 0, transform: `translateY(${dy}px) scale(${s})` },
|
|
64
|
+
{ opacity: 1, transform: 'translateY(0) scale(1)' },
|
|
65
|
+
], { duration: param.duration ?? 140, easing: 'cubic-bezier(0.16, 1, 0.3, 1)' });
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
42
68
|
/**
|
|
43
69
|
* Compute a `position: fixed` rect anchored to `triggerRect`, flipping above the
|
|
44
70
|
* trigger when there isn't room below and there's more room above. Mirrors the
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* recurrence - a small, pure repeat-pattern engine for SvCalendar (and anywhere
|
|
3
|
+
* you need "does this date match a recurring rule"). Supports daily / weekly /
|
|
4
|
+
* monthly / yearly frequencies with an interval, weekday lists, a day-of-month,
|
|
5
|
+
* an anchor (`from`) and an inclusive `until`. Framework-free + pure so it is
|
|
6
|
+
* unit-tested directly - no RRULE dependency.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* const standup = { freq: 'weekly', weekdays: [1, 2, 3, 4, 5] } // every weekday
|
|
10
|
+
* const payday = { freq: 'monthly', day: 1 } // the 1st
|
|
11
|
+
* const sprint = { freq: 'weekly', weekdays: [1], interval: 2, from: '2026-01-05' } // every other Monday
|
|
12
|
+
* matchesRecurrence(someDate, [standup, payday, sprint])
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
import { type DateLike } from './datetime/date-core';
|
|
16
|
+
export type RecurrenceFreq = 'daily' | 'weekly' | 'monthly' | 'yearly';
|
|
17
|
+
export type RecurrenceRule = {
|
|
18
|
+
freq: RecurrenceFreq;
|
|
19
|
+
/** Repeat every N units of `freq`. Default 1. Uses `from` as the phase anchor. */
|
|
20
|
+
interval?: number;
|
|
21
|
+
/** weekly: the weekdays it lands on (0 = Sunday .. 6 = Saturday). */
|
|
22
|
+
weekdays?: ReadonlyArray<number>;
|
|
23
|
+
/** monthly / yearly: day of the month (1..31). */
|
|
24
|
+
day?: number;
|
|
25
|
+
/** yearly: the month (0 = January .. 11 = December). */
|
|
26
|
+
month?: number;
|
|
27
|
+
/** First occurrence + the phase for `interval`. */
|
|
28
|
+
from?: DateLike;
|
|
29
|
+
/** Last day the pattern applies (inclusive). */
|
|
30
|
+
until?: DateLike | null;
|
|
31
|
+
};
|
|
32
|
+
/** Whether `date` matches any of the given recurrence rule(s). */
|
|
33
|
+
export declare function matchesRecurrence(date: Date, rules: RecurrenceRule | ReadonlyArray<RecurrenceRule> | null | undefined): boolean;
|
|
34
|
+
/** Every matching date within [start, end] (inclusive), in order - for building
|
|
35
|
+
* event lists / agendas. Bounded to avoid runaway loops. */
|
|
36
|
+
export declare function expandRecurrence(rules: RecurrenceRule | ReadonlyArray<RecurrenceRule> | null | undefined, start: Date, end: Date): Date[];
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* recurrence - a small, pure repeat-pattern engine for SvCalendar (and anywhere
|
|
3
|
+
* you need "does this date match a recurring rule"). Supports daily / weekly /
|
|
4
|
+
* monthly / yearly frequencies with an interval, weekday lists, a day-of-month,
|
|
5
|
+
* an anchor (`from`) and an inclusive `until`. Framework-free + pure so it is
|
|
6
|
+
* unit-tested directly - no RRULE dependency.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* const standup = { freq: 'weekly', weekdays: [1, 2, 3, 4, 5] } // every weekday
|
|
10
|
+
* const payday = { freq: 'monthly', day: 1 } // the 1st
|
|
11
|
+
* const sprint = { freq: 'weekly', weekdays: [1], interval: 2, from: '2026-01-05' } // every other Monday
|
|
12
|
+
* matchesRecurrence(someDate, [standup, payday, sprint])
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
import { startOfDay, startOfWeek, toDate } from './datetime/date-core';
|
|
16
|
+
const MS_DAY = 86400000;
|
|
17
|
+
/** Whole-day index, rounded so DST transitions don't shift it. */
|
|
18
|
+
const dayIndex = (d) => Math.round(startOfDay(d).getTime() / MS_DAY);
|
|
19
|
+
function matchesRule(date, r) {
|
|
20
|
+
const d = startOfDay(date);
|
|
21
|
+
const fromD = r.from != null ? startOfDay(toDate(r.from) ?? d) : null;
|
|
22
|
+
const untilD = r.until != null ? startOfDay(toDate(r.until) ?? d) : null;
|
|
23
|
+
if (fromD && d < fromD)
|
|
24
|
+
return false;
|
|
25
|
+
if (untilD && d > untilD)
|
|
26
|
+
return false;
|
|
27
|
+
const interval = Math.max(1, Math.floor(r.interval ?? 1));
|
|
28
|
+
switch (r.freq) {
|
|
29
|
+
case 'daily':
|
|
30
|
+
if (!fromD)
|
|
31
|
+
return true;
|
|
32
|
+
return (dayIndex(d) - dayIndex(fromD)) % interval === 0;
|
|
33
|
+
case 'weekly': {
|
|
34
|
+
// The weekdays it repeats on: an explicit list, else the anchor's weekday.
|
|
35
|
+
const weekdays = r.weekdays && r.weekdays.length ? r.weekdays : fromD ? [fromD.getDay()] : null;
|
|
36
|
+
if (!weekdays)
|
|
37
|
+
return false;
|
|
38
|
+
if (!weekdays.includes(d.getDay()))
|
|
39
|
+
return false;
|
|
40
|
+
if (interval > 1 && fromD) {
|
|
41
|
+
const weeks = Math.round((startOfWeek(d, 0).getTime() - startOfWeek(fromD, 0).getTime()) / (MS_DAY * 7));
|
|
42
|
+
if (weeks % interval !== 0)
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
case 'monthly': {
|
|
48
|
+
const dom = r.day ?? fromD?.getDate();
|
|
49
|
+
if (dom != null && d.getDate() !== dom)
|
|
50
|
+
return false;
|
|
51
|
+
if (!fromD)
|
|
52
|
+
return dom != null;
|
|
53
|
+
const months = (d.getFullYear() - fromD.getFullYear()) * 12 + (d.getMonth() - fromD.getMonth());
|
|
54
|
+
return months % interval === 0;
|
|
55
|
+
}
|
|
56
|
+
case 'yearly': {
|
|
57
|
+
if (r.month != null && d.getMonth() !== r.month)
|
|
58
|
+
return false;
|
|
59
|
+
const dom = r.day ?? fromD?.getDate();
|
|
60
|
+
if (dom != null && d.getDate() !== dom)
|
|
61
|
+
return false;
|
|
62
|
+
if (!fromD)
|
|
63
|
+
return r.month != null || dom != null;
|
|
64
|
+
return (d.getFullYear() - fromD.getFullYear()) % interval === 0;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Whether `date` matches any of the given recurrence rule(s). */
|
|
69
|
+
export function matchesRecurrence(date, rules) {
|
|
70
|
+
if (!rules)
|
|
71
|
+
return false;
|
|
72
|
+
const list = Array.isArray(rules) ? rules : [rules];
|
|
73
|
+
return list.some((r) => matchesRule(date, r));
|
|
74
|
+
}
|
|
75
|
+
/** Every matching date within [start, end] (inclusive), in order - for building
|
|
76
|
+
* event lists / agendas. Bounded to avoid runaway loops. */
|
|
77
|
+
export function expandRecurrence(rules, start, end) {
|
|
78
|
+
if (!rules)
|
|
79
|
+
return [];
|
|
80
|
+
const out = [];
|
|
81
|
+
const last = startOfDay(end);
|
|
82
|
+
let cur = startOfDay(start);
|
|
83
|
+
let guard = 0;
|
|
84
|
+
while (cur <= last && guard++ < 4000) {
|
|
85
|
+
if (matchesRecurrence(cur, rules))
|
|
86
|
+
out.push(cur);
|
|
87
|
+
cur = new Date(cur.getFullYear(), cur.getMonth(), cur.getDate() + 1);
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
@@ -34,6 +34,11 @@ export type ServerFilterModel = {
|
|
|
34
34
|
selectedValues?: string[];
|
|
35
35
|
}>;
|
|
36
36
|
};
|
|
37
|
+
/** A value column to roll up per group. */
|
|
38
|
+
export type ServerAggregation = {
|
|
39
|
+
col: string;
|
|
40
|
+
fn: 'sum' | 'avg' | 'min' | 'max' | 'count';
|
|
41
|
+
};
|
|
37
42
|
export type ServerRequest = {
|
|
38
43
|
/** Zero-based index of the first row wanted (inclusive). */
|
|
39
44
|
startRow: number;
|
|
@@ -43,7 +48,91 @@ export type ServerRequest = {
|
|
|
43
48
|
pageSize: number;
|
|
44
49
|
sortModel: ServerSortModel;
|
|
45
50
|
filterModel: ServerFilterModel;
|
|
51
|
+
/**
|
|
52
|
+
* Server-side grouping / tree: the columns being grouped on, outer to inner.
|
|
53
|
+
* Omitted / empty for a flat request.
|
|
54
|
+
*/
|
|
55
|
+
groupBy?: string[];
|
|
56
|
+
/**
|
|
57
|
+
* The path of group keys the grid is expanding, e.g. `['Germany', 'Berlin']`.
|
|
58
|
+
* Empty (`[]`) asks for the top level. When `groupKeys.length < groupBy.length`
|
|
59
|
+
* the server returns **group rows** (one per distinct key at this level,
|
|
60
|
+
* carrying the group key + aggregates); when they are equal it returns the
|
|
61
|
+
* **leaf rows** under that path.
|
|
62
|
+
*/
|
|
63
|
+
groupKeys?: string[];
|
|
64
|
+
/** Value columns to aggregate per group. */
|
|
65
|
+
aggregations?: ServerAggregation[];
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* A group row in the server-side group/tree model - one distinct key at a
|
|
69
|
+
* level, with its rolled-up aggregates. The grid renders it with an expander;
|
|
70
|
+
* expanding it fetches its children through the same `getRows`.
|
|
71
|
+
*/
|
|
72
|
+
export type ServerGroupRow<TData> = {
|
|
73
|
+
kind: 'group';
|
|
74
|
+
/** Stable id (the group path). */
|
|
75
|
+
id: string;
|
|
76
|
+
/** Group keys from the root to this node, e.g. `['Germany', 'Berlin']`. */
|
|
77
|
+
path: string[];
|
|
78
|
+
/** The column this group is on (the `groupBy` entry for this level). */
|
|
79
|
+
field: string;
|
|
80
|
+
/** This group's key value. */
|
|
81
|
+
key: string;
|
|
82
|
+
/** Zero-based depth (0 = top level). */
|
|
83
|
+
level: number;
|
|
84
|
+
expanded: boolean;
|
|
85
|
+
loading: boolean;
|
|
86
|
+
/** Aggregate values keyed by column id, read from the group's response row. */
|
|
87
|
+
aggregates: Record<string, unknown>;
|
|
88
|
+
/** The raw response row for this group (key + aggregates), for cell rendering. */
|
|
89
|
+
data: TData;
|
|
90
|
+
};
|
|
91
|
+
export type ServerLeafRow<TData> = {
|
|
92
|
+
kind: 'leaf';
|
|
93
|
+
id: string;
|
|
94
|
+
level: number;
|
|
95
|
+
data: TData;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* A "load more" affordance emitted at the end of a group whose children are
|
|
99
|
+
* only partially loaded (intra-group paging). Trigger `loadMoreChildren(path)`
|
|
100
|
+
* to fetch the next block.
|
|
101
|
+
*/
|
|
102
|
+
export type ServerMoreRow = {
|
|
103
|
+
kind: 'more';
|
|
104
|
+
id: string;
|
|
105
|
+
level: number;
|
|
106
|
+
/** Path of the parent group whose children to load more of. */
|
|
107
|
+
path: string[];
|
|
108
|
+
/** How many children remain unloaded. */
|
|
109
|
+
remaining: number;
|
|
110
|
+
loading: boolean;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* A subtotal / footer row emitted after an expanded group's children when
|
|
114
|
+
* `groupFooters` is on. Carries the group's aggregates a second time so a
|
|
115
|
+
* "Total" line sits under the detail.
|
|
116
|
+
*/
|
|
117
|
+
export type ServerFooterRow<TData> = {
|
|
118
|
+
kind: 'footer';
|
|
119
|
+
id: string;
|
|
120
|
+
level: number;
|
|
121
|
+
path: string[];
|
|
122
|
+
/** The group this footer totals (its key). */
|
|
123
|
+
key: string;
|
|
124
|
+
aggregates: Record<string, unknown>;
|
|
125
|
+
/** The group's response row (key + aggregates), so value columns show totals. */
|
|
126
|
+
data: TData;
|
|
127
|
+
};
|
|
128
|
+
/** A placeholder row shown while a block of children is being fetched. */
|
|
129
|
+
export type ServerSkeletonRow = {
|
|
130
|
+
kind: 'skeleton';
|
|
131
|
+
id: string;
|
|
132
|
+
level: number;
|
|
46
133
|
};
|
|
134
|
+
/** A row in the flattened server-side group/tree display list. */
|
|
135
|
+
export type ServerDisplayRow<TData> = ServerGroupRow<TData> | ServerLeafRow<TData> | ServerMoreRow | ServerFooterRow<TData> | ServerSkeletonRow;
|
|
47
136
|
export type ServerResult<TData> = {
|
|
48
137
|
rows: ReadonlyArray<TData>;
|
|
49
138
|
/** Total row count after filtering (for the pager). */
|
|
@@ -35,6 +35,10 @@ export function createServerDataSource(source, options) {
|
|
|
35
35
|
pageSize: state.pageSize,
|
|
36
36
|
sortModel: state.sortModel,
|
|
37
37
|
filterModel: state.filterModel,
|
|
38
|
+
// Flat mode: no grouping. Group mode lives in createServerGroupModel.
|
|
39
|
+
groupBy: [],
|
|
40
|
+
groupKeys: [],
|
|
41
|
+
aggregations: [],
|
|
38
42
|
});
|
|
39
43
|
if (disposed || id !== requestSeq)
|
|
40
44
|
return; // stale
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side GROUP row model (SSRM grouping) - the first-class
|
|
3
|
+
* companion to `createServerDataSource`. Grouping, aggregation, and lazy
|
|
4
|
+
* expansion all flow through the SAME `ServerDataSource.getRows` contract:
|
|
5
|
+
*
|
|
6
|
+
* - The request carries `groupBy` (the columns grouped on) and `groupKeys`
|
|
7
|
+
* (the path of the group being expanded). While `groupKeys.length <
|
|
8
|
+
* groupBy.length` the server returns GROUP rows (one per distinct key at
|
|
9
|
+
* that level, carrying the key + aggregate values); at the bottom level it
|
|
10
|
+
* returns the leaf rows under that path.
|
|
11
|
+
* - Expanding a group is just another `getRows` with `groupKeys` set to that
|
|
12
|
+
* group's path. This controller owns the group tree: expand / collapse,
|
|
13
|
+
* per-node lazy fetch + cache, race-safety, and flattening to a display
|
|
14
|
+
* list the grid renders (group rows with an expander, leaves underneath).
|
|
15
|
+
*
|
|
16
|
+
* Headless and framework-agnostic on purpose: render from `state.displayRows`
|
|
17
|
+
* and call `toggleGroup` from the group cell's expander.
|
|
18
|
+
*/
|
|
19
|
+
import type { ServerAggregation, ServerDataSource, ServerDisplayRow, ServerFilterModel, ServerGroupRow, ServerSortModel } from './server-data-source';
|
|
20
|
+
export type ServerGroupState<TData> = {
|
|
21
|
+
/** The flattened tree: top-level groups, with expanded groups' children spliced in. */
|
|
22
|
+
displayRows: ServerDisplayRow<TData>[];
|
|
23
|
+
groupBy: string[];
|
|
24
|
+
/** True during the initial top-level fetch (before the root has ever loaded). */
|
|
25
|
+
loading: boolean;
|
|
26
|
+
/** The rejection from the last failed top-level fetch, else null. */
|
|
27
|
+
error: unknown;
|
|
28
|
+
sortModel: ServerSortModel;
|
|
29
|
+
filterModel: ServerFilterModel;
|
|
30
|
+
/** Ids (JSON of the path) of the currently expanded groups. */
|
|
31
|
+
expandedGroups: string[];
|
|
32
|
+
};
|
|
33
|
+
export type ServerGroupControllerOptions<TData> = {
|
|
34
|
+
/** Columns to group on, outer to inner. Empty in `treeData` mode. */
|
|
35
|
+
groupBy?: string[];
|
|
36
|
+
/** Value columns to roll up per group. */
|
|
37
|
+
aggregations?: ServerAggregation[];
|
|
38
|
+
/** Max children fetched per group in one request. Default 200. */
|
|
39
|
+
pageSize?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Self-referential tree mode: instead of grouping flat rows by columns, each
|
|
42
|
+
* row is a node whose children are fetched on expand. Requires `getRowId`
|
|
43
|
+
* (the node id, which builds the `groupKeys` path) and `hasChildren` (whether
|
|
44
|
+
* a node is expandable). `getRows` receives `groupKeys` = the path to the
|
|
45
|
+
* node being expanded, and returns that node's direct children.
|
|
46
|
+
*/
|
|
47
|
+
treeData?: boolean;
|
|
48
|
+
/** Node id, used to build the `groupKeys` path. Required in `treeData` mode. */
|
|
49
|
+
getRowId?: (row: TData) => string;
|
|
50
|
+
/** Whether a node can be expanded. Required in `treeData` mode. */
|
|
51
|
+
hasChildren?: (row: TData) => boolean;
|
|
52
|
+
/** Emit a subtotal "footer" row after each expanded group's children. */
|
|
53
|
+
groupFooters?: boolean;
|
|
54
|
+
/** Placeholder rows shown while a group's first block is loading. Default 3. */
|
|
55
|
+
skeletonRows?: number;
|
|
56
|
+
onChange: (state: ServerGroupState<TData>) => void;
|
|
57
|
+
};
|
|
58
|
+
export type ServerGroupController<TData> = {
|
|
59
|
+
/** (Re-)fetch the tree from the top. Call once to load the first level. */
|
|
60
|
+
refresh(): void;
|
|
61
|
+
setSort(sortModel: ServerSortModel): void;
|
|
62
|
+
setFilter(filterModel: ServerFilterModel): void;
|
|
63
|
+
/** Change the grouping columns. Collapses everything and reloads the top level. */
|
|
64
|
+
setGroupBy(groupBy: string[]): void;
|
|
65
|
+
/** Expand or collapse a group row (from its expander). */
|
|
66
|
+
toggleGroup(row: ServerGroupRow<TData>): void;
|
|
67
|
+
expandGroup(path: string[]): void;
|
|
68
|
+
collapseGroup(path: string[]): void;
|
|
69
|
+
/** Fetch the next block of a group's children (intra-group paging). */
|
|
70
|
+
loadMoreChildren(path: string[]): void;
|
|
71
|
+
isExpanded(path: string[]): boolean;
|
|
72
|
+
getState(): ServerGroupState<TData>;
|
|
73
|
+
/** Stop accepting in-flight responses. Call on unmount. */
|
|
74
|
+
dispose(): void;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Map a `ServerGroupState.displayRows` to grid rows: each row's data spread at
|
|
78
|
+
* the top level (so normal `field` columns show group subtotals on group rows
|
|
79
|
+
* and cell values on leaves) plus a `__group` marker the built-in `SvGroupCell`
|
|
80
|
+
* reads to draw the expander + indentation. Feed the result to `<SvGrid data>`.
|
|
81
|
+
*/
|
|
82
|
+
export type ServerGroupGridRow<TData> = TData & {
|
|
83
|
+
__group: ServerDisplayRow<TData>;
|
|
84
|
+
};
|
|
85
|
+
export declare function serverGroupRows<TData>(state: ServerGroupState<TData> | undefined | null): ServerGroupGridRow<TData>[];
|
|
86
|
+
/**
|
|
87
|
+
* Build the `serverGroup` prop for `<SvGrid>` from a controller, so the grid's
|
|
88
|
+
* built-in tree keyboard (ArrowRight / ArrowLeft expand / collapse) and treegrid
|
|
89
|
+
* a11y work with no app-level key handling. Reads the `__group` marker that
|
|
90
|
+
* `serverGroupRows` attaches. Usage: `<SvGrid ... serverGroup={serverGroupNav(ctl)} />`.
|
|
91
|
+
*/
|
|
92
|
+
export declare function serverGroupNav<TData>(ctl: ServerGroupController<TData>): {
|
|
93
|
+
isGroup: (row: ServerGroupGridRow<TData>) => boolean;
|
|
94
|
+
level: (row: ServerGroupGridRow<TData>) => number;
|
|
95
|
+
expanded: (row: ServerGroupGridRow<TData>) => boolean;
|
|
96
|
+
onToggle: (row: ServerGroupGridRow<TData>) => void;
|
|
97
|
+
};
|
|
98
|
+
export declare function createServerGroupModel<TData>(source: ServerDataSource<TData>, options: ServerGroupControllerOptions<TData>): ServerGroupController<TData>;
|