@svgrid/grid 2.2.35 → 2.5.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/FlexRender.svelte +96 -96
- package/dist/GridFooter.svelte +178 -178
- package/dist/GridMenus.svelte +705 -705
- 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/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 -2814
- package/dist/SvGrid.svelte +3490 -3490
- package/dist/SvGridChart.svelte +1716 -1716
- package/dist/SvGridChartPanel.svelte +485 -485
- package/dist/SvGridChartView.svelte +70 -70
- package/dist/SvGridDropdown.svelte +728 -728
- package/dist/SvGridSelect.svelte +266 -266
- package/dist/SvGroupCell.svelte +116 -116
- 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/SvMultiSelect.svelte +289 -289
- 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 -211
- 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 -208
- package/dist/SvTree.svelte +444 -444
- package/dist/SvTreeSelect.svelte +235 -235
- package/dist/cdn/{GridMenus-oQYElQll.js → GridMenus-BpVcKyUr.js} +2 -2
- package/dist/cdn/{GridMenus-T-bZNprc.js → GridMenus-CeXL5IW4.js} +2 -2
- package/dist/cdn/{SvDateTimePicker-CHnUkWcH.js → SvDateTimePicker-DSUhIta8.js} +2 -2
- package/dist/cdn/{SvDateTimePicker-CRQH_U7E.js → SvDateTimePicker-h9kPyszT.js} +2 -2
- package/dist/cdn/{SvGridChart-BwVos976.js → SvGridChart-Bs2GIR2Q.js} +1 -1
- package/dist/cdn/{SvGridChart-BEJmNNx9.js → SvGridChart-CwhFz7GV.js} +1 -1
- package/dist/cdn/{SvGridChartPanel-BOknOkrP.js → SvGridChartPanel-1WXuStzM.js} +1 -1
- package/dist/cdn/{SvGridChartPanel-D2PjII4O.js → SvGridChartPanel-e5_nqNP9.js} +1 -1
- package/dist/cdn/{SvGridChartView-00LPUHL1.js → SvGridChartView-SmPW10dI.js} +1 -1
- package/dist/cdn/{SvGridChartView-BhUEJ5ki.js → SvGridChartView-eSPuJE6g.js} +1 -1
- package/dist/cdn/{SvGridDropdown-D0VdjeR8.js → SvGridDropdown-B1ZcLpgs.js} +1 -1
- package/dist/cdn/{SvGridDropdown-D13MtJ2j.js → SvGridDropdown-CtdbHcIS.js} +1 -1
- package/dist/cdn/{src-Cm7C_WOZ.js → src-DbeN1ReZ.js} +24 -24
- package/dist/cdn/{src-72QTH8lh.js → src-DmEQFW5_.js} +23 -23
- package/dist/cdn/svgrid.js +5 -5
- package/dist/cdn/svgrid.svelte-external.js +5 -5
- package/dist/chart-export.js +8 -8
- 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/themes/index.js +28 -9
- package/package.json +11 -11
- package/src/FlexRender.svelte +96 -96
- package/src/GridFooter.svelte +178 -178
- package/src/GridMenus.svelte +705 -705
- 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/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 -3680
- package/src/SvGrid.css +2814 -2814
- package/src/SvGrid.svelte +3490 -3490
- package/src/SvGrid.types.ts +1708 -1708
- package/src/SvGridChart.svelte +1716 -1716
- package/src/SvGridChartPanel.svelte +485 -485
- package/src/SvGridChartView.svelte +70 -70
- package/src/SvGridDropdown.svelte +728 -728
- package/src/SvGridSelect.svelte +266 -266
- package/src/SvGroupCell.svelte +116 -116
- 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/SvMultiSelect.svelte +289 -289
- 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 -211
- 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 -208
- package/src/SvTree.svelte +444 -444
- package/src/SvTreeSelect.svelte +235 -235
- 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 -805
- package/src/builtin-editors.grid.test.ts +85 -85
- package/src/cell-formatting.ts +169 -169
- package/src/cell-render.test.ts +513 -513
- package/src/cell-render.ts +496 -496
- 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 -2295
- package/src/collaboration.test.ts +104 -104
- package/src/collaboration.ts +167 -167
- 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 -224
- 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 -606
- package/src/editor-contract.ts +164 -164
- package/src/editor-registry.grid.test.ts +144 -144
- 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 -601
- 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.ts +270 -270
- 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.ts +567 -567
- package/src/merge-objects.ts +48 -48
- 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-resize.ts +210 -210
- package/src/scheduler-model.test.ts +562 -562
- package/src/scheduler-model.ts +872 -872
- package/src/selection.test.ts +754 -754
- package/src/selection.ts +491 -491
- package/src/server-data-source.test.ts +289 -289
- package/src/server-data-source.ts +413 -413
- 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/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 -705
- package/src/svgrid.charting.test.ts +534 -534
- 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 +331 -322
- package/src/svgrid.filter-menu-scroll.test.ts +112 -112
- 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 +278 -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 -168
- 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/themes/ag-alpine.css +2 -2
- package/themes/antd.css +4 -4
- package/themes/atlassian.css +1 -1
- package/themes/ember.css +2 -2
- package/themes/fluent.css +1 -1
- package/themes/github.css +1 -1
- package/themes/nord.css +2 -2
- package/themes/notion.css +2 -2
- package/themes/salesforce.css +1 -1
- package/themes/tailwind.css +1 -1
- package/themes/vercel.css +1 -1
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Filter menu + scroll. The funnel popover is position:fixed and anchored by a
|
|
3
|
-
* one-time measurement, so a scroll of the page/grid has to close it - but
|
|
4
|
-
* scrolling the popover's OWN body or its facet list must not, or the value
|
|
5
|
-
* list is unusable (reported on the 03-excel-filters demo).
|
|
6
|
-
*/
|
|
7
|
-
import { describe, expect, it, vi } from 'vitest'
|
|
8
|
-
import { mount, unmount } from 'svelte'
|
|
9
|
-
import SvGrid from './SvGrid.svelte'
|
|
10
|
-
import {
|
|
11
|
-
columnFilteringFeature,
|
|
12
|
-
createCoreRowModel,
|
|
13
|
-
createFilteredRowModel,
|
|
14
|
-
createSortedRowModel,
|
|
15
|
-
rowSortingFeature,
|
|
16
|
-
sortFns,
|
|
17
|
-
tableFeatures,
|
|
18
|
-
} from './index'
|
|
19
|
-
import type { ColumnDef, SvGridApi } from './index'
|
|
20
|
-
|
|
21
|
-
type Row = { id: number; name: string; team: string }
|
|
22
|
-
const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })
|
|
23
|
-
const rows: Row[] = Array.from({ length: 12 }, (_, i) => ({
|
|
24
|
-
id: i + 1,
|
|
25
|
-
name: `Person ${i + 1}`,
|
|
26
|
-
team: ['A', 'B', 'C'][i % 3]!,
|
|
27
|
-
}))
|
|
28
|
-
const cols: ColumnDef<typeof features, Row>[] = [
|
|
29
|
-
{ field: 'name', header: 'Name', width: 200, editorType: 'text' },
|
|
30
|
-
{ field: 'team', header: 'Team', width: 160, editorType: 'text' },
|
|
31
|
-
]
|
|
32
|
-
const tick = () => new Promise<void>((r) => setTimeout(r))
|
|
33
|
-
|
|
34
|
-
function mountGrid() {
|
|
35
|
-
return new Promise<{ target: HTMLElement; destroy: () => void }>((res, rej) => {
|
|
36
|
-
const target = document.createElement('div')
|
|
37
|
-
document.body.appendChild(target)
|
|
38
|
-
const app = mount(SvGrid, {
|
|
39
|
-
target,
|
|
40
|
-
props: {
|
|
41
|
-
data: rows,
|
|
42
|
-
columns: cols,
|
|
43
|
-
features,
|
|
44
|
-
_rowModels: {
|
|
45
|
-
coreRowModel: createCoreRowModel(),
|
|
46
|
-
filteredRowModel: createFilteredRowModel(),
|
|
47
|
-
sortedRowModel: createSortedRowModel(sortFns),
|
|
48
|
-
},
|
|
49
|
-
rowHeight: 32,
|
|
50
|
-
containerHeight: 400,
|
|
51
|
-
virtualization: false,
|
|
52
|
-
filterMode: 'menu',
|
|
53
|
-
showColumnFilters: true,
|
|
54
|
-
onApiReady(_api: SvGridApi<typeof features, Row>) {
|
|
55
|
-
res({ target, destroy: () => { unmount(app); target.remove() } })
|
|
56
|
-
},
|
|
57
|
-
} as any,
|
|
58
|
-
})
|
|
59
|
-
queueMicrotask(() => { if (!target.querySelector('[role="grid"]')) rej(new Error('no grid')) })
|
|
60
|
-
})
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async function openFilterMenu(target: HTMLElement) {
|
|
64
|
-
const btn = target.querySelector('.sv-grid-col-filter-btn') as HTMLButtonElement
|
|
65
|
-
expect(btn).not.toBeNull()
|
|
66
|
-
btn.click()
|
|
67
|
-
// GridMenus is a lazy chunk, so poll until the popover mounts AND its value
|
|
68
|
-
// checklist is in the DOM. Waiting only for the popover element returns while
|
|
69
|
-
// the menu body is still filling in, so a caller that reaches for
|
|
70
|
-
// `.sv-listbox` can get null - which is how this file flaked under
|
|
71
|
-
// full-suite parallel load.
|
|
72
|
-
await vi.waitFor(() => {
|
|
73
|
-
const menu = target.querySelector('.sv-grid-filter-menu')
|
|
74
|
-
expect(menu).not.toBeNull()
|
|
75
|
-
expect(menu!.querySelector('.sv-listbox')).not.toBeNull()
|
|
76
|
-
})
|
|
77
|
-
return target.querySelector('.sv-grid-filter-menu') as HTMLElement
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
describe('SvGrid filter menu scrolling', () => {
|
|
81
|
-
it('stays open while its own body / facet list is scrolled', async () => {
|
|
82
|
-
const { target, destroy } = await mountGrid()
|
|
83
|
-
await tick()
|
|
84
|
-
const menu = await openFilterMenu(target)
|
|
85
|
-
|
|
86
|
-
menu.dispatchEvent(new Event('scroll'))
|
|
87
|
-
await tick()
|
|
88
|
-
expect(target.querySelector('.sv-grid-filter-menu')).not.toBeNull()
|
|
89
|
-
|
|
90
|
-
// The value checklist is an SvListBox; under the virtualization threshold
|
|
91
|
-
// it scrolls natively, so it still emits the scroll that must be ignored.
|
|
92
|
-
const facets = menu.querySelector('.sv-listbox')
|
|
93
|
-
expect(facets).not.toBeNull()
|
|
94
|
-
facets!.dispatchEvent(new Event('scroll'))
|
|
95
|
-
await tick()
|
|
96
|
-
expect(target.querySelector('.sv-grid-filter-menu')).not.toBeNull()
|
|
97
|
-
|
|
98
|
-
destroy()
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
it('still closes when something outside it scrolls', async () => {
|
|
102
|
-
const { target, destroy } = await mountGrid()
|
|
103
|
-
await tick()
|
|
104
|
-
await openFilterMenu(target)
|
|
105
|
-
|
|
106
|
-
const viewport = target.querySelector('.sv-grid-viewport') ?? target
|
|
107
|
-
viewport.dispatchEvent(new Event('scroll'))
|
|
108
|
-
await vi.waitFor(() => expect(target.querySelector('.sv-grid-filter-menu')).toBeNull())
|
|
109
|
-
|
|
110
|
-
destroy()
|
|
111
|
-
})
|
|
112
|
-
})
|
|
1
|
+
/**
|
|
2
|
+
* Filter menu + scroll. The funnel popover is position:fixed and anchored by a
|
|
3
|
+
* one-time measurement, so a scroll of the page/grid has to close it - but
|
|
4
|
+
* scrolling the popover's OWN body or its facet list must not, or the value
|
|
5
|
+
* list is unusable (reported on the 03-excel-filters demo).
|
|
6
|
+
*/
|
|
7
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
8
|
+
import { mount, unmount } from 'svelte'
|
|
9
|
+
import SvGrid from './SvGrid.svelte'
|
|
10
|
+
import {
|
|
11
|
+
columnFilteringFeature,
|
|
12
|
+
createCoreRowModel,
|
|
13
|
+
createFilteredRowModel,
|
|
14
|
+
createSortedRowModel,
|
|
15
|
+
rowSortingFeature,
|
|
16
|
+
sortFns,
|
|
17
|
+
tableFeatures,
|
|
18
|
+
} from './index'
|
|
19
|
+
import type { ColumnDef, SvGridApi } from './index'
|
|
20
|
+
|
|
21
|
+
type Row = { id: number; name: string; team: string }
|
|
22
|
+
const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })
|
|
23
|
+
const rows: Row[] = Array.from({ length: 12 }, (_, i) => ({
|
|
24
|
+
id: i + 1,
|
|
25
|
+
name: `Person ${i + 1}`,
|
|
26
|
+
team: ['A', 'B', 'C'][i % 3]!,
|
|
27
|
+
}))
|
|
28
|
+
const cols: ColumnDef<typeof features, Row>[] = [
|
|
29
|
+
{ field: 'name', header: 'Name', width: 200, editorType: 'text' },
|
|
30
|
+
{ field: 'team', header: 'Team', width: 160, editorType: 'text' },
|
|
31
|
+
]
|
|
32
|
+
const tick = () => new Promise<void>((r) => setTimeout(r))
|
|
33
|
+
|
|
34
|
+
function mountGrid() {
|
|
35
|
+
return new Promise<{ target: HTMLElement; destroy: () => void }>((res, rej) => {
|
|
36
|
+
const target = document.createElement('div')
|
|
37
|
+
document.body.appendChild(target)
|
|
38
|
+
const app = mount(SvGrid, {
|
|
39
|
+
target,
|
|
40
|
+
props: {
|
|
41
|
+
data: rows,
|
|
42
|
+
columns: cols,
|
|
43
|
+
features,
|
|
44
|
+
_rowModels: {
|
|
45
|
+
coreRowModel: createCoreRowModel(),
|
|
46
|
+
filteredRowModel: createFilteredRowModel(),
|
|
47
|
+
sortedRowModel: createSortedRowModel(sortFns),
|
|
48
|
+
},
|
|
49
|
+
rowHeight: 32,
|
|
50
|
+
containerHeight: 400,
|
|
51
|
+
virtualization: false,
|
|
52
|
+
filterMode: 'menu',
|
|
53
|
+
showColumnFilters: true,
|
|
54
|
+
onApiReady(_api: SvGridApi<typeof features, Row>) {
|
|
55
|
+
res({ target, destroy: () => { unmount(app); target.remove() } })
|
|
56
|
+
},
|
|
57
|
+
} as any,
|
|
58
|
+
})
|
|
59
|
+
queueMicrotask(() => { if (!target.querySelector('[role="grid"]')) rej(new Error('no grid')) })
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function openFilterMenu(target: HTMLElement) {
|
|
64
|
+
const btn = target.querySelector('.sv-grid-col-filter-btn') as HTMLButtonElement
|
|
65
|
+
expect(btn).not.toBeNull()
|
|
66
|
+
btn.click()
|
|
67
|
+
// GridMenus is a lazy chunk, so poll until the popover mounts AND its value
|
|
68
|
+
// checklist is in the DOM. Waiting only for the popover element returns while
|
|
69
|
+
// the menu body is still filling in, so a caller that reaches for
|
|
70
|
+
// `.sv-listbox` can get null - which is how this file flaked under
|
|
71
|
+
// full-suite parallel load.
|
|
72
|
+
await vi.waitFor(() => {
|
|
73
|
+
const menu = target.querySelector('.sv-grid-filter-menu')
|
|
74
|
+
expect(menu).not.toBeNull()
|
|
75
|
+
expect(menu!.querySelector('.sv-listbox')).not.toBeNull()
|
|
76
|
+
})
|
|
77
|
+
return target.querySelector('.sv-grid-filter-menu') as HTMLElement
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
describe('SvGrid filter menu scrolling', () => {
|
|
81
|
+
it('stays open while its own body / facet list is scrolled', async () => {
|
|
82
|
+
const { target, destroy } = await mountGrid()
|
|
83
|
+
await tick()
|
|
84
|
+
const menu = await openFilterMenu(target)
|
|
85
|
+
|
|
86
|
+
menu.dispatchEvent(new Event('scroll'))
|
|
87
|
+
await tick()
|
|
88
|
+
expect(target.querySelector('.sv-grid-filter-menu')).not.toBeNull()
|
|
89
|
+
|
|
90
|
+
// The value checklist is an SvListBox; under the virtualization threshold
|
|
91
|
+
// it scrolls natively, so it still emits the scroll that must be ignored.
|
|
92
|
+
const facets = menu.querySelector('.sv-listbox')
|
|
93
|
+
expect(facets).not.toBeNull()
|
|
94
|
+
facets!.dispatchEvent(new Event('scroll'))
|
|
95
|
+
await tick()
|
|
96
|
+
expect(target.querySelector('.sv-grid-filter-menu')).not.toBeNull()
|
|
97
|
+
|
|
98
|
+
destroy()
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('still closes when something outside it scrolls', async () => {
|
|
102
|
+
const { target, destroy } = await mountGrid()
|
|
103
|
+
await tick()
|
|
104
|
+
await openFilterMenu(target)
|
|
105
|
+
|
|
106
|
+
const viewport = target.querySelector('.sv-grid-viewport') ?? target
|
|
107
|
+
viewport.dispatchEvent(new Event('scroll'))
|
|
108
|
+
await vi.waitFor(() => expect(target.querySelector('.sv-grid-filter-menu')).toBeNull())
|
|
109
|
+
|
|
110
|
+
destroy()
|
|
111
|
+
})
|
|
112
|
+
})
|
|
@@ -1,188 +1,188 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DOM: `grandTotalRow` appends one totals row for the whole filtered set.
|
|
3
|
-
*
|
|
4
|
-
* It is shaped like a group footer (so totals render under their own columns
|
|
5
|
-
* through the normal cell path) but closes the dataset rather than a group:
|
|
6
|
-
* it must appear exactly once, last, on the LAST page only, aggregate the
|
|
7
|
-
* LEAF rows (not the group banners, which already carry subtotals and would
|
|
8
|
-
* otherwise be counted twice), and follow the filtered set rather than the
|
|
9
|
-
* raw data.
|
|
10
|
-
*/
|
|
11
|
-
import { afterEach, describe, expect, it } from 'vitest'
|
|
12
|
-
import { mount, unmount } from 'svelte'
|
|
13
|
-
import SvGrid from './SvGrid.svelte'
|
|
14
|
-
import {
|
|
15
|
-
createCoreRowModel,
|
|
16
|
-
createExpandedRowModel,
|
|
17
|
-
createFilteredRowModel,
|
|
18
|
-
createGroupedRowModel,
|
|
19
|
-
createPaginatedRowModel,
|
|
20
|
-
createSortedRowModel,
|
|
21
|
-
sortFns,
|
|
22
|
-
tableFeatures,
|
|
23
|
-
rowSortingFeature,
|
|
24
|
-
columnGroupingFeature,
|
|
25
|
-
} from './index'
|
|
26
|
-
|
|
27
|
-
type Row = { id: number; region: string; amount: number }
|
|
28
|
-
|
|
29
|
-
const data: Row[] = [
|
|
30
|
-
{ id: 1, region: 'East', amount: 10 },
|
|
31
|
-
{ id: 2, region: 'East', amount: 5 },
|
|
32
|
-
{ id: 3, region: 'West', amount: 7 },
|
|
33
|
-
]
|
|
34
|
-
|
|
35
|
-
const columns = [
|
|
36
|
-
{ field: 'region', header: 'Region', width: 120 },
|
|
37
|
-
{ field: 'amount', header: 'Amount', width: 100, aggregate: 'sum' },
|
|
38
|
-
]
|
|
39
|
-
|
|
40
|
-
const features = tableFeatures({ rowSortingFeature, columnGroupingFeature })
|
|
41
|
-
const tick = () => new Promise<void>((r) => queueMicrotask(r))
|
|
42
|
-
|
|
43
|
-
type Api = {
|
|
44
|
-
setGroupBy: (ids: string[]) => void
|
|
45
|
-
nextPage: () => void
|
|
46
|
-
setState: (s: Record<string, unknown>) => void
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function mountGrid(props: Record<string, unknown>) {
|
|
50
|
-
const target = document.createElement('div')
|
|
51
|
-
document.body.appendChild(target)
|
|
52
|
-
let api: Api | null = null
|
|
53
|
-
const app = mount(SvGrid, {
|
|
54
|
-
target,
|
|
55
|
-
props: {
|
|
56
|
-
data,
|
|
57
|
-
columns,
|
|
58
|
-
features,
|
|
59
|
-
groupable: true,
|
|
60
|
-
onApiReady: (a: never) => { api = a as never },
|
|
61
|
-
_rowModels: {
|
|
62
|
-
coreRowModel: createCoreRowModel(),
|
|
63
|
-
filteredRowModel: createFilteredRowModel(),
|
|
64
|
-
sortedRowModel: createSortedRowModel(sortFns),
|
|
65
|
-
groupedRowModel: createGroupedRowModel(),
|
|
66
|
-
expandedRowModel: createExpandedRowModel(),
|
|
67
|
-
paginatedRowModel: createPaginatedRowModel(),
|
|
68
|
-
},
|
|
69
|
-
containerHeight: 600,
|
|
70
|
-
virtualization: false,
|
|
71
|
-
...props,
|
|
72
|
-
} as never,
|
|
73
|
-
})
|
|
74
|
-
return {
|
|
75
|
-
target,
|
|
76
|
-
api: () => api,
|
|
77
|
-
ready: async () => { await tick() },
|
|
78
|
-
group: async () => {
|
|
79
|
-
await tick()
|
|
80
|
-
api?.setGroupBy(['region'])
|
|
81
|
-
await tick()
|
|
82
|
-
for (const btn of target.querySelectorAll<HTMLButtonElement>('.sv-grid-group-toggle')) {
|
|
83
|
-
if (btn.getAttribute('aria-expanded') !== 'true') btn.click()
|
|
84
|
-
}
|
|
85
|
-
await tick()
|
|
86
|
-
},
|
|
87
|
-
destroy: () => { unmount(app); target.remove() },
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
let cleanup: (() => void) | null = null
|
|
92
|
-
afterEach(() => { cleanup?.(); cleanup = null })
|
|
93
|
-
|
|
94
|
-
const totals = (t: HTMLElement) => [...t.querySelectorAll('tr.sv-grid-grand-total-row')]
|
|
95
|
-
|
|
96
|
-
describe('grandTotalRow', () => {
|
|
97
|
-
it('renders nothing when off', async () => {
|
|
98
|
-
const g = mountGrid({})
|
|
99
|
-
cleanup = g.destroy
|
|
100
|
-
await g.ready()
|
|
101
|
-
expect(totals(g.target)).toHaveLength(0)
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
it('appends exactly one total row on a flat (ungrouped) grid', async () => {
|
|
105
|
-
const g = mountGrid({ grandTotalRow: true })
|
|
106
|
-
cleanup = g.destroy
|
|
107
|
-
await g.ready()
|
|
108
|
-
const rows = totals(g.target)
|
|
109
|
-
expect(rows).toHaveLength(1)
|
|
110
|
-
// 10 + 5 + 7
|
|
111
|
-
expect(rows[0]?.textContent).toContain('22')
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it('is the last row in the body', async () => {
|
|
115
|
-
const g = mountGrid({ grandTotalRow: true })
|
|
116
|
-
cleanup = g.destroy
|
|
117
|
-
await g.ready()
|
|
118
|
-
const bodyRows = [...g.target.querySelectorAll('tbody tr')]
|
|
119
|
-
expect(bodyRows.at(-1)?.classList.contains('sv-grid-grand-total-row')).toBe(true)
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
it('counts leaf rows once when grouping is on (banners are not double-counted)', async () => {
|
|
123
|
-
const g = mountGrid({ grandTotalRow: true })
|
|
124
|
-
cleanup = g.destroy
|
|
125
|
-
await g.group()
|
|
126
|
-
const rows = totals(g.target)
|
|
127
|
-
expect(rows).toHaveLength(1)
|
|
128
|
-
// Still 22, not 44 - the East(15)/West(7) banners must not be summed too.
|
|
129
|
-
expect(rows[0]?.textContent).toContain('22')
|
|
130
|
-
expect(rows[0]?.textContent).not.toContain('44')
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
it('coexists with group footers without becoming one of them', async () => {
|
|
134
|
-
const g = mountGrid({ grandTotalRow: true, groupFooters: true })
|
|
135
|
-
cleanup = g.destroy
|
|
136
|
-
await g.group()
|
|
137
|
-
// Two group subtotals + one grand total, and the grand total is last.
|
|
138
|
-
expect(g.target.querySelectorAll('tr.sv-grid-group-footer-row')).toHaveLength(3)
|
|
139
|
-
expect(totals(g.target)).toHaveLength(1)
|
|
140
|
-
const bodyRows = [...g.target.querySelectorAll('tbody tr')]
|
|
141
|
-
expect(bodyRows.at(-1)?.classList.contains('sv-grid-grand-total-row')).toBe(true)
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
it('is not an expandable banner', async () => {
|
|
145
|
-
const g = mountGrid({ grandTotalRow: true })
|
|
146
|
-
cleanup = g.destroy
|
|
147
|
-
await g.ready()
|
|
148
|
-
const row = totals(g.target)[0]!
|
|
149
|
-
expect(row.classList.contains('sv-grid-group-row')).toBe(false)
|
|
150
|
-
expect(row.querySelector('.sv-grid-group-toggle')).toBeNull()
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
it('appears only on the last page when paginating', async () => {
|
|
154
|
-
// pageSize 2 over 3 rows: page 0 has no total, page 1 (the last) has it.
|
|
155
|
-
const g = mountGrid({ grandTotalRow: true, pageable: true, pageSize: 2 })
|
|
156
|
-
cleanup = g.destroy
|
|
157
|
-
await g.ready()
|
|
158
|
-
expect(totals(g.target)).toHaveLength(0)
|
|
159
|
-
g.api()?.nextPage()
|
|
160
|
-
await tick()
|
|
161
|
-
expect(totals(g.target)).toHaveLength(1)
|
|
162
|
-
// The total is over the whole set (22), not just the last page's row.
|
|
163
|
-
expect(totals(g.target)[0]?.textContent).toContain('22')
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
it('totals the FILTERED set, not the raw data', async () => {
|
|
167
|
-
const g = mountGrid({ grandTotalRow: true })
|
|
168
|
-
cleanup = g.destroy
|
|
169
|
-
await g.ready()
|
|
170
|
-
g.api()?.setState({ globalFilter: 'East' })
|
|
171
|
-
await tick()
|
|
172
|
-
// East only: 10 + 5 = 15.
|
|
173
|
-
expect(totals(g.target)[0]?.textContent).toContain('15')
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
it('renders no total row when no column declares an aggregate', async () => {
|
|
177
|
-
const g = mountGrid({
|
|
178
|
-
grandTotalRow: true,
|
|
179
|
-
columns: [
|
|
180
|
-
{ field: 'region', header: 'Region', width: 120 },
|
|
181
|
-
{ field: 'amount', header: 'Amount', width: 100 },
|
|
182
|
-
],
|
|
183
|
-
})
|
|
184
|
-
cleanup = g.destroy
|
|
185
|
-
await g.ready()
|
|
186
|
-
expect(totals(g.target)).toHaveLength(0)
|
|
187
|
-
})
|
|
188
|
-
})
|
|
1
|
+
/**
|
|
2
|
+
* DOM: `grandTotalRow` appends one totals row for the whole filtered set.
|
|
3
|
+
*
|
|
4
|
+
* It is shaped like a group footer (so totals render under their own columns
|
|
5
|
+
* through the normal cell path) but closes the dataset rather than a group:
|
|
6
|
+
* it must appear exactly once, last, on the LAST page only, aggregate the
|
|
7
|
+
* LEAF rows (not the group banners, which already carry subtotals and would
|
|
8
|
+
* otherwise be counted twice), and follow the filtered set rather than the
|
|
9
|
+
* raw data.
|
|
10
|
+
*/
|
|
11
|
+
import { afterEach, describe, expect, it } from 'vitest'
|
|
12
|
+
import { mount, unmount } from 'svelte'
|
|
13
|
+
import SvGrid from './SvGrid.svelte'
|
|
14
|
+
import {
|
|
15
|
+
createCoreRowModel,
|
|
16
|
+
createExpandedRowModel,
|
|
17
|
+
createFilteredRowModel,
|
|
18
|
+
createGroupedRowModel,
|
|
19
|
+
createPaginatedRowModel,
|
|
20
|
+
createSortedRowModel,
|
|
21
|
+
sortFns,
|
|
22
|
+
tableFeatures,
|
|
23
|
+
rowSortingFeature,
|
|
24
|
+
columnGroupingFeature,
|
|
25
|
+
} from './index'
|
|
26
|
+
|
|
27
|
+
type Row = { id: number; region: string; amount: number }
|
|
28
|
+
|
|
29
|
+
const data: Row[] = [
|
|
30
|
+
{ id: 1, region: 'East', amount: 10 },
|
|
31
|
+
{ id: 2, region: 'East', amount: 5 },
|
|
32
|
+
{ id: 3, region: 'West', amount: 7 },
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
const columns = [
|
|
36
|
+
{ field: 'region', header: 'Region', width: 120 },
|
|
37
|
+
{ field: 'amount', header: 'Amount', width: 100, aggregate: 'sum' },
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
const features = tableFeatures({ rowSortingFeature, columnGroupingFeature })
|
|
41
|
+
const tick = () => new Promise<void>((r) => queueMicrotask(r))
|
|
42
|
+
|
|
43
|
+
type Api = {
|
|
44
|
+
setGroupBy: (ids: string[]) => void
|
|
45
|
+
nextPage: () => void
|
|
46
|
+
setState: (s: Record<string, unknown>) => void
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function mountGrid(props: Record<string, unknown>) {
|
|
50
|
+
const target = document.createElement('div')
|
|
51
|
+
document.body.appendChild(target)
|
|
52
|
+
let api: Api | null = null
|
|
53
|
+
const app = mount(SvGrid, {
|
|
54
|
+
target,
|
|
55
|
+
props: {
|
|
56
|
+
data,
|
|
57
|
+
columns,
|
|
58
|
+
features,
|
|
59
|
+
groupable: true,
|
|
60
|
+
onApiReady: (a: never) => { api = a as never },
|
|
61
|
+
_rowModels: {
|
|
62
|
+
coreRowModel: createCoreRowModel(),
|
|
63
|
+
filteredRowModel: createFilteredRowModel(),
|
|
64
|
+
sortedRowModel: createSortedRowModel(sortFns),
|
|
65
|
+
groupedRowModel: createGroupedRowModel(),
|
|
66
|
+
expandedRowModel: createExpandedRowModel(),
|
|
67
|
+
paginatedRowModel: createPaginatedRowModel(),
|
|
68
|
+
},
|
|
69
|
+
containerHeight: 600,
|
|
70
|
+
virtualization: false,
|
|
71
|
+
...props,
|
|
72
|
+
} as never,
|
|
73
|
+
})
|
|
74
|
+
return {
|
|
75
|
+
target,
|
|
76
|
+
api: () => api,
|
|
77
|
+
ready: async () => { await tick() },
|
|
78
|
+
group: async () => {
|
|
79
|
+
await tick()
|
|
80
|
+
api?.setGroupBy(['region'])
|
|
81
|
+
await tick()
|
|
82
|
+
for (const btn of target.querySelectorAll<HTMLButtonElement>('.sv-grid-group-toggle')) {
|
|
83
|
+
if (btn.getAttribute('aria-expanded') !== 'true') btn.click()
|
|
84
|
+
}
|
|
85
|
+
await tick()
|
|
86
|
+
},
|
|
87
|
+
destroy: () => { unmount(app); target.remove() },
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let cleanup: (() => void) | null = null
|
|
92
|
+
afterEach(() => { cleanup?.(); cleanup = null })
|
|
93
|
+
|
|
94
|
+
const totals = (t: HTMLElement) => [...t.querySelectorAll('tr.sv-grid-grand-total-row')]
|
|
95
|
+
|
|
96
|
+
describe('grandTotalRow', () => {
|
|
97
|
+
it('renders nothing when off', async () => {
|
|
98
|
+
const g = mountGrid({})
|
|
99
|
+
cleanup = g.destroy
|
|
100
|
+
await g.ready()
|
|
101
|
+
expect(totals(g.target)).toHaveLength(0)
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('appends exactly one total row on a flat (ungrouped) grid', async () => {
|
|
105
|
+
const g = mountGrid({ grandTotalRow: true })
|
|
106
|
+
cleanup = g.destroy
|
|
107
|
+
await g.ready()
|
|
108
|
+
const rows = totals(g.target)
|
|
109
|
+
expect(rows).toHaveLength(1)
|
|
110
|
+
// 10 + 5 + 7
|
|
111
|
+
expect(rows[0]?.textContent).toContain('22')
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('is the last row in the body', async () => {
|
|
115
|
+
const g = mountGrid({ grandTotalRow: true })
|
|
116
|
+
cleanup = g.destroy
|
|
117
|
+
await g.ready()
|
|
118
|
+
const bodyRows = [...g.target.querySelectorAll('tbody tr')]
|
|
119
|
+
expect(bodyRows.at(-1)?.classList.contains('sv-grid-grand-total-row')).toBe(true)
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('counts leaf rows once when grouping is on (banners are not double-counted)', async () => {
|
|
123
|
+
const g = mountGrid({ grandTotalRow: true })
|
|
124
|
+
cleanup = g.destroy
|
|
125
|
+
await g.group()
|
|
126
|
+
const rows = totals(g.target)
|
|
127
|
+
expect(rows).toHaveLength(1)
|
|
128
|
+
// Still 22, not 44 - the East(15)/West(7) banners must not be summed too.
|
|
129
|
+
expect(rows[0]?.textContent).toContain('22')
|
|
130
|
+
expect(rows[0]?.textContent).not.toContain('44')
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('coexists with group footers without becoming one of them', async () => {
|
|
134
|
+
const g = mountGrid({ grandTotalRow: true, groupFooters: true })
|
|
135
|
+
cleanup = g.destroy
|
|
136
|
+
await g.group()
|
|
137
|
+
// Two group subtotals + one grand total, and the grand total is last.
|
|
138
|
+
expect(g.target.querySelectorAll('tr.sv-grid-group-footer-row')).toHaveLength(3)
|
|
139
|
+
expect(totals(g.target)).toHaveLength(1)
|
|
140
|
+
const bodyRows = [...g.target.querySelectorAll('tbody tr')]
|
|
141
|
+
expect(bodyRows.at(-1)?.classList.contains('sv-grid-grand-total-row')).toBe(true)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
it('is not an expandable banner', async () => {
|
|
145
|
+
const g = mountGrid({ grandTotalRow: true })
|
|
146
|
+
cleanup = g.destroy
|
|
147
|
+
await g.ready()
|
|
148
|
+
const row = totals(g.target)[0]!
|
|
149
|
+
expect(row.classList.contains('sv-grid-group-row')).toBe(false)
|
|
150
|
+
expect(row.querySelector('.sv-grid-group-toggle')).toBeNull()
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
it('appears only on the last page when paginating', async () => {
|
|
154
|
+
// pageSize 2 over 3 rows: page 0 has no total, page 1 (the last) has it.
|
|
155
|
+
const g = mountGrid({ grandTotalRow: true, pageable: true, pageSize: 2 })
|
|
156
|
+
cleanup = g.destroy
|
|
157
|
+
await g.ready()
|
|
158
|
+
expect(totals(g.target)).toHaveLength(0)
|
|
159
|
+
g.api()?.nextPage()
|
|
160
|
+
await tick()
|
|
161
|
+
expect(totals(g.target)).toHaveLength(1)
|
|
162
|
+
// The total is over the whole set (22), not just the last page's row.
|
|
163
|
+
expect(totals(g.target)[0]?.textContent).toContain('22')
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
it('totals the FILTERED set, not the raw data', async () => {
|
|
167
|
+
const g = mountGrid({ grandTotalRow: true })
|
|
168
|
+
cleanup = g.destroy
|
|
169
|
+
await g.ready()
|
|
170
|
+
g.api()?.setState({ globalFilter: 'East' })
|
|
171
|
+
await tick()
|
|
172
|
+
// East only: 10 + 5 = 15.
|
|
173
|
+
expect(totals(g.target)[0]?.textContent).toContain('15')
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('renders no total row when no column declares an aggregate', async () => {
|
|
177
|
+
const g = mountGrid({
|
|
178
|
+
grandTotalRow: true,
|
|
179
|
+
columns: [
|
|
180
|
+
{ field: 'region', header: 'Region', width: 120 },
|
|
181
|
+
{ field: 'amount', header: 'Amount', width: 100 },
|
|
182
|
+
],
|
|
183
|
+
})
|
|
184
|
+
cleanup = g.destroy
|
|
185
|
+
await g.ready()
|
|
186
|
+
expect(totals(g.target)).toHaveLength(0)
|
|
187
|
+
})
|
|
188
|
+
})
|