@svgrid/grid 2.2.32 → 2.4.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 +199 -199
- package/dist/DockNodeView.svelte +1 -1
- package/dist/FlexRender.svelte +96 -96
- package/dist/GridFooter.svelte +178 -179
- package/dist/GridMenus.svelte +705 -782
- package/dist/SvAutoComplete.svelte +165 -165
- package/dist/SvAvatar.svelte +75 -75
- package/dist/SvCalendar.svelte +503 -503
- package/dist/SvCarousel.svelte +141 -141
- package/dist/SvCheckBox.svelte +102 -102
- package/dist/SvCircularProgress.svelte +109 -109
- package/dist/SvColorInput.svelte +181 -181
- package/dist/SvComboBox.svelte +275 -275
- package/dist/SvContextMenu.svelte +116 -116
- package/dist/SvCountryInput.svelte +160 -160
- package/dist/SvDateRangeInput.svelte +1 -1
- package/dist/SvDrawer.svelte +254 -254
- package/dist/SvDropDownList.svelte +374 -374
- package/dist/SvDurationInput.svelte +126 -126
- package/dist/SvField.svelte +293 -293
- package/dist/SvForm.svelte +437 -437
- package/dist/SvGrid.css +2814 -2804
- package/dist/SvGrid.svelte +3490 -3513
- package/dist/SvGridChart.svelte +1716 -1724
- package/dist/SvGridChartPanel.svelte +485 -485
- package/dist/SvGridChartView.svelte +70 -70
- package/dist/SvGridDropdown.svelte +728 -728
- package/dist/SvGridSelect.svelte +266 -268
- package/dist/SvGroupCell.svelte +116 -116
- package/dist/SvKbd.svelte +1 -1
- package/dist/SvList.svelte +1 -1
- package/dist/SvListBox.svelte +326 -326
- package/dist/SvMaskedInput.svelte +122 -122
- package/dist/SvMenu.svelte +124 -124
- package/dist/SvMenuList.svelte +146 -146
- package/dist/SvMenubar.svelte +1 -1
- package/dist/SvMultiSelect.svelte +289 -290
- package/dist/SvNumberInput.svelte +168 -168
- package/dist/SvOtpInput.svelte +158 -158
- package/dist/SvPasswordInput.svelte +151 -151
- package/dist/SvPhoneInput.svelte +133 -133
- package/dist/SvPopover.svelte +197 -197
- package/dist/SvProgress.svelte +116 -116
- package/dist/SvRadioGroup.svelte +107 -107
- package/dist/SvRating.svelte +112 -112
- package/dist/SvResult.svelte +73 -73
- package/dist/SvRichText.svelte +211 -207
- package/dist/SvRowGroupPanel.svelte +170 -170
- package/dist/SvScrollArea.svelte +61 -61
- package/dist/SvSlider.svelte +200 -200
- package/dist/SvSwitchButton.svelte +108 -108
- package/dist/SvTagsInput.svelte +112 -112
- package/dist/SvTextInput.svelte +147 -147
- package/dist/SvTimePicker.svelte +245 -245
- package/dist/SvToaster.svelte +159 -159
- package/dist/SvToggleButton.svelte +85 -85
- package/dist/SvTooltip.svelte +161 -161
- package/dist/SvTour.svelte +208 -204
- package/dist/SvTree.svelte +444 -444
- package/dist/SvTreeSelect.svelte +235 -237
- package/dist/cdn/{GridMenus-C6ixSGWW.js → GridMenus-BpVcKyUr.js} +5 -7
- package/dist/cdn/{GridMenus-Cyk3qpJ7.js → GridMenus-CeXL5IW4.js} +153 -152
- package/dist/cdn/{SvDateTimePicker-ClqtVIj3.js → SvDateTimePicker-DSUhIta8.js} +165 -165
- package/dist/cdn/{SvDateTimePicker-CdqaP61H.js → SvDateTimePicker-h9kPyszT.js} +572 -555
- package/dist/cdn/{SvGridChart-BcLCYvw9.js → SvGridChart-Bs2GIR2Q.js} +28 -21
- package/dist/cdn/{SvGridChart-BhnFdLd0.js → SvGridChart-CwhFz7GV.js} +2 -2
- package/dist/cdn/{SvGridChartPanel-Cmx9DHAS.js → SvGridChartPanel-1WXuStzM.js} +2 -2
- package/dist/cdn/{SvGridChartPanel-DvjwxLvK.js → SvGridChartPanel-e5_nqNP9.js} +22 -14
- package/dist/cdn/{SvGridChartView-PwqI4s02.js → SvGridChartView-SmPW10dI.js} +3 -3
- package/dist/cdn/{SvGridChartView-B40DTJSX.js → SvGridChartView-eSPuJE6g.js} +2 -2
- package/dist/cdn/{SvGridDropdown-D0VdjeR8.js → SvGridDropdown-B1ZcLpgs.js} +1 -1
- package/dist/cdn/{SvGridDropdown-Dh-2ej8j.js → SvGridDropdown-CtdbHcIS.js} +6 -5
- package/dist/cdn/{chart-T1usDN0o.js → chart-i4XcXyHJ.js} +12 -10
- package/dist/cdn/disclose-version-Dr7rEVv-.js +2866 -0
- package/dist/cdn/{export-format-JT5pWVT8.js → export-format-Cv1Dll6k.js} +66 -245
- package/dist/cdn/{src-CgD-wiuS.js → src-DbeN1ReZ.js} +9223 -8944
- package/dist/cdn/{src-BgHjWF0Q.js → src-DmEQFW5_.js} +9023 -8828
- package/dist/cdn/svgrid.js +9 -9
- package/dist/cdn/svgrid.svelte-external.js +9 -9
- package/dist/chart-export.js +8 -8
- package/dist/chart.d.ts +2 -0
- package/dist/chart.js +1 -4
- package/dist/columns.js +9 -2
- package/dist/createMenu.svelte.js +0 -1
- package/dist/createPopoverSelect.svelte.d.ts +2 -2
- package/dist/editing.js +1 -1
- package/dist/export-format.js +3 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/_svelte_metadata.json +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/_metadata.json +178 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/attachments-qzRy9DX4.js +3843 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/attachments-qzRy9DX4.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/constants-RLNOXCpz.js +23 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/constants-RLNOXCpz.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/dev-DPd12uEU.js +1925 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/dev-DPd12uEU.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/events-CDC4DKuQ.js +206 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/events-CDC4DKuQ.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/flags-BD-lYX7s.js +20 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/flags-BD-lYX7s.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/hydration-D3UBU2t8.js +264 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/hydration-D3UBU2t8.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/legacy-client-B0ZUlbSQ.js +698 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/legacy-client-B0ZUlbSQ.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/package.json +3 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte.js +135 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_animate.js +57 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_animate.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_attachments.js +2 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_compiler.js +46691 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_compiler.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_easing.js +239 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_easing.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_events.js +2 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal.js +6 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_client.js +7 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_disclose-version.js +6 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_disclose-version.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_async.js +7 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_async.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_legacy.js +7 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_legacy.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_tracing.js +7 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_tracing.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_server.js +6 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_legacy.js +85 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_legacy.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_motion.js +561 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_motion.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity.js +26 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity_window.js +124 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity_window.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_server.js +2 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_store.js +91 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_store.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_transition.js +242 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_transition.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-lObbumRX.js +497 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-lObbumRX.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-mR9mAWyK.js +4929 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-mR9mAWyK.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/validate-CezNmRkM.js +192 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/validate-CezNmRkM.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/version-BHHo0WE-.js +10 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/version-BHHo0WE-.js.map +1 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/warnings-yiExAB06.js +140 -0
- package/dist/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/warnings-yiExAB06.js.map +1 -0
- package/dist/selection.js +0 -1
- package/package.json +11 -10
- package/src/DockNodeView.svelte +1 -1
- package/src/FlexRender.svelte +96 -96
- package/src/GridFooter.svelte +178 -179
- package/src/GridMenus.svelte +705 -782
- package/src/SvAutoComplete.svelte +165 -165
- package/src/SvAvatar.svelte +75 -75
- package/src/SvCalendar.svelte +503 -503
- package/src/SvCalendar.test.ts +226 -226
- package/src/SvCarousel.svelte +141 -141
- package/src/SvCheckBox.svelte +102 -102
- package/src/SvCircularProgress.svelte +109 -109
- package/src/SvColorInput.svelte +181 -181
- package/src/SvComboBox.svelte +275 -275
- package/src/SvContextMenu.svelte +116 -116
- package/src/SvCountryInput.svelte +160 -160
- package/src/SvDateRangeInput.svelte +1 -1
- package/src/SvDrawer.svelte +254 -254
- package/src/SvDropDownList.svelte +374 -374
- package/src/SvDurationInput.svelte +126 -126
- package/src/SvField.svelte +293 -293
- package/src/SvForm.svelte +437 -437
- package/src/SvForm.test.ts +411 -411
- package/src/SvGrid.controller.svelte.ts +3680 -3685
- package/src/SvGrid.css +2814 -2804
- package/src/SvGrid.svelte +3490 -3513
- package/src/SvGrid.types.ts +1708 -1709
- package/src/SvGridChart.svelte +1716 -1724
- package/src/SvGridChartPanel.svelte +485 -485
- package/src/SvGridChartView.svelte +70 -70
- package/src/SvGridDropdown.svelte +728 -728
- package/src/SvGridSelect.svelte +266 -268
- package/src/SvGroupCell.svelte +116 -116
- package/src/SvKbd.svelte +1 -1
- package/src/SvList.svelte +1 -1
- package/src/SvListBox.svelte +326 -326
- package/src/SvMaskedInput.svelte +122 -122
- package/src/SvMenu.svelte +124 -124
- package/src/SvMenu.test.ts +97 -97
- package/src/SvMenuList.svelte +146 -146
- package/src/SvMenubar.svelte +1 -1
- package/src/SvMultiSelect.svelte +289 -290
- package/src/SvNumberInput.svelte +168 -168
- package/src/SvOtpInput.svelte +158 -158
- package/src/SvPasswordInput.svelte +151 -151
- package/src/SvPhoneInput.svelte +133 -133
- package/src/SvPopover.svelte +197 -197
- package/src/SvProgress.svelte +116 -116
- package/src/SvRadioGroup.svelte +107 -107
- package/src/SvRating.svelte +112 -112
- package/src/SvResult.svelte +73 -73
- package/src/SvRichText.svelte +211 -207
- package/src/SvRowGroupPanel.svelte +170 -170
- package/src/SvScrollArea.svelte +61 -61
- package/src/SvSlider.svelte +200 -200
- package/src/SvSwitchButton.svelte +108 -108
- package/src/SvTagsInput.svelte +112 -112
- package/src/SvTextInput.svelte +147 -147
- package/src/SvTimePicker.svelte +245 -245
- package/src/SvToaster.svelte +159 -159
- package/src/SvToaster.test.ts +95 -95
- package/src/SvToggleButton.svelte +85 -85
- package/src/SvTooltip.svelte +161 -161
- package/src/SvTour.svelte +208 -204
- package/src/SvTree.svelte +444 -444
- package/src/SvTreeSelect.svelte +235 -237
- package/src/a11y/dismissable.test.ts +119 -119
- package/src/a11y/dismissable.ts +114 -114
- package/src/a11y.contract.test.ts +49 -49
- package/src/a11y.test.ts +59 -59
- package/src/a11y.ts +61 -61
- package/src/ai.test.ts +502 -502
- package/src/ai.ts +1391 -1391
- package/src/build-api.coverage.test.ts +633 -633
- package/src/build-api.ts +805 -910
- package/src/builtin-editors.grid.test.ts +85 -85
- package/src/cell-formatting.test.ts +1 -1
- package/src/cell-formatting.ts +169 -169
- package/src/cell-render.test.ts +513 -513
- package/src/cell-render.ts +496 -590
- package/src/cell-values.ts +118 -118
- package/src/chart-export.ts +201 -201
- package/src/chart-view.svelte.ts +36 -36
- package/src/chart.ts +2295 -2296
- package/src/clipboard.ts +0 -102
- package/src/collaboration.test.ts +104 -104
- package/src/collaboration.ts +167 -167
- package/src/columns.ts +7 -117
- package/src/core.performance.test.ts +30 -30
- package/src/core.ts +1261 -1261
- package/src/createAutocomplete.svelte.ts +132 -132
- package/src/createCombobox.svelte.ts +191 -191
- package/src/createCountryInput.svelte.ts +157 -157
- package/src/createDropdownList.svelte.ts +168 -168
- package/src/createForm.svelte.ts +386 -386
- 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 +250 -250
- package/src/createMenu.svelte.ts +224 -225
- package/src/createPopoverSelect.svelte.ts +213 -213
- package/src/createSlider.svelte.ts +191 -191
- package/src/createTooltip.svelte.ts +144 -144
- package/src/createTree.svelte.ts +319 -319
- package/src/editing.test.ts +949 -949
- package/src/editing.ts +606 -709
- package/src/editor-contract.ts +164 -164
- package/src/editor-registry.grid.test.ts +144 -146
- package/src/editor-registry.ts +122 -122
- package/src/export-data-api.test.ts +126 -126
- package/src/export-format.test.ts +107 -107
- package/src/export-format.ts +601 -598
- package/src/features.ts +0 -90
- package/src/filter-operators.ts +157 -157
- package/src/flex-render.ts +3 -3
- package/src/form-field.ts +127 -127
- package/src/group-display.test.ts +167 -167
- package/src/group-display.ts +200 -200
- package/src/index.ts +724 -724
- package/src/js-scroller.svelte.ts +173 -173
- package/src/keyboard-handlers.coverage.test.ts +1 -1
- package/src/keyboard-handlers.ts +270 -390
- package/src/keyboard.test.ts +59 -59
- package/src/keyboard.ts +97 -97
- package/src/list-nav.test.ts +49 -49
- package/src/list-nav.ts +29 -29
- package/src/list-option.test.ts +56 -56
- package/src/list-option.ts +172 -172
- package/src/menus.test.ts +0 -1
- package/src/menus.ts +567 -679
- package/src/merge-objects.ts +48 -48
- package/src/new-features.test.ts +3 -1
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/_svelte_metadata.json +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/_metadata.json +178 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/attachments-qzRy9DX4.js +3843 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/attachments-qzRy9DX4.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/constants-RLNOXCpz.js +23 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/constants-RLNOXCpz.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/dev-DPd12uEU.js +1925 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/dev-DPd12uEU.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/events-CDC4DKuQ.js +206 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/events-CDC4DKuQ.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/flags-BD-lYX7s.js +20 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/flags-BD-lYX7s.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/hydration-D3UBU2t8.js +264 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/hydration-D3UBU2t8.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/legacy-client-B0ZUlbSQ.js +698 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/legacy-client-B0ZUlbSQ.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/package.json +3 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte.js +135 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_animate.js +57 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_animate.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_attachments.js +2 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_compiler.js +46691 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_compiler.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_easing.js +239 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_easing.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_events.js +2 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal.js +6 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_client.js +7 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_disclose-version.js +6 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_disclose-version.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_async.js +7 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_async.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_legacy.js +7 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_legacy.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_tracing.js +7 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_flags_tracing.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_internal_server.js +6 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_legacy.js +85 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_legacy.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_motion.js +561 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_motion.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity.js +26 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity_window.js +124 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_reactivity_window.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_server.js +2 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_store.js +91 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_store.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_transition.js +242 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/svelte_transition.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-lObbumRX.js +497 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-lObbumRX.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-mR9mAWyK.js +4929 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/utils-mR9mAWyK.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/validate-CezNmRkM.js +192 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/validate-CezNmRkM.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/version-BHHo0WE-.js +10 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/version-BHHo0WE-.js.map +1 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/warnings-yiExAB06.js +140 -0
- package/src/node_modules/.vite/vitest/67d8ed22ed986c5e2e948f64d892f30be166cc36/deps___vitest__/warnings-yiExAB06.js.map +1 -0
- package/src/overlays.test.ts +90 -90
- package/src/render-component.ts +28 -28
- package/src/row-drag.test.ts +1 -1
- package/src/row-resize.test.ts +1 -2
- package/src/row-resize.ts +210 -210
- package/src/scheduler-model.test.ts +562 -562
- package/src/scheduler-model.ts +872 -872
- package/src/scroll-sync.test.ts +4 -7
- package/src/scroll-sync.ts +0 -122
- package/src/selection.test.ts +754 -754
- package/src/selection.ts +491 -600
- package/src/server-data-source.test.ts +289 -289
- package/src/server-data-source.ts +413 -413
- package/src/server-group-model.test.ts +2 -2
- package/src/sparkline.test.ts +68 -68
- package/src/sparkline.ts +169 -169
- package/src/spreadsheet.test.ts +488 -488
- package/src/spreadsheet.ts +312 -312
- package/src/static-functions.ts +11 -11
- package/src/subscribe.ts +38 -38
- package/src/summaries.ts +0 -112
- package/src/svgrid-wrapper.types.ts +526 -526
- package/src/svgrid.async-editor-options.test.ts +271 -271
- package/src/svgrid.auto-row-height.test.ts +204 -204
- package/src/svgrid.behavior.test.ts +705 -706
- package/src/svgrid.charting.test.ts +534 -534
- package/src/svgrid.column-reorder.test.ts +0 -8
- package/src/svgrid.comments-autocomplete.test.ts +123 -123
- package/src/svgrid.context-menu.test.ts +147 -147
- package/src/svgrid.features.test.ts +157 -157
- package/src/svgrid.filter-depth.test.ts +163 -163
- package/src/svgrid.filter-menu-listbox.svelte.test.ts +322 -322
- package/src/svgrid.filter-menu-scroll.test.ts +112 -112
- package/src/svgrid.footer-pagesize.svelte.test.ts +86 -0
- package/src/svgrid.grand-total.test.ts +188 -188
- package/src/svgrid.group-display-mode.test.ts +171 -171
- package/src/svgrid.group-footers.test.ts +121 -121
- package/src/svgrid.group-pagination.test.ts +153 -153
- package/src/svgrid.new-features.wrapper.test.ts +251 -251
- package/src/svgrid.tree-data.test.ts +186 -186
- package/src/svgrid.wrapper.test.ts +40 -40
- package/src/svgriddropdown.async-panel.svelte.test.ts +195 -195
- package/src/test-setup.ts +62 -62
- package/src/themes/index.ts +257 -257
- package/src/toast-store.svelte.ts +246 -246
- package/src/toast-store.test.ts +147 -147
- package/src/tree-row-model.test.ts +168 -169
- package/src/ui-buttons.test.ts +144 -144
- package/src/ui-inputs.test.ts +118 -118
- package/src/ui-localization.test.ts +113 -113
- package/src/ui-range.test.ts +70 -70
- package/src/ui-selection.test.ts +155 -155
- package/src/ui-tier1.test.ts +142 -142
- package/src/virtual.test.ts +88 -88
- 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/cdn/disclose-version-DoD9AFD_.js +0 -2958
|
@@ -1,271 +1,271 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Async `editorOptions` (#18): an option list that arrives from the server.
|
|
3
|
-
*
|
|
4
|
-
* Render paths call the option resolver synchronously and often, so an async
|
|
5
|
-
* source cannot block. The first call starts the fetch and returns an empty
|
|
6
|
-
* list; the resolved value lands in reactive state and re-renders the open
|
|
7
|
-
* editor. In-flight keys are tracked so repeated renders do not refire the
|
|
8
|
-
* request, and so the dropdown can say "Loading…" rather than "No options",
|
|
9
|
-
* which would read as "nothing to pick".
|
|
10
|
-
*/
|
|
11
|
-
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
12
|
-
import { mount, unmount } from 'svelte'
|
|
13
|
-
import SvGrid from './SvGrid.svelte'
|
|
14
|
-
import {
|
|
15
|
-
createCoreRowModel,
|
|
16
|
-
createFilteredRowModel,
|
|
17
|
-
createPaginatedRowModel,
|
|
18
|
-
createSortedRowModel,
|
|
19
|
-
sortFns,
|
|
20
|
-
tableFeatures,
|
|
21
|
-
rowSortingFeature,
|
|
22
|
-
} from './index'
|
|
23
|
-
|
|
24
|
-
type Row = { id: number; country: string; city: string }
|
|
25
|
-
|
|
26
|
-
const data: Row[] = [
|
|
27
|
-
{ id: 1, country: 'FR', city: 'Paris' },
|
|
28
|
-
{ id: 2, country: 'JP', city: 'Osaka' },
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
const tick = () => new Promise<void>((r) => queueMicrotask(r))
|
|
32
|
-
// The list editors lazy-load `SvGridDropdown` with a dynamic import, so
|
|
33
|
-
// microtasks alone never get it mounted - the settle has to yield the macrotask
|
|
34
|
-
// queue too, and then again for the resolved options to re-render.
|
|
35
|
-
const settle = async () => {
|
|
36
|
-
for (let i = 0; i < 4; i += 1) {
|
|
37
|
-
await new Promise((r) => setTimeout(r, 0))
|
|
38
|
-
await tick()
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function mountGrid(columns: unknown[]) {
|
|
43
|
-
const target = document.createElement('div')
|
|
44
|
-
document.body.appendChild(target)
|
|
45
|
-
let api: never = null as never
|
|
46
|
-
const app = mount(SvGrid, {
|
|
47
|
-
target,
|
|
48
|
-
props: {
|
|
49
|
-
data,
|
|
50
|
-
columns,
|
|
51
|
-
features: tableFeatures({ rowSortingFeature }),
|
|
52
|
-
editable: true,
|
|
53
|
-
onApiReady: (a: never) => { api = a },
|
|
54
|
-
_rowModels: {
|
|
55
|
-
coreRowModel: createCoreRowModel(),
|
|
56
|
-
filteredRowModel: createFilteredRowModel(),
|
|
57
|
-
sortedRowModel: createSortedRowModel(sortFns),
|
|
58
|
-
paginatedRowModel: createPaginatedRowModel(),
|
|
59
|
-
},
|
|
60
|
-
containerHeight: 400,
|
|
61
|
-
virtualization: false,
|
|
62
|
-
} as never,
|
|
63
|
-
})
|
|
64
|
-
return { target, getApi: () => api, destroy: () => { unmount(app); target.remove() } }
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
let cleanup: (() => void) | null = null
|
|
68
|
-
afterEach(() => { cleanup?.(); cleanup = null })
|
|
69
|
-
|
|
70
|
-
/** Open the editor for row 0 of `columnId` through the public api. */
|
|
71
|
-
async function openEditor(api: never, columnId: string) {
|
|
72
|
-
;(api as never as { startEditing: (r: number, c: string) => boolean }).startEditing(0, columnId)
|
|
73
|
-
await settle()
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
describe('async editorOptions (#18)', () => {
|
|
77
|
-
it('resolves a promised option list and renders it', async () => {
|
|
78
|
-
const columns = [
|
|
79
|
-
{ field: 'country', header: 'Country', width: 120 },
|
|
80
|
-
{
|
|
81
|
-
field: 'city',
|
|
82
|
-
header: 'City',
|
|
83
|
-
width: 160,
|
|
84
|
-
editorType: 'select',
|
|
85
|
-
editorOptions: Promise.resolve(['Paris', 'Lyon', 'Osaka']),
|
|
86
|
-
},
|
|
87
|
-
]
|
|
88
|
-
const g = mountGrid(columns)
|
|
89
|
-
cleanup = g.destroy
|
|
90
|
-
await settle()
|
|
91
|
-
await openEditor(g.getApi(), 'city')
|
|
92
|
-
expect(document.body.textContent).toContain('Lyon')
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
it('fetches once no matter how many times render asks', async () => {
|
|
96
|
-
const source = vi.fn(async () => ['a', 'b'])
|
|
97
|
-
const columns = [
|
|
98
|
-
{ field: 'country', header: 'Country', width: 120 },
|
|
99
|
-
{
|
|
100
|
-
field: 'city',
|
|
101
|
-
header: 'City',
|
|
102
|
-
width: 160,
|
|
103
|
-
editorType: 'select',
|
|
104
|
-
editorOptions: source(),
|
|
105
|
-
},
|
|
106
|
-
]
|
|
107
|
-
const g = mountGrid(columns)
|
|
108
|
-
cleanup = g.destroy
|
|
109
|
-
await settle()
|
|
110
|
-
await openEditor(g.getApi(), 'city')
|
|
111
|
-
await settle()
|
|
112
|
-
// The promise was created once; the resolver must not re-await per render.
|
|
113
|
-
expect(source).toHaveBeenCalledTimes(1)
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
it('calls a per-row async source ONCE per row, not once per render', async () => {
|
|
117
|
-
// The resolver runs inside the template, so calling an async source on
|
|
118
|
-
// every render fires a real request per render - and any state the source
|
|
119
|
-
// touches gets mutated mid-render, which Svelte rejects outright. Reported
|
|
120
|
-
// from the demo as `state_unsafe_mutation`.
|
|
121
|
-
const calls: number[] = []
|
|
122
|
-
const columns = [
|
|
123
|
-
{ field: 'country', header: 'Country', width: 120 },
|
|
124
|
-
{
|
|
125
|
-
field: 'city',
|
|
126
|
-
header: 'City',
|
|
127
|
-
width: 160,
|
|
128
|
-
editorType: 'select',
|
|
129
|
-
editorOptions: (row: Row) => {
|
|
130
|
-
calls.push(row.id)
|
|
131
|
-
return Promise.resolve(['Paris', 'Lyon'])
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
]
|
|
135
|
-
const g = mountGrid(columns)
|
|
136
|
-
cleanup = g.destroy
|
|
137
|
-
await settle()
|
|
138
|
-
await openEditor(g.getApi(), 'city')
|
|
139
|
-
await settle()
|
|
140
|
-
const afterOpen = calls.length
|
|
141
|
-
expect(afterOpen).toBeGreaterThan(0)
|
|
142
|
-
// Force real re-render passes while the editor is open. Each one used to
|
|
143
|
-
// re-invoke the source and start another request, which in a browser
|
|
144
|
-
// becomes an endless fetch loop as every resolution re-renders.
|
|
145
|
-
const api = g.getApi() as never as {
|
|
146
|
-
setOption: (k: string, v: unknown) => void
|
|
147
|
-
}
|
|
148
|
-
for (const zebra of [true, false, true]) {
|
|
149
|
-
api.setOption('zebraRows', zebra)
|
|
150
|
-
await settle()
|
|
151
|
-
}
|
|
152
|
-
expect(calls.length).toBe(afterOpen)
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
it('refetches a cascade when the row it depends on changes', async () => {
|
|
156
|
-
// A cascade is a function of the row's OTHER cells. Keying the cache by row
|
|
157
|
-
// id alone made the first result permanent - changing Country left the old
|
|
158
|
-
// city list in place forever.
|
|
159
|
-
const asked: string[] = []
|
|
160
|
-
const columns = [
|
|
161
|
-
{ field: 'country', header: 'Country', width: 120 },
|
|
162
|
-
{
|
|
163
|
-
field: 'city',
|
|
164
|
-
header: 'City',
|
|
165
|
-
width: 160,
|
|
166
|
-
editorType: 'select',
|
|
167
|
-
editorOptions: (row: Row) => {
|
|
168
|
-
asked.push(row.country)
|
|
169
|
-
return Promise.resolve(row.country === 'FR' ? ['Paris', 'Lyon'] : ['Osaka', 'Kyoto'])
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
]
|
|
173
|
-
const g = mountGrid(columns)
|
|
174
|
-
cleanup = g.destroy
|
|
175
|
-
await settle()
|
|
176
|
-
const api = g.getApi() as never as {
|
|
177
|
-
startEditing: (r: number, c: string) => boolean
|
|
178
|
-
stopEditing: (cancel?: boolean) => boolean
|
|
179
|
-
setCellValue: (r: number, c: string, v: unknown) => void
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
await openEditor(api as never, 'city')
|
|
183
|
-
expect(document.body.textContent).toContain('Lyon')
|
|
184
|
-
api.stopEditing(true)
|
|
185
|
-
await settle()
|
|
186
|
-
|
|
187
|
-
// Row 0 moves from FR to JP.
|
|
188
|
-
api.setCellValue(0, 'country', 'JP')
|
|
189
|
-
await settle()
|
|
190
|
-
|
|
191
|
-
await openEditor(api as never, 'city')
|
|
192
|
-
expect(asked).toContain('JP')
|
|
193
|
-
expect(document.body.textContent).toContain('Kyoto')
|
|
194
|
-
expect(document.body.textContent).not.toContain('Lyon')
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
it('resolves a per-row (cascading) async source', async () => {
|
|
198
|
-
const columns = [
|
|
199
|
-
{ field: 'country', header: 'Country', width: 120 },
|
|
200
|
-
{
|
|
201
|
-
field: 'city',
|
|
202
|
-
header: 'City',
|
|
203
|
-
width: 160,
|
|
204
|
-
editorType: 'select',
|
|
205
|
-
editorOptions: (row: Row) =>
|
|
206
|
-
Promise.resolve(row.country === 'FR' ? ['Paris', 'Lyon'] : ['Osaka', 'Kyoto']),
|
|
207
|
-
},
|
|
208
|
-
]
|
|
209
|
-
const g = mountGrid(columns)
|
|
210
|
-
cleanup = g.destroy
|
|
211
|
-
await settle()
|
|
212
|
-
await openEditor(g.getApi(), 'city')
|
|
213
|
-
// Row 1 is FR - it must not be offered the JP list.
|
|
214
|
-
expect(document.body.textContent).toContain('Lyon')
|
|
215
|
-
expect(document.body.textContent).not.toContain('Kyoto')
|
|
216
|
-
})
|
|
217
|
-
|
|
218
|
-
it('falls back to an empty list when the source rejects', async () => {
|
|
219
|
-
const rejected = Promise.reject(new Error('offline'))
|
|
220
|
-
rejected.catch(() => {}) // keep the reporter clean; the grid attaches its own handler
|
|
221
|
-
const columns = [
|
|
222
|
-
{ field: 'country', header: 'Country', width: 120 },
|
|
223
|
-
{
|
|
224
|
-
field: 'city',
|
|
225
|
-
header: 'City',
|
|
226
|
-
width: 160,
|
|
227
|
-
editorType: 'select',
|
|
228
|
-
editorOptions: rejected,
|
|
229
|
-
},
|
|
230
|
-
]
|
|
231
|
-
const g = mountGrid(columns)
|
|
232
|
-
cleanup = g.destroy
|
|
233
|
-
await settle()
|
|
234
|
-
await openEditor(g.getApi(), 'city')
|
|
235
|
-
await settle()
|
|
236
|
-
// The editor must settle on "No options", never spin forever.
|
|
237
|
-
expect(document.body.textContent).toContain('No options')
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
it('exposes refreshEditorOptions on the api', async () => {
|
|
241
|
-
const columns = [
|
|
242
|
-
{ field: 'country', header: 'Country', width: 120 },
|
|
243
|
-
{ field: 'city', header: 'City', width: 160 },
|
|
244
|
-
]
|
|
245
|
-
const g = mountGrid(columns)
|
|
246
|
-
cleanup = g.destroy
|
|
247
|
-
await settle()
|
|
248
|
-
const api = g.getApi() as never as { refreshEditorOptions: (c?: string) => void }
|
|
249
|
-
expect(typeof api.refreshEditorOptions).toBe('function')
|
|
250
|
-
expect(() => api.refreshEditorOptions('city')).not.toThrow()
|
|
251
|
-
expect(() => api.refreshEditorOptions()).not.toThrow()
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
it('leaves a plain array source synchronous', async () => {
|
|
255
|
-
const columns = [
|
|
256
|
-
{ field: 'country', header: 'Country', width: 120 },
|
|
257
|
-
{
|
|
258
|
-
field: 'city',
|
|
259
|
-
header: 'City',
|
|
260
|
-
width: 160,
|
|
261
|
-
editorType: 'select',
|
|
262
|
-
editorOptions: ['Paris', 'Lyon'],
|
|
263
|
-
},
|
|
264
|
-
]
|
|
265
|
-
const g = mountGrid(columns)
|
|
266
|
-
cleanup = g.destroy
|
|
267
|
-
await settle()
|
|
268
|
-
await openEditor(g.getApi(), 'city')
|
|
269
|
-
expect(document.body.textContent).toContain('Lyon')
|
|
270
|
-
})
|
|
271
|
-
})
|
|
1
|
+
/**
|
|
2
|
+
* Async `editorOptions` (#18): an option list that arrives from the server.
|
|
3
|
+
*
|
|
4
|
+
* Render paths call the option resolver synchronously and often, so an async
|
|
5
|
+
* source cannot block. The first call starts the fetch and returns an empty
|
|
6
|
+
* list; the resolved value lands in reactive state and re-renders the open
|
|
7
|
+
* editor. In-flight keys are tracked so repeated renders do not refire the
|
|
8
|
+
* request, and so the dropdown can say "Loading…" rather than "No options",
|
|
9
|
+
* which would read as "nothing to pick".
|
|
10
|
+
*/
|
|
11
|
+
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
12
|
+
import { mount, unmount } from 'svelte'
|
|
13
|
+
import SvGrid from './SvGrid.svelte'
|
|
14
|
+
import {
|
|
15
|
+
createCoreRowModel,
|
|
16
|
+
createFilteredRowModel,
|
|
17
|
+
createPaginatedRowModel,
|
|
18
|
+
createSortedRowModel,
|
|
19
|
+
sortFns,
|
|
20
|
+
tableFeatures,
|
|
21
|
+
rowSortingFeature,
|
|
22
|
+
} from './index'
|
|
23
|
+
|
|
24
|
+
type Row = { id: number; country: string; city: string }
|
|
25
|
+
|
|
26
|
+
const data: Row[] = [
|
|
27
|
+
{ id: 1, country: 'FR', city: 'Paris' },
|
|
28
|
+
{ id: 2, country: 'JP', city: 'Osaka' },
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
const tick = () => new Promise<void>((r) => queueMicrotask(r))
|
|
32
|
+
// The list editors lazy-load `SvGridDropdown` with a dynamic import, so
|
|
33
|
+
// microtasks alone never get it mounted - the settle has to yield the macrotask
|
|
34
|
+
// queue too, and then again for the resolved options to re-render.
|
|
35
|
+
const settle = async () => {
|
|
36
|
+
for (let i = 0; i < 4; i += 1) {
|
|
37
|
+
await new Promise((r) => setTimeout(r, 0))
|
|
38
|
+
await tick()
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function mountGrid(columns: unknown[]) {
|
|
43
|
+
const target = document.createElement('div')
|
|
44
|
+
document.body.appendChild(target)
|
|
45
|
+
let api: never = null as never
|
|
46
|
+
const app = mount(SvGrid, {
|
|
47
|
+
target,
|
|
48
|
+
props: {
|
|
49
|
+
data,
|
|
50
|
+
columns,
|
|
51
|
+
features: tableFeatures({ rowSortingFeature }),
|
|
52
|
+
editable: true,
|
|
53
|
+
onApiReady: (a: never) => { api = a },
|
|
54
|
+
_rowModels: {
|
|
55
|
+
coreRowModel: createCoreRowModel(),
|
|
56
|
+
filteredRowModel: createFilteredRowModel(),
|
|
57
|
+
sortedRowModel: createSortedRowModel(sortFns),
|
|
58
|
+
paginatedRowModel: createPaginatedRowModel(),
|
|
59
|
+
},
|
|
60
|
+
containerHeight: 400,
|
|
61
|
+
virtualization: false,
|
|
62
|
+
} as never,
|
|
63
|
+
})
|
|
64
|
+
return { target, getApi: () => api, destroy: () => { unmount(app); target.remove() } }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let cleanup: (() => void) | null = null
|
|
68
|
+
afterEach(() => { cleanup?.(); cleanup = null })
|
|
69
|
+
|
|
70
|
+
/** Open the editor for row 0 of `columnId` through the public api. */
|
|
71
|
+
async function openEditor(api: never, columnId: string) {
|
|
72
|
+
;(api as never as { startEditing: (r: number, c: string) => boolean }).startEditing(0, columnId)
|
|
73
|
+
await settle()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
describe('async editorOptions (#18)', () => {
|
|
77
|
+
it('resolves a promised option list and renders it', async () => {
|
|
78
|
+
const columns = [
|
|
79
|
+
{ field: 'country', header: 'Country', width: 120 },
|
|
80
|
+
{
|
|
81
|
+
field: 'city',
|
|
82
|
+
header: 'City',
|
|
83
|
+
width: 160,
|
|
84
|
+
editorType: 'select',
|
|
85
|
+
editorOptions: Promise.resolve(['Paris', 'Lyon', 'Osaka']),
|
|
86
|
+
},
|
|
87
|
+
]
|
|
88
|
+
const g = mountGrid(columns)
|
|
89
|
+
cleanup = g.destroy
|
|
90
|
+
await settle()
|
|
91
|
+
await openEditor(g.getApi(), 'city')
|
|
92
|
+
expect(document.body.textContent).toContain('Lyon')
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('fetches once no matter how many times render asks', async () => {
|
|
96
|
+
const source = vi.fn(async () => ['a', 'b'])
|
|
97
|
+
const columns = [
|
|
98
|
+
{ field: 'country', header: 'Country', width: 120 },
|
|
99
|
+
{
|
|
100
|
+
field: 'city',
|
|
101
|
+
header: 'City',
|
|
102
|
+
width: 160,
|
|
103
|
+
editorType: 'select',
|
|
104
|
+
editorOptions: source(),
|
|
105
|
+
},
|
|
106
|
+
]
|
|
107
|
+
const g = mountGrid(columns)
|
|
108
|
+
cleanup = g.destroy
|
|
109
|
+
await settle()
|
|
110
|
+
await openEditor(g.getApi(), 'city')
|
|
111
|
+
await settle()
|
|
112
|
+
// The promise was created once; the resolver must not re-await per render.
|
|
113
|
+
expect(source).toHaveBeenCalledTimes(1)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('calls a per-row async source ONCE per row, not once per render', async () => {
|
|
117
|
+
// The resolver runs inside the template, so calling an async source on
|
|
118
|
+
// every render fires a real request per render - and any state the source
|
|
119
|
+
// touches gets mutated mid-render, which Svelte rejects outright. Reported
|
|
120
|
+
// from the demo as `state_unsafe_mutation`.
|
|
121
|
+
const calls: number[] = []
|
|
122
|
+
const columns = [
|
|
123
|
+
{ field: 'country', header: 'Country', width: 120 },
|
|
124
|
+
{
|
|
125
|
+
field: 'city',
|
|
126
|
+
header: 'City',
|
|
127
|
+
width: 160,
|
|
128
|
+
editorType: 'select',
|
|
129
|
+
editorOptions: (row: Row) => {
|
|
130
|
+
calls.push(row.id)
|
|
131
|
+
return Promise.resolve(['Paris', 'Lyon'])
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
]
|
|
135
|
+
const g = mountGrid(columns)
|
|
136
|
+
cleanup = g.destroy
|
|
137
|
+
await settle()
|
|
138
|
+
await openEditor(g.getApi(), 'city')
|
|
139
|
+
await settle()
|
|
140
|
+
const afterOpen = calls.length
|
|
141
|
+
expect(afterOpen).toBeGreaterThan(0)
|
|
142
|
+
// Force real re-render passes while the editor is open. Each one used to
|
|
143
|
+
// re-invoke the source and start another request, which in a browser
|
|
144
|
+
// becomes an endless fetch loop as every resolution re-renders.
|
|
145
|
+
const api = g.getApi() as never as {
|
|
146
|
+
setOption: (k: string, v: unknown) => void
|
|
147
|
+
}
|
|
148
|
+
for (const zebra of [true, false, true]) {
|
|
149
|
+
api.setOption('zebraRows', zebra)
|
|
150
|
+
await settle()
|
|
151
|
+
}
|
|
152
|
+
expect(calls.length).toBe(afterOpen)
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
it('refetches a cascade when the row it depends on changes', async () => {
|
|
156
|
+
// A cascade is a function of the row's OTHER cells. Keying the cache by row
|
|
157
|
+
// id alone made the first result permanent - changing Country left the old
|
|
158
|
+
// city list in place forever.
|
|
159
|
+
const asked: string[] = []
|
|
160
|
+
const columns = [
|
|
161
|
+
{ field: 'country', header: 'Country', width: 120 },
|
|
162
|
+
{
|
|
163
|
+
field: 'city',
|
|
164
|
+
header: 'City',
|
|
165
|
+
width: 160,
|
|
166
|
+
editorType: 'select',
|
|
167
|
+
editorOptions: (row: Row) => {
|
|
168
|
+
asked.push(row.country)
|
|
169
|
+
return Promise.resolve(row.country === 'FR' ? ['Paris', 'Lyon'] : ['Osaka', 'Kyoto'])
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
]
|
|
173
|
+
const g = mountGrid(columns)
|
|
174
|
+
cleanup = g.destroy
|
|
175
|
+
await settle()
|
|
176
|
+
const api = g.getApi() as never as {
|
|
177
|
+
startEditing: (r: number, c: string) => boolean
|
|
178
|
+
stopEditing: (cancel?: boolean) => boolean
|
|
179
|
+
setCellValue: (r: number, c: string, v: unknown) => void
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
await openEditor(api as never, 'city')
|
|
183
|
+
expect(document.body.textContent).toContain('Lyon')
|
|
184
|
+
api.stopEditing(true)
|
|
185
|
+
await settle()
|
|
186
|
+
|
|
187
|
+
// Row 0 moves from FR to JP.
|
|
188
|
+
api.setCellValue(0, 'country', 'JP')
|
|
189
|
+
await settle()
|
|
190
|
+
|
|
191
|
+
await openEditor(api as never, 'city')
|
|
192
|
+
expect(asked).toContain('JP')
|
|
193
|
+
expect(document.body.textContent).toContain('Kyoto')
|
|
194
|
+
expect(document.body.textContent).not.toContain('Lyon')
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
it('resolves a per-row (cascading) async source', async () => {
|
|
198
|
+
const columns = [
|
|
199
|
+
{ field: 'country', header: 'Country', width: 120 },
|
|
200
|
+
{
|
|
201
|
+
field: 'city',
|
|
202
|
+
header: 'City',
|
|
203
|
+
width: 160,
|
|
204
|
+
editorType: 'select',
|
|
205
|
+
editorOptions: (row: Row) =>
|
|
206
|
+
Promise.resolve(row.country === 'FR' ? ['Paris', 'Lyon'] : ['Osaka', 'Kyoto']),
|
|
207
|
+
},
|
|
208
|
+
]
|
|
209
|
+
const g = mountGrid(columns)
|
|
210
|
+
cleanup = g.destroy
|
|
211
|
+
await settle()
|
|
212
|
+
await openEditor(g.getApi(), 'city')
|
|
213
|
+
// Row 1 is FR - it must not be offered the JP list.
|
|
214
|
+
expect(document.body.textContent).toContain('Lyon')
|
|
215
|
+
expect(document.body.textContent).not.toContain('Kyoto')
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
it('falls back to an empty list when the source rejects', async () => {
|
|
219
|
+
const rejected = Promise.reject(new Error('offline'))
|
|
220
|
+
rejected.catch(() => {}) // keep the reporter clean; the grid attaches its own handler
|
|
221
|
+
const columns = [
|
|
222
|
+
{ field: 'country', header: 'Country', width: 120 },
|
|
223
|
+
{
|
|
224
|
+
field: 'city',
|
|
225
|
+
header: 'City',
|
|
226
|
+
width: 160,
|
|
227
|
+
editorType: 'select',
|
|
228
|
+
editorOptions: rejected,
|
|
229
|
+
},
|
|
230
|
+
]
|
|
231
|
+
const g = mountGrid(columns)
|
|
232
|
+
cleanup = g.destroy
|
|
233
|
+
await settle()
|
|
234
|
+
await openEditor(g.getApi(), 'city')
|
|
235
|
+
await settle()
|
|
236
|
+
// The editor must settle on "No options", never spin forever.
|
|
237
|
+
expect(document.body.textContent).toContain('No options')
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
it('exposes refreshEditorOptions on the api', async () => {
|
|
241
|
+
const columns = [
|
|
242
|
+
{ field: 'country', header: 'Country', width: 120 },
|
|
243
|
+
{ field: 'city', header: 'City', width: 160 },
|
|
244
|
+
]
|
|
245
|
+
const g = mountGrid(columns)
|
|
246
|
+
cleanup = g.destroy
|
|
247
|
+
await settle()
|
|
248
|
+
const api = g.getApi() as never as { refreshEditorOptions: (c?: string) => void }
|
|
249
|
+
expect(typeof api.refreshEditorOptions).toBe('function')
|
|
250
|
+
expect(() => api.refreshEditorOptions('city')).not.toThrow()
|
|
251
|
+
expect(() => api.refreshEditorOptions()).not.toThrow()
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
it('leaves a plain array source synchronous', async () => {
|
|
255
|
+
const columns = [
|
|
256
|
+
{ field: 'country', header: 'Country', width: 120 },
|
|
257
|
+
{
|
|
258
|
+
field: 'city',
|
|
259
|
+
header: 'City',
|
|
260
|
+
width: 160,
|
|
261
|
+
editorType: 'select',
|
|
262
|
+
editorOptions: ['Paris', 'Lyon'],
|
|
263
|
+
},
|
|
264
|
+
]
|
|
265
|
+
const g = mountGrid(columns)
|
|
266
|
+
cleanup = g.destroy
|
|
267
|
+
await settle()
|
|
268
|
+
await openEditor(g.getApi(), 'city')
|
|
269
|
+
expect(document.body.textContent).toContain('Lyon')
|
|
270
|
+
})
|
|
271
|
+
})
|