@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
package/src/SvGrid.types.ts
CHANGED
|
@@ -1,1708 +1,1708 @@
|
|
|
1
|
-
// Type definitions extracted from SvGrid.svelte. These are compile-time
|
|
2
|
-
// only - moving them out keeps the component's <script> focused on logic.
|
|
3
|
-
import type { Snippet } from "svelte";
|
|
4
|
-
import type {
|
|
5
|
-
CellEditorType,
|
|
6
|
-
ColumnDef,
|
|
7
|
-
RowData,
|
|
8
|
-
SvGridApi,
|
|
9
|
-
TableFeatures,
|
|
10
|
-
} from "./index";
|
|
11
|
-
import type { ConditionalFormat } from "./conditional-formatting";
|
|
12
|
-
import type { GroupDisplayType } from "./group-display";
|
|
13
|
-
import type { GridMessages } from "./grid-messages";
|
|
14
|
-
import type { GridPivotConfig } from "./pivot-view.svelte";
|
|
15
|
-
import type { MenuItem } from "./SvMenuList.svelte";
|
|
16
|
-
|
|
17
|
-
/** The calendar views the scheduler can render. {@link SchedulerConfig}. The
|
|
18
|
-
* `timeline*` views are horizontal: time runs left→right and resources are
|
|
19
|
-
* rows (a single "All" row without `resourceField`). */
|
|
20
|
-
export type SchedulerView =
|
|
21
|
-
| "month"
|
|
22
|
-
| "week"
|
|
23
|
-
| "day"
|
|
24
|
-
| "agenda"
|
|
25
|
-
| "timelineDay"
|
|
26
|
-
| "timelineWeek"
|
|
27
|
-
| "timelineMonth"
|
|
28
|
-
| "timelineYear";
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* How overlapping ("colliding") time-grid events are laid out:
|
|
32
|
-
* - `split` - every collision divides the column width evenly (default).
|
|
33
|
-
* - `cap` - show up to `maxColumns` columns; the rest collapse into a
|
|
34
|
-
* clickable `+N more` overflow tile.
|
|
35
|
-
* - `stack` - overlapping events overlap with a horizontal offset + z-order
|
|
36
|
-
* instead of shrinking, so each stays readable (hover to raise).
|
|
37
|
-
*/
|
|
38
|
-
export type SchedulerCollisionMode = "split" | "cap" | "stack";
|
|
39
|
-
|
|
40
|
-
/** A scheduler resource - a person / room / machine an event can be assigned to. */
|
|
41
|
-
export type SchedulerResource = {
|
|
42
|
-
id: string;
|
|
43
|
-
title?: string;
|
|
44
|
-
color?: string;
|
|
45
|
-
/**
|
|
46
|
-
* This resource's own working windows (hours), optionally per weekday - e.g. a
|
|
47
|
-
* doctor available Mon/Wed/Fri 9-13 and Tue/Thu 14-18. Overrides the global
|
|
48
|
-
* `businessHours` / `nonWorkingDays` for this resource's columns: time outside
|
|
49
|
-
* every matching window is shaded, and (with `restrictToBusinessHours`)
|
|
50
|
-
* non-bookable. A weekday with no matching window is a full day off.
|
|
51
|
-
*/
|
|
52
|
-
availability?: ReadonlyArray<{ days?: ReadonlyArray<number>; start: number; end: number }>;
|
|
53
|
-
/**
|
|
54
|
-
* Per-date overrides to this resource's weekly `availability` - a specific day
|
|
55
|
-
* off (`off: true`, e.g. vacation) or custom hours (`windows`) for that one
|
|
56
|
-
* date. Matched by calendar date; takes precedence over `availability` for the
|
|
57
|
-
* matching day.
|
|
58
|
-
*/
|
|
59
|
-
dateOverrides?: ReadonlyArray<{
|
|
60
|
-
date: Date | number | string;
|
|
61
|
-
off?: boolean;
|
|
62
|
-
windows?: ReadonlyArray<{ start: number; end: number }>;
|
|
63
|
-
}>;
|
|
64
|
-
};
|
|
65
|
-
import type {
|
|
66
|
-
ChartType,
|
|
67
|
-
ChartSpec,
|
|
68
|
-
ChartAnnotation,
|
|
69
|
-
ChartReferenceLine,
|
|
70
|
-
ChartValueFormat,
|
|
71
|
-
} from "./chart";
|
|
72
|
-
|
|
73
|
-
/** One aggregated bucket returned by a server-side `getAggregate`. */
|
|
74
|
-
export type ChartAggregateBucket = { category: string; series?: string; value: number };
|
|
75
|
-
/** The request a server-side `getAggregate` receives (whole-dataset charting). */
|
|
76
|
-
export type ChartAggregateRequest = {
|
|
77
|
-
dimension: string | undefined;
|
|
78
|
-
measure: string | null;
|
|
79
|
-
series?: string;
|
|
80
|
-
reduce: "sum" | "avg" | "count";
|
|
81
|
-
filterModel: Record<string, unknown>;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Config for the built-in `charting` prop. All fields optional and additive;
|
|
86
|
-
* `charting={true}` is the zero-config form. Column references are column
|
|
87
|
-
* field names / ids.
|
|
88
|
-
*/
|
|
89
|
-
export type ChartingConfig<TData extends RowData = RowData> = {
|
|
90
|
-
/** Right-side drawer (default) or bottom dock. */
|
|
91
|
-
position?: "bottom" | "right";
|
|
92
|
-
/** Open the panel on first render. */
|
|
93
|
-
defaultOpen?: boolean;
|
|
94
|
-
/** Initial chart type. */
|
|
95
|
-
defaultType?: ChartType;
|
|
96
|
-
/** Docked-bottom height (px). */
|
|
97
|
-
height?: number;
|
|
98
|
-
/** Drawer width (px). */
|
|
99
|
-
width?: number;
|
|
100
|
-
/** Clicking a chart category filters the grid on the charted dimension. */
|
|
101
|
-
crossFilter?: boolean;
|
|
102
|
-
/** Group-by column. */
|
|
103
|
-
dimension?: string;
|
|
104
|
-
/** Split-by column: one series per distinct value. */
|
|
105
|
-
series?: string;
|
|
106
|
-
/** Measure column, or several for a multi-series chart. */
|
|
107
|
-
measures?: string | string[];
|
|
108
|
-
reduce?: "sum" | "avg" | "count";
|
|
109
|
-
stacked?: boolean;
|
|
110
|
-
stacked100?: boolean;
|
|
111
|
-
/** Per-series-label type override (combo). */
|
|
112
|
-
seriesTypes?: Record<string, "bar" | "line" | "area">;
|
|
113
|
-
/** Per-series-label axis override (dual axis). */
|
|
114
|
-
seriesAxes?: Record<string, "left" | "right">;
|
|
115
|
-
referenceLines?: ChartReferenceLine[];
|
|
116
|
-
averageLine?: boolean;
|
|
117
|
-
trend?: "sma" | "ema" | "linear";
|
|
118
|
-
annotations?: ChartAnnotation[];
|
|
119
|
-
yScale?: "linear" | "log";
|
|
120
|
-
timeAxis?: boolean;
|
|
121
|
-
valueFormat?: "number" | "currency" | "percent" | "compact";
|
|
122
|
-
smooth?: boolean;
|
|
123
|
-
orientation?: "vertical" | "horizontal";
|
|
124
|
-
donut?: number | boolean;
|
|
125
|
-
palette?: string[];
|
|
126
|
-
patternFallback?: boolean;
|
|
127
|
-
topN?: number;
|
|
128
|
-
otherLabel?: string;
|
|
129
|
-
sort?: "value-desc" | "value-asc" | "category" | "none";
|
|
130
|
-
dataLabels?: boolean;
|
|
131
|
-
zoom?: boolean;
|
|
132
|
-
brush?: boolean;
|
|
133
|
-
/** Show the chart's PNG/SVG export toolbar. */
|
|
134
|
-
export?: boolean;
|
|
135
|
-
/** Escape hatch: build a fully custom ChartSpec from the (scoped) rows. */
|
|
136
|
-
buildSpec?: (rows: TData[]) => ChartSpec | null;
|
|
137
|
-
/** Server-side aggregation: chart the whole dataset, not just loaded rows. */
|
|
138
|
-
getAggregate?: (
|
|
139
|
-
request: ChartAggregateRequest,
|
|
140
|
-
) => Promise<ReadonlyArray<ChartAggregateBucket>>;
|
|
141
|
-
/** Bump to force a server-side refetch. */
|
|
142
|
-
refreshKey?: unknown;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* The built-in card detail drawer. Set `board.drawer` (`true` for all fields,
|
|
147
|
-
* or this object to customize) and opening a card shows a drawer with an
|
|
148
|
-
* `SvForm` of its fields, rendered with the UI-kit editors.
|
|
149
|
-
*/
|
|
150
|
-
export type BoardDrawerConfig<TData extends RowData = RowData> = {
|
|
151
|
-
/** Fields to show, in order. Omit for every column that has a `field`. */
|
|
152
|
-
fields?: ReadonlyArray<keyof TData & string>;
|
|
153
|
-
/** Drawer title - a string or derived from the row. Defaults to the title field. */
|
|
154
|
-
title?: string | ((row: TData) => string);
|
|
155
|
-
/** Which edge the drawer opens from. Defaults to `'right'`. */
|
|
156
|
-
side?: "right" | "left" | "top" | "bottom";
|
|
157
|
-
/** Drawer size (any CSS length). Defaults to `'380px'`. */
|
|
158
|
-
size?: string;
|
|
159
|
-
/** Save button label. Defaults to `'Save'`. */
|
|
160
|
-
submitLabel?: string;
|
|
161
|
-
/** Form columns inside the drawer. Defaults to `1`. */
|
|
162
|
-
columns?: number;
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
/** Board-native helpers passed to `board.cardMenu` for building context items. */
|
|
166
|
-
export type BoardMenuContext<TData extends RowData = RowData> = {
|
|
167
|
-
/** The board's lanes (id + title). */
|
|
168
|
-
lanes: BoardLane[];
|
|
169
|
-
/** Move this card to a lane (board-native; fires onCardMove). */
|
|
170
|
-
moveTo: (laneId: string) => void;
|
|
171
|
-
/** Open this card's editor (inline, or your `onCardEdit`). */
|
|
172
|
-
edit: () => void;
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
/** Board-native helpers passed to `board.laneMenu` for building lane context items. */
|
|
176
|
-
export type BoardLaneMenuContext<TData extends RowData = RowData> = {
|
|
177
|
-
/** The lane's id. */
|
|
178
|
-
laneId: string;
|
|
179
|
-
/** The lane's current cards (this swimlane's, if any). */
|
|
180
|
-
cards: TData[];
|
|
181
|
-
/** Whether the lane is collapsed. */
|
|
182
|
-
collapsed: boolean;
|
|
183
|
-
/** Collapse / expand the lane (needs `collapsibleLanes`). */
|
|
184
|
-
toggleCollapse: () => void;
|
|
185
|
-
/** Add a card to the lane (fires `onCardAdd`). */
|
|
186
|
-
addCard: (title?: string) => void;
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
/** The cell a context menu was opened on. Passed to every item's callbacks. */
|
|
190
|
-
export type ContextMenuTarget<TData extends RowData = RowData> = {
|
|
191
|
-
rowIndex: number;
|
|
192
|
-
colIndex: number;
|
|
193
|
-
columnId: string;
|
|
194
|
-
/** Stable row id (from getRowId / row model), for keying notes etc. */
|
|
195
|
-
rowId: string;
|
|
196
|
-
row: TData | null;
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* A context-menu entry. Either a built-in action key, the `"separator"`
|
|
201
|
-
* divider, or a custom item. Built-in keys: `"copy" | "cut" | "paste" |
|
|
202
|
-
* "clear" | "row_above" | "row_below" | "remove_row" | "remove_col" |
|
|
203
|
-
* "chart"`. The `"chart"` item (chart the selected range) is only shown when
|
|
204
|
-
* `charting` is enabled; it is appended to the default menu automatically.
|
|
205
|
-
*/
|
|
206
|
-
export type ContextMenuItem<TData extends RowData = RowData> =
|
|
207
|
-
| string
|
|
208
|
-
| {
|
|
209
|
-
key: string;
|
|
210
|
-
label: string;
|
|
211
|
-
/** Hide the item entirely for this target. */
|
|
212
|
-
hidden?: (target: ContextMenuTarget<TData>) => boolean;
|
|
213
|
-
/** Render the item greyed-out and non-clickable for this target. */
|
|
214
|
-
disabled?: (target: ContextMenuTarget<TData>) => boolean;
|
|
215
|
-
/** Invoked on click. The menu closes afterwards. */
|
|
216
|
-
action: (target: ContextMenuTarget<TData>) => void;
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
/** A single Kanban lane (board column). {@link BoardConfig}. */
|
|
220
|
-
export type BoardLane = {
|
|
221
|
-
/** Lane id - equals the `groupBy` field value of the cards it holds. */
|
|
222
|
-
id: string;
|
|
223
|
-
/** Header title. Defaults to the id (or `(empty)` for a blank value). */
|
|
224
|
-
title?: string;
|
|
225
|
-
/** Accent color (any CSS color) for the lane header bar + card ring. */
|
|
226
|
-
color?: string;
|
|
227
|
-
/**
|
|
228
|
-
* Soft max number of cards. When exceeded the lane header is flagged
|
|
229
|
-
* over-limit. Enforcement/styling is an enterprise concern; the count is
|
|
230
|
-
* always shown.
|
|
231
|
-
*/
|
|
232
|
-
wipLimit?: number;
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
/** A checklist item inside a card. See {@link BoardConfig.subtasks}. */
|
|
236
|
-
export type BoardSubtask = {
|
|
237
|
-
id: string | number;
|
|
238
|
-
title: string;
|
|
239
|
-
done: boolean;
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
/** A comment on a card. See {@link BoardConfig.commentsField}. */
|
|
243
|
-
export type BoardComment = {
|
|
244
|
-
id: string | number;
|
|
245
|
-
text: string;
|
|
246
|
-
author?: string;
|
|
247
|
-
/** Timestamp label (any string). */
|
|
248
|
-
at?: string;
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* The serializable board layout - the per-card position/edit overlay plus
|
|
253
|
-
* collapsed lanes. Persisted by `board.persistKey` and passed to
|
|
254
|
-
* `board.onLayoutChange`.
|
|
255
|
-
*/
|
|
256
|
-
export type BoardLayout = {
|
|
257
|
-
/** rowId -> lane id. */
|
|
258
|
-
laneOf?: Record<string, string>;
|
|
259
|
-
/** rowId -> sort order within its lane. */
|
|
260
|
-
orderOf?: Record<string, number>;
|
|
261
|
-
/** rowId -> swimlane id. */
|
|
262
|
-
swimOf?: Record<string, string>;
|
|
263
|
-
/** rowId -> edited field values. */
|
|
264
|
-
edits?: Record<string, Record<string, unknown>>;
|
|
265
|
-
/** lane id -> collapsed. */
|
|
266
|
-
collapsed?: Record<string, boolean>;
|
|
267
|
-
/** swimlane id -> collapsed. */
|
|
268
|
-
collapsedSwim?: Record<string, boolean>;
|
|
269
|
-
/** Explicit lane order (ids), when lanes have been drag-reordered. */
|
|
270
|
-
laneOrder?: string[];
|
|
271
|
-
/** rowId -> subtaskId -> done override. */
|
|
272
|
-
subDone?: Record<string, Record<string, boolean>>;
|
|
273
|
-
/** rowId -> subtasks added on the card. */
|
|
274
|
-
subAdded?: Record<string, BoardSubtask[]>;
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
/** Emitted when a card's built-in editor is saved. */
|
|
278
|
-
export type BoardCardCommitEvent<TData extends RowData = RowData> = {
|
|
279
|
-
/** The edited row. */
|
|
280
|
-
row: TData;
|
|
281
|
-
/** Only the fields that changed, `{ field: newValue }`. */
|
|
282
|
-
changes: Record<string, unknown>;
|
|
283
|
-
/** The full set of edited field values. */
|
|
284
|
-
values: Record<string, unknown>;
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
/** Emitted when a card is dragged to a new lane and/or position. */
|
|
288
|
-
export type BoardCardMoveEvent<TData extends RowData = RowData> = {
|
|
289
|
-
/** The dragged row. */
|
|
290
|
-
row: TData;
|
|
291
|
-
/** Lane the card came from. */
|
|
292
|
-
fromLane: string;
|
|
293
|
-
/** Lane the card was dropped on. */
|
|
294
|
-
toLane: string;
|
|
295
|
-
/** Insertion index within the destination lane. */
|
|
296
|
-
toIndex: number;
|
|
297
|
-
/** Swimlane the card came from (only when `swimlaneBy` is set). */
|
|
298
|
-
fromSwimlane?: string;
|
|
299
|
-
/** Swimlane the card was dropped on (only when `swimlaneBy` is set). */
|
|
300
|
-
toSwimlane?: string;
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Turns the grid into a Kanban board. Set `board` and the grid renders its
|
|
305
|
-
* rows as cards in horizontal lanes (bucketed by the `groupBy` field) instead
|
|
306
|
-
* of a table. Dragging a card between lanes fires {@link BoardConfig.onCardMove}
|
|
307
|
-
* where you reassign the `groupBy` field on your own data.
|
|
308
|
-
*/
|
|
309
|
-
/**
|
|
310
|
-
* Chart view of the grid. Setting the `chart` prop on `<SvGrid>` swaps the table
|
|
311
|
-
* for a chart driven by the grid's FILTERED + SORTED rows - so the search box,
|
|
312
|
-
* column filters and sort all flow through to the chart. Unlike the board and
|
|
313
|
-
* scheduler views, the renderer is free: the grid lazy-loads a built-in
|
|
314
|
-
* `SvChart` view unless a host overrides it via `registerChartView`.
|
|
315
|
-
*
|
|
316
|
-
* The config maps directly onto `rowsToChartSpec` - one row field for the
|
|
317
|
-
* category axis, one or more for the value series (or a `series` field to pivot
|
|
318
|
-
* one series per distinct value).
|
|
319
|
-
*
|
|
320
|
-
* ```svelte
|
|
321
|
-
* <SvGrid {data} {columns}
|
|
322
|
-
* chart={{ type: 'bar', category: 'month', value: 'revenue', reduce: 'sum' }} />
|
|
323
|
-
* ```
|
|
324
|
-
*/
|
|
325
|
-
export type ChartViewConfig<
|
|
326
|
-
TFeatures extends TableFeatures = TableFeatures,
|
|
327
|
-
TData extends RowData = RowData,
|
|
328
|
-
> = {
|
|
329
|
-
/** Chart type. Default `'bar'`. */
|
|
330
|
-
type?: ChartType;
|
|
331
|
-
/** Row field for the category (x) axis. */
|
|
332
|
-
category: keyof TData & string;
|
|
333
|
-
/** Row field(s) for the value (y) series. */
|
|
334
|
-
value: (keyof TData & string) | Array<keyof TData & string>;
|
|
335
|
-
/** Pivot dimension: one series per distinct value of this field. */
|
|
336
|
-
series?: keyof TData & string;
|
|
337
|
-
/** Aggregation when several rows share a category. Default `'sum'`. */
|
|
338
|
-
reduce?: "sum" | "avg" | "count";
|
|
339
|
-
/** Stack bar / area series instead of grouping them. */
|
|
340
|
-
stacked?: boolean;
|
|
341
|
-
/** Stack to 100% (implies `stacked`). */
|
|
342
|
-
stacked100?: boolean;
|
|
343
|
-
/** Order categories. Default: insertion order (value-desc when `topN` is set). */
|
|
344
|
-
sort?: "value-desc" | "value-asc" | "category" | "none";
|
|
345
|
-
/** Keep only the top N categories; bucket the rest into "Other". */
|
|
346
|
-
topN?: number;
|
|
347
|
-
/** Palette for series without an explicit colour. */
|
|
348
|
-
palette?: string[];
|
|
349
|
-
/** Number format for the value axis, tooltips and data labels. */
|
|
350
|
-
valueFormat?: ChartValueFormat;
|
|
351
|
-
/** Show the clickable legend. Default `true`. */
|
|
352
|
-
legend?: boolean;
|
|
353
|
-
/** Draw the value on each bar / point / slice. Default `false`. */
|
|
354
|
-
dataLabels?: boolean;
|
|
355
|
-
/** Show the search box above the chart (filters rows first). Default `true`. */
|
|
356
|
-
searchable?: boolean;
|
|
357
|
-
/** Placeholder for the search box. */
|
|
358
|
-
searchPlaceholder?: string;
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
export type BoardConfig<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> = {
|
|
362
|
-
/** Field whose value buckets each row into a lane. */
|
|
363
|
-
groupBy: keyof TData & string;
|
|
364
|
-
/**
|
|
365
|
-
* Explicit, ordered lanes. Omit to derive lanes from the distinct
|
|
366
|
-
* `groupBy` values found in the data (first-seen order).
|
|
367
|
-
*/
|
|
368
|
-
lanes?: ReadonlyArray<BoardLane>;
|
|
369
|
-
/** Custom card body. Receives the row. Omit for the built-in default card. */
|
|
370
|
-
card?: Snippet<[TData]>;
|
|
371
|
-
/**
|
|
372
|
-
* Fired when a card is dragged to a new lane/position. Update your data
|
|
373
|
-
* here (reassign the `groupBy` field, and optionally reorder). Without it
|
|
374
|
-
* the board is display-only.
|
|
375
|
-
*/
|
|
376
|
-
onCardMove?: (event: BoardCardMoveEvent<TData>) => void;
|
|
377
|
-
/**
|
|
378
|
-
* Add-card affordance. A `+` in the lane header (or, with `composer`, a
|
|
379
|
-
* type-a-title box at the bottom of the lane) fires this with the lane id
|
|
380
|
-
* and - from the composer - the typed title.
|
|
381
|
-
*/
|
|
382
|
-
onCardAdd?: (laneId: string, title?: string) => void;
|
|
383
|
-
/**
|
|
384
|
-
* Show a quick-add composer at the bottom of each lane (a "+ Add a card"
|
|
385
|
-
* button that opens an inline title input; Enter calls `onCardAdd(lane,
|
|
386
|
-
* title)`). Without it, `onCardAdd` shows a plain `+` in the header.
|
|
387
|
-
*/
|
|
388
|
-
composer?: boolean;
|
|
389
|
-
/**
|
|
390
|
-
* Field holding a card's checklist of sub-tasks (`BoardSubtask[]`). The card
|
|
391
|
-
* shows a progress chip + bar and expands to an inline checklist with a
|
|
392
|
-
* quick-add. Toggles/adds run through an overlay (never mutating your data)
|
|
393
|
-
* and fire the callbacks below.
|
|
394
|
-
*/
|
|
395
|
-
subtasks?: keyof TData & string;
|
|
396
|
-
/** Fired when a sub-task checkbox is toggled. */
|
|
397
|
-
onSubtaskToggle?: (row: TData, subtaskId: string | number, done: boolean) => void;
|
|
398
|
-
/** Fired when a sub-task is added from the card. */
|
|
399
|
-
onSubtaskAdd?: (row: TData, title: string) => void;
|
|
400
|
-
/**
|
|
401
|
-
* Field holding label/tag strings (or `{ text, color }`) shown as chips on
|
|
402
|
-
* the default card's badge row.
|
|
403
|
-
*/
|
|
404
|
-
labelsField?: keyof TData & string;
|
|
405
|
-
/** Field holding a due date (Date | ISO string); shown as a badge, red when overdue. */
|
|
406
|
-
dueField?: keyof TData & string;
|
|
407
|
-
/**
|
|
408
|
-
* Field holding one or more assignee names (string | string[]); shown as
|
|
409
|
-
* avatar(s) on the default card's badge row.
|
|
410
|
-
*/
|
|
411
|
-
assigneesField?: keyof TData & string;
|
|
412
|
-
/**
|
|
413
|
-
* Enable the built-in card editor: double-click a card (or press F2 while
|
|
414
|
-
* it is focused) to edit its fields inline. Fields are rendered from the
|
|
415
|
-
* columns that declare an `editorType` (or all fields if none do). Ignored
|
|
416
|
-
* when `onCardEdit` is set.
|
|
417
|
-
*/
|
|
418
|
-
editable?: boolean;
|
|
419
|
-
/**
|
|
420
|
-
* Open your own editor instead of the built-in one. Called on double-click /
|
|
421
|
-
* F2 with the row; you might open a drawer or route to a detail screen.
|
|
422
|
-
*/
|
|
423
|
-
onCardEdit?: (row: TData) => void;
|
|
424
|
-
/**
|
|
425
|
-
* Built-in **detail drawer**: opening a card (double-click / F2) shows an
|
|
426
|
-
* `SvDrawer` with an `SvForm` of its fields (kit editors). `true` = all
|
|
427
|
-
* fields; pass a {@link BoardDrawerConfig} to pick a subset / customize.
|
|
428
|
-
* Ignored when `onCardEdit` is set.
|
|
429
|
-
*/
|
|
430
|
-
drawer?: boolean | BoardDrawerConfig<TData>;
|
|
431
|
-
/** Fired when the built-in editor is saved. Persist / mirror the changes. */
|
|
432
|
-
onCardCommit?: (event: BoardCardCommitEvent<TData>) => void;
|
|
433
|
-
/** Field used as the card title. Defaults to the first column's field. */
|
|
434
|
-
titleField?: keyof TData & string;
|
|
435
|
-
/**
|
|
436
|
-
* Column fields shown as label:value meta lines on the default card
|
|
437
|
-
* (max 4). Defaults to the first few non-title, non-groupBy columns.
|
|
438
|
-
*/
|
|
439
|
-
cardFields?: ReadonlyArray<keyof TData & string>;
|
|
440
|
-
/**
|
|
441
|
-
* Second grouping axis: split the board into horizontal **swimlanes** by
|
|
442
|
-
* this field. Each swimlane band shows the full lane set with only its own
|
|
443
|
-
* cards. Dragging a card into another band reassigns this field too.
|
|
444
|
-
*/
|
|
445
|
-
swimlaneBy?: keyof TData & string;
|
|
446
|
-
/** Let users collapse a swimlane band via its header chevron. */
|
|
447
|
-
collapsibleSwimlanes?: boolean;
|
|
448
|
-
/**
|
|
449
|
-
* Field holding a card's comments - `BoardComment[]` (or plain strings, or a
|
|
450
|
-
* number for a count only). Renders a comment-count badge that expands to a
|
|
451
|
-
* thread; provide the callbacks below to let users write / delete comments.
|
|
452
|
-
*/
|
|
453
|
-
commentsField?: keyof TData & string;
|
|
454
|
-
/** Fired when a comment is added on the card; append it to your data. */
|
|
455
|
-
onCommentAdd?: (row: TData, text: string) => void;
|
|
456
|
-
/** Fired when a comment's delete button is pressed; remove it from your data. */
|
|
457
|
-
onCommentDelete?: (row: TData, commentId: string | number) => void;
|
|
458
|
-
/**
|
|
459
|
-
* Field holding a card's attachments - an array or a number. Renders an
|
|
460
|
-
* attachment-count badge on the default card.
|
|
461
|
-
*/
|
|
462
|
-
attachmentsField?: keyof TData & string;
|
|
463
|
-
/**
|
|
464
|
-
* Field holding a cover colour (any CSS colour string) shown as a strip
|
|
465
|
-
* across the top of the default card.
|
|
466
|
-
*/
|
|
467
|
-
coverField?: keyof TData & string;
|
|
468
|
-
/**
|
|
469
|
-
* Enforce `wipLimit`: reject a drop / keyboard move that would push a lane
|
|
470
|
-
* past its limit (the card snaps back). Off by default (the limit is a
|
|
471
|
-
* soft, visual flag only).
|
|
472
|
-
*/
|
|
473
|
-
enforceWip?: boolean;
|
|
474
|
-
/** Let users collapse a lane to a slim strip by clicking its header. */
|
|
475
|
-
collapsibleLanes?: boolean;
|
|
476
|
-
/** Let users drag lane headers to reorder lanes (persisted with `persistKey`). */
|
|
477
|
-
reorderableLanes?: boolean;
|
|
478
|
-
/** Fired after a lane drag-reorder, with the new ordered lane ids. */
|
|
479
|
-
onLaneReorder?: (orderedIds: string[]) => void;
|
|
480
|
-
/**
|
|
481
|
-
* Enable inline lane rename: double-click a lane title to edit it. Fires
|
|
482
|
-
* with the lane id and new title - update your own lane config / data.
|
|
483
|
-
*/
|
|
484
|
-
onLaneRename?: (laneId: string, title: string) => void;
|
|
485
|
-
/**
|
|
486
|
-
* Per-swimlane summary shown in the band header (e.g. a points/$ total or a
|
|
487
|
-
* WIP count). Receives the swimlane's cards and its id; return a short string.
|
|
488
|
-
*/
|
|
489
|
-
swimlaneSummary?: (rows: TData[], swimId: string) => string;
|
|
490
|
-
/**
|
|
491
|
-
* Right-click (or long-press) a card to open a context menu. Return the
|
|
492
|
-
* menu items for that card; `ctx` gives board-native `moveTo(laneId)` and
|
|
493
|
-
* `edit()` helpers plus the lane list. Return empty/undefined for no menu.
|
|
494
|
-
*/
|
|
495
|
-
cardMenu?: (row: TData, ctx: BoardMenuContext<TData>) => ReadonlyArray<MenuItem> | undefined;
|
|
496
|
-
/** Right-click a lane header for a lane context menu (rename / clear / add / collapse). */
|
|
497
|
-
laneMenu?: (laneId: string, ctx: BoardLaneMenuContext<TData>) => ReadonlyArray<MenuItem> | undefined;
|
|
498
|
-
/**
|
|
499
|
-
* Truthy field marks a card as **blocked** (waiting on a dependency): a red
|
|
500
|
-
* corner + a "Blocked" badge on the card. If the value is a non-empty string
|
|
501
|
-
* it is used as the blocked **reason** (shown in the badge tooltip). A blocked
|
|
502
|
-
* card is **locked from moving** (drag + keyboard) until it is unblocked - set
|
|
503
|
-
* {@link BoardConfig.flagBlocksMoves} `false` for a purely visual flag.
|
|
504
|
-
*/
|
|
505
|
-
flagField?: keyof TData & string;
|
|
506
|
-
/** Whether a blocked (`flagField`) card is locked from moving. Defaults to `true`. */
|
|
507
|
-
flagBlocksMoves?: boolean;
|
|
508
|
-
/**
|
|
509
|
-
* Field holding a created/started date (Date | ISO string); shown as a
|
|
510
|
-
* relative **age** badge (e.g. `3d`).
|
|
511
|
-
*/
|
|
512
|
-
ageField?: keyof TData & string;
|
|
513
|
-
/**
|
|
514
|
-
* Fields to expose as a **facet filter bar** above the board - a chip per
|
|
515
|
-
* distinct value; selecting chips filters the visible cards.
|
|
516
|
-
*/
|
|
517
|
-
facets?: ReadonlyArray<keyof TData & string>;
|
|
518
|
-
/**
|
|
519
|
-
* Enable card **multi-select**: click to select, Ctrl/Cmd-click to toggle,
|
|
520
|
-
* and dragging a selected card moves the whole selection. Fires
|
|
521
|
-
* `onSelectionChange`.
|
|
522
|
-
*/
|
|
523
|
-
selectable?: boolean;
|
|
524
|
-
/** Fired when the selection changes, with the selected rows. */
|
|
525
|
-
onSelectionChange?: (rows: TData[]) => void;
|
|
526
|
-
/**
|
|
527
|
-
* Field holding a card's **child rows** (`TData[]`) - the card gets a
|
|
528
|
-
* children count and expands to show them as nested mini-cards (epic ->
|
|
529
|
-
* stories). Each child renders its title and, if present, its `groupBy` value.
|
|
530
|
-
*/
|
|
531
|
-
childrenField?: keyof TData & string;
|
|
532
|
-
/**
|
|
533
|
-
* Optional per-lane summary shown in the lane header (e.g. a story-point or
|
|
534
|
-
* dollar total). Receives the lane's cards (the current swimlane's, when
|
|
535
|
-
* `swimlaneBy` is set) and the lane id; return a short string.
|
|
536
|
-
*/
|
|
537
|
-
laneSummary?: (rows: TData[], laneId: string) => string;
|
|
538
|
-
/** Show the built-in card search box (default `true`). */
|
|
539
|
-
searchable?: boolean;
|
|
540
|
-
/** Placeholder for the search box. Defaults to `"Search cards..."`. */
|
|
541
|
-
searchPlaceholder?: string;
|
|
542
|
-
/**
|
|
543
|
-
* Virtualize each lane so only the cards in view are in the DOM - for boards
|
|
544
|
-
* with thousands of cards per lane. Assumes roughly uniform card height; set
|
|
545
|
-
* `cardHeight` to match your cards.
|
|
546
|
-
*/
|
|
547
|
-
virtualized?: boolean;
|
|
548
|
-
/** Estimated card height in px used by `virtualized` windowing (default 76). */
|
|
549
|
-
cardHeight?: number;
|
|
550
|
-
/**
|
|
551
|
-
* Persist the board layout (card positions, edits, collapsed lanes) to
|
|
552
|
-
* `localStorage` under this key, restored on load. Requires `getRowId` for
|
|
553
|
-
* stable identity across reloads.
|
|
554
|
-
*/
|
|
555
|
-
persistKey?: string;
|
|
556
|
-
/** Called whenever the board layout changes, with the serializable state. */
|
|
557
|
-
onLayoutChange?: (layout: BoardLayout) => void;
|
|
558
|
-
};
|
|
559
|
-
|
|
560
|
-
/**
|
|
561
|
-
* The built-in event detail drawer for the scheduler. Set `scheduler.drawer`
|
|
562
|
-
* (`true` for all fields, or this object) and clicking an event opens a drawer
|
|
563
|
-
* with an `SvForm` of its fields. Mirrors {@link BoardDrawerConfig}.
|
|
564
|
-
*/
|
|
565
|
-
export type SchedulerDrawerConfig<TData extends RowData = RowData> = {
|
|
566
|
-
/** Fields to show, in order. Omit for every column that has a `field`. */
|
|
567
|
-
fields?: ReadonlyArray<keyof TData & string>;
|
|
568
|
-
/** Drawer title - a string or derived from the row. Defaults to the title field. */
|
|
569
|
-
title?: string | ((row: TData) => string);
|
|
570
|
-
/** Which edge the drawer opens from. Defaults to `'right'`. */
|
|
571
|
-
side?: "right" | "left" | "top" | "bottom";
|
|
572
|
-
/** Drawer size (any CSS length). Defaults to `'380px'`. */
|
|
573
|
-
size?: string;
|
|
574
|
-
/** Save button label. Defaults to `'Save'`. */
|
|
575
|
-
submitLabel?: string;
|
|
576
|
-
/** Form columns inside the drawer. Defaults to `1`. */
|
|
577
|
-
columns?: number;
|
|
578
|
-
};
|
|
579
|
-
|
|
580
|
-
/** Emitted when an event is dragged to a new time (and/or resource). */
|
|
581
|
-
export type SchedulerEventMoveEvent<TData extends RowData = RowData> = {
|
|
582
|
-
/** The dragged row. */
|
|
583
|
-
row: TData;
|
|
584
|
-
/** New start / end after the move. */
|
|
585
|
-
start: Date;
|
|
586
|
-
end: Date;
|
|
587
|
-
/** Whether the event is all-day after the move. */
|
|
588
|
-
allDay: boolean;
|
|
589
|
-
/** Resource it came from (only with `resourceField`). */
|
|
590
|
-
fromResource?: string;
|
|
591
|
-
/** Resource it was dropped on (only with `resourceField`). */
|
|
592
|
-
toResource?: string;
|
|
593
|
-
};
|
|
594
|
-
|
|
595
|
-
/** Emitted when an event's start or end edge is dragged to resize it. */
|
|
596
|
-
export type SchedulerEventResizeEvent<TData extends RowData = RowData> = {
|
|
597
|
-
row: TData;
|
|
598
|
-
start: Date;
|
|
599
|
-
end: Date;
|
|
600
|
-
};
|
|
601
|
-
|
|
602
|
-
/**
|
|
603
|
-
* A drag-selected range (see `rangeSelectable`). `start`/`end` are a single
|
|
604
|
-
* CONTINUOUS datetime range - dragging across days makes it a longer span, not a
|
|
605
|
-
* per-day rectangle. `days` / `resourceIds` list the days / resources the range
|
|
606
|
-
* touched (for reference); `allDay` is true when the all-day row was dragged.
|
|
607
|
-
*/
|
|
608
|
-
export type SchedulerRangeSelection = {
|
|
609
|
-
start: Date;
|
|
610
|
-
end: Date;
|
|
611
|
-
allDay?: boolean;
|
|
612
|
-
/** Every day the range touched (one entry for a within-a-day drag). */
|
|
613
|
-
days: Date[];
|
|
614
|
-
/** Every resource the range touched (empty without `resourceField`). */
|
|
615
|
-
resourceIds: string[];
|
|
616
|
-
};
|
|
617
|
-
|
|
618
|
-
/** Emitted when an event's built-in editor/drawer is saved. */
|
|
619
|
-
export type SchedulerEventCommitEvent<TData extends RowData = RowData> = {
|
|
620
|
-
row: TData;
|
|
621
|
-
/** Only the fields that changed, `{ field: newValue }`. */
|
|
622
|
-
changes: Record<string, unknown>;
|
|
623
|
-
/** The full set of edited field values. */
|
|
624
|
-
values: Record<string, unknown>;
|
|
625
|
-
};
|
|
626
|
-
|
|
627
|
-
/**
|
|
628
|
-
* One override of a single occurrence of a recurring event (stored in the row's
|
|
629
|
-
* `recurrenceExceptionsField`). `occurrenceStart` identifies the occurrence (its
|
|
630
|
-
* original start, like an iCal `RECURRENCE-ID`); `deleted` removes just that one,
|
|
631
|
-
* otherwise the given fields override it. Times are the same ISO / Date shape you
|
|
632
|
-
* store on the row.
|
|
633
|
-
*/
|
|
634
|
-
export type SchedulerException = {
|
|
635
|
-
occurrenceStart: string | number | Date;
|
|
636
|
-
deleted?: boolean;
|
|
637
|
-
start?: string | number | Date;
|
|
638
|
-
end?: string | number | Date;
|
|
639
|
-
title?: string;
|
|
640
|
-
allDay?: boolean;
|
|
641
|
-
/**
|
|
642
|
-
* Per-occurrence overrides for ANY other field (e.g. attendees, calendar,
|
|
643
|
-
* color, resource). Merged over the row for just this occurrence, so "This
|
|
644
|
-
* event" can change fields beyond start / end / title / all-day.
|
|
645
|
-
*/
|
|
646
|
-
fields?: Record<string, unknown>;
|
|
647
|
-
};
|
|
648
|
-
|
|
649
|
-
/** How a change to a recurring event should apply. */
|
|
650
|
-
export type SchedulerEditScope = "occurrence" | "following" | "series";
|
|
651
|
-
|
|
652
|
-
/**
|
|
653
|
-
* Fired when a single occurrence of a recurring event is edited or deleted (the
|
|
654
|
-
* user chose "This event"). Append/merge `exception` into the row's
|
|
655
|
-
* `recurrenceExceptionsField`; for `deleted` it carries `{ deleted: true }`.
|
|
656
|
-
*/
|
|
657
|
-
export type SchedulerOccurrenceChangeEvent<TData extends RowData = RowData> = {
|
|
658
|
-
row: TData;
|
|
659
|
-
/** The occurrence's original start (its identity within the series). */
|
|
660
|
-
occurrenceStart: Date;
|
|
661
|
-
/** The override to store (already in real-instant time). */
|
|
662
|
-
exception: SchedulerException;
|
|
663
|
-
/**
|
|
664
|
-
* Which scope the user chose. `'occurrence'` (default): merge `exception` into
|
|
665
|
-
* the row. `'following'` ("this and all following"): split the series - stop
|
|
666
|
-
* the original series before `occurrenceStart` and start a NEW series at it
|
|
667
|
-
* carrying `exception`'s start/end/deleted. `'series'` never reaches here (it
|
|
668
|
-
* edits the base row directly). Handle `'following'` in your own data.
|
|
669
|
-
*/
|
|
670
|
-
scope: SchedulerEditScope;
|
|
671
|
-
};
|
|
672
|
-
|
|
673
|
-
/**
|
|
674
|
-
* Turns the grid into a calendar / scheduler. Set `scheduler` and the grid
|
|
675
|
-
* renders its rows as events on a Month / Week / Day / Agenda calendar (bucketed
|
|
676
|
-
* by time, and optionally split into per-resource columns) instead of a table.
|
|
677
|
-
* Dragging an event fires {@link SchedulerConfig.onEventMove} where you reassign
|
|
678
|
-
* the start / end (and resource) on your own data. Like the Kanban board, it is
|
|
679
|
-
* a pure *view of the grid*: it renders the grid's filtered + sorted rows and
|
|
680
|
-
* writes back only through callbacks, never mutating your data.
|
|
681
|
-
*/
|
|
682
|
-
export type SchedulerConfig<
|
|
683
|
-
TFeatures extends TableFeatures = TableFeatures,
|
|
684
|
-
TData extends RowData = RowData,
|
|
685
|
-
> = {
|
|
686
|
-
/** Field holding each event's start (`Date` | epoch-ms | ISO string). Required. */
|
|
687
|
-
startField: keyof TData & string;
|
|
688
|
-
/** Field holding the end. Omit to use `defaultDurationMin` from the start. */
|
|
689
|
-
endField?: keyof TData & string;
|
|
690
|
-
/** Boolean field marking an event as all-day (rendered in the all-day row). */
|
|
691
|
-
allDayField?: keyof TData & string;
|
|
692
|
-
/** Field for the event title. Defaults to the first column's field. */
|
|
693
|
-
titleField?: keyof TData & string;
|
|
694
|
-
/** Field holding a per-event accent color (any CSS color). Else `color`. */
|
|
695
|
-
colorField?: keyof TData & string;
|
|
696
|
-
/** Fallback accent color for every event. */
|
|
697
|
-
color?: string;
|
|
698
|
-
/**
|
|
699
|
-
* Field holding a SECONDARY accent color, rendered as a strip on the LEFT edge
|
|
700
|
-
* of the event - distinct from the main `colorField`. Lets an event encode two
|
|
701
|
-
* dimensions at once (e.g. main color = person, left strip = role).
|
|
702
|
-
*/
|
|
703
|
-
secondaryColorField?: keyof TData & string;
|
|
704
|
-
/**
|
|
705
|
-
* Field holding a free/busy status that drives a distinct visual treatment
|
|
706
|
-
* (Outlook-style): `'busy'` (default solid), `'free'` (hollow / outline),
|
|
707
|
-
* `'tentative'` (hatched), `'oof'` / `'outOfOffice'` (distinct tint). Ties to
|
|
708
|
-
* iCal `STATUS`. Unrecognised values render as busy.
|
|
709
|
-
*/
|
|
710
|
-
statusField?: keyof TData & string;
|
|
711
|
-
/**
|
|
712
|
-
* Field holding minutes-before-start for a reminder. When set (and the event
|
|
713
|
-
* is upcoming) the scheduler fires `onReminder` once as that lead time is
|
|
714
|
-
* crossed - pair it with a toast. Ties to iCal `VALARM`.
|
|
715
|
-
*/
|
|
716
|
-
reminderField?: keyof TData & string;
|
|
717
|
-
/** Fired once when an event's reminder lead time is crossed (see `reminderField`). */
|
|
718
|
-
onReminder?: (row: TData, minutesUntil: number) => void;
|
|
719
|
-
/**
|
|
720
|
-
* Field holding a {@link RecurrenceRule} (or array) - the row renders as one
|
|
721
|
-
* event per matching day in view, keeping its time-of-day + duration.
|
|
722
|
-
*/
|
|
723
|
-
recurrenceField?: keyof TData & string;
|
|
724
|
-
/**
|
|
725
|
-
* Field holding an array of {@link SchedulerException} - per-occurrence
|
|
726
|
-
* overrides of a recurring event (a moved / edited / deleted single instance).
|
|
727
|
-
* When set, editing a recurring occurrence offers "This event" vs "All events"
|
|
728
|
-
* and "This event" fires {@link onOccurrenceChange}.
|
|
729
|
-
*/
|
|
730
|
-
recurrenceExceptionsField?: keyof TData & string;
|
|
731
|
-
/** Event length in minutes when a row has a start but no `endField`. Default 60. */
|
|
732
|
-
defaultDurationMin?: number;
|
|
733
|
-
|
|
734
|
-
/** Which views to offer in the toolbar. Default all four. */
|
|
735
|
-
views?: ReadonlyArray<SchedulerView>;
|
|
736
|
-
/** The view shown first. Default `'month'`. */
|
|
737
|
-
initialView?: SchedulerView;
|
|
738
|
-
/** The date the calendar opens on. Defaults to "today". */
|
|
739
|
-
initialDate?: Date | number | string;
|
|
740
|
-
/**
|
|
741
|
-
* Controlled anchor date - when this changes the calendar navigates to it (a
|
|
742
|
-
* mini date-picker or external "go to" can drive the view). Pair with
|
|
743
|
-
* {@link onNavigate} for two-way sync.
|
|
744
|
-
*/
|
|
745
|
-
date?: Date | number | string;
|
|
746
|
-
/** Fired when the visible date changes (prev / next / today). */
|
|
747
|
-
onNavigate?: (date: Date) => void;
|
|
748
|
-
/** First day of the week, 0-6 (0 = Sunday). Default 0. */
|
|
749
|
-
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
750
|
-
/** Time-grid slot size in minutes (week / day snap granularity). Default 30. */
|
|
751
|
-
slotMinutes?: number;
|
|
752
|
-
/**
|
|
753
|
-
* Slot sizes (minutes) offered as a runtime picker in the Week / Day time-grid
|
|
754
|
-
* ruler, e.g. `[60, 30, 15, 5]`. When set, a size selector appears in the
|
|
755
|
-
* toolbar and the ruler subdivides accordingly; the active size starts at
|
|
756
|
-
* `slotMinutes`. Omit to hide the picker (the ruler still uses `slotMinutes`).
|
|
757
|
-
*/
|
|
758
|
-
slotSizes?: ReadonlyArray<number>;
|
|
759
|
-
/** First / last hour shown in the time-grid band (0-24). Default 0..24. */
|
|
760
|
-
dayStartHour?: number;
|
|
761
|
-
dayEndHour?: number;
|
|
762
|
-
|
|
763
|
-
// --- booking rules: working hours, non-working days, conflicts -------------
|
|
764
|
-
/**
|
|
765
|
-
* Working-hours window (hours, e.g. `{ start: 9, end: 17 }`). Time outside it
|
|
766
|
-
* is shaded in the Week / Day time-grid. Visual only - see `disableConflicts`
|
|
767
|
-
* to enforce.
|
|
768
|
-
*/
|
|
769
|
-
businessHours?: { start: number; end: number };
|
|
770
|
-
/** Weekday numbers (0 = Sun … 6 = Sat) shaded as non-working (e.g. `[0, 6]`). */
|
|
771
|
-
nonWorkingDays?: ReadonlyArray<number>;
|
|
772
|
-
/** Shade elapsed time on today's column (the past is "used up"). */
|
|
773
|
-
shadeUntilNow?: boolean;
|
|
774
|
-
/**
|
|
775
|
-
* Enforce the shaded time: reject a drag / resize / create that lands outside
|
|
776
|
-
* `businessHours` or on a `nonWorkingDays` day (snap back + flash). Without
|
|
777
|
-
* this the shading is a visual hint only.
|
|
778
|
-
*/
|
|
779
|
-
restrictToBusinessHours?: boolean;
|
|
780
|
-
/**
|
|
781
|
-
* Prevent double-booking: dragging / resizing / creating an event so it
|
|
782
|
-
* overlaps another event **on the same resource** is rejected and reverted.
|
|
783
|
-
*/
|
|
784
|
-
disableConflicts?: boolean;
|
|
785
|
-
/**
|
|
786
|
-
* Hard-blocked hour bands (e.g. a daily maintenance window `[{ start: 12, end: 13 }]`).
|
|
787
|
-
* Unlike `businessHours` these are ALWAYS non-bookable (drop / create rejected,
|
|
788
|
-
* no opt-in needed) and rendered as a distinct restricted (hatched) band.
|
|
789
|
-
*/
|
|
790
|
-
restrictedHours?: ReadonlyArray<{ start: number; end: number }>;
|
|
791
|
-
/** Specific calendar dates that are fully blocked (no bookings) - e.g. closures. */
|
|
792
|
-
restrictedDates?: ReadonlyArray<Date | number | string>;
|
|
793
|
-
/**
|
|
794
|
-
* Highlighted dates (holidays, launches …) - a coloured strip + optional label
|
|
795
|
-
* on that day's column / month cell. Decorative; does not block booking.
|
|
796
|
-
*/
|
|
797
|
-
specialDates?: ReadonlyArray<{ date: Date | number | string; label?: string; color?: string }>;
|
|
798
|
-
/** Earliest navigable / bookable date. Prev-nav stops here and creates are blocked before it. */
|
|
799
|
-
minDate?: Date | number | string;
|
|
800
|
-
/** Latest navigable / bookable date. Next-nav stops here and creates are blocked after it. */
|
|
801
|
-
maxDate?: Date | number | string;
|
|
802
|
-
/**
|
|
803
|
-
* Cap concurrent events per resource at any moment: a drag / resize / create
|
|
804
|
-
* that would make more than N events overlap on the same resource is rejected.
|
|
805
|
-
*/
|
|
806
|
-
maxEventsPerSlot?: number;
|
|
807
|
-
/**
|
|
808
|
-
* Enable **undo / redo** of drag-move + resize with `Ctrl/Cmd+Z` and
|
|
809
|
-
* `Ctrl/Cmd+Shift+Z` (or `Ctrl+Y`). The scheduler re-emits the move/resize
|
|
810
|
-
* callbacks with the reversed values, so your data follows.
|
|
811
|
-
*/
|
|
812
|
-
history?: boolean;
|
|
813
|
-
/**
|
|
814
|
-
* Show the current-time indicator - a line across today's column(s) in the
|
|
815
|
-
* Week / Day time-grid and the Day timeline, tracking the local time. On by
|
|
816
|
-
* default; set to `false` to hide it.
|
|
817
|
-
*/
|
|
818
|
-
nowIndicator?: boolean;
|
|
819
|
-
/**
|
|
820
|
-
* IANA time zone (e.g. `'America/New_York'`) the whole calendar is shown in -
|
|
821
|
-
* the hour ruler, event positions, day boundaries, all-day grouping and the
|
|
822
|
-
* now-line. Defaults to the browser's local zone. Event `start`/`end` must be
|
|
823
|
-
* instant-unambiguous (UTC / offset ISO or epoch ms) for this to be correct;
|
|
824
|
-
* bare local strings are read as wall-clock in this zone.
|
|
825
|
-
*/
|
|
826
|
-
timeZone?: string;
|
|
827
|
-
/**
|
|
828
|
-
* Extra read-only hour rulers for other zones (a "world clock"), shown left of
|
|
829
|
-
* the primary ruler in the Week / Day time-grid. Each entry's `label` heads its
|
|
830
|
-
* column (defaults to a short zone abbreviation).
|
|
831
|
-
*/
|
|
832
|
-
secondaryTimeZones?: ReadonlyArray<{ id: string; label?: string }>;
|
|
833
|
-
/**
|
|
834
|
-
* How overlapping time-grid events are laid out. `split` (default) divides the
|
|
835
|
-
* width evenly per collision; `cap` shows up to `maxColumns` then a clickable
|
|
836
|
-
* `+N more` tile; `stack` overlaps them with an offset instead of shrinking.
|
|
837
|
-
*/
|
|
838
|
-
collisionMode?: SchedulerCollisionMode;
|
|
839
|
-
/** For `collisionMode: 'cap'`: max side-by-side columns before overflow (min 2). Default 3. */
|
|
840
|
-
maxColumns?: number;
|
|
841
|
-
/** How many days the agenda view spans. Default 30. */
|
|
842
|
-
agendaDays?: number;
|
|
843
|
-
|
|
844
|
-
/**
|
|
845
|
-
* Field whose value groups events by resource (people, rooms, machines). In
|
|
846
|
-
* the Week / Day time-grid the columns split into resource x day groups; a
|
|
847
|
-
* resource filter/legend appears in every view. See {@link SchedulerResource}.
|
|
848
|
-
*/
|
|
849
|
-
resourceField?: keyof TData & string;
|
|
850
|
-
/** Explicit, ordered resources (with colors). Omit to derive from the data. */
|
|
851
|
-
resources?: ReadonlyArray<SchedulerResource>;
|
|
852
|
-
/**
|
|
853
|
-
* Time-grid resource grouping order. `false` (default) groups by resource then
|
|
854
|
-
* day (resource-major); `true` groups by day then resource (date-major), like
|
|
855
|
-
* Smart's `groupByDate`. Only affects Week / Day when `resourceField` is set.
|
|
856
|
-
*/
|
|
857
|
-
groupByDate?: boolean;
|
|
858
|
-
|
|
859
|
-
/** Timeline views only: width (px) of the left resource-label gutter. Default 160. */
|
|
860
|
-
resourceAreaWidth?: number;
|
|
861
|
-
/** `timelineDay` tick size + move/resize snap, in minutes. Default = `slotMinutes`. */
|
|
862
|
-
timelineSlotMinutes?: number;
|
|
863
|
-
/** Timeline views only: height (px) of one event lane inside a resource row. Default 26. */
|
|
864
|
-
timelineLaneHeight?: number;
|
|
865
|
-
|
|
866
|
-
/** Enable drag-to-move and edge-resize. Without it the calendar is read-only. */
|
|
867
|
-
editable?: boolean;
|
|
868
|
-
/** Fired when an event is dragged to a new time / resource. */
|
|
869
|
-
onEventMove?: (event: SchedulerEventMoveEvent<TData>) => void;
|
|
870
|
-
/** Fired when an event edge is dragged to resize it. */
|
|
871
|
-
onEventResize?: (event: SchedulerEventResizeEvent<TData>) => void;
|
|
872
|
-
/**
|
|
873
|
-
* Fired to create an event - double-clicking an empty slot, or confirming a
|
|
874
|
-
* pending range when no {@link onRangeSelect} is set. `allDay` is `true` when
|
|
875
|
-
* the slot / range is an all-day one (the all-day row, a month day cell, or a
|
|
876
|
-
* multi-day timeline zoom), so the handler can set the `allDayField`.
|
|
877
|
-
*/
|
|
878
|
-
onEventAdd?: (start: Date, end: Date, resourceId?: string, allDay?: boolean) => void;
|
|
879
|
-
/**
|
|
880
|
-
* Fired when the event's Delete button is used. Setting this shows a Delete
|
|
881
|
-
* button in the detail drawer (and a `Delete` item is easy to add via
|
|
882
|
-
* `eventMenu`). Remove the row from your data in the handler.
|
|
883
|
-
*/
|
|
884
|
-
onEventDelete?: (row: TData) => void;
|
|
885
|
-
/**
|
|
886
|
-
* Fired when a single occurrence of a recurring event is moved / resized /
|
|
887
|
-
* deleted with scope "This event". Merge `event.exception` into the row's
|
|
888
|
-
* `recurrenceExceptionsField` array (keyed by `occurrenceStart`).
|
|
889
|
-
*/
|
|
890
|
-
onOccurrenceChange?: (event: SchedulerOccurrenceChangeEvent<TData>) => void;
|
|
891
|
-
|
|
892
|
-
/**
|
|
893
|
-
* Selecting empty cells: click or drag across the time-grid / timeline to mark
|
|
894
|
-
* a time range (and, across days / resources, a rectangle of cells). Arrow keys
|
|
895
|
-
* move the selection and `Shift`+arrows extend it. Marking only *marks* the
|
|
896
|
-
* range - it does NOT create anything. The event is created on an explicit
|
|
897
|
-
* confirm: press `Enter`, or right-click the selection and choose "Add Event".
|
|
898
|
-
* Confirming fires {@link onRangeSelect}, or falls back to `onEventAdd` for the
|
|
899
|
-
* first cell; `Escape` cancels the marker.
|
|
900
|
-
*
|
|
901
|
-
* On by default; set to `false` to disable.
|
|
902
|
-
*/
|
|
903
|
-
rangeSelectable?: boolean;
|
|
904
|
-
/**
|
|
905
|
-
* Fired when a pending cell range is confirmed with `Enter` or the "Add Event"
|
|
906
|
-
* context menu (see {@link rangeSelectable}) - not on drag release.
|
|
907
|
-
*/
|
|
908
|
-
onRangeSelect?: (selection: SchedulerRangeSelection) => void;
|
|
909
|
-
/**
|
|
910
|
-
* Multi-selecting existing events: Ctrl/Cmd-click toggles, Shift-click
|
|
911
|
-
* range-selects; a plain click clears. Selected events move together when one
|
|
912
|
-
* is dragged, and `Delete` removes them (via `onEventDelete`).
|
|
913
|
-
*
|
|
914
|
-
* On by default; set to `false` to disable.
|
|
915
|
-
*/
|
|
916
|
-
eventSelectable?: boolean;
|
|
917
|
-
/** Fired when the set of multi-selected events changes. */
|
|
918
|
-
onEventSelectionChange?: (rows: TData[]) => void;
|
|
919
|
-
|
|
920
|
-
/**
|
|
921
|
-
* An "unscheduled" backlog list shown beside the Week / Day grid: drag an item
|
|
922
|
-
* onto the calendar to schedule it. Each item is `{ id, title, durationMin?,
|
|
923
|
-
* color? }`. Dropping fires {@link onSchedule} with the drop time + resource.
|
|
924
|
-
*/
|
|
925
|
-
unscheduled?: ReadonlyArray<{ id: string; title: string; durationMin?: number; color?: string }>;
|
|
926
|
-
/** Optional heading for the unscheduled backlog panel. Default "Unscheduled". */
|
|
927
|
-
backlogTitle?: string;
|
|
928
|
-
/** Fired when an unscheduled item is dropped on the grid - create an event from it. */
|
|
929
|
-
onSchedule?: (item: { id: string; title: string; durationMin?: number; color?: string }, start: Date, resourceId?: string) => void;
|
|
930
|
-
/**
|
|
931
|
-
* Fired when an event is dragged OFF the calendar onto the backlog panel -
|
|
932
|
-
* remove it from the schedule (and typically push it back to `unscheduled`).
|
|
933
|
-
* Requires the backlog panel (an `unscheduled` list) to be visible.
|
|
934
|
-
*/
|
|
935
|
-
onUnschedule?: (row: TData) => void;
|
|
936
|
-
|
|
937
|
-
/** Custom event body. Receives the row. Omit for the built-in default (title). */
|
|
938
|
-
event?: Snippet<[TData]>;
|
|
939
|
-
/**
|
|
940
|
-
* Hover tooltip for an event. Set a `Snippet<[TData]>` for custom content, or
|
|
941
|
-
* `true` for the built-in tooltip (title + time + resource). Omit to disable.
|
|
942
|
-
*/
|
|
943
|
-
tooltip?: boolean | Snippet<[TData]>;
|
|
944
|
-
/** Delay (ms) before the hover tooltip opens. Default 400. */
|
|
945
|
-
tooltipDelay?: number;
|
|
946
|
-
/** Built-in detail drawer: `true` for all fields, or a config object. */
|
|
947
|
-
drawer?: boolean | SchedulerDrawerConfig<TData>;
|
|
948
|
-
/** Fired when the drawer / editor is saved. */
|
|
949
|
-
onEventCommit?: (event: SchedulerEventCommitEvent<TData>) => void;
|
|
950
|
-
/** Right-click menu for an event. Return items or `undefined` to suppress. */
|
|
951
|
-
eventMenu?: (row: TData) => MenuItem[] | undefined;
|
|
952
|
-
|
|
953
|
-
/** Show the search box (binds to the grid's global filter). Default `true`. */
|
|
954
|
-
searchable?: boolean;
|
|
955
|
-
searchPlaceholder?: string;
|
|
956
|
-
};
|
|
957
|
-
|
|
958
|
-
export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> = {
|
|
959
|
-
data: ReadonlyArray<TData>;
|
|
960
|
-
columns: Array<ColumnDef<TFeatures, TData>>;
|
|
961
|
-
/**
|
|
962
|
-
* Kanban board mode. When set, the grid renders its rows as cards in
|
|
963
|
-
* horizontal lanes (bucketed by `board.groupBy`) instead of a table. See
|
|
964
|
-
* {@link BoardConfig}.
|
|
965
|
-
*/
|
|
966
|
-
board?: BoardConfig<TFeatures, TData>;
|
|
967
|
-
/**
|
|
968
|
-
* Scheduler / calendar mode. When set, the grid renders its rows as events on
|
|
969
|
-
* a Month / Week / Day / Agenda calendar instead of a table. See
|
|
970
|
-
* {@link SchedulerConfig}.
|
|
971
|
-
*/
|
|
972
|
-
scheduler?: SchedulerConfig<TFeatures, TData>;
|
|
973
|
-
/**
|
|
974
|
-
* Chart view. When set, the grid renders its FILTERED + SORTED rows as a chart
|
|
975
|
-
* instead of a table (search / filters / sort flow through). Unlike board and
|
|
976
|
-
* scheduler, the renderer is free - the grid lazy-loads a built-in `SvChart`
|
|
977
|
-
* view, overridable via `registerChartView`. See {@link ChartViewConfig}.
|
|
978
|
-
*/
|
|
979
|
-
chart?: ChartViewConfig<TFeatures, TData>;
|
|
980
|
-
/**
|
|
981
|
-
* Pivot mode. When set (and `pivotMode` is on), the grid renders its rows as a
|
|
982
|
-
* pivot table in place - the same grid, aggregated across `pivot.rows` /
|
|
983
|
-
* `pivot.cols` with nested column headers - instead of the flat table. The
|
|
984
|
-
* pivot ENGINE ships in `@svgrid/enterprise`; call `enablePivot()` (or
|
|
985
|
-
* `installEnterprise(api)`) to register it, otherwise an upsell note shows.
|
|
986
|
-
* See {@link GridPivotConfig}.
|
|
987
|
-
*/
|
|
988
|
-
pivot?: GridPivotConfig<TData>;
|
|
989
|
-
/**
|
|
990
|
-
* Whether pivot mode is currently active. Defaults to `true` when `pivot` is
|
|
991
|
-
* set. Bindable so a toolbar toggle can flip between the pivot and the flat
|
|
992
|
-
* table over the same data.
|
|
993
|
-
*/
|
|
994
|
-
pivotMode?: boolean;
|
|
995
|
-
/** Fired when the in-grid Pivot toggle flips `pivotMode`. */
|
|
996
|
-
onPivotModeChange?: (on: boolean) => void;
|
|
997
|
-
/**
|
|
998
|
-
* Right-click context menu. `true` shows the default item set (copy, cut,
|
|
999
|
-
* paste, clear, insert row above/below, remove row, remove column). Pass an
|
|
1000
|
-
* array to customize: strings are built-in keys, `"separator"` is a divider,
|
|
1001
|
-
* and objects are custom items. Omitted/`false` disables the menu (native
|
|
1002
|
-
* browser menu shows instead).
|
|
1003
|
-
*/
|
|
1004
|
-
contextMenu?: boolean | ReadonlyArray<ContextMenuItem<TData>>;
|
|
1005
|
-
/**
|
|
1006
|
-
* The feature set built with `tableFeatures({ ... })`. Optional - the
|
|
1007
|
-
* `sortable` / `filterable` / `groupable` shortcuts below inject the
|
|
1008
|
-
* matching feature for you, so a grid can be configured entirely from
|
|
1009
|
-
* the boolean shortcuts without importing the feature constants.
|
|
1010
|
-
*/
|
|
1011
|
-
features?: TFeatures;
|
|
1012
|
-
/**
|
|
1013
|
-
* Convenience shortcuts to switch a whole capability on without wiring
|
|
1014
|
-
* `features` or the finer-grained props by hand. Every capability is OFF
|
|
1015
|
-
* by default - a bare grid is a plain read-only table - so set the
|
|
1016
|
-
* shortcut `true` to opt in. (`false` / omitted both leave it off; the
|
|
1017
|
-
* shortcut is mainly there to turn things ON.)
|
|
1018
|
-
*
|
|
1019
|
-
* `sortable` - column sorting (injects `rowSortingFeature`)
|
|
1020
|
-
* `filterable` - column filtering (injects `columnFilteringFeature`)
|
|
1021
|
-
* `editable` - inline cell editing (alias of `enableInlineEditing`)
|
|
1022
|
-
* `groupable` - row grouping controls(alias of `showGroupingControls`,
|
|
1023
|
-
* also injects `columnGroupingFeature`)
|
|
1024
|
-
* `pageable` - pagination footer (alias of `showPagination`)
|
|
1025
|
-
*
|
|
1026
|
-
* Fine-grained props (`enableInlineEditing`, `showPagination`, ...) still
|
|
1027
|
-
* work; the shortcut wins only when it is explicitly set.
|
|
1028
|
-
*/
|
|
1029
|
-
sortable?: boolean;
|
|
1030
|
-
filterable?: boolean;
|
|
1031
|
-
editable?: boolean;
|
|
1032
|
-
/**
|
|
1033
|
-
* Client-side tree data: nest rows into a hierarchy by parent id.
|
|
1034
|
-
*
|
|
1035
|
-
* ```svelte
|
|
1036
|
-
* <SvGrid {data} {columns} treeData={{ parentField: 'managerId', column: 'name' }} />
|
|
1037
|
-
* ```
|
|
1038
|
-
*
|
|
1039
|
-
* Unlike grouping, tree rows are real data rows - they keep their cells,
|
|
1040
|
-
* editing and selection, and only gain an expander plus indentation in
|
|
1041
|
-
* `column`. Rows whose parent is missing become roots rather than vanishing.
|
|
1042
|
-
*
|
|
1043
|
-
* For NESTED source data (`children: [...]`), flatten it first with
|
|
1044
|
-
* `flattenTreeData(data, { childrenField: 'children' })` and point
|
|
1045
|
-
* `parentField` at the `__parentId` it stamps on.
|
|
1046
|
-
*
|
|
1047
|
-
* Setting this replaces row grouping - a row cannot be both.
|
|
1048
|
-
*/
|
|
1049
|
-
treeData?: {
|
|
1050
|
-
/** Field holding each row's parent id. */
|
|
1051
|
-
parentField: string;
|
|
1052
|
-
/** Field holding the row's own id. Defaults to `'id'`. */
|
|
1053
|
-
idField?: string;
|
|
1054
|
-
/**
|
|
1055
|
-
* Column id that carries the expander + indentation. Defaults to the first
|
|
1056
|
-
* visible column.
|
|
1057
|
-
*/
|
|
1058
|
-
column?: string;
|
|
1059
|
-
/** Indent per depth level, in px. Default `12`. */
|
|
1060
|
-
indentPx?: number;
|
|
1061
|
-
};
|
|
1062
|
-
groupable?: boolean;
|
|
1063
|
-
/**
|
|
1064
|
-
* Render a subtotal row after each group's children, carrying that group's
|
|
1065
|
-
* aggregate values under the columns they belong to (the columns with an
|
|
1066
|
-
* `aggregate` set). Off by default.
|
|
1067
|
-
*
|
|
1068
|
-
* Footers are inserted after paging, so they never count against `pageSize` -
|
|
1069
|
-
* a page shows its `pageSize` data rows plus whatever footers close on it.
|
|
1070
|
-
*/
|
|
1071
|
-
groupFooters?: boolean;
|
|
1072
|
-
/**
|
|
1073
|
-
* Append a grand-total row at the very end, aggregating the whole filtered
|
|
1074
|
-
* set (not just the current page) with each column's `aggregate` function.
|
|
1075
|
-
*
|
|
1076
|
-
* Independent of `groupFooters`: use it on a flat grid for a bottom totals
|
|
1077
|
-
* line, or alongside group subtotals for both. Like group footers it is
|
|
1078
|
-
* appended after paging, so it never counts against `pageSize` - but it is
|
|
1079
|
-
* only appended on the LAST page, so a total never appears mid-dataset.
|
|
1080
|
-
* Columns without an `aggregate` are left blank.
|
|
1081
|
-
*/
|
|
1082
|
-
grandTotalRow?: boolean;
|
|
1083
|
-
/**
|
|
1084
|
-
* How grouped rows are displayed.
|
|
1085
|
-
*
|
|
1086
|
-
* - `groupRows` (default): a full-width banner row per group. Unchanged
|
|
1087
|
-
* behaviour - existing grids are untouched.
|
|
1088
|
-
* - `singleColumn`: one synthetic "Group" column holding every level,
|
|
1089
|
-
* indented by depth.
|
|
1090
|
-
* - `multipleColumns`: one synthetic column per grouped field.
|
|
1091
|
-
*
|
|
1092
|
-
* Both column modes hide the grouped source columns, since their values move
|
|
1093
|
-
* into the auto column(s), and render group rows as ordinary rows so their
|
|
1094
|
-
* aggregate cells line up under the real columns.
|
|
1095
|
-
*/
|
|
1096
|
-
groupDisplayMode?: GroupDisplayType;
|
|
1097
|
-
/** Header for the combined `singleColumn` auto-group column. Default `"Group"`. */
|
|
1098
|
-
autoGroupColumnHeader?: string;
|
|
1099
|
-
/** Width (px) of each auto-group column. Default `220`. */
|
|
1100
|
-
autoGroupColumnWidth?: number;
|
|
1101
|
-
pageable?: boolean;
|
|
1102
|
-
loading?: boolean;
|
|
1103
|
-
/**
|
|
1104
|
-
* Render `loading` as a non-blocking overlay instead of replacing the
|
|
1105
|
-
* whole grid: the current rows stay visible (dimmed, with a top progress
|
|
1106
|
-
* bar) during a refetch, and the first load shows shimmer skeleton rows.
|
|
1107
|
-
* Ideal for server-paged grids so paging/sorting doesn't flash. Defaults
|
|
1108
|
-
* to `false` (the classic full "Loading..." replacement).
|
|
1109
|
-
*/
|
|
1110
|
-
loadingOverlay?: boolean;
|
|
1111
|
-
/** Skeleton placeholder rows to show on first load. Defaults to 8. */
|
|
1112
|
-
loadingSkeletonRows?: number;
|
|
1113
|
-
error?: string | null;
|
|
1114
|
-
emptyMessage?: string;
|
|
1115
|
-
/**
|
|
1116
|
-
* The single place to localize the grid. One object with two fields:
|
|
1117
|
-
*
|
|
1118
|
-
* - `locale` - BCP-47 tag(s) for the DATA: accent/case-insensitive filter
|
|
1119
|
-
* matching AND every column's number / currency / percent / date formatting
|
|
1120
|
-
* (when the column's own `format.locales` is unset). The default for
|
|
1121
|
-
* `filterLocale` and per-column format locales.
|
|
1122
|
-
* - `text` - overrides for the grid's own UI STRINGS (empty state, tool panel,
|
|
1123
|
-
* pager, status bar, filter operator labels, context-menu items, upsell
|
|
1124
|
-
* notes). Any subset overrides the English defaults; unset keys stay English.
|
|
1125
|
-
*
|
|
1126
|
-
* ```svelte
|
|
1127
|
-
* <SvGrid localization={{ locale: 'fr-FR', text: { noRows: 'Aucune ligne' } }} />
|
|
1128
|
-
* ```
|
|
1129
|
-
*
|
|
1130
|
-
* Omitting it (or any field) is a no-op. See {@link GridMessages}.
|
|
1131
|
-
*/
|
|
1132
|
-
localization?: GridLocalization;
|
|
1133
|
-
showGlobalFilter?: boolean;
|
|
1134
|
-
showColumnFilters?: boolean;
|
|
1135
|
-
/**
|
|
1136
|
-
* Quick way to pick a single filtering UI. When set it controls which of
|
|
1137
|
-
* the three filter surfaces appears (and is overridden per-surface by the
|
|
1138
|
-
* `showGlobalFilter` / `showColumnFilters` / `showFilterRow` props).
|
|
1139
|
-
* Defaults to `'menu'` (only the column menu's filter section is shown).
|
|
1140
|
-
*/
|
|
1141
|
-
filterMode?: "row" | "menu" | "global" | "none";
|
|
1142
|
-
showGroupingControls?: boolean;
|
|
1143
|
-
showRowSelection?: boolean;
|
|
1144
|
-
showPagination?: boolean;
|
|
1145
|
-
/** Initial page size when pagination is enabled. Defaults to 10. */
|
|
1146
|
-
pageSize?: number;
|
|
1147
|
-
/** Page-size choices shown in the footer's selector. Defaults to `[10, 25, 50, 100]`. */
|
|
1148
|
-
pageSizeOptions?: number[];
|
|
1149
|
-
/**
|
|
1150
|
-
* Where the pagination footer sits: `'bottom'` (default), `'top'`, or `'both'`.
|
|
1151
|
-
* The status bar (when enabled) always stays at the bottom.
|
|
1152
|
-
*/
|
|
1153
|
-
paginationPosition?: 'top' | 'bottom' | 'both';
|
|
1154
|
-
/**
|
|
1155
|
-
* Server-side pagination. When `true`, the grid renders its native
|
|
1156
|
-
* pagination footer from the `rowCount` / `pageIndex` you provide (rather
|
|
1157
|
-
* than counting the local rows), does NOT slice `data` (the rows you pass are
|
|
1158
|
-
* treated as the current page), and emits `onPaginationChange` when the user
|
|
1159
|
-
* pages or changes page size. Pair with `externalSort` / `externalFilter`
|
|
1160
|
-
* and a server data source. Requires `showPagination` / `pageable` to show
|
|
1161
|
-
* the footer. Controlled: you own `pageIndex` + `pageSize` + `rowCount`.
|
|
1162
|
-
*/
|
|
1163
|
-
externalPagination?: boolean;
|
|
1164
|
-
/** Total rows on the server, for the footer's range + page count. Used with `externalPagination`. */
|
|
1165
|
-
rowCount?: number;
|
|
1166
|
-
/** Current 0-based page index. Used with `externalPagination` (controlled). */
|
|
1167
|
-
pageIndex?: number;
|
|
1168
|
-
/**
|
|
1169
|
-
* Fires when the user changes page or page size while `externalPagination`
|
|
1170
|
-
* is on. Fetch that page and update `data` / `rowCount` / `pageIndex`.
|
|
1171
|
-
*/
|
|
1172
|
-
onPaginationChange?: (pagination: { pageIndex: number; pageSize: number }) => void;
|
|
1173
|
-
virtualization?: boolean;
|
|
1174
|
-
/** Row height in pixels. Pass a function `(rowIndex) => px` for
|
|
1175
|
-
* per-row variable heights (e.g. an interactive row-resize feature).
|
|
1176
|
-
* Defaults to 30. */
|
|
1177
|
-
rowHeight?: number | ((rowIndex: number) => number);
|
|
1178
|
-
/**
|
|
1179
|
-
* Size each row to its own content instead of a fixed height: cell text wraps
|
|
1180
|
-
* and the row grows to fit the tallest cell. Rows are measured after they
|
|
1181
|
-
* render, so this works with virtualization - `rowHeight` (or 30) is the
|
|
1182
|
-
* estimate used before a row has been measured, which keeps the scrollbar
|
|
1183
|
-
* stable while you scroll into new rows.
|
|
1184
|
-
*
|
|
1185
|
-
* Costs a measurement pass per row, so prefer a fixed `rowHeight` when your
|
|
1186
|
-
* content is uniform. Ignored when `rowHeight` is a function (you are already
|
|
1187
|
-
* supplying per-row heights).
|
|
1188
|
-
*/
|
|
1189
|
-
autoRowHeight?: boolean;
|
|
1190
|
-
/**
|
|
1191
|
-
* Height (px) of a single column-header level row. With multi-level
|
|
1192
|
-
* (grouped) headers the total header height is `levels * headerHeight`,
|
|
1193
|
-
* since each level renders as its own row. When omitted, header rows size
|
|
1194
|
-
* to their content (the default). Does not affect the filter row.
|
|
1195
|
-
*/
|
|
1196
|
-
headerHeight?: number;
|
|
1197
|
-
overscan?: number;
|
|
1198
|
-
/**
|
|
1199
|
-
* Height of the grid's scrollable shell. A number is treated as pixels;
|
|
1200
|
-
* a string is used as-is, so callers can pass `'100%'` or `'auto'` to
|
|
1201
|
-
* make the grid fill its parent. Defaults to 520 px.
|
|
1202
|
-
*/
|
|
1203
|
-
containerHeight?: number | string;
|
|
1204
|
-
columnVirtualization?: boolean;
|
|
1205
|
-
columnOverscan?: number;
|
|
1206
|
-
columnWidth?: number;
|
|
1207
|
-
/**
|
|
1208
|
-
* Columns pinned to the left/right edge on mount. Each entry is a
|
|
1209
|
-
* column id (matches `ColumnDef.field` when no explicit id is set).
|
|
1210
|
-
* The internal pinning state is seeded once at mount; user-driven
|
|
1211
|
-
* pinning via the column menu still works and overrides this default.
|
|
1212
|
-
* Requires `columnVirtualization={false}` to be visible in the menu
|
|
1213
|
-
* UI (sticky positioning can't co-exist with column virtualization
|
|
1214
|
-
* since the virtualizer recycles DOM nodes).
|
|
1215
|
-
*/
|
|
1216
|
-
initialColumnPinning?: {
|
|
1217
|
-
left?: ReadonlyArray<string>;
|
|
1218
|
-
right?: ReadonlyArray<string>;
|
|
1219
|
-
};
|
|
1220
|
-
/**
|
|
1221
|
-
* When `true`, columns are scaled proportionally so their total width
|
|
1222
|
-
* fills the viewport (no empty space on the right). Disabled by
|
|
1223
|
-
* default - explicit `width` values are used as-is. User resizes still
|
|
1224
|
-
* win once they happen.
|
|
1225
|
-
*/
|
|
1226
|
-
fitColumns?: boolean;
|
|
1227
|
-
/**
|
|
1228
|
-
* Make the grid usable on narrow screens. When the grid's own width drops
|
|
1229
|
-
* below the breakpoint (default `640`px), pinned columns are un-pinned so the
|
|
1230
|
-
* whole grid pans, `fitColumns` scaling is suspended (columns keep their
|
|
1231
|
-
* natural widths and scroll), touch panning is smoothed, and columns whose
|
|
1232
|
-
* `hideBelow` exceeds the width are hidden. `true` uses the default
|
|
1233
|
-
* breakpoint; pass `{ breakpoint }` to change it. Off by default.
|
|
1234
|
-
*/
|
|
1235
|
-
responsive?: boolean | { breakpoint?: number };
|
|
1236
|
-
showFilterMenu?: boolean;
|
|
1237
|
-
showFilterRow?: boolean;
|
|
1238
|
-
enableCellSelection?: boolean;
|
|
1239
|
-
/**
|
|
1240
|
-
* Highlight the row under the pointer. Default **false** - the hover tint can
|
|
1241
|
-
* compete with the cell selection / fill marquee. Set `true` to opt in; when
|
|
1242
|
-
* on, the hover no longer paints over selected cells so the selection stays
|
|
1243
|
-
* visible.
|
|
1244
|
-
*/
|
|
1245
|
-
enableRowHover?: boolean;
|
|
1246
|
-
/**
|
|
1247
|
-
* Prepend a header row (the column labels) to copied cell ranges, so pasting
|
|
1248
|
-
* into Excel / Sheets includes the headers. Applies per copied range.
|
|
1249
|
-
*/
|
|
1250
|
-
copyHeadersToClipboard?: boolean;
|
|
1251
|
-
/**
|
|
1252
|
-
* Transform each cell value on its way to the clipboard - e.g. strip
|
|
1253
|
-
* currency symbols, expand codes to labels, or redact. Receives the display
|
|
1254
|
-
* value plus the row/column context; return the string (or value) to copy.
|
|
1255
|
-
*/
|
|
1256
|
-
processCellForClipboard?: (params: {
|
|
1257
|
-
value: unknown;
|
|
1258
|
-
column: unknown;
|
|
1259
|
-
row: TData;
|
|
1260
|
-
rowIndex: number;
|
|
1261
|
-
columnId: string;
|
|
1262
|
-
}) => unknown;
|
|
1263
|
-
enableInlineEditing?: boolean;
|
|
1264
|
-
/**
|
|
1265
|
-
* Full-row editing. When `true`, starting an edit puts the WHOLE row into
|
|
1266
|
-
* edit mode - every editable cell shows an inline editor at once - and a
|
|
1267
|
-
* single Enter (or focus leaving the row) commits all of them; Esc cancels
|
|
1268
|
-
* the whole row. Requires `enableInlineEditing`. The full-row editor covers
|
|
1269
|
-
* text / number / date / datetime / checkbox / list-select editor types.
|
|
1270
|
-
*/
|
|
1271
|
-
fullRowEditing?: boolean;
|
|
1272
|
-
enableRowSummaries?: boolean;
|
|
1273
|
-
/**
|
|
1274
|
-
* Excel-style status bar under the grid showing live aggregates of the
|
|
1275
|
-
* selected cell range (count, numeric count, sum, average, min, max).
|
|
1276
|
-
* `true` shows the default set; pass `{ aggregates: [...] }` to choose
|
|
1277
|
-
* which. Requires `enableCellSelection`.
|
|
1278
|
-
*/
|
|
1279
|
-
statusBar?:
|
|
1280
|
-
| boolean
|
|
1281
|
-
| {
|
|
1282
|
-
aggregates?: ReadonlyArray<
|
|
1283
|
-
"count" | "numericCount" | "sum" | "avg" | "min" | "max"
|
|
1284
|
-
>;
|
|
1285
|
-
};
|
|
1286
|
-
/**
|
|
1287
|
-
* Show the docked tool panel - the enterprise sidebar with Columns and
|
|
1288
|
-
* Filters tabs. A "Columns & Filters" button appears in a toolbar above the
|
|
1289
|
-
* grid; the panel docks on the right edge.
|
|
1290
|
-
*/
|
|
1291
|
-
toolPanel?: boolean;
|
|
1292
|
-
/**
|
|
1293
|
-
* Integrated charting: `true` for the zero-config docked chart panel, or a
|
|
1294
|
-
* {@link ChartingConfig} object to author defaults + advanced options.
|
|
1295
|
-
*/
|
|
1296
|
-
charting?: boolean | ChartingConfig<TData>;
|
|
1297
|
-
/**
|
|
1298
|
-
* Render the header column menu (⋮) as a tabbed popover - **General**,
|
|
1299
|
-
* **Filter**, and **Columns** tabs (the AG-Grid layout). Defaults to `false`,
|
|
1300
|
-
* which keeps the flat menu (actions list + "Choose columns" submenu).
|
|
1301
|
-
*/
|
|
1302
|
-
columnMenuTabs?: boolean;
|
|
1303
|
-
/** Open the tool panel on first render (instead of collapsed). */
|
|
1304
|
-
toolPanelDefaultOpen?: boolean;
|
|
1305
|
-
/** Which tab the tool panel starts on. Defaults to `'columns'`. */
|
|
1306
|
-
toolPanelDefaultTab?: "columns" | "filters";
|
|
1307
|
-
/**
|
|
1308
|
-
* Quick way to pick which selection surfaces are active. `'row'` shows the
|
|
1309
|
-
* selection checkbox column only, `'cell'` allows rectangle/range cell
|
|
1310
|
-
* selection only, `'both'` (default) enables both, `'none'` disables both.
|
|
1311
|
-
* Overridden per-surface by `showRowSelection` / `enableCellSelection`.
|
|
1312
|
-
*/
|
|
1313
|
-
selectionMode?: "row" | "cell" | "both" | "none";
|
|
1314
|
-
/**
|
|
1315
|
-
* Render a leading row-number column (1-based) before any selection
|
|
1316
|
-
* column. Useful as a permanent anchor when scrolling wide grids.
|
|
1317
|
-
*/
|
|
1318
|
-
showRowNumbers?: boolean;
|
|
1319
|
-
/**
|
|
1320
|
-
* Paint alternating data rows with the `--sg-row-alt-bg` color (zebra
|
|
1321
|
-
* striping). Only data rows stripe - pinned, group, detail, and summary
|
|
1322
|
-
* rows keep their single background. Defaults to `false`.
|
|
1323
|
-
*/
|
|
1324
|
-
zebraRows?: boolean;
|
|
1325
|
-
/**
|
|
1326
|
-
* Width (px) of the row-number column. Defaults to 56, which fits up
|
|
1327
|
-
* to "99,999"; bump this when the dataset crosses six digits so the
|
|
1328
|
-
* largest row number stays fully visible at the bottom of a scroll.
|
|
1329
|
-
*/
|
|
1330
|
-
rowNumberWidth?: number;
|
|
1331
|
-
/** Receives the imperative grid API once the component has mounted. */
|
|
1332
|
-
onApiReady?: (api: SvGridApi<TFeatures, TData>) => void;
|
|
1333
|
-
/**
|
|
1334
|
-
* Fires whenever the row-selection state changes. The first argument
|
|
1335
|
-
* is the new selection record `{ [rowId]: true }`; the second is the
|
|
1336
|
-
* array of selected `TData` rows.
|
|
1337
|
-
*/
|
|
1338
|
-
onRowSelectionChange?: (
|
|
1339
|
-
selection: Record<string, boolean>,
|
|
1340
|
-
rows: TData[],
|
|
1341
|
-
) => void;
|
|
1342
|
-
/**
|
|
1343
|
-
* Fires whenever the cell-selection rectangle changes (mouse, keyboard,
|
|
1344
|
-
* or `api.selectCells()`). `ranges` matches `api.getSelected()` -
|
|
1345
|
-
* `[rowStart, colStart, rowEnd, colEnd]` rectangles in grid coords.
|
|
1346
|
-
* Empty array when the user clears the selection.
|
|
1347
|
-
*/
|
|
1348
|
-
onCellSelectionChange?: (
|
|
1349
|
-
ranges: Array<[number, number, number, number]>,
|
|
1350
|
-
) => void;
|
|
1351
|
-
/**
|
|
1352
|
-
* When `true`, the grid records sort state (and renders sort indicators
|
|
1353
|
-
* + cycling on headers) but does NOT actually re-order the rows. The
|
|
1354
|
-
* consumer is expected to sort `data` themselves - typically via
|
|
1355
|
-
* `onSortingChange`. Use this for tree/hierarchical data, where a flat
|
|
1356
|
-
* global sort would break parent-child adjacency. Defaults to `false`.
|
|
1357
|
-
*/
|
|
1358
|
-
externalSort?: boolean;
|
|
1359
|
-
/**
|
|
1360
|
-
* Fires whenever the sort clauses change. Receives the new array of
|
|
1361
|
-
* `{ id, desc }` entries. Pair with `externalSort={true}` when the
|
|
1362
|
-
* consumer wants to own the row ordering.
|
|
1363
|
-
*/
|
|
1364
|
-
onSortingChange?: (sorting: Array<{ id: string; desc: boolean }>) => void;
|
|
1365
|
-
/**
|
|
1366
|
-
* The sort state to start in - `{ id, desc }` entries. Use with `externalSort`
|
|
1367
|
-
* when the initial ordering is decided server-side (e.g. a URL `?sort=` param
|
|
1368
|
-
* read in a SvelteKit `load`), so the header sort indicators match the already-
|
|
1369
|
-
* sorted data on first render. Applied once at mount; user sorting takes over.
|
|
1370
|
-
*/
|
|
1371
|
-
initialSorting?: Array<{ id: string; desc: boolean }>;
|
|
1372
|
-
/**
|
|
1373
|
-
* When `true`, the grid still records column-filter / global-filter /
|
|
1374
|
-
* facet state (so the menu UI works and indicators light up) but does
|
|
1375
|
-
* NOT actually filter the rows. The consumer is expected to fetch / sort
|
|
1376
|
-
* / filter the data themselves - typically via `onFiltersChange`. Used
|
|
1377
|
-
* by server-side data sources. Defaults to `false`.
|
|
1378
|
-
*/
|
|
1379
|
-
externalFilter?: boolean;
|
|
1380
|
-
/**
|
|
1381
|
-
* Fires whenever any of the in-grid filter state changes - global
|
|
1382
|
-
* search, per-column operator filters, or facet (value-checklist)
|
|
1383
|
-
* filters. Pair with `externalFilter={true}` when the consumer wants to
|
|
1384
|
-
* push the query to the server.
|
|
1385
|
-
*/
|
|
1386
|
-
onFiltersChange?: (filters: {
|
|
1387
|
-
global: string;
|
|
1388
|
-
columns: Array<{
|
|
1389
|
-
id: string;
|
|
1390
|
-
operator: FilterOperator;
|
|
1391
|
-
value: string;
|
|
1392
|
-
/**
|
|
1393
|
-
* Upper bound for the `between` operator. Only set when
|
|
1394
|
-
* `operator === 'between'` AND the user has typed both values.
|
|
1395
|
-
*/
|
|
1396
|
-
valueTo?: string;
|
|
1397
|
-
selectedValues?: Array<string>;
|
|
1398
|
-
}>;
|
|
1399
|
-
}) => void;
|
|
1400
|
-
/**
|
|
1401
|
-
* Fires when an inline edit is committed (Enter / Tab / blur). Useful
|
|
1402
|
-
* for cascade-recompute pipelines: a parent listens, then refreshes
|
|
1403
|
-
* derived columns or aggregates. The wrapper has already written the
|
|
1404
|
-
* parsed value back into the row by the time this fires.
|
|
1405
|
-
*/
|
|
1406
|
-
/**
|
|
1407
|
-
* Resolve a stable id per row. Drives selection, expansion, edit,
|
|
1408
|
-
* and active-cell state. When omitted, the row's array index is
|
|
1409
|
-
* used - fine for read-only views but the wrong choice if `data`
|
|
1410
|
-
* gets reordered or filtered outside the grid (selection would
|
|
1411
|
-
* follow positions, not actual rows). Use a database PK, a UUID,
|
|
1412
|
-
* or any stable string.
|
|
1413
|
-
*/
|
|
1414
|
-
getRowId?: (row: TData, index: number) => string;
|
|
1415
|
-
/**
|
|
1416
|
-
* Conditional class(es) added to every `<tr>` body row. Receives
|
|
1417
|
-
* the row's `original` data + its data-array index. Return a
|
|
1418
|
-
* string, an array of strings, or an object mapping class names to
|
|
1419
|
-
* booleans. Useful for "highlight overdue rows", "tint cancelled
|
|
1420
|
-
* orders", and similar row-level state mappings.
|
|
1421
|
-
*/
|
|
1422
|
-
rowClass?: (ctx: {
|
|
1423
|
-
row: TData;
|
|
1424
|
-
rowIndex: number;
|
|
1425
|
-
}) => string | ReadonlyArray<string> | Record<string, boolean> | undefined | null;
|
|
1426
|
-
/**
|
|
1427
|
-
* Per-cell notes - longer free-form comments shown as a corner
|
|
1428
|
-
* indicator + tooltip on hover. Keyed by row id then column id;
|
|
1429
|
-
* empty / missing entries mean "no note". The grid owns rendering;
|
|
1430
|
-
* you own storage (write your own callbacks to add / edit notes).
|
|
1431
|
-
*/
|
|
1432
|
-
notes?: Record<string, Record<string, string>>;
|
|
1433
|
-
/**
|
|
1434
|
-
* Allow editing per-cell notes/comments through the UI: the context menu
|
|
1435
|
-
* gains an "Edit comment" item that opens a popover editor. Edits are
|
|
1436
|
-
* applied to an internal overlay for immediate feedback and emitted via
|
|
1437
|
-
* `onNoteChange` so you can persist them back into `notes`.
|
|
1438
|
-
*/
|
|
1439
|
-
editableComments?: boolean;
|
|
1440
|
-
/** Fires when a comment is saved or removed (removed = empty `note`). */
|
|
1441
|
-
onNoteChange?: (event: { rowId: string; columnId: string; note: string }) => void;
|
|
1442
|
-
/**
|
|
1443
|
-
* Excel-style conditional formatting. A list of value-driven rules that
|
|
1444
|
-
* color cells: `colorScale` (gradient across the column range),
|
|
1445
|
-
* `dataBar` (in-cell proportional bar), `iconSet` (arrows / traffic /
|
|
1446
|
-
* triangles by threshold), and `rule` (apply a style when a predicate
|
|
1447
|
-
* matches). Scope a format to specific columns with `columns: [...]`,
|
|
1448
|
-
* or omit it to apply to every column. Later entries win on conflict.
|
|
1449
|
-
*/
|
|
1450
|
-
conditionalFormats?: ReadonlyArray<ConditionalFormat<TData>>;
|
|
1451
|
-
/**
|
|
1452
|
-
* Which rows feed the min/max range that `colorScale` / `dataBar` formats
|
|
1453
|
-
* scale against.
|
|
1454
|
-
*
|
|
1455
|
-
* - `filtered` (default): every row that survives the filters, ignoring the
|
|
1456
|
-
* page slice. The scale follows what you filtered to but does not shift
|
|
1457
|
-
* when you page, so the same value keeps the same colour on page 1 and
|
|
1458
|
-
* page 2.
|
|
1459
|
-
* - `visible`: only the rows currently on screen. Rescales per page - use it
|
|
1460
|
-
* when you want each page's heat map normalized to that page.
|
|
1461
|
-
* - `all`: the full unfiltered dataset, for a scale that stays put as you
|
|
1462
|
-
* filter.
|
|
1463
|
-
*/
|
|
1464
|
-
conditionalStatScope?: "filtered" | "visible" | "all";
|
|
1465
|
-
onCellValueChange?: (event: {
|
|
1466
|
-
rowIndex: number;
|
|
1467
|
-
columnId: string;
|
|
1468
|
-
oldValue: unknown;
|
|
1469
|
-
newValue: unknown;
|
|
1470
|
-
row: TData;
|
|
1471
|
-
}) => void;
|
|
1472
|
-
/**
|
|
1473
|
-
* Fires whenever the active cell changes - click, keyboard move,
|
|
1474
|
-
* tab, page-up/down, etc. Consumers (toolbars, ribbon UIs) use this
|
|
1475
|
-
* to stay synced with the grid's selection without polling the DOM.
|
|
1476
|
-
*/
|
|
1477
|
-
onActiveCellChange?: (cell: {
|
|
1478
|
-
rowIndex: number;
|
|
1479
|
-
colIndex: number;
|
|
1480
|
-
columnId: string;
|
|
1481
|
-
}) => void;
|
|
1482
|
-
/**
|
|
1483
|
-
* Fires when a data cell (and therefore a row) is single-clicked.
|
|
1484
|
-
* Group-header rows are excluded. `value` is the displayed cell value.
|
|
1485
|
-
*/
|
|
1486
|
-
onCellClick?: (event: {
|
|
1487
|
-
rowIndex: number;
|
|
1488
|
-
colIndex: number;
|
|
1489
|
-
columnId: string;
|
|
1490
|
-
value: unknown;
|
|
1491
|
-
row: TData;
|
|
1492
|
-
}) => void;
|
|
1493
|
-
/** Fires when a data row is single-clicked (any cell). Group rows excluded. */
|
|
1494
|
-
onRowClick?: (event: {
|
|
1495
|
-
rowIndex: number;
|
|
1496
|
-
columnId: string;
|
|
1497
|
-
row: TData;
|
|
1498
|
-
}) => void;
|
|
1499
|
-
/**
|
|
1500
|
-
* Fires when a data cell is double-clicked - independent of whether the
|
|
1501
|
-
* cell is editable, so it fires even on read-only grids. Group rows excluded.
|
|
1502
|
-
*/
|
|
1503
|
-
onCellDoubleClick?: (event: {
|
|
1504
|
-
rowIndex: number;
|
|
1505
|
-
colIndex: number;
|
|
1506
|
-
columnId: string;
|
|
1507
|
-
value: unknown;
|
|
1508
|
-
row: TData;
|
|
1509
|
-
}) => void;
|
|
1510
|
-
/** Fires when a data row is double-clicked (any cell). Group rows excluded. */
|
|
1511
|
-
onRowDoubleClick?: (event: {
|
|
1512
|
-
rowIndex: number;
|
|
1513
|
-
columnId: string;
|
|
1514
|
-
row: TData;
|
|
1515
|
-
}) => void;
|
|
1516
|
-
/**
|
|
1517
|
-
* Fires once each time the body is scrolled to (within ~32px of) the
|
|
1518
|
-
* bottom. Re-arms after the user scrolls back up. The canonical hook for
|
|
1519
|
-
* infinite / lazy loading - append more rows to `data` when it fires.
|
|
1520
|
-
*/
|
|
1521
|
-
onScrollBottomReached?: (event: {
|
|
1522
|
-
scrollTop: number;
|
|
1523
|
-
scrollHeight: number;
|
|
1524
|
-
clientHeight: number;
|
|
1525
|
-
}) => void;
|
|
1526
|
-
/**
|
|
1527
|
-
* Marks a row as an expandable "detail row". When this returns true the
|
|
1528
|
-
* grid renders that row as a SINGLE full-width cell (colspan across every
|
|
1529
|
-
* column) using `renderDetailRow`, instead of the normal per-column cells
|
|
1530
|
-
* - the canonical Stripe / GitHub "expand a rich panel beneath the row"
|
|
1531
|
-
* pattern. Insert the detail rows into `data` yourself (typically right
|
|
1532
|
-
* after the row they belong to) and toggle them with your own expanded
|
|
1533
|
-
* state. Pair with `virtualization={false}` so the variable-height detail
|
|
1534
|
-
* isn't clipped by the fixed-row-height virtualizer.
|
|
1535
|
-
*/
|
|
1536
|
-
isDetailRow?: (row: TData, rowIndex: number) => boolean;
|
|
1537
|
-
/**
|
|
1538
|
-
* Snippet rendered inside the full-width detail cell for rows where
|
|
1539
|
-
* `isDetailRow` is true. Receives the row's data and its index.
|
|
1540
|
-
*/
|
|
1541
|
-
renderDetailRow?: Snippet<[{ row: TData; rowIndex: number }]>;
|
|
1542
|
-
/**
|
|
1543
|
-
* Server-side group / tree keyboard + accessibility, built into the grid. When
|
|
1544
|
-
* set, the grid uses the treegrid role and marks matching rows with
|
|
1545
|
-
* `aria-level` / `aria-expanded`, and ArrowRight / ArrowLeft expand / collapse
|
|
1546
|
-
* the focused group row (no app-level key handling). Pair with `serverGroupRows`
|
|
1547
|
-
* + `SvGroupCell` for the visual expander. Every accessor receives the row data.
|
|
1548
|
-
*/
|
|
1549
|
-
serverGroup?: {
|
|
1550
|
-
/** Whether a row is an expandable group / branch. */
|
|
1551
|
-
isGroup: (row: TData) => boolean;
|
|
1552
|
-
/** Tree depth of the row (0 = top level), for `aria-level`. */
|
|
1553
|
-
level: (row: TData) => number;
|
|
1554
|
-
/** Whether an expandable row is currently expanded. */
|
|
1555
|
-
expanded?: (row: TData) => boolean;
|
|
1556
|
-
/** Expand / collapse a group row. Called on ArrowRight / ArrowLeft. */
|
|
1557
|
-
onToggle: (row: TData) => void;
|
|
1558
|
-
};
|
|
1559
|
-
/**
|
|
1560
|
-
* Server-side set-filter values. When set, a column's filter checklist is
|
|
1561
|
-
* populated by fetching the distinct values from the server (once per column,
|
|
1562
|
-
* cached) instead of deriving them from the loaded page - so the checklist
|
|
1563
|
-
* shows every value, not just those on screen. Return the distinct string
|
|
1564
|
-
* values for the column id.
|
|
1565
|
-
*/
|
|
1566
|
-
serverFilterValues?: (columnId: string) => Promise<string[]>;
|
|
1567
|
-
/**
|
|
1568
|
-
* Rows to pin to the TOP of the grid - rendered above the regular
|
|
1569
|
-
* rows and sticky-positioned so they stay visible while the user
|
|
1570
|
-
* scrolls. Typical use: a "totals" or "headline" row that should
|
|
1571
|
-
* always be in view. Rows are read-only (no inline editing, no
|
|
1572
|
-
* row-selection checkbox). They share the column schema with the
|
|
1573
|
-
* main grid; field/format/cell/cellClass all apply.
|
|
1574
|
-
*/
|
|
1575
|
-
pinnedTopRows?: ReadonlyArray<TData>;
|
|
1576
|
-
/**
|
|
1577
|
-
* Rows to pin to the BOTTOM of the grid - rendered below the regular
|
|
1578
|
-
* rows and sticky-positioned (sticks to the bottom of the viewport
|
|
1579
|
-
* while the user scrolls). Typical use: a "page totals" or "grand
|
|
1580
|
-
* total" row computed from `getDisplayedRows()`.
|
|
1581
|
-
*/
|
|
1582
|
-
pinnedBottomRows?: ReadonlyArray<TData>;
|
|
1583
|
-
/**
|
|
1584
|
-
* Enables drag-to-reorder on the grid's column headers. When `true`,
|
|
1585
|
-
* every header gets `draggable=true` and a drop indicator paints
|
|
1586
|
-
* between headers during a drag. On drop the grid mutates its
|
|
1587
|
-
* internal column order and fires `onColumnOrderChange` with the
|
|
1588
|
-
* new order. Defaults to `false`.
|
|
1589
|
-
*/
|
|
1590
|
-
enableColumnReorder?: boolean;
|
|
1591
|
-
/**
|
|
1592
|
-
* Initial column order, by `id` (falls back to `field`). When the
|
|
1593
|
-
* user reorders columns, this is the starting state. After mount,
|
|
1594
|
-
* the grid owns the order internally and emits `onColumnOrderChange`
|
|
1595
|
-
* on every change - persist that to `localStorage` to restore.
|
|
1596
|
-
*/
|
|
1597
|
-
columnOrder?: ReadonlyArray<string>;
|
|
1598
|
-
/** Fires every time the column order changes (drag or `api.setColumnOrder`). */
|
|
1599
|
-
onColumnOrderChange?: (order: ReadonlyArray<string>) => void;
|
|
1600
|
-
/**
|
|
1601
|
-
* Infer each column's data type (number / boolean / date / ISO date-string /
|
|
1602
|
-
* text) from the first data row, for columns that declare neither an
|
|
1603
|
-
* explicit `editorType` nor a `cellDataType`. Sets the matching editor,
|
|
1604
|
-
* alignment, date format, and filter operators automatically. Explicit
|
|
1605
|
-
* column config always wins. Defaults to `false`.
|
|
1606
|
-
*/
|
|
1607
|
-
inferColumnTypes?: boolean;
|
|
1608
|
-
/**
|
|
1609
|
-
* Enables managed row dragging. When `true`, every row becomes a drag
|
|
1610
|
-
* source (grab cursor + a grip in the row-number cell) and a drop
|
|
1611
|
-
* indicator paints between rows during a drag. On drop the grid mutates
|
|
1612
|
-
* its own internal data - reordering within the grid, or moving the row
|
|
1613
|
-
* across grids that share the same {@link rowDragGroup}. Defaults to
|
|
1614
|
-
* `false`.
|
|
1615
|
-
*/
|
|
1616
|
-
rowDragManaged?: boolean;
|
|
1617
|
-
/**
|
|
1618
|
-
* Connection group for cross-grid row dragging. Grids that share the same
|
|
1619
|
-
* non-empty `rowDragGroup` string (and have `rowDragManaged` on) can
|
|
1620
|
-
* exchange rows: dragging a row out of one and dropping it into another
|
|
1621
|
-
* removes it from the source and inserts it into the target. Omit to keep
|
|
1622
|
-
* dragging confined to reordering within a single grid.
|
|
1623
|
-
*/
|
|
1624
|
-
rowDragGroup?: string;
|
|
1625
|
-
/**
|
|
1626
|
-
* Fires on the TARGET grid after a managed row drag settles, with the
|
|
1627
|
-
* moved row, its landing index, whether it stayed in the same grid, and
|
|
1628
|
-
* the source / target grid ids. Use it to mirror the move into your own
|
|
1629
|
-
* state (persistence, server sync). The grid has already applied the
|
|
1630
|
-
* change to its internal data by the time this fires.
|
|
1631
|
-
*/
|
|
1632
|
-
onRowDragEnd?: (event: {
|
|
1633
|
-
row: TData;
|
|
1634
|
-
toIndex: number;
|
|
1635
|
-
sameGrid: boolean;
|
|
1636
|
-
fromGridId: number;
|
|
1637
|
-
toGridId: number;
|
|
1638
|
-
}) => void;
|
|
1639
|
-
/**
|
|
1640
|
-
* Align this grid with others that share the same non-empty
|
|
1641
|
-
* `alignedGridGroup` string: horizontal scroll and column-resize widths are
|
|
1642
|
-
* kept in lockstep across every grid in the group. Use for a totals/header
|
|
1643
|
-
* grid above a body grid, or side-by-side comparison grids that must line up.
|
|
1644
|
-
* The grids should declare the same columns (matched by id) for widths to map.
|
|
1645
|
-
*/
|
|
1646
|
-
alignedGridGroup?: string;
|
|
1647
|
-
/**
|
|
1648
|
-
* BCP-47 locale tag (or array of fallbacks) used for accent- and
|
|
1649
|
-
* case-insensitive text filtering / sorting / search. Powered by
|
|
1650
|
-
* `Intl.Collator` with `sensitivity: 'base'`, so "cafe", "Café"
|
|
1651
|
-
* and "CAFÉ" all match "cafe" without strain. Defaults to the
|
|
1652
|
-
* browser's locale.
|
|
1653
|
-
*/
|
|
1654
|
-
filterLocale?: string | ReadonlyArray<string>;
|
|
1655
|
-
};
|
|
1656
|
-
|
|
1657
|
-
/**
|
|
1658
|
-
* The grid's single localization surface (see {@link Props.localization}):
|
|
1659
|
-
* `locale` handles the data (filter matching + number/date formatting) and
|
|
1660
|
-
* `text` handles the UI strings.
|
|
1661
|
-
*/
|
|
1662
|
-
export type GridLocalization = {
|
|
1663
|
-
/** BCP-47 tag(s) for filter matching + number / date formatting. */
|
|
1664
|
-
locale?: string | ReadonlyArray<string>;
|
|
1665
|
-
/** Overrides for the grid's own UI strings. */
|
|
1666
|
-
text?: Partial<GridMessages>;
|
|
1667
|
-
};
|
|
1668
|
-
|
|
1669
|
-
export type SelectionPoint = { rowIndex: number; colIndex: number };
|
|
1670
|
-
export type SelectionRange = {
|
|
1671
|
-
anchor: SelectionPoint | null;
|
|
1672
|
-
focus: SelectionPoint | null;
|
|
1673
|
-
};
|
|
1674
|
-
export type CellEditState = {
|
|
1675
|
-
rowId: string;
|
|
1676
|
-
columnId: string;
|
|
1677
|
-
editorType: CellEditorType;
|
|
1678
|
-
value: unknown;
|
|
1679
|
-
/**
|
|
1680
|
-
* The row's underlying data object, captured when the edit started. The
|
|
1681
|
-
* commit path resolves the row by id first; this is the fallback for when
|
|
1682
|
-
* the row has left the row model mid-edit (a filter typed into the filter
|
|
1683
|
-
* row while an editor is open), so the typed value still lands instead of
|
|
1684
|
-
* being silently dropped.
|
|
1685
|
-
*/
|
|
1686
|
-
rowRef?: unknown;
|
|
1687
|
-
} | null;
|
|
1688
|
-
export type FilterOperator =
|
|
1689
|
-
| "contains"
|
|
1690
|
-
| "notContains"
|
|
1691
|
-
| "equals"
|
|
1692
|
-
| "notEquals"
|
|
1693
|
-
| "startsWith"
|
|
1694
|
-
| "endsWith"
|
|
1695
|
-
| "regex"
|
|
1696
|
-
| "in"
|
|
1697
|
-
| "notIn"
|
|
1698
|
-
| "greaterThan"
|
|
1699
|
-
| "lessThan"
|
|
1700
|
-
| "between"
|
|
1701
|
-
| "isBlank"
|
|
1702
|
-
| "isNotBlank";
|
|
1703
|
-
export type FilterOption = {
|
|
1704
|
-
value: FilterOperator;
|
|
1705
|
-
label: string;
|
|
1706
|
-
iconName: string;
|
|
1707
|
-
};
|
|
1708
|
-
export type MenuPosition = { x: number; y: number };
|
|
1
|
+
// Type definitions extracted from SvGrid.svelte. These are compile-time
|
|
2
|
+
// only - moving them out keeps the component's <script> focused on logic.
|
|
3
|
+
import type { Snippet } from "svelte";
|
|
4
|
+
import type {
|
|
5
|
+
CellEditorType,
|
|
6
|
+
ColumnDef,
|
|
7
|
+
RowData,
|
|
8
|
+
SvGridApi,
|
|
9
|
+
TableFeatures,
|
|
10
|
+
} from "./index";
|
|
11
|
+
import type { ConditionalFormat } from "./conditional-formatting";
|
|
12
|
+
import type { GroupDisplayType } from "./group-display";
|
|
13
|
+
import type { GridMessages } from "./grid-messages";
|
|
14
|
+
import type { GridPivotConfig } from "./pivot-view.svelte";
|
|
15
|
+
import type { MenuItem } from "./SvMenuList.svelte";
|
|
16
|
+
|
|
17
|
+
/** The calendar views the scheduler can render. {@link SchedulerConfig}. The
|
|
18
|
+
* `timeline*` views are horizontal: time runs left→right and resources are
|
|
19
|
+
* rows (a single "All" row without `resourceField`). */
|
|
20
|
+
export type SchedulerView =
|
|
21
|
+
| "month"
|
|
22
|
+
| "week"
|
|
23
|
+
| "day"
|
|
24
|
+
| "agenda"
|
|
25
|
+
| "timelineDay"
|
|
26
|
+
| "timelineWeek"
|
|
27
|
+
| "timelineMonth"
|
|
28
|
+
| "timelineYear";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* How overlapping ("colliding") time-grid events are laid out:
|
|
32
|
+
* - `split` - every collision divides the column width evenly (default).
|
|
33
|
+
* - `cap` - show up to `maxColumns` columns; the rest collapse into a
|
|
34
|
+
* clickable `+N more` overflow tile.
|
|
35
|
+
* - `stack` - overlapping events overlap with a horizontal offset + z-order
|
|
36
|
+
* instead of shrinking, so each stays readable (hover to raise).
|
|
37
|
+
*/
|
|
38
|
+
export type SchedulerCollisionMode = "split" | "cap" | "stack";
|
|
39
|
+
|
|
40
|
+
/** A scheduler resource - a person / room / machine an event can be assigned to. */
|
|
41
|
+
export type SchedulerResource = {
|
|
42
|
+
id: string;
|
|
43
|
+
title?: string;
|
|
44
|
+
color?: string;
|
|
45
|
+
/**
|
|
46
|
+
* This resource's own working windows (hours), optionally per weekday - e.g. a
|
|
47
|
+
* doctor available Mon/Wed/Fri 9-13 and Tue/Thu 14-18. Overrides the global
|
|
48
|
+
* `businessHours` / `nonWorkingDays` for this resource's columns: time outside
|
|
49
|
+
* every matching window is shaded, and (with `restrictToBusinessHours`)
|
|
50
|
+
* non-bookable. A weekday with no matching window is a full day off.
|
|
51
|
+
*/
|
|
52
|
+
availability?: ReadonlyArray<{ days?: ReadonlyArray<number>; start: number; end: number }>;
|
|
53
|
+
/**
|
|
54
|
+
* Per-date overrides to this resource's weekly `availability` - a specific day
|
|
55
|
+
* off (`off: true`, e.g. vacation) or custom hours (`windows`) for that one
|
|
56
|
+
* date. Matched by calendar date; takes precedence over `availability` for the
|
|
57
|
+
* matching day.
|
|
58
|
+
*/
|
|
59
|
+
dateOverrides?: ReadonlyArray<{
|
|
60
|
+
date: Date | number | string;
|
|
61
|
+
off?: boolean;
|
|
62
|
+
windows?: ReadonlyArray<{ start: number; end: number }>;
|
|
63
|
+
}>;
|
|
64
|
+
};
|
|
65
|
+
import type {
|
|
66
|
+
ChartType,
|
|
67
|
+
ChartSpec,
|
|
68
|
+
ChartAnnotation,
|
|
69
|
+
ChartReferenceLine,
|
|
70
|
+
ChartValueFormat,
|
|
71
|
+
} from "./chart";
|
|
72
|
+
|
|
73
|
+
/** One aggregated bucket returned by a server-side `getAggregate`. */
|
|
74
|
+
export type ChartAggregateBucket = { category: string; series?: string; value: number };
|
|
75
|
+
/** The request a server-side `getAggregate` receives (whole-dataset charting). */
|
|
76
|
+
export type ChartAggregateRequest = {
|
|
77
|
+
dimension: string | undefined;
|
|
78
|
+
measure: string | null;
|
|
79
|
+
series?: string;
|
|
80
|
+
reduce: "sum" | "avg" | "count";
|
|
81
|
+
filterModel: Record<string, unknown>;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Config for the built-in `charting` prop. All fields optional and additive;
|
|
86
|
+
* `charting={true}` is the zero-config form. Column references are column
|
|
87
|
+
* field names / ids.
|
|
88
|
+
*/
|
|
89
|
+
export type ChartingConfig<TData extends RowData = RowData> = {
|
|
90
|
+
/** Right-side drawer (default) or bottom dock. */
|
|
91
|
+
position?: "bottom" | "right";
|
|
92
|
+
/** Open the panel on first render. */
|
|
93
|
+
defaultOpen?: boolean;
|
|
94
|
+
/** Initial chart type. */
|
|
95
|
+
defaultType?: ChartType;
|
|
96
|
+
/** Docked-bottom height (px). */
|
|
97
|
+
height?: number;
|
|
98
|
+
/** Drawer width (px). */
|
|
99
|
+
width?: number;
|
|
100
|
+
/** Clicking a chart category filters the grid on the charted dimension. */
|
|
101
|
+
crossFilter?: boolean;
|
|
102
|
+
/** Group-by column. */
|
|
103
|
+
dimension?: string;
|
|
104
|
+
/** Split-by column: one series per distinct value. */
|
|
105
|
+
series?: string;
|
|
106
|
+
/** Measure column, or several for a multi-series chart. */
|
|
107
|
+
measures?: string | string[];
|
|
108
|
+
reduce?: "sum" | "avg" | "count";
|
|
109
|
+
stacked?: boolean;
|
|
110
|
+
stacked100?: boolean;
|
|
111
|
+
/** Per-series-label type override (combo). */
|
|
112
|
+
seriesTypes?: Record<string, "bar" | "line" | "area">;
|
|
113
|
+
/** Per-series-label axis override (dual axis). */
|
|
114
|
+
seriesAxes?: Record<string, "left" | "right">;
|
|
115
|
+
referenceLines?: ChartReferenceLine[];
|
|
116
|
+
averageLine?: boolean;
|
|
117
|
+
trend?: "sma" | "ema" | "linear";
|
|
118
|
+
annotations?: ChartAnnotation[];
|
|
119
|
+
yScale?: "linear" | "log";
|
|
120
|
+
timeAxis?: boolean;
|
|
121
|
+
valueFormat?: "number" | "currency" | "percent" | "compact";
|
|
122
|
+
smooth?: boolean;
|
|
123
|
+
orientation?: "vertical" | "horizontal";
|
|
124
|
+
donut?: number | boolean;
|
|
125
|
+
palette?: string[];
|
|
126
|
+
patternFallback?: boolean;
|
|
127
|
+
topN?: number;
|
|
128
|
+
otherLabel?: string;
|
|
129
|
+
sort?: "value-desc" | "value-asc" | "category" | "none";
|
|
130
|
+
dataLabels?: boolean;
|
|
131
|
+
zoom?: boolean;
|
|
132
|
+
brush?: boolean;
|
|
133
|
+
/** Show the chart's PNG/SVG export toolbar. */
|
|
134
|
+
export?: boolean;
|
|
135
|
+
/** Escape hatch: build a fully custom ChartSpec from the (scoped) rows. */
|
|
136
|
+
buildSpec?: (rows: TData[]) => ChartSpec | null;
|
|
137
|
+
/** Server-side aggregation: chart the whole dataset, not just loaded rows. */
|
|
138
|
+
getAggregate?: (
|
|
139
|
+
request: ChartAggregateRequest,
|
|
140
|
+
) => Promise<ReadonlyArray<ChartAggregateBucket>>;
|
|
141
|
+
/** Bump to force a server-side refetch. */
|
|
142
|
+
refreshKey?: unknown;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The built-in card detail drawer. Set `board.drawer` (`true` for all fields,
|
|
147
|
+
* or this object to customize) and opening a card shows a drawer with an
|
|
148
|
+
* `SvForm` of its fields, rendered with the UI-kit editors.
|
|
149
|
+
*/
|
|
150
|
+
export type BoardDrawerConfig<TData extends RowData = RowData> = {
|
|
151
|
+
/** Fields to show, in order. Omit for every column that has a `field`. */
|
|
152
|
+
fields?: ReadonlyArray<keyof TData & string>;
|
|
153
|
+
/** Drawer title - a string or derived from the row. Defaults to the title field. */
|
|
154
|
+
title?: string | ((row: TData) => string);
|
|
155
|
+
/** Which edge the drawer opens from. Defaults to `'right'`. */
|
|
156
|
+
side?: "right" | "left" | "top" | "bottom";
|
|
157
|
+
/** Drawer size (any CSS length). Defaults to `'380px'`. */
|
|
158
|
+
size?: string;
|
|
159
|
+
/** Save button label. Defaults to `'Save'`. */
|
|
160
|
+
submitLabel?: string;
|
|
161
|
+
/** Form columns inside the drawer. Defaults to `1`. */
|
|
162
|
+
columns?: number;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/** Board-native helpers passed to `board.cardMenu` for building context items. */
|
|
166
|
+
export type BoardMenuContext<TData extends RowData = RowData> = {
|
|
167
|
+
/** The board's lanes (id + title). */
|
|
168
|
+
lanes: BoardLane[];
|
|
169
|
+
/** Move this card to a lane (board-native; fires onCardMove). */
|
|
170
|
+
moveTo: (laneId: string) => void;
|
|
171
|
+
/** Open this card's editor (inline, or your `onCardEdit`). */
|
|
172
|
+
edit: () => void;
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
/** Board-native helpers passed to `board.laneMenu` for building lane context items. */
|
|
176
|
+
export type BoardLaneMenuContext<TData extends RowData = RowData> = {
|
|
177
|
+
/** The lane's id. */
|
|
178
|
+
laneId: string;
|
|
179
|
+
/** The lane's current cards (this swimlane's, if any). */
|
|
180
|
+
cards: TData[];
|
|
181
|
+
/** Whether the lane is collapsed. */
|
|
182
|
+
collapsed: boolean;
|
|
183
|
+
/** Collapse / expand the lane (needs `collapsibleLanes`). */
|
|
184
|
+
toggleCollapse: () => void;
|
|
185
|
+
/** Add a card to the lane (fires `onCardAdd`). */
|
|
186
|
+
addCard: (title?: string) => void;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/** The cell a context menu was opened on. Passed to every item's callbacks. */
|
|
190
|
+
export type ContextMenuTarget<TData extends RowData = RowData> = {
|
|
191
|
+
rowIndex: number;
|
|
192
|
+
colIndex: number;
|
|
193
|
+
columnId: string;
|
|
194
|
+
/** Stable row id (from getRowId / row model), for keying notes etc. */
|
|
195
|
+
rowId: string;
|
|
196
|
+
row: TData | null;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* A context-menu entry. Either a built-in action key, the `"separator"`
|
|
201
|
+
* divider, or a custom item. Built-in keys: `"copy" | "cut" | "paste" |
|
|
202
|
+
* "clear" | "row_above" | "row_below" | "remove_row" | "remove_col" |
|
|
203
|
+
* "chart"`. The `"chart"` item (chart the selected range) is only shown when
|
|
204
|
+
* `charting` is enabled; it is appended to the default menu automatically.
|
|
205
|
+
*/
|
|
206
|
+
export type ContextMenuItem<TData extends RowData = RowData> =
|
|
207
|
+
| string
|
|
208
|
+
| {
|
|
209
|
+
key: string;
|
|
210
|
+
label: string;
|
|
211
|
+
/** Hide the item entirely for this target. */
|
|
212
|
+
hidden?: (target: ContextMenuTarget<TData>) => boolean;
|
|
213
|
+
/** Render the item greyed-out and non-clickable for this target. */
|
|
214
|
+
disabled?: (target: ContextMenuTarget<TData>) => boolean;
|
|
215
|
+
/** Invoked on click. The menu closes afterwards. */
|
|
216
|
+
action: (target: ContextMenuTarget<TData>) => void;
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
/** A single Kanban lane (board column). {@link BoardConfig}. */
|
|
220
|
+
export type BoardLane = {
|
|
221
|
+
/** Lane id - equals the `groupBy` field value of the cards it holds. */
|
|
222
|
+
id: string;
|
|
223
|
+
/** Header title. Defaults to the id (or `(empty)` for a blank value). */
|
|
224
|
+
title?: string;
|
|
225
|
+
/** Accent color (any CSS color) for the lane header bar + card ring. */
|
|
226
|
+
color?: string;
|
|
227
|
+
/**
|
|
228
|
+
* Soft max number of cards. When exceeded the lane header is flagged
|
|
229
|
+
* over-limit. Enforcement/styling is an enterprise concern; the count is
|
|
230
|
+
* always shown.
|
|
231
|
+
*/
|
|
232
|
+
wipLimit?: number;
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
/** A checklist item inside a card. See {@link BoardConfig.subtasks}. */
|
|
236
|
+
export type BoardSubtask = {
|
|
237
|
+
id: string | number;
|
|
238
|
+
title: string;
|
|
239
|
+
done: boolean;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/** A comment on a card. See {@link BoardConfig.commentsField}. */
|
|
243
|
+
export type BoardComment = {
|
|
244
|
+
id: string | number;
|
|
245
|
+
text: string;
|
|
246
|
+
author?: string;
|
|
247
|
+
/** Timestamp label (any string). */
|
|
248
|
+
at?: string;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* The serializable board layout - the per-card position/edit overlay plus
|
|
253
|
+
* collapsed lanes. Persisted by `board.persistKey` and passed to
|
|
254
|
+
* `board.onLayoutChange`.
|
|
255
|
+
*/
|
|
256
|
+
export type BoardLayout = {
|
|
257
|
+
/** rowId -> lane id. */
|
|
258
|
+
laneOf?: Record<string, string>;
|
|
259
|
+
/** rowId -> sort order within its lane. */
|
|
260
|
+
orderOf?: Record<string, number>;
|
|
261
|
+
/** rowId -> swimlane id. */
|
|
262
|
+
swimOf?: Record<string, string>;
|
|
263
|
+
/** rowId -> edited field values. */
|
|
264
|
+
edits?: Record<string, Record<string, unknown>>;
|
|
265
|
+
/** lane id -> collapsed. */
|
|
266
|
+
collapsed?: Record<string, boolean>;
|
|
267
|
+
/** swimlane id -> collapsed. */
|
|
268
|
+
collapsedSwim?: Record<string, boolean>;
|
|
269
|
+
/** Explicit lane order (ids), when lanes have been drag-reordered. */
|
|
270
|
+
laneOrder?: string[];
|
|
271
|
+
/** rowId -> subtaskId -> done override. */
|
|
272
|
+
subDone?: Record<string, Record<string, boolean>>;
|
|
273
|
+
/** rowId -> subtasks added on the card. */
|
|
274
|
+
subAdded?: Record<string, BoardSubtask[]>;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
/** Emitted when a card's built-in editor is saved. */
|
|
278
|
+
export type BoardCardCommitEvent<TData extends RowData = RowData> = {
|
|
279
|
+
/** The edited row. */
|
|
280
|
+
row: TData;
|
|
281
|
+
/** Only the fields that changed, `{ field: newValue }`. */
|
|
282
|
+
changes: Record<string, unknown>;
|
|
283
|
+
/** The full set of edited field values. */
|
|
284
|
+
values: Record<string, unknown>;
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
/** Emitted when a card is dragged to a new lane and/or position. */
|
|
288
|
+
export type BoardCardMoveEvent<TData extends RowData = RowData> = {
|
|
289
|
+
/** The dragged row. */
|
|
290
|
+
row: TData;
|
|
291
|
+
/** Lane the card came from. */
|
|
292
|
+
fromLane: string;
|
|
293
|
+
/** Lane the card was dropped on. */
|
|
294
|
+
toLane: string;
|
|
295
|
+
/** Insertion index within the destination lane. */
|
|
296
|
+
toIndex: number;
|
|
297
|
+
/** Swimlane the card came from (only when `swimlaneBy` is set). */
|
|
298
|
+
fromSwimlane?: string;
|
|
299
|
+
/** Swimlane the card was dropped on (only when `swimlaneBy` is set). */
|
|
300
|
+
toSwimlane?: string;
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Turns the grid into a Kanban board. Set `board` and the grid renders its
|
|
305
|
+
* rows as cards in horizontal lanes (bucketed by the `groupBy` field) instead
|
|
306
|
+
* of a table. Dragging a card between lanes fires {@link BoardConfig.onCardMove}
|
|
307
|
+
* where you reassign the `groupBy` field on your own data.
|
|
308
|
+
*/
|
|
309
|
+
/**
|
|
310
|
+
* Chart view of the grid. Setting the `chart` prop on `<SvGrid>` swaps the table
|
|
311
|
+
* for a chart driven by the grid's FILTERED + SORTED rows - so the search box,
|
|
312
|
+
* column filters and sort all flow through to the chart. Unlike the board and
|
|
313
|
+
* scheduler views, the renderer is free: the grid lazy-loads a built-in
|
|
314
|
+
* `SvChart` view unless a host overrides it via `registerChartView`.
|
|
315
|
+
*
|
|
316
|
+
* The config maps directly onto `rowsToChartSpec` - one row field for the
|
|
317
|
+
* category axis, one or more for the value series (or a `series` field to pivot
|
|
318
|
+
* one series per distinct value).
|
|
319
|
+
*
|
|
320
|
+
* ```svelte
|
|
321
|
+
* <SvGrid {data} {columns}
|
|
322
|
+
* chart={{ type: 'bar', category: 'month', value: 'revenue', reduce: 'sum' }} />
|
|
323
|
+
* ```
|
|
324
|
+
*/
|
|
325
|
+
export type ChartViewConfig<
|
|
326
|
+
TFeatures extends TableFeatures = TableFeatures,
|
|
327
|
+
TData extends RowData = RowData,
|
|
328
|
+
> = {
|
|
329
|
+
/** Chart type. Default `'bar'`. */
|
|
330
|
+
type?: ChartType;
|
|
331
|
+
/** Row field for the category (x) axis. */
|
|
332
|
+
category: keyof TData & string;
|
|
333
|
+
/** Row field(s) for the value (y) series. */
|
|
334
|
+
value: (keyof TData & string) | Array<keyof TData & string>;
|
|
335
|
+
/** Pivot dimension: one series per distinct value of this field. */
|
|
336
|
+
series?: keyof TData & string;
|
|
337
|
+
/** Aggregation when several rows share a category. Default `'sum'`. */
|
|
338
|
+
reduce?: "sum" | "avg" | "count";
|
|
339
|
+
/** Stack bar / area series instead of grouping them. */
|
|
340
|
+
stacked?: boolean;
|
|
341
|
+
/** Stack to 100% (implies `stacked`). */
|
|
342
|
+
stacked100?: boolean;
|
|
343
|
+
/** Order categories. Default: insertion order (value-desc when `topN` is set). */
|
|
344
|
+
sort?: "value-desc" | "value-asc" | "category" | "none";
|
|
345
|
+
/** Keep only the top N categories; bucket the rest into "Other". */
|
|
346
|
+
topN?: number;
|
|
347
|
+
/** Palette for series without an explicit colour. */
|
|
348
|
+
palette?: string[];
|
|
349
|
+
/** Number format for the value axis, tooltips and data labels. */
|
|
350
|
+
valueFormat?: ChartValueFormat;
|
|
351
|
+
/** Show the clickable legend. Default `true`. */
|
|
352
|
+
legend?: boolean;
|
|
353
|
+
/** Draw the value on each bar / point / slice. Default `false`. */
|
|
354
|
+
dataLabels?: boolean;
|
|
355
|
+
/** Show the search box above the chart (filters rows first). Default `true`. */
|
|
356
|
+
searchable?: boolean;
|
|
357
|
+
/** Placeholder for the search box. */
|
|
358
|
+
searchPlaceholder?: string;
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
export type BoardConfig<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> = {
|
|
362
|
+
/** Field whose value buckets each row into a lane. */
|
|
363
|
+
groupBy: keyof TData & string;
|
|
364
|
+
/**
|
|
365
|
+
* Explicit, ordered lanes. Omit to derive lanes from the distinct
|
|
366
|
+
* `groupBy` values found in the data (first-seen order).
|
|
367
|
+
*/
|
|
368
|
+
lanes?: ReadonlyArray<BoardLane>;
|
|
369
|
+
/** Custom card body. Receives the row. Omit for the built-in default card. */
|
|
370
|
+
card?: Snippet<[TData]>;
|
|
371
|
+
/**
|
|
372
|
+
* Fired when a card is dragged to a new lane/position. Update your data
|
|
373
|
+
* here (reassign the `groupBy` field, and optionally reorder). Without it
|
|
374
|
+
* the board is display-only.
|
|
375
|
+
*/
|
|
376
|
+
onCardMove?: (event: BoardCardMoveEvent<TData>) => void;
|
|
377
|
+
/**
|
|
378
|
+
* Add-card affordance. A `+` in the lane header (or, with `composer`, a
|
|
379
|
+
* type-a-title box at the bottom of the lane) fires this with the lane id
|
|
380
|
+
* and - from the composer - the typed title.
|
|
381
|
+
*/
|
|
382
|
+
onCardAdd?: (laneId: string, title?: string) => void;
|
|
383
|
+
/**
|
|
384
|
+
* Show a quick-add composer at the bottom of each lane (a "+ Add a card"
|
|
385
|
+
* button that opens an inline title input; Enter calls `onCardAdd(lane,
|
|
386
|
+
* title)`). Without it, `onCardAdd` shows a plain `+` in the header.
|
|
387
|
+
*/
|
|
388
|
+
composer?: boolean;
|
|
389
|
+
/**
|
|
390
|
+
* Field holding a card's checklist of sub-tasks (`BoardSubtask[]`). The card
|
|
391
|
+
* shows a progress chip + bar and expands to an inline checklist with a
|
|
392
|
+
* quick-add. Toggles/adds run through an overlay (never mutating your data)
|
|
393
|
+
* and fire the callbacks below.
|
|
394
|
+
*/
|
|
395
|
+
subtasks?: keyof TData & string;
|
|
396
|
+
/** Fired when a sub-task checkbox is toggled. */
|
|
397
|
+
onSubtaskToggle?: (row: TData, subtaskId: string | number, done: boolean) => void;
|
|
398
|
+
/** Fired when a sub-task is added from the card. */
|
|
399
|
+
onSubtaskAdd?: (row: TData, title: string) => void;
|
|
400
|
+
/**
|
|
401
|
+
* Field holding label/tag strings (or `{ text, color }`) shown as chips on
|
|
402
|
+
* the default card's badge row.
|
|
403
|
+
*/
|
|
404
|
+
labelsField?: keyof TData & string;
|
|
405
|
+
/** Field holding a due date (Date | ISO string); shown as a badge, red when overdue. */
|
|
406
|
+
dueField?: keyof TData & string;
|
|
407
|
+
/**
|
|
408
|
+
* Field holding one or more assignee names (string | string[]); shown as
|
|
409
|
+
* avatar(s) on the default card's badge row.
|
|
410
|
+
*/
|
|
411
|
+
assigneesField?: keyof TData & string;
|
|
412
|
+
/**
|
|
413
|
+
* Enable the built-in card editor: double-click a card (or press F2 while
|
|
414
|
+
* it is focused) to edit its fields inline. Fields are rendered from the
|
|
415
|
+
* columns that declare an `editorType` (or all fields if none do). Ignored
|
|
416
|
+
* when `onCardEdit` is set.
|
|
417
|
+
*/
|
|
418
|
+
editable?: boolean;
|
|
419
|
+
/**
|
|
420
|
+
* Open your own editor instead of the built-in one. Called on double-click /
|
|
421
|
+
* F2 with the row; you might open a drawer or route to a detail screen.
|
|
422
|
+
*/
|
|
423
|
+
onCardEdit?: (row: TData) => void;
|
|
424
|
+
/**
|
|
425
|
+
* Built-in **detail drawer**: opening a card (double-click / F2) shows an
|
|
426
|
+
* `SvDrawer` with an `SvForm` of its fields (kit editors). `true` = all
|
|
427
|
+
* fields; pass a {@link BoardDrawerConfig} to pick a subset / customize.
|
|
428
|
+
* Ignored when `onCardEdit` is set.
|
|
429
|
+
*/
|
|
430
|
+
drawer?: boolean | BoardDrawerConfig<TData>;
|
|
431
|
+
/** Fired when the built-in editor is saved. Persist / mirror the changes. */
|
|
432
|
+
onCardCommit?: (event: BoardCardCommitEvent<TData>) => void;
|
|
433
|
+
/** Field used as the card title. Defaults to the first column's field. */
|
|
434
|
+
titleField?: keyof TData & string;
|
|
435
|
+
/**
|
|
436
|
+
* Column fields shown as label:value meta lines on the default card
|
|
437
|
+
* (max 4). Defaults to the first few non-title, non-groupBy columns.
|
|
438
|
+
*/
|
|
439
|
+
cardFields?: ReadonlyArray<keyof TData & string>;
|
|
440
|
+
/**
|
|
441
|
+
* Second grouping axis: split the board into horizontal **swimlanes** by
|
|
442
|
+
* this field. Each swimlane band shows the full lane set with only its own
|
|
443
|
+
* cards. Dragging a card into another band reassigns this field too.
|
|
444
|
+
*/
|
|
445
|
+
swimlaneBy?: keyof TData & string;
|
|
446
|
+
/** Let users collapse a swimlane band via its header chevron. */
|
|
447
|
+
collapsibleSwimlanes?: boolean;
|
|
448
|
+
/**
|
|
449
|
+
* Field holding a card's comments - `BoardComment[]` (or plain strings, or a
|
|
450
|
+
* number for a count only). Renders a comment-count badge that expands to a
|
|
451
|
+
* thread; provide the callbacks below to let users write / delete comments.
|
|
452
|
+
*/
|
|
453
|
+
commentsField?: keyof TData & string;
|
|
454
|
+
/** Fired when a comment is added on the card; append it to your data. */
|
|
455
|
+
onCommentAdd?: (row: TData, text: string) => void;
|
|
456
|
+
/** Fired when a comment's delete button is pressed; remove it from your data. */
|
|
457
|
+
onCommentDelete?: (row: TData, commentId: string | number) => void;
|
|
458
|
+
/**
|
|
459
|
+
* Field holding a card's attachments - an array or a number. Renders an
|
|
460
|
+
* attachment-count badge on the default card.
|
|
461
|
+
*/
|
|
462
|
+
attachmentsField?: keyof TData & string;
|
|
463
|
+
/**
|
|
464
|
+
* Field holding a cover colour (any CSS colour string) shown as a strip
|
|
465
|
+
* across the top of the default card.
|
|
466
|
+
*/
|
|
467
|
+
coverField?: keyof TData & string;
|
|
468
|
+
/**
|
|
469
|
+
* Enforce `wipLimit`: reject a drop / keyboard move that would push a lane
|
|
470
|
+
* past its limit (the card snaps back). Off by default (the limit is a
|
|
471
|
+
* soft, visual flag only).
|
|
472
|
+
*/
|
|
473
|
+
enforceWip?: boolean;
|
|
474
|
+
/** Let users collapse a lane to a slim strip by clicking its header. */
|
|
475
|
+
collapsibleLanes?: boolean;
|
|
476
|
+
/** Let users drag lane headers to reorder lanes (persisted with `persistKey`). */
|
|
477
|
+
reorderableLanes?: boolean;
|
|
478
|
+
/** Fired after a lane drag-reorder, with the new ordered lane ids. */
|
|
479
|
+
onLaneReorder?: (orderedIds: string[]) => void;
|
|
480
|
+
/**
|
|
481
|
+
* Enable inline lane rename: double-click a lane title to edit it. Fires
|
|
482
|
+
* with the lane id and new title - update your own lane config / data.
|
|
483
|
+
*/
|
|
484
|
+
onLaneRename?: (laneId: string, title: string) => void;
|
|
485
|
+
/**
|
|
486
|
+
* Per-swimlane summary shown in the band header (e.g. a points/$ total or a
|
|
487
|
+
* WIP count). Receives the swimlane's cards and its id; return a short string.
|
|
488
|
+
*/
|
|
489
|
+
swimlaneSummary?: (rows: TData[], swimId: string) => string;
|
|
490
|
+
/**
|
|
491
|
+
* Right-click (or long-press) a card to open a context menu. Return the
|
|
492
|
+
* menu items for that card; `ctx` gives board-native `moveTo(laneId)` and
|
|
493
|
+
* `edit()` helpers plus the lane list. Return empty/undefined for no menu.
|
|
494
|
+
*/
|
|
495
|
+
cardMenu?: (row: TData, ctx: BoardMenuContext<TData>) => ReadonlyArray<MenuItem> | undefined;
|
|
496
|
+
/** Right-click a lane header for a lane context menu (rename / clear / add / collapse). */
|
|
497
|
+
laneMenu?: (laneId: string, ctx: BoardLaneMenuContext<TData>) => ReadonlyArray<MenuItem> | undefined;
|
|
498
|
+
/**
|
|
499
|
+
* Truthy field marks a card as **blocked** (waiting on a dependency): a red
|
|
500
|
+
* corner + a "Blocked" badge on the card. If the value is a non-empty string
|
|
501
|
+
* it is used as the blocked **reason** (shown in the badge tooltip). A blocked
|
|
502
|
+
* card is **locked from moving** (drag + keyboard) until it is unblocked - set
|
|
503
|
+
* {@link BoardConfig.flagBlocksMoves} `false` for a purely visual flag.
|
|
504
|
+
*/
|
|
505
|
+
flagField?: keyof TData & string;
|
|
506
|
+
/** Whether a blocked (`flagField`) card is locked from moving. Defaults to `true`. */
|
|
507
|
+
flagBlocksMoves?: boolean;
|
|
508
|
+
/**
|
|
509
|
+
* Field holding a created/started date (Date | ISO string); shown as a
|
|
510
|
+
* relative **age** badge (e.g. `3d`).
|
|
511
|
+
*/
|
|
512
|
+
ageField?: keyof TData & string;
|
|
513
|
+
/**
|
|
514
|
+
* Fields to expose as a **facet filter bar** above the board - a chip per
|
|
515
|
+
* distinct value; selecting chips filters the visible cards.
|
|
516
|
+
*/
|
|
517
|
+
facets?: ReadonlyArray<keyof TData & string>;
|
|
518
|
+
/**
|
|
519
|
+
* Enable card **multi-select**: click to select, Ctrl/Cmd-click to toggle,
|
|
520
|
+
* and dragging a selected card moves the whole selection. Fires
|
|
521
|
+
* `onSelectionChange`.
|
|
522
|
+
*/
|
|
523
|
+
selectable?: boolean;
|
|
524
|
+
/** Fired when the selection changes, with the selected rows. */
|
|
525
|
+
onSelectionChange?: (rows: TData[]) => void;
|
|
526
|
+
/**
|
|
527
|
+
* Field holding a card's **child rows** (`TData[]`) - the card gets a
|
|
528
|
+
* children count and expands to show them as nested mini-cards (epic ->
|
|
529
|
+
* stories). Each child renders its title and, if present, its `groupBy` value.
|
|
530
|
+
*/
|
|
531
|
+
childrenField?: keyof TData & string;
|
|
532
|
+
/**
|
|
533
|
+
* Optional per-lane summary shown in the lane header (e.g. a story-point or
|
|
534
|
+
* dollar total). Receives the lane's cards (the current swimlane's, when
|
|
535
|
+
* `swimlaneBy` is set) and the lane id; return a short string.
|
|
536
|
+
*/
|
|
537
|
+
laneSummary?: (rows: TData[], laneId: string) => string;
|
|
538
|
+
/** Show the built-in card search box (default `true`). */
|
|
539
|
+
searchable?: boolean;
|
|
540
|
+
/** Placeholder for the search box. Defaults to `"Search cards..."`. */
|
|
541
|
+
searchPlaceholder?: string;
|
|
542
|
+
/**
|
|
543
|
+
* Virtualize each lane so only the cards in view are in the DOM - for boards
|
|
544
|
+
* with thousands of cards per lane. Assumes roughly uniform card height; set
|
|
545
|
+
* `cardHeight` to match your cards.
|
|
546
|
+
*/
|
|
547
|
+
virtualized?: boolean;
|
|
548
|
+
/** Estimated card height in px used by `virtualized` windowing (default 76). */
|
|
549
|
+
cardHeight?: number;
|
|
550
|
+
/**
|
|
551
|
+
* Persist the board layout (card positions, edits, collapsed lanes) to
|
|
552
|
+
* `localStorage` under this key, restored on load. Requires `getRowId` for
|
|
553
|
+
* stable identity across reloads.
|
|
554
|
+
*/
|
|
555
|
+
persistKey?: string;
|
|
556
|
+
/** Called whenever the board layout changes, with the serializable state. */
|
|
557
|
+
onLayoutChange?: (layout: BoardLayout) => void;
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* The built-in event detail drawer for the scheduler. Set `scheduler.drawer`
|
|
562
|
+
* (`true` for all fields, or this object) and clicking an event opens a drawer
|
|
563
|
+
* with an `SvForm` of its fields. Mirrors {@link BoardDrawerConfig}.
|
|
564
|
+
*/
|
|
565
|
+
export type SchedulerDrawerConfig<TData extends RowData = RowData> = {
|
|
566
|
+
/** Fields to show, in order. Omit for every column that has a `field`. */
|
|
567
|
+
fields?: ReadonlyArray<keyof TData & string>;
|
|
568
|
+
/** Drawer title - a string or derived from the row. Defaults to the title field. */
|
|
569
|
+
title?: string | ((row: TData) => string);
|
|
570
|
+
/** Which edge the drawer opens from. Defaults to `'right'`. */
|
|
571
|
+
side?: "right" | "left" | "top" | "bottom";
|
|
572
|
+
/** Drawer size (any CSS length). Defaults to `'380px'`. */
|
|
573
|
+
size?: string;
|
|
574
|
+
/** Save button label. Defaults to `'Save'`. */
|
|
575
|
+
submitLabel?: string;
|
|
576
|
+
/** Form columns inside the drawer. Defaults to `1`. */
|
|
577
|
+
columns?: number;
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
/** Emitted when an event is dragged to a new time (and/or resource). */
|
|
581
|
+
export type SchedulerEventMoveEvent<TData extends RowData = RowData> = {
|
|
582
|
+
/** The dragged row. */
|
|
583
|
+
row: TData;
|
|
584
|
+
/** New start / end after the move. */
|
|
585
|
+
start: Date;
|
|
586
|
+
end: Date;
|
|
587
|
+
/** Whether the event is all-day after the move. */
|
|
588
|
+
allDay: boolean;
|
|
589
|
+
/** Resource it came from (only with `resourceField`). */
|
|
590
|
+
fromResource?: string;
|
|
591
|
+
/** Resource it was dropped on (only with `resourceField`). */
|
|
592
|
+
toResource?: string;
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
/** Emitted when an event's start or end edge is dragged to resize it. */
|
|
596
|
+
export type SchedulerEventResizeEvent<TData extends RowData = RowData> = {
|
|
597
|
+
row: TData;
|
|
598
|
+
start: Date;
|
|
599
|
+
end: Date;
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* A drag-selected range (see `rangeSelectable`). `start`/`end` are a single
|
|
604
|
+
* CONTINUOUS datetime range - dragging across days makes it a longer span, not a
|
|
605
|
+
* per-day rectangle. `days` / `resourceIds` list the days / resources the range
|
|
606
|
+
* touched (for reference); `allDay` is true when the all-day row was dragged.
|
|
607
|
+
*/
|
|
608
|
+
export type SchedulerRangeSelection = {
|
|
609
|
+
start: Date;
|
|
610
|
+
end: Date;
|
|
611
|
+
allDay?: boolean;
|
|
612
|
+
/** Every day the range touched (one entry for a within-a-day drag). */
|
|
613
|
+
days: Date[];
|
|
614
|
+
/** Every resource the range touched (empty without `resourceField`). */
|
|
615
|
+
resourceIds: string[];
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
/** Emitted when an event's built-in editor/drawer is saved. */
|
|
619
|
+
export type SchedulerEventCommitEvent<TData extends RowData = RowData> = {
|
|
620
|
+
row: TData;
|
|
621
|
+
/** Only the fields that changed, `{ field: newValue }`. */
|
|
622
|
+
changes: Record<string, unknown>;
|
|
623
|
+
/** The full set of edited field values. */
|
|
624
|
+
values: Record<string, unknown>;
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* One override of a single occurrence of a recurring event (stored in the row's
|
|
629
|
+
* `recurrenceExceptionsField`). `occurrenceStart` identifies the occurrence (its
|
|
630
|
+
* original start, like an iCal `RECURRENCE-ID`); `deleted` removes just that one,
|
|
631
|
+
* otherwise the given fields override it. Times are the same ISO / Date shape you
|
|
632
|
+
* store on the row.
|
|
633
|
+
*/
|
|
634
|
+
export type SchedulerException = {
|
|
635
|
+
occurrenceStart: string | number | Date;
|
|
636
|
+
deleted?: boolean;
|
|
637
|
+
start?: string | number | Date;
|
|
638
|
+
end?: string | number | Date;
|
|
639
|
+
title?: string;
|
|
640
|
+
allDay?: boolean;
|
|
641
|
+
/**
|
|
642
|
+
* Per-occurrence overrides for ANY other field (e.g. attendees, calendar,
|
|
643
|
+
* color, resource). Merged over the row for just this occurrence, so "This
|
|
644
|
+
* event" can change fields beyond start / end / title / all-day.
|
|
645
|
+
*/
|
|
646
|
+
fields?: Record<string, unknown>;
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
/** How a change to a recurring event should apply. */
|
|
650
|
+
export type SchedulerEditScope = "occurrence" | "following" | "series";
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Fired when a single occurrence of a recurring event is edited or deleted (the
|
|
654
|
+
* user chose "This event"). Append/merge `exception` into the row's
|
|
655
|
+
* `recurrenceExceptionsField`; for `deleted` it carries `{ deleted: true }`.
|
|
656
|
+
*/
|
|
657
|
+
export type SchedulerOccurrenceChangeEvent<TData extends RowData = RowData> = {
|
|
658
|
+
row: TData;
|
|
659
|
+
/** The occurrence's original start (its identity within the series). */
|
|
660
|
+
occurrenceStart: Date;
|
|
661
|
+
/** The override to store (already in real-instant time). */
|
|
662
|
+
exception: SchedulerException;
|
|
663
|
+
/**
|
|
664
|
+
* Which scope the user chose. `'occurrence'` (default): merge `exception` into
|
|
665
|
+
* the row. `'following'` ("this and all following"): split the series - stop
|
|
666
|
+
* the original series before `occurrenceStart` and start a NEW series at it
|
|
667
|
+
* carrying `exception`'s start/end/deleted. `'series'` never reaches here (it
|
|
668
|
+
* edits the base row directly). Handle `'following'` in your own data.
|
|
669
|
+
*/
|
|
670
|
+
scope: SchedulerEditScope;
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Turns the grid into a calendar / scheduler. Set `scheduler` and the grid
|
|
675
|
+
* renders its rows as events on a Month / Week / Day / Agenda calendar (bucketed
|
|
676
|
+
* by time, and optionally split into per-resource columns) instead of a table.
|
|
677
|
+
* Dragging an event fires {@link SchedulerConfig.onEventMove} where you reassign
|
|
678
|
+
* the start / end (and resource) on your own data. Like the Kanban board, it is
|
|
679
|
+
* a pure *view of the grid*: it renders the grid's filtered + sorted rows and
|
|
680
|
+
* writes back only through callbacks, never mutating your data.
|
|
681
|
+
*/
|
|
682
|
+
export type SchedulerConfig<
|
|
683
|
+
TFeatures extends TableFeatures = TableFeatures,
|
|
684
|
+
TData extends RowData = RowData,
|
|
685
|
+
> = {
|
|
686
|
+
/** Field holding each event's start (`Date` | epoch-ms | ISO string). Required. */
|
|
687
|
+
startField: keyof TData & string;
|
|
688
|
+
/** Field holding the end. Omit to use `defaultDurationMin` from the start. */
|
|
689
|
+
endField?: keyof TData & string;
|
|
690
|
+
/** Boolean field marking an event as all-day (rendered in the all-day row). */
|
|
691
|
+
allDayField?: keyof TData & string;
|
|
692
|
+
/** Field for the event title. Defaults to the first column's field. */
|
|
693
|
+
titleField?: keyof TData & string;
|
|
694
|
+
/** Field holding a per-event accent color (any CSS color). Else `color`. */
|
|
695
|
+
colorField?: keyof TData & string;
|
|
696
|
+
/** Fallback accent color for every event. */
|
|
697
|
+
color?: string;
|
|
698
|
+
/**
|
|
699
|
+
* Field holding a SECONDARY accent color, rendered as a strip on the LEFT edge
|
|
700
|
+
* of the event - distinct from the main `colorField`. Lets an event encode two
|
|
701
|
+
* dimensions at once (e.g. main color = person, left strip = role).
|
|
702
|
+
*/
|
|
703
|
+
secondaryColorField?: keyof TData & string;
|
|
704
|
+
/**
|
|
705
|
+
* Field holding a free/busy status that drives a distinct visual treatment
|
|
706
|
+
* (Outlook-style): `'busy'` (default solid), `'free'` (hollow / outline),
|
|
707
|
+
* `'tentative'` (hatched), `'oof'` / `'outOfOffice'` (distinct tint). Ties to
|
|
708
|
+
* iCal `STATUS`. Unrecognised values render as busy.
|
|
709
|
+
*/
|
|
710
|
+
statusField?: keyof TData & string;
|
|
711
|
+
/**
|
|
712
|
+
* Field holding minutes-before-start for a reminder. When set (and the event
|
|
713
|
+
* is upcoming) the scheduler fires `onReminder` once as that lead time is
|
|
714
|
+
* crossed - pair it with a toast. Ties to iCal `VALARM`.
|
|
715
|
+
*/
|
|
716
|
+
reminderField?: keyof TData & string;
|
|
717
|
+
/** Fired once when an event's reminder lead time is crossed (see `reminderField`). */
|
|
718
|
+
onReminder?: (row: TData, minutesUntil: number) => void;
|
|
719
|
+
/**
|
|
720
|
+
* Field holding a {@link RecurrenceRule} (or array) - the row renders as one
|
|
721
|
+
* event per matching day in view, keeping its time-of-day + duration.
|
|
722
|
+
*/
|
|
723
|
+
recurrenceField?: keyof TData & string;
|
|
724
|
+
/**
|
|
725
|
+
* Field holding an array of {@link SchedulerException} - per-occurrence
|
|
726
|
+
* overrides of a recurring event (a moved / edited / deleted single instance).
|
|
727
|
+
* When set, editing a recurring occurrence offers "This event" vs "All events"
|
|
728
|
+
* and "This event" fires {@link onOccurrenceChange}.
|
|
729
|
+
*/
|
|
730
|
+
recurrenceExceptionsField?: keyof TData & string;
|
|
731
|
+
/** Event length in minutes when a row has a start but no `endField`. Default 60. */
|
|
732
|
+
defaultDurationMin?: number;
|
|
733
|
+
|
|
734
|
+
/** Which views to offer in the toolbar. Default all four. */
|
|
735
|
+
views?: ReadonlyArray<SchedulerView>;
|
|
736
|
+
/** The view shown first. Default `'month'`. */
|
|
737
|
+
initialView?: SchedulerView;
|
|
738
|
+
/** The date the calendar opens on. Defaults to "today". */
|
|
739
|
+
initialDate?: Date | number | string;
|
|
740
|
+
/**
|
|
741
|
+
* Controlled anchor date - when this changes the calendar navigates to it (a
|
|
742
|
+
* mini date-picker or external "go to" can drive the view). Pair with
|
|
743
|
+
* {@link onNavigate} for two-way sync.
|
|
744
|
+
*/
|
|
745
|
+
date?: Date | number | string;
|
|
746
|
+
/** Fired when the visible date changes (prev / next / today). */
|
|
747
|
+
onNavigate?: (date: Date) => void;
|
|
748
|
+
/** First day of the week, 0-6 (0 = Sunday). Default 0. */
|
|
749
|
+
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
750
|
+
/** Time-grid slot size in minutes (week / day snap granularity). Default 30. */
|
|
751
|
+
slotMinutes?: number;
|
|
752
|
+
/**
|
|
753
|
+
* Slot sizes (minutes) offered as a runtime picker in the Week / Day time-grid
|
|
754
|
+
* ruler, e.g. `[60, 30, 15, 5]`. When set, a size selector appears in the
|
|
755
|
+
* toolbar and the ruler subdivides accordingly; the active size starts at
|
|
756
|
+
* `slotMinutes`. Omit to hide the picker (the ruler still uses `slotMinutes`).
|
|
757
|
+
*/
|
|
758
|
+
slotSizes?: ReadonlyArray<number>;
|
|
759
|
+
/** First / last hour shown in the time-grid band (0-24). Default 0..24. */
|
|
760
|
+
dayStartHour?: number;
|
|
761
|
+
dayEndHour?: number;
|
|
762
|
+
|
|
763
|
+
// --- booking rules: working hours, non-working days, conflicts -------------
|
|
764
|
+
/**
|
|
765
|
+
* Working-hours window (hours, e.g. `{ start: 9, end: 17 }`). Time outside it
|
|
766
|
+
* is shaded in the Week / Day time-grid. Visual only - see `disableConflicts`
|
|
767
|
+
* to enforce.
|
|
768
|
+
*/
|
|
769
|
+
businessHours?: { start: number; end: number };
|
|
770
|
+
/** Weekday numbers (0 = Sun … 6 = Sat) shaded as non-working (e.g. `[0, 6]`). */
|
|
771
|
+
nonWorkingDays?: ReadonlyArray<number>;
|
|
772
|
+
/** Shade elapsed time on today's column (the past is "used up"). */
|
|
773
|
+
shadeUntilNow?: boolean;
|
|
774
|
+
/**
|
|
775
|
+
* Enforce the shaded time: reject a drag / resize / create that lands outside
|
|
776
|
+
* `businessHours` or on a `nonWorkingDays` day (snap back + flash). Without
|
|
777
|
+
* this the shading is a visual hint only.
|
|
778
|
+
*/
|
|
779
|
+
restrictToBusinessHours?: boolean;
|
|
780
|
+
/**
|
|
781
|
+
* Prevent double-booking: dragging / resizing / creating an event so it
|
|
782
|
+
* overlaps another event **on the same resource** is rejected and reverted.
|
|
783
|
+
*/
|
|
784
|
+
disableConflicts?: boolean;
|
|
785
|
+
/**
|
|
786
|
+
* Hard-blocked hour bands (e.g. a daily maintenance window `[{ start: 12, end: 13 }]`).
|
|
787
|
+
* Unlike `businessHours` these are ALWAYS non-bookable (drop / create rejected,
|
|
788
|
+
* no opt-in needed) and rendered as a distinct restricted (hatched) band.
|
|
789
|
+
*/
|
|
790
|
+
restrictedHours?: ReadonlyArray<{ start: number; end: number }>;
|
|
791
|
+
/** Specific calendar dates that are fully blocked (no bookings) - e.g. closures. */
|
|
792
|
+
restrictedDates?: ReadonlyArray<Date | number | string>;
|
|
793
|
+
/**
|
|
794
|
+
* Highlighted dates (holidays, launches …) - a coloured strip + optional label
|
|
795
|
+
* on that day's column / month cell. Decorative; does not block booking.
|
|
796
|
+
*/
|
|
797
|
+
specialDates?: ReadonlyArray<{ date: Date | number | string; label?: string; color?: string }>;
|
|
798
|
+
/** Earliest navigable / bookable date. Prev-nav stops here and creates are blocked before it. */
|
|
799
|
+
minDate?: Date | number | string;
|
|
800
|
+
/** Latest navigable / bookable date. Next-nav stops here and creates are blocked after it. */
|
|
801
|
+
maxDate?: Date | number | string;
|
|
802
|
+
/**
|
|
803
|
+
* Cap concurrent events per resource at any moment: a drag / resize / create
|
|
804
|
+
* that would make more than N events overlap on the same resource is rejected.
|
|
805
|
+
*/
|
|
806
|
+
maxEventsPerSlot?: number;
|
|
807
|
+
/**
|
|
808
|
+
* Enable **undo / redo** of drag-move + resize with `Ctrl/Cmd+Z` and
|
|
809
|
+
* `Ctrl/Cmd+Shift+Z` (or `Ctrl+Y`). The scheduler re-emits the move/resize
|
|
810
|
+
* callbacks with the reversed values, so your data follows.
|
|
811
|
+
*/
|
|
812
|
+
history?: boolean;
|
|
813
|
+
/**
|
|
814
|
+
* Show the current-time indicator - a line across today's column(s) in the
|
|
815
|
+
* Week / Day time-grid and the Day timeline, tracking the local time. On by
|
|
816
|
+
* default; set to `false` to hide it.
|
|
817
|
+
*/
|
|
818
|
+
nowIndicator?: boolean;
|
|
819
|
+
/**
|
|
820
|
+
* IANA time zone (e.g. `'America/New_York'`) the whole calendar is shown in -
|
|
821
|
+
* the hour ruler, event positions, day boundaries, all-day grouping and the
|
|
822
|
+
* now-line. Defaults to the browser's local zone. Event `start`/`end` must be
|
|
823
|
+
* instant-unambiguous (UTC / offset ISO or epoch ms) for this to be correct;
|
|
824
|
+
* bare local strings are read as wall-clock in this zone.
|
|
825
|
+
*/
|
|
826
|
+
timeZone?: string;
|
|
827
|
+
/**
|
|
828
|
+
* Extra read-only hour rulers for other zones (a "world clock"), shown left of
|
|
829
|
+
* the primary ruler in the Week / Day time-grid. Each entry's `label` heads its
|
|
830
|
+
* column (defaults to a short zone abbreviation).
|
|
831
|
+
*/
|
|
832
|
+
secondaryTimeZones?: ReadonlyArray<{ id: string; label?: string }>;
|
|
833
|
+
/**
|
|
834
|
+
* How overlapping time-grid events are laid out. `split` (default) divides the
|
|
835
|
+
* width evenly per collision; `cap` shows up to `maxColumns` then a clickable
|
|
836
|
+
* `+N more` tile; `stack` overlaps them with an offset instead of shrinking.
|
|
837
|
+
*/
|
|
838
|
+
collisionMode?: SchedulerCollisionMode;
|
|
839
|
+
/** For `collisionMode: 'cap'`: max side-by-side columns before overflow (min 2). Default 3. */
|
|
840
|
+
maxColumns?: number;
|
|
841
|
+
/** How many days the agenda view spans. Default 30. */
|
|
842
|
+
agendaDays?: number;
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Field whose value groups events by resource (people, rooms, machines). In
|
|
846
|
+
* the Week / Day time-grid the columns split into resource x day groups; a
|
|
847
|
+
* resource filter/legend appears in every view. See {@link SchedulerResource}.
|
|
848
|
+
*/
|
|
849
|
+
resourceField?: keyof TData & string;
|
|
850
|
+
/** Explicit, ordered resources (with colors). Omit to derive from the data. */
|
|
851
|
+
resources?: ReadonlyArray<SchedulerResource>;
|
|
852
|
+
/**
|
|
853
|
+
* Time-grid resource grouping order. `false` (default) groups by resource then
|
|
854
|
+
* day (resource-major); `true` groups by day then resource (date-major), like
|
|
855
|
+
* Smart's `groupByDate`. Only affects Week / Day when `resourceField` is set.
|
|
856
|
+
*/
|
|
857
|
+
groupByDate?: boolean;
|
|
858
|
+
|
|
859
|
+
/** Timeline views only: width (px) of the left resource-label gutter. Default 160. */
|
|
860
|
+
resourceAreaWidth?: number;
|
|
861
|
+
/** `timelineDay` tick size + move/resize snap, in minutes. Default = `slotMinutes`. */
|
|
862
|
+
timelineSlotMinutes?: number;
|
|
863
|
+
/** Timeline views only: height (px) of one event lane inside a resource row. Default 26. */
|
|
864
|
+
timelineLaneHeight?: number;
|
|
865
|
+
|
|
866
|
+
/** Enable drag-to-move and edge-resize. Without it the calendar is read-only. */
|
|
867
|
+
editable?: boolean;
|
|
868
|
+
/** Fired when an event is dragged to a new time / resource. */
|
|
869
|
+
onEventMove?: (event: SchedulerEventMoveEvent<TData>) => void;
|
|
870
|
+
/** Fired when an event edge is dragged to resize it. */
|
|
871
|
+
onEventResize?: (event: SchedulerEventResizeEvent<TData>) => void;
|
|
872
|
+
/**
|
|
873
|
+
* Fired to create an event - double-clicking an empty slot, or confirming a
|
|
874
|
+
* pending range when no {@link onRangeSelect} is set. `allDay` is `true` when
|
|
875
|
+
* the slot / range is an all-day one (the all-day row, a month day cell, or a
|
|
876
|
+
* multi-day timeline zoom), so the handler can set the `allDayField`.
|
|
877
|
+
*/
|
|
878
|
+
onEventAdd?: (start: Date, end: Date, resourceId?: string, allDay?: boolean) => void;
|
|
879
|
+
/**
|
|
880
|
+
* Fired when the event's Delete button is used. Setting this shows a Delete
|
|
881
|
+
* button in the detail drawer (and a `Delete` item is easy to add via
|
|
882
|
+
* `eventMenu`). Remove the row from your data in the handler.
|
|
883
|
+
*/
|
|
884
|
+
onEventDelete?: (row: TData) => void;
|
|
885
|
+
/**
|
|
886
|
+
* Fired when a single occurrence of a recurring event is moved / resized /
|
|
887
|
+
* deleted with scope "This event". Merge `event.exception` into the row's
|
|
888
|
+
* `recurrenceExceptionsField` array (keyed by `occurrenceStart`).
|
|
889
|
+
*/
|
|
890
|
+
onOccurrenceChange?: (event: SchedulerOccurrenceChangeEvent<TData>) => void;
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Selecting empty cells: click or drag across the time-grid / timeline to mark
|
|
894
|
+
* a time range (and, across days / resources, a rectangle of cells). Arrow keys
|
|
895
|
+
* move the selection and `Shift`+arrows extend it. Marking only *marks* the
|
|
896
|
+
* range - it does NOT create anything. The event is created on an explicit
|
|
897
|
+
* confirm: press `Enter`, or right-click the selection and choose "Add Event".
|
|
898
|
+
* Confirming fires {@link onRangeSelect}, or falls back to `onEventAdd` for the
|
|
899
|
+
* first cell; `Escape` cancels the marker.
|
|
900
|
+
*
|
|
901
|
+
* On by default; set to `false` to disable.
|
|
902
|
+
*/
|
|
903
|
+
rangeSelectable?: boolean;
|
|
904
|
+
/**
|
|
905
|
+
* Fired when a pending cell range is confirmed with `Enter` or the "Add Event"
|
|
906
|
+
* context menu (see {@link rangeSelectable}) - not on drag release.
|
|
907
|
+
*/
|
|
908
|
+
onRangeSelect?: (selection: SchedulerRangeSelection) => void;
|
|
909
|
+
/**
|
|
910
|
+
* Multi-selecting existing events: Ctrl/Cmd-click toggles, Shift-click
|
|
911
|
+
* range-selects; a plain click clears. Selected events move together when one
|
|
912
|
+
* is dragged, and `Delete` removes them (via `onEventDelete`).
|
|
913
|
+
*
|
|
914
|
+
* On by default; set to `false` to disable.
|
|
915
|
+
*/
|
|
916
|
+
eventSelectable?: boolean;
|
|
917
|
+
/** Fired when the set of multi-selected events changes. */
|
|
918
|
+
onEventSelectionChange?: (rows: TData[]) => void;
|
|
919
|
+
|
|
920
|
+
/**
|
|
921
|
+
* An "unscheduled" backlog list shown beside the Week / Day grid: drag an item
|
|
922
|
+
* onto the calendar to schedule it. Each item is `{ id, title, durationMin?,
|
|
923
|
+
* color? }`. Dropping fires {@link onSchedule} with the drop time + resource.
|
|
924
|
+
*/
|
|
925
|
+
unscheduled?: ReadonlyArray<{ id: string; title: string; durationMin?: number; color?: string }>;
|
|
926
|
+
/** Optional heading for the unscheduled backlog panel. Default "Unscheduled". */
|
|
927
|
+
backlogTitle?: string;
|
|
928
|
+
/** Fired when an unscheduled item is dropped on the grid - create an event from it. */
|
|
929
|
+
onSchedule?: (item: { id: string; title: string; durationMin?: number; color?: string }, start: Date, resourceId?: string) => void;
|
|
930
|
+
/**
|
|
931
|
+
* Fired when an event is dragged OFF the calendar onto the backlog panel -
|
|
932
|
+
* remove it from the schedule (and typically push it back to `unscheduled`).
|
|
933
|
+
* Requires the backlog panel (an `unscheduled` list) to be visible.
|
|
934
|
+
*/
|
|
935
|
+
onUnschedule?: (row: TData) => void;
|
|
936
|
+
|
|
937
|
+
/** Custom event body. Receives the row. Omit for the built-in default (title). */
|
|
938
|
+
event?: Snippet<[TData]>;
|
|
939
|
+
/**
|
|
940
|
+
* Hover tooltip for an event. Set a `Snippet<[TData]>` for custom content, or
|
|
941
|
+
* `true` for the built-in tooltip (title + time + resource). Omit to disable.
|
|
942
|
+
*/
|
|
943
|
+
tooltip?: boolean | Snippet<[TData]>;
|
|
944
|
+
/** Delay (ms) before the hover tooltip opens. Default 400. */
|
|
945
|
+
tooltipDelay?: number;
|
|
946
|
+
/** Built-in detail drawer: `true` for all fields, or a config object. */
|
|
947
|
+
drawer?: boolean | SchedulerDrawerConfig<TData>;
|
|
948
|
+
/** Fired when the drawer / editor is saved. */
|
|
949
|
+
onEventCommit?: (event: SchedulerEventCommitEvent<TData>) => void;
|
|
950
|
+
/** Right-click menu for an event. Return items or `undefined` to suppress. */
|
|
951
|
+
eventMenu?: (row: TData) => MenuItem[] | undefined;
|
|
952
|
+
|
|
953
|
+
/** Show the search box (binds to the grid's global filter). Default `true`. */
|
|
954
|
+
searchable?: boolean;
|
|
955
|
+
searchPlaceholder?: string;
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> = {
|
|
959
|
+
data: ReadonlyArray<TData>;
|
|
960
|
+
columns: Array<ColumnDef<TFeatures, TData>>;
|
|
961
|
+
/**
|
|
962
|
+
* Kanban board mode. When set, the grid renders its rows as cards in
|
|
963
|
+
* horizontal lanes (bucketed by `board.groupBy`) instead of a table. See
|
|
964
|
+
* {@link BoardConfig}.
|
|
965
|
+
*/
|
|
966
|
+
board?: BoardConfig<TFeatures, TData>;
|
|
967
|
+
/**
|
|
968
|
+
* Scheduler / calendar mode. When set, the grid renders its rows as events on
|
|
969
|
+
* a Month / Week / Day / Agenda calendar instead of a table. See
|
|
970
|
+
* {@link SchedulerConfig}.
|
|
971
|
+
*/
|
|
972
|
+
scheduler?: SchedulerConfig<TFeatures, TData>;
|
|
973
|
+
/**
|
|
974
|
+
* Chart view. When set, the grid renders its FILTERED + SORTED rows as a chart
|
|
975
|
+
* instead of a table (search / filters / sort flow through). Unlike board and
|
|
976
|
+
* scheduler, the renderer is free - the grid lazy-loads a built-in `SvChart`
|
|
977
|
+
* view, overridable via `registerChartView`. See {@link ChartViewConfig}.
|
|
978
|
+
*/
|
|
979
|
+
chart?: ChartViewConfig<TFeatures, TData>;
|
|
980
|
+
/**
|
|
981
|
+
* Pivot mode. When set (and `pivotMode` is on), the grid renders its rows as a
|
|
982
|
+
* pivot table in place - the same grid, aggregated across `pivot.rows` /
|
|
983
|
+
* `pivot.cols` with nested column headers - instead of the flat table. The
|
|
984
|
+
* pivot ENGINE ships in `@svgrid/enterprise`; call `enablePivot()` (or
|
|
985
|
+
* `installEnterprise(api)`) to register it, otherwise an upsell note shows.
|
|
986
|
+
* See {@link GridPivotConfig}.
|
|
987
|
+
*/
|
|
988
|
+
pivot?: GridPivotConfig<TData>;
|
|
989
|
+
/**
|
|
990
|
+
* Whether pivot mode is currently active. Defaults to `true` when `pivot` is
|
|
991
|
+
* set. Bindable so a toolbar toggle can flip between the pivot and the flat
|
|
992
|
+
* table over the same data.
|
|
993
|
+
*/
|
|
994
|
+
pivotMode?: boolean;
|
|
995
|
+
/** Fired when the in-grid Pivot toggle flips `pivotMode`. */
|
|
996
|
+
onPivotModeChange?: (on: boolean) => void;
|
|
997
|
+
/**
|
|
998
|
+
* Right-click context menu. `true` shows the default item set (copy, cut,
|
|
999
|
+
* paste, clear, insert row above/below, remove row, remove column). Pass an
|
|
1000
|
+
* array to customize: strings are built-in keys, `"separator"` is a divider,
|
|
1001
|
+
* and objects are custom items. Omitted/`false` disables the menu (native
|
|
1002
|
+
* browser menu shows instead).
|
|
1003
|
+
*/
|
|
1004
|
+
contextMenu?: boolean | ReadonlyArray<ContextMenuItem<TData>>;
|
|
1005
|
+
/**
|
|
1006
|
+
* The feature set built with `tableFeatures({ ... })`. Optional - the
|
|
1007
|
+
* `sortable` / `filterable` / `groupable` shortcuts below inject the
|
|
1008
|
+
* matching feature for you, so a grid can be configured entirely from
|
|
1009
|
+
* the boolean shortcuts without importing the feature constants.
|
|
1010
|
+
*/
|
|
1011
|
+
features?: TFeatures;
|
|
1012
|
+
/**
|
|
1013
|
+
* Convenience shortcuts to switch a whole capability on without wiring
|
|
1014
|
+
* `features` or the finer-grained props by hand. Every capability is OFF
|
|
1015
|
+
* by default - a bare grid is a plain read-only table - so set the
|
|
1016
|
+
* shortcut `true` to opt in. (`false` / omitted both leave it off; the
|
|
1017
|
+
* shortcut is mainly there to turn things ON.)
|
|
1018
|
+
*
|
|
1019
|
+
* `sortable` - column sorting (injects `rowSortingFeature`)
|
|
1020
|
+
* `filterable` - column filtering (injects `columnFilteringFeature`)
|
|
1021
|
+
* `editable` - inline cell editing (alias of `enableInlineEditing`)
|
|
1022
|
+
* `groupable` - row grouping controls(alias of `showGroupingControls`,
|
|
1023
|
+
* also injects `columnGroupingFeature`)
|
|
1024
|
+
* `pageable` - pagination footer (alias of `showPagination`)
|
|
1025
|
+
*
|
|
1026
|
+
* Fine-grained props (`enableInlineEditing`, `showPagination`, ...) still
|
|
1027
|
+
* work; the shortcut wins only when it is explicitly set.
|
|
1028
|
+
*/
|
|
1029
|
+
sortable?: boolean;
|
|
1030
|
+
filterable?: boolean;
|
|
1031
|
+
editable?: boolean;
|
|
1032
|
+
/**
|
|
1033
|
+
* Client-side tree data: nest rows into a hierarchy by parent id.
|
|
1034
|
+
*
|
|
1035
|
+
* ```svelte
|
|
1036
|
+
* <SvGrid {data} {columns} treeData={{ parentField: 'managerId', column: 'name' }} />
|
|
1037
|
+
* ```
|
|
1038
|
+
*
|
|
1039
|
+
* Unlike grouping, tree rows are real data rows - they keep their cells,
|
|
1040
|
+
* editing and selection, and only gain an expander plus indentation in
|
|
1041
|
+
* `column`. Rows whose parent is missing become roots rather than vanishing.
|
|
1042
|
+
*
|
|
1043
|
+
* For NESTED source data (`children: [...]`), flatten it first with
|
|
1044
|
+
* `flattenTreeData(data, { childrenField: 'children' })` and point
|
|
1045
|
+
* `parentField` at the `__parentId` it stamps on.
|
|
1046
|
+
*
|
|
1047
|
+
* Setting this replaces row grouping - a row cannot be both.
|
|
1048
|
+
*/
|
|
1049
|
+
treeData?: {
|
|
1050
|
+
/** Field holding each row's parent id. */
|
|
1051
|
+
parentField: string;
|
|
1052
|
+
/** Field holding the row's own id. Defaults to `'id'`. */
|
|
1053
|
+
idField?: string;
|
|
1054
|
+
/**
|
|
1055
|
+
* Column id that carries the expander + indentation. Defaults to the first
|
|
1056
|
+
* visible column.
|
|
1057
|
+
*/
|
|
1058
|
+
column?: string;
|
|
1059
|
+
/** Indent per depth level, in px. Default `12`. */
|
|
1060
|
+
indentPx?: number;
|
|
1061
|
+
};
|
|
1062
|
+
groupable?: boolean;
|
|
1063
|
+
/**
|
|
1064
|
+
* Render a subtotal row after each group's children, carrying that group's
|
|
1065
|
+
* aggregate values under the columns they belong to (the columns with an
|
|
1066
|
+
* `aggregate` set). Off by default.
|
|
1067
|
+
*
|
|
1068
|
+
* Footers are inserted after paging, so they never count against `pageSize` -
|
|
1069
|
+
* a page shows its `pageSize` data rows plus whatever footers close on it.
|
|
1070
|
+
*/
|
|
1071
|
+
groupFooters?: boolean;
|
|
1072
|
+
/**
|
|
1073
|
+
* Append a grand-total row at the very end, aggregating the whole filtered
|
|
1074
|
+
* set (not just the current page) with each column's `aggregate` function.
|
|
1075
|
+
*
|
|
1076
|
+
* Independent of `groupFooters`: use it on a flat grid for a bottom totals
|
|
1077
|
+
* line, or alongside group subtotals for both. Like group footers it is
|
|
1078
|
+
* appended after paging, so it never counts against `pageSize` - but it is
|
|
1079
|
+
* only appended on the LAST page, so a total never appears mid-dataset.
|
|
1080
|
+
* Columns without an `aggregate` are left blank.
|
|
1081
|
+
*/
|
|
1082
|
+
grandTotalRow?: boolean;
|
|
1083
|
+
/**
|
|
1084
|
+
* How grouped rows are displayed.
|
|
1085
|
+
*
|
|
1086
|
+
* - `groupRows` (default): a full-width banner row per group. Unchanged
|
|
1087
|
+
* behaviour - existing grids are untouched.
|
|
1088
|
+
* - `singleColumn`: one synthetic "Group" column holding every level,
|
|
1089
|
+
* indented by depth.
|
|
1090
|
+
* - `multipleColumns`: one synthetic column per grouped field.
|
|
1091
|
+
*
|
|
1092
|
+
* Both column modes hide the grouped source columns, since their values move
|
|
1093
|
+
* into the auto column(s), and render group rows as ordinary rows so their
|
|
1094
|
+
* aggregate cells line up under the real columns.
|
|
1095
|
+
*/
|
|
1096
|
+
groupDisplayMode?: GroupDisplayType;
|
|
1097
|
+
/** Header for the combined `singleColumn` auto-group column. Default `"Group"`. */
|
|
1098
|
+
autoGroupColumnHeader?: string;
|
|
1099
|
+
/** Width (px) of each auto-group column. Default `220`. */
|
|
1100
|
+
autoGroupColumnWidth?: number;
|
|
1101
|
+
pageable?: boolean;
|
|
1102
|
+
loading?: boolean;
|
|
1103
|
+
/**
|
|
1104
|
+
* Render `loading` as a non-blocking overlay instead of replacing the
|
|
1105
|
+
* whole grid: the current rows stay visible (dimmed, with a top progress
|
|
1106
|
+
* bar) during a refetch, and the first load shows shimmer skeleton rows.
|
|
1107
|
+
* Ideal for server-paged grids so paging/sorting doesn't flash. Defaults
|
|
1108
|
+
* to `false` (the classic full "Loading..." replacement).
|
|
1109
|
+
*/
|
|
1110
|
+
loadingOverlay?: boolean;
|
|
1111
|
+
/** Skeleton placeholder rows to show on first load. Defaults to 8. */
|
|
1112
|
+
loadingSkeletonRows?: number;
|
|
1113
|
+
error?: string | null;
|
|
1114
|
+
emptyMessage?: string;
|
|
1115
|
+
/**
|
|
1116
|
+
* The single place to localize the grid. One object with two fields:
|
|
1117
|
+
*
|
|
1118
|
+
* - `locale` - BCP-47 tag(s) for the DATA: accent/case-insensitive filter
|
|
1119
|
+
* matching AND every column's number / currency / percent / date formatting
|
|
1120
|
+
* (when the column's own `format.locales` is unset). The default for
|
|
1121
|
+
* `filterLocale` and per-column format locales.
|
|
1122
|
+
* - `text` - overrides for the grid's own UI STRINGS (empty state, tool panel,
|
|
1123
|
+
* pager, status bar, filter operator labels, context-menu items, upsell
|
|
1124
|
+
* notes). Any subset overrides the English defaults; unset keys stay English.
|
|
1125
|
+
*
|
|
1126
|
+
* ```svelte
|
|
1127
|
+
* <SvGrid localization={{ locale: 'fr-FR', text: { noRows: 'Aucune ligne' } }} />
|
|
1128
|
+
* ```
|
|
1129
|
+
*
|
|
1130
|
+
* Omitting it (or any field) is a no-op. See {@link GridMessages}.
|
|
1131
|
+
*/
|
|
1132
|
+
localization?: GridLocalization;
|
|
1133
|
+
showGlobalFilter?: boolean;
|
|
1134
|
+
showColumnFilters?: boolean;
|
|
1135
|
+
/**
|
|
1136
|
+
* Quick way to pick a single filtering UI. When set it controls which of
|
|
1137
|
+
* the three filter surfaces appears (and is overridden per-surface by the
|
|
1138
|
+
* `showGlobalFilter` / `showColumnFilters` / `showFilterRow` props).
|
|
1139
|
+
* Defaults to `'menu'` (only the column menu's filter section is shown).
|
|
1140
|
+
*/
|
|
1141
|
+
filterMode?: "row" | "menu" | "global" | "none";
|
|
1142
|
+
showGroupingControls?: boolean;
|
|
1143
|
+
showRowSelection?: boolean;
|
|
1144
|
+
showPagination?: boolean;
|
|
1145
|
+
/** Initial page size when pagination is enabled. Defaults to 10. */
|
|
1146
|
+
pageSize?: number;
|
|
1147
|
+
/** Page-size choices shown in the footer's selector. Defaults to `[10, 25, 50, 100]`. */
|
|
1148
|
+
pageSizeOptions?: number[];
|
|
1149
|
+
/**
|
|
1150
|
+
* Where the pagination footer sits: `'bottom'` (default), `'top'`, or `'both'`.
|
|
1151
|
+
* The status bar (when enabled) always stays at the bottom.
|
|
1152
|
+
*/
|
|
1153
|
+
paginationPosition?: 'top' | 'bottom' | 'both';
|
|
1154
|
+
/**
|
|
1155
|
+
* Server-side pagination. When `true`, the grid renders its native
|
|
1156
|
+
* pagination footer from the `rowCount` / `pageIndex` you provide (rather
|
|
1157
|
+
* than counting the local rows), does NOT slice `data` (the rows you pass are
|
|
1158
|
+
* treated as the current page), and emits `onPaginationChange` when the user
|
|
1159
|
+
* pages or changes page size. Pair with `externalSort` / `externalFilter`
|
|
1160
|
+
* and a server data source. Requires `showPagination` / `pageable` to show
|
|
1161
|
+
* the footer. Controlled: you own `pageIndex` + `pageSize` + `rowCount`.
|
|
1162
|
+
*/
|
|
1163
|
+
externalPagination?: boolean;
|
|
1164
|
+
/** Total rows on the server, for the footer's range + page count. Used with `externalPagination`. */
|
|
1165
|
+
rowCount?: number;
|
|
1166
|
+
/** Current 0-based page index. Used with `externalPagination` (controlled). */
|
|
1167
|
+
pageIndex?: number;
|
|
1168
|
+
/**
|
|
1169
|
+
* Fires when the user changes page or page size while `externalPagination`
|
|
1170
|
+
* is on. Fetch that page and update `data` / `rowCount` / `pageIndex`.
|
|
1171
|
+
*/
|
|
1172
|
+
onPaginationChange?: (pagination: { pageIndex: number; pageSize: number }) => void;
|
|
1173
|
+
virtualization?: boolean;
|
|
1174
|
+
/** Row height in pixels. Pass a function `(rowIndex) => px` for
|
|
1175
|
+
* per-row variable heights (e.g. an interactive row-resize feature).
|
|
1176
|
+
* Defaults to 30. */
|
|
1177
|
+
rowHeight?: number | ((rowIndex: number) => number);
|
|
1178
|
+
/**
|
|
1179
|
+
* Size each row to its own content instead of a fixed height: cell text wraps
|
|
1180
|
+
* and the row grows to fit the tallest cell. Rows are measured after they
|
|
1181
|
+
* render, so this works with virtualization - `rowHeight` (or 30) is the
|
|
1182
|
+
* estimate used before a row has been measured, which keeps the scrollbar
|
|
1183
|
+
* stable while you scroll into new rows.
|
|
1184
|
+
*
|
|
1185
|
+
* Costs a measurement pass per row, so prefer a fixed `rowHeight` when your
|
|
1186
|
+
* content is uniform. Ignored when `rowHeight` is a function (you are already
|
|
1187
|
+
* supplying per-row heights).
|
|
1188
|
+
*/
|
|
1189
|
+
autoRowHeight?: boolean;
|
|
1190
|
+
/**
|
|
1191
|
+
* Height (px) of a single column-header level row. With multi-level
|
|
1192
|
+
* (grouped) headers the total header height is `levels * headerHeight`,
|
|
1193
|
+
* since each level renders as its own row. When omitted, header rows size
|
|
1194
|
+
* to their content (the default). Does not affect the filter row.
|
|
1195
|
+
*/
|
|
1196
|
+
headerHeight?: number;
|
|
1197
|
+
overscan?: number;
|
|
1198
|
+
/**
|
|
1199
|
+
* Height of the grid's scrollable shell. A number is treated as pixels;
|
|
1200
|
+
* a string is used as-is, so callers can pass `'100%'` or `'auto'` to
|
|
1201
|
+
* make the grid fill its parent. Defaults to 520 px.
|
|
1202
|
+
*/
|
|
1203
|
+
containerHeight?: number | string;
|
|
1204
|
+
columnVirtualization?: boolean;
|
|
1205
|
+
columnOverscan?: number;
|
|
1206
|
+
columnWidth?: number;
|
|
1207
|
+
/**
|
|
1208
|
+
* Columns pinned to the left/right edge on mount. Each entry is a
|
|
1209
|
+
* column id (matches `ColumnDef.field` when no explicit id is set).
|
|
1210
|
+
* The internal pinning state is seeded once at mount; user-driven
|
|
1211
|
+
* pinning via the column menu still works and overrides this default.
|
|
1212
|
+
* Requires `columnVirtualization={false}` to be visible in the menu
|
|
1213
|
+
* UI (sticky positioning can't co-exist with column virtualization
|
|
1214
|
+
* since the virtualizer recycles DOM nodes).
|
|
1215
|
+
*/
|
|
1216
|
+
initialColumnPinning?: {
|
|
1217
|
+
left?: ReadonlyArray<string>;
|
|
1218
|
+
right?: ReadonlyArray<string>;
|
|
1219
|
+
};
|
|
1220
|
+
/**
|
|
1221
|
+
* When `true`, columns are scaled proportionally so their total width
|
|
1222
|
+
* fills the viewport (no empty space on the right). Disabled by
|
|
1223
|
+
* default - explicit `width` values are used as-is. User resizes still
|
|
1224
|
+
* win once they happen.
|
|
1225
|
+
*/
|
|
1226
|
+
fitColumns?: boolean;
|
|
1227
|
+
/**
|
|
1228
|
+
* Make the grid usable on narrow screens. When the grid's own width drops
|
|
1229
|
+
* below the breakpoint (default `640`px), pinned columns are un-pinned so the
|
|
1230
|
+
* whole grid pans, `fitColumns` scaling is suspended (columns keep their
|
|
1231
|
+
* natural widths and scroll), touch panning is smoothed, and columns whose
|
|
1232
|
+
* `hideBelow` exceeds the width are hidden. `true` uses the default
|
|
1233
|
+
* breakpoint; pass `{ breakpoint }` to change it. Off by default.
|
|
1234
|
+
*/
|
|
1235
|
+
responsive?: boolean | { breakpoint?: number };
|
|
1236
|
+
showFilterMenu?: boolean;
|
|
1237
|
+
showFilterRow?: boolean;
|
|
1238
|
+
enableCellSelection?: boolean;
|
|
1239
|
+
/**
|
|
1240
|
+
* Highlight the row under the pointer. Default **false** - the hover tint can
|
|
1241
|
+
* compete with the cell selection / fill marquee. Set `true` to opt in; when
|
|
1242
|
+
* on, the hover no longer paints over selected cells so the selection stays
|
|
1243
|
+
* visible.
|
|
1244
|
+
*/
|
|
1245
|
+
enableRowHover?: boolean;
|
|
1246
|
+
/**
|
|
1247
|
+
* Prepend a header row (the column labels) to copied cell ranges, so pasting
|
|
1248
|
+
* into Excel / Sheets includes the headers. Applies per copied range.
|
|
1249
|
+
*/
|
|
1250
|
+
copyHeadersToClipboard?: boolean;
|
|
1251
|
+
/**
|
|
1252
|
+
* Transform each cell value on its way to the clipboard - e.g. strip
|
|
1253
|
+
* currency symbols, expand codes to labels, or redact. Receives the display
|
|
1254
|
+
* value plus the row/column context; return the string (or value) to copy.
|
|
1255
|
+
*/
|
|
1256
|
+
processCellForClipboard?: (params: {
|
|
1257
|
+
value: unknown;
|
|
1258
|
+
column: unknown;
|
|
1259
|
+
row: TData;
|
|
1260
|
+
rowIndex: number;
|
|
1261
|
+
columnId: string;
|
|
1262
|
+
}) => unknown;
|
|
1263
|
+
enableInlineEditing?: boolean;
|
|
1264
|
+
/**
|
|
1265
|
+
* Full-row editing. When `true`, starting an edit puts the WHOLE row into
|
|
1266
|
+
* edit mode - every editable cell shows an inline editor at once - and a
|
|
1267
|
+
* single Enter (or focus leaving the row) commits all of them; Esc cancels
|
|
1268
|
+
* the whole row. Requires `enableInlineEditing`. The full-row editor covers
|
|
1269
|
+
* text / number / date / datetime / checkbox / list-select editor types.
|
|
1270
|
+
*/
|
|
1271
|
+
fullRowEditing?: boolean;
|
|
1272
|
+
enableRowSummaries?: boolean;
|
|
1273
|
+
/**
|
|
1274
|
+
* Excel-style status bar under the grid showing live aggregates of the
|
|
1275
|
+
* selected cell range (count, numeric count, sum, average, min, max).
|
|
1276
|
+
* `true` shows the default set; pass `{ aggregates: [...] }` to choose
|
|
1277
|
+
* which. Requires `enableCellSelection`.
|
|
1278
|
+
*/
|
|
1279
|
+
statusBar?:
|
|
1280
|
+
| boolean
|
|
1281
|
+
| {
|
|
1282
|
+
aggregates?: ReadonlyArray<
|
|
1283
|
+
"count" | "numericCount" | "sum" | "avg" | "min" | "max"
|
|
1284
|
+
>;
|
|
1285
|
+
};
|
|
1286
|
+
/**
|
|
1287
|
+
* Show the docked tool panel - the enterprise sidebar with Columns and
|
|
1288
|
+
* Filters tabs. A "Columns & Filters" button appears in a toolbar above the
|
|
1289
|
+
* grid; the panel docks on the right edge.
|
|
1290
|
+
*/
|
|
1291
|
+
toolPanel?: boolean;
|
|
1292
|
+
/**
|
|
1293
|
+
* Integrated charting: `true` for the zero-config docked chart panel, or a
|
|
1294
|
+
* {@link ChartingConfig} object to author defaults + advanced options.
|
|
1295
|
+
*/
|
|
1296
|
+
charting?: boolean | ChartingConfig<TData>;
|
|
1297
|
+
/**
|
|
1298
|
+
* Render the header column menu (⋮) as a tabbed popover - **General**,
|
|
1299
|
+
* **Filter**, and **Columns** tabs (the AG-Grid layout). Defaults to `false`,
|
|
1300
|
+
* which keeps the flat menu (actions list + "Choose columns" submenu).
|
|
1301
|
+
*/
|
|
1302
|
+
columnMenuTabs?: boolean;
|
|
1303
|
+
/** Open the tool panel on first render (instead of collapsed). */
|
|
1304
|
+
toolPanelDefaultOpen?: boolean;
|
|
1305
|
+
/** Which tab the tool panel starts on. Defaults to `'columns'`. */
|
|
1306
|
+
toolPanelDefaultTab?: "columns" | "filters";
|
|
1307
|
+
/**
|
|
1308
|
+
* Quick way to pick which selection surfaces are active. `'row'` shows the
|
|
1309
|
+
* selection checkbox column only, `'cell'` allows rectangle/range cell
|
|
1310
|
+
* selection only, `'both'` (default) enables both, `'none'` disables both.
|
|
1311
|
+
* Overridden per-surface by `showRowSelection` / `enableCellSelection`.
|
|
1312
|
+
*/
|
|
1313
|
+
selectionMode?: "row" | "cell" | "both" | "none";
|
|
1314
|
+
/**
|
|
1315
|
+
* Render a leading row-number column (1-based) before any selection
|
|
1316
|
+
* column. Useful as a permanent anchor when scrolling wide grids.
|
|
1317
|
+
*/
|
|
1318
|
+
showRowNumbers?: boolean;
|
|
1319
|
+
/**
|
|
1320
|
+
* Paint alternating data rows with the `--sg-row-alt-bg` color (zebra
|
|
1321
|
+
* striping). Only data rows stripe - pinned, group, detail, and summary
|
|
1322
|
+
* rows keep their single background. Defaults to `false`.
|
|
1323
|
+
*/
|
|
1324
|
+
zebraRows?: boolean;
|
|
1325
|
+
/**
|
|
1326
|
+
* Width (px) of the row-number column. Defaults to 56, which fits up
|
|
1327
|
+
* to "99,999"; bump this when the dataset crosses six digits so the
|
|
1328
|
+
* largest row number stays fully visible at the bottom of a scroll.
|
|
1329
|
+
*/
|
|
1330
|
+
rowNumberWidth?: number;
|
|
1331
|
+
/** Receives the imperative grid API once the component has mounted. */
|
|
1332
|
+
onApiReady?: (api: SvGridApi<TFeatures, TData>) => void;
|
|
1333
|
+
/**
|
|
1334
|
+
* Fires whenever the row-selection state changes. The first argument
|
|
1335
|
+
* is the new selection record `{ [rowId]: true }`; the second is the
|
|
1336
|
+
* array of selected `TData` rows.
|
|
1337
|
+
*/
|
|
1338
|
+
onRowSelectionChange?: (
|
|
1339
|
+
selection: Record<string, boolean>,
|
|
1340
|
+
rows: TData[],
|
|
1341
|
+
) => void;
|
|
1342
|
+
/**
|
|
1343
|
+
* Fires whenever the cell-selection rectangle changes (mouse, keyboard,
|
|
1344
|
+
* or `api.selectCells()`). `ranges` matches `api.getSelected()` -
|
|
1345
|
+
* `[rowStart, colStart, rowEnd, colEnd]` rectangles in grid coords.
|
|
1346
|
+
* Empty array when the user clears the selection.
|
|
1347
|
+
*/
|
|
1348
|
+
onCellSelectionChange?: (
|
|
1349
|
+
ranges: Array<[number, number, number, number]>,
|
|
1350
|
+
) => void;
|
|
1351
|
+
/**
|
|
1352
|
+
* When `true`, the grid records sort state (and renders sort indicators
|
|
1353
|
+
* + cycling on headers) but does NOT actually re-order the rows. The
|
|
1354
|
+
* consumer is expected to sort `data` themselves - typically via
|
|
1355
|
+
* `onSortingChange`. Use this for tree/hierarchical data, where a flat
|
|
1356
|
+
* global sort would break parent-child adjacency. Defaults to `false`.
|
|
1357
|
+
*/
|
|
1358
|
+
externalSort?: boolean;
|
|
1359
|
+
/**
|
|
1360
|
+
* Fires whenever the sort clauses change. Receives the new array of
|
|
1361
|
+
* `{ id, desc }` entries. Pair with `externalSort={true}` when the
|
|
1362
|
+
* consumer wants to own the row ordering.
|
|
1363
|
+
*/
|
|
1364
|
+
onSortingChange?: (sorting: Array<{ id: string; desc: boolean }>) => void;
|
|
1365
|
+
/**
|
|
1366
|
+
* The sort state to start in - `{ id, desc }` entries. Use with `externalSort`
|
|
1367
|
+
* when the initial ordering is decided server-side (e.g. a URL `?sort=` param
|
|
1368
|
+
* read in a SvelteKit `load`), so the header sort indicators match the already-
|
|
1369
|
+
* sorted data on first render. Applied once at mount; user sorting takes over.
|
|
1370
|
+
*/
|
|
1371
|
+
initialSorting?: Array<{ id: string; desc: boolean }>;
|
|
1372
|
+
/**
|
|
1373
|
+
* When `true`, the grid still records column-filter / global-filter /
|
|
1374
|
+
* facet state (so the menu UI works and indicators light up) but does
|
|
1375
|
+
* NOT actually filter the rows. The consumer is expected to fetch / sort
|
|
1376
|
+
* / filter the data themselves - typically via `onFiltersChange`. Used
|
|
1377
|
+
* by server-side data sources. Defaults to `false`.
|
|
1378
|
+
*/
|
|
1379
|
+
externalFilter?: boolean;
|
|
1380
|
+
/**
|
|
1381
|
+
* Fires whenever any of the in-grid filter state changes - global
|
|
1382
|
+
* search, per-column operator filters, or facet (value-checklist)
|
|
1383
|
+
* filters. Pair with `externalFilter={true}` when the consumer wants to
|
|
1384
|
+
* push the query to the server.
|
|
1385
|
+
*/
|
|
1386
|
+
onFiltersChange?: (filters: {
|
|
1387
|
+
global: string;
|
|
1388
|
+
columns: Array<{
|
|
1389
|
+
id: string;
|
|
1390
|
+
operator: FilterOperator;
|
|
1391
|
+
value: string;
|
|
1392
|
+
/**
|
|
1393
|
+
* Upper bound for the `between` operator. Only set when
|
|
1394
|
+
* `operator === 'between'` AND the user has typed both values.
|
|
1395
|
+
*/
|
|
1396
|
+
valueTo?: string;
|
|
1397
|
+
selectedValues?: Array<string>;
|
|
1398
|
+
}>;
|
|
1399
|
+
}) => void;
|
|
1400
|
+
/**
|
|
1401
|
+
* Fires when an inline edit is committed (Enter / Tab / blur). Useful
|
|
1402
|
+
* for cascade-recompute pipelines: a parent listens, then refreshes
|
|
1403
|
+
* derived columns or aggregates. The wrapper has already written the
|
|
1404
|
+
* parsed value back into the row by the time this fires.
|
|
1405
|
+
*/
|
|
1406
|
+
/**
|
|
1407
|
+
* Resolve a stable id per row. Drives selection, expansion, edit,
|
|
1408
|
+
* and active-cell state. When omitted, the row's array index is
|
|
1409
|
+
* used - fine for read-only views but the wrong choice if `data`
|
|
1410
|
+
* gets reordered or filtered outside the grid (selection would
|
|
1411
|
+
* follow positions, not actual rows). Use a database PK, a UUID,
|
|
1412
|
+
* or any stable string.
|
|
1413
|
+
*/
|
|
1414
|
+
getRowId?: (row: TData, index: number) => string;
|
|
1415
|
+
/**
|
|
1416
|
+
* Conditional class(es) added to every `<tr>` body row. Receives
|
|
1417
|
+
* the row's `original` data + its data-array index. Return a
|
|
1418
|
+
* string, an array of strings, or an object mapping class names to
|
|
1419
|
+
* booleans. Useful for "highlight overdue rows", "tint cancelled
|
|
1420
|
+
* orders", and similar row-level state mappings.
|
|
1421
|
+
*/
|
|
1422
|
+
rowClass?: (ctx: {
|
|
1423
|
+
row: TData;
|
|
1424
|
+
rowIndex: number;
|
|
1425
|
+
}) => string | ReadonlyArray<string> | Record<string, boolean> | undefined | null;
|
|
1426
|
+
/**
|
|
1427
|
+
* Per-cell notes - longer free-form comments shown as a corner
|
|
1428
|
+
* indicator + tooltip on hover. Keyed by row id then column id;
|
|
1429
|
+
* empty / missing entries mean "no note". The grid owns rendering;
|
|
1430
|
+
* you own storage (write your own callbacks to add / edit notes).
|
|
1431
|
+
*/
|
|
1432
|
+
notes?: Record<string, Record<string, string>>;
|
|
1433
|
+
/**
|
|
1434
|
+
* Allow editing per-cell notes/comments through the UI: the context menu
|
|
1435
|
+
* gains an "Edit comment" item that opens a popover editor. Edits are
|
|
1436
|
+
* applied to an internal overlay for immediate feedback and emitted via
|
|
1437
|
+
* `onNoteChange` so you can persist them back into `notes`.
|
|
1438
|
+
*/
|
|
1439
|
+
editableComments?: boolean;
|
|
1440
|
+
/** Fires when a comment is saved or removed (removed = empty `note`). */
|
|
1441
|
+
onNoteChange?: (event: { rowId: string; columnId: string; note: string }) => void;
|
|
1442
|
+
/**
|
|
1443
|
+
* Excel-style conditional formatting. A list of value-driven rules that
|
|
1444
|
+
* color cells: `colorScale` (gradient across the column range),
|
|
1445
|
+
* `dataBar` (in-cell proportional bar), `iconSet` (arrows / traffic /
|
|
1446
|
+
* triangles by threshold), and `rule` (apply a style when a predicate
|
|
1447
|
+
* matches). Scope a format to specific columns with `columns: [...]`,
|
|
1448
|
+
* or omit it to apply to every column. Later entries win on conflict.
|
|
1449
|
+
*/
|
|
1450
|
+
conditionalFormats?: ReadonlyArray<ConditionalFormat<TData>>;
|
|
1451
|
+
/**
|
|
1452
|
+
* Which rows feed the min/max range that `colorScale` / `dataBar` formats
|
|
1453
|
+
* scale against.
|
|
1454
|
+
*
|
|
1455
|
+
* - `filtered` (default): every row that survives the filters, ignoring the
|
|
1456
|
+
* page slice. The scale follows what you filtered to but does not shift
|
|
1457
|
+
* when you page, so the same value keeps the same colour on page 1 and
|
|
1458
|
+
* page 2.
|
|
1459
|
+
* - `visible`: only the rows currently on screen. Rescales per page - use it
|
|
1460
|
+
* when you want each page's heat map normalized to that page.
|
|
1461
|
+
* - `all`: the full unfiltered dataset, for a scale that stays put as you
|
|
1462
|
+
* filter.
|
|
1463
|
+
*/
|
|
1464
|
+
conditionalStatScope?: "filtered" | "visible" | "all";
|
|
1465
|
+
onCellValueChange?: (event: {
|
|
1466
|
+
rowIndex: number;
|
|
1467
|
+
columnId: string;
|
|
1468
|
+
oldValue: unknown;
|
|
1469
|
+
newValue: unknown;
|
|
1470
|
+
row: TData;
|
|
1471
|
+
}) => void;
|
|
1472
|
+
/**
|
|
1473
|
+
* Fires whenever the active cell changes - click, keyboard move,
|
|
1474
|
+
* tab, page-up/down, etc. Consumers (toolbars, ribbon UIs) use this
|
|
1475
|
+
* to stay synced with the grid's selection without polling the DOM.
|
|
1476
|
+
*/
|
|
1477
|
+
onActiveCellChange?: (cell: {
|
|
1478
|
+
rowIndex: number;
|
|
1479
|
+
colIndex: number;
|
|
1480
|
+
columnId: string;
|
|
1481
|
+
}) => void;
|
|
1482
|
+
/**
|
|
1483
|
+
* Fires when a data cell (and therefore a row) is single-clicked.
|
|
1484
|
+
* Group-header rows are excluded. `value` is the displayed cell value.
|
|
1485
|
+
*/
|
|
1486
|
+
onCellClick?: (event: {
|
|
1487
|
+
rowIndex: number;
|
|
1488
|
+
colIndex: number;
|
|
1489
|
+
columnId: string;
|
|
1490
|
+
value: unknown;
|
|
1491
|
+
row: TData;
|
|
1492
|
+
}) => void;
|
|
1493
|
+
/** Fires when a data row is single-clicked (any cell). Group rows excluded. */
|
|
1494
|
+
onRowClick?: (event: {
|
|
1495
|
+
rowIndex: number;
|
|
1496
|
+
columnId: string;
|
|
1497
|
+
row: TData;
|
|
1498
|
+
}) => void;
|
|
1499
|
+
/**
|
|
1500
|
+
* Fires when a data cell is double-clicked - independent of whether the
|
|
1501
|
+
* cell is editable, so it fires even on read-only grids. Group rows excluded.
|
|
1502
|
+
*/
|
|
1503
|
+
onCellDoubleClick?: (event: {
|
|
1504
|
+
rowIndex: number;
|
|
1505
|
+
colIndex: number;
|
|
1506
|
+
columnId: string;
|
|
1507
|
+
value: unknown;
|
|
1508
|
+
row: TData;
|
|
1509
|
+
}) => void;
|
|
1510
|
+
/** Fires when a data row is double-clicked (any cell). Group rows excluded. */
|
|
1511
|
+
onRowDoubleClick?: (event: {
|
|
1512
|
+
rowIndex: number;
|
|
1513
|
+
columnId: string;
|
|
1514
|
+
row: TData;
|
|
1515
|
+
}) => void;
|
|
1516
|
+
/**
|
|
1517
|
+
* Fires once each time the body is scrolled to (within ~32px of) the
|
|
1518
|
+
* bottom. Re-arms after the user scrolls back up. The canonical hook for
|
|
1519
|
+
* infinite / lazy loading - append more rows to `data` when it fires.
|
|
1520
|
+
*/
|
|
1521
|
+
onScrollBottomReached?: (event: {
|
|
1522
|
+
scrollTop: number;
|
|
1523
|
+
scrollHeight: number;
|
|
1524
|
+
clientHeight: number;
|
|
1525
|
+
}) => void;
|
|
1526
|
+
/**
|
|
1527
|
+
* Marks a row as an expandable "detail row". When this returns true the
|
|
1528
|
+
* grid renders that row as a SINGLE full-width cell (colspan across every
|
|
1529
|
+
* column) using `renderDetailRow`, instead of the normal per-column cells
|
|
1530
|
+
* - the canonical Stripe / GitHub "expand a rich panel beneath the row"
|
|
1531
|
+
* pattern. Insert the detail rows into `data` yourself (typically right
|
|
1532
|
+
* after the row they belong to) and toggle them with your own expanded
|
|
1533
|
+
* state. Pair with `virtualization={false}` so the variable-height detail
|
|
1534
|
+
* isn't clipped by the fixed-row-height virtualizer.
|
|
1535
|
+
*/
|
|
1536
|
+
isDetailRow?: (row: TData, rowIndex: number) => boolean;
|
|
1537
|
+
/**
|
|
1538
|
+
* Snippet rendered inside the full-width detail cell for rows where
|
|
1539
|
+
* `isDetailRow` is true. Receives the row's data and its index.
|
|
1540
|
+
*/
|
|
1541
|
+
renderDetailRow?: Snippet<[{ row: TData; rowIndex: number }]>;
|
|
1542
|
+
/**
|
|
1543
|
+
* Server-side group / tree keyboard + accessibility, built into the grid. When
|
|
1544
|
+
* set, the grid uses the treegrid role and marks matching rows with
|
|
1545
|
+
* `aria-level` / `aria-expanded`, and ArrowRight / ArrowLeft expand / collapse
|
|
1546
|
+
* the focused group row (no app-level key handling). Pair with `serverGroupRows`
|
|
1547
|
+
* + `SvGroupCell` for the visual expander. Every accessor receives the row data.
|
|
1548
|
+
*/
|
|
1549
|
+
serverGroup?: {
|
|
1550
|
+
/** Whether a row is an expandable group / branch. */
|
|
1551
|
+
isGroup: (row: TData) => boolean;
|
|
1552
|
+
/** Tree depth of the row (0 = top level), for `aria-level`. */
|
|
1553
|
+
level: (row: TData) => number;
|
|
1554
|
+
/** Whether an expandable row is currently expanded. */
|
|
1555
|
+
expanded?: (row: TData) => boolean;
|
|
1556
|
+
/** Expand / collapse a group row. Called on ArrowRight / ArrowLeft. */
|
|
1557
|
+
onToggle: (row: TData) => void;
|
|
1558
|
+
};
|
|
1559
|
+
/**
|
|
1560
|
+
* Server-side set-filter values. When set, a column's filter checklist is
|
|
1561
|
+
* populated by fetching the distinct values from the server (once per column,
|
|
1562
|
+
* cached) instead of deriving them from the loaded page - so the checklist
|
|
1563
|
+
* shows every value, not just those on screen. Return the distinct string
|
|
1564
|
+
* values for the column id.
|
|
1565
|
+
*/
|
|
1566
|
+
serverFilterValues?: (columnId: string) => Promise<string[]>;
|
|
1567
|
+
/**
|
|
1568
|
+
* Rows to pin to the TOP of the grid - rendered above the regular
|
|
1569
|
+
* rows and sticky-positioned so they stay visible while the user
|
|
1570
|
+
* scrolls. Typical use: a "totals" or "headline" row that should
|
|
1571
|
+
* always be in view. Rows are read-only (no inline editing, no
|
|
1572
|
+
* row-selection checkbox). They share the column schema with the
|
|
1573
|
+
* main grid; field/format/cell/cellClass all apply.
|
|
1574
|
+
*/
|
|
1575
|
+
pinnedTopRows?: ReadonlyArray<TData>;
|
|
1576
|
+
/**
|
|
1577
|
+
* Rows to pin to the BOTTOM of the grid - rendered below the regular
|
|
1578
|
+
* rows and sticky-positioned (sticks to the bottom of the viewport
|
|
1579
|
+
* while the user scrolls). Typical use: a "page totals" or "grand
|
|
1580
|
+
* total" row computed from `getDisplayedRows()`.
|
|
1581
|
+
*/
|
|
1582
|
+
pinnedBottomRows?: ReadonlyArray<TData>;
|
|
1583
|
+
/**
|
|
1584
|
+
* Enables drag-to-reorder on the grid's column headers. When `true`,
|
|
1585
|
+
* every header gets `draggable=true` and a drop indicator paints
|
|
1586
|
+
* between headers during a drag. On drop the grid mutates its
|
|
1587
|
+
* internal column order and fires `onColumnOrderChange` with the
|
|
1588
|
+
* new order. Defaults to `false`.
|
|
1589
|
+
*/
|
|
1590
|
+
enableColumnReorder?: boolean;
|
|
1591
|
+
/**
|
|
1592
|
+
* Initial column order, by `id` (falls back to `field`). When the
|
|
1593
|
+
* user reorders columns, this is the starting state. After mount,
|
|
1594
|
+
* the grid owns the order internally and emits `onColumnOrderChange`
|
|
1595
|
+
* on every change - persist that to `localStorage` to restore.
|
|
1596
|
+
*/
|
|
1597
|
+
columnOrder?: ReadonlyArray<string>;
|
|
1598
|
+
/** Fires every time the column order changes (drag or `api.setColumnOrder`). */
|
|
1599
|
+
onColumnOrderChange?: (order: ReadonlyArray<string>) => void;
|
|
1600
|
+
/**
|
|
1601
|
+
* Infer each column's data type (number / boolean / date / ISO date-string /
|
|
1602
|
+
* text) from the first data row, for columns that declare neither an
|
|
1603
|
+
* explicit `editorType` nor a `cellDataType`. Sets the matching editor,
|
|
1604
|
+
* alignment, date format, and filter operators automatically. Explicit
|
|
1605
|
+
* column config always wins. Defaults to `false`.
|
|
1606
|
+
*/
|
|
1607
|
+
inferColumnTypes?: boolean;
|
|
1608
|
+
/**
|
|
1609
|
+
* Enables managed row dragging. When `true`, every row becomes a drag
|
|
1610
|
+
* source (grab cursor + a grip in the row-number cell) and a drop
|
|
1611
|
+
* indicator paints between rows during a drag. On drop the grid mutates
|
|
1612
|
+
* its own internal data - reordering within the grid, or moving the row
|
|
1613
|
+
* across grids that share the same {@link rowDragGroup}. Defaults to
|
|
1614
|
+
* `false`.
|
|
1615
|
+
*/
|
|
1616
|
+
rowDragManaged?: boolean;
|
|
1617
|
+
/**
|
|
1618
|
+
* Connection group for cross-grid row dragging. Grids that share the same
|
|
1619
|
+
* non-empty `rowDragGroup` string (and have `rowDragManaged` on) can
|
|
1620
|
+
* exchange rows: dragging a row out of one and dropping it into another
|
|
1621
|
+
* removes it from the source and inserts it into the target. Omit to keep
|
|
1622
|
+
* dragging confined to reordering within a single grid.
|
|
1623
|
+
*/
|
|
1624
|
+
rowDragGroup?: string;
|
|
1625
|
+
/**
|
|
1626
|
+
* Fires on the TARGET grid after a managed row drag settles, with the
|
|
1627
|
+
* moved row, its landing index, whether it stayed in the same grid, and
|
|
1628
|
+
* the source / target grid ids. Use it to mirror the move into your own
|
|
1629
|
+
* state (persistence, server sync). The grid has already applied the
|
|
1630
|
+
* change to its internal data by the time this fires.
|
|
1631
|
+
*/
|
|
1632
|
+
onRowDragEnd?: (event: {
|
|
1633
|
+
row: TData;
|
|
1634
|
+
toIndex: number;
|
|
1635
|
+
sameGrid: boolean;
|
|
1636
|
+
fromGridId: number;
|
|
1637
|
+
toGridId: number;
|
|
1638
|
+
}) => void;
|
|
1639
|
+
/**
|
|
1640
|
+
* Align this grid with others that share the same non-empty
|
|
1641
|
+
* `alignedGridGroup` string: horizontal scroll and column-resize widths are
|
|
1642
|
+
* kept in lockstep across every grid in the group. Use for a totals/header
|
|
1643
|
+
* grid above a body grid, or side-by-side comparison grids that must line up.
|
|
1644
|
+
* The grids should declare the same columns (matched by id) for widths to map.
|
|
1645
|
+
*/
|
|
1646
|
+
alignedGridGroup?: string;
|
|
1647
|
+
/**
|
|
1648
|
+
* BCP-47 locale tag (or array of fallbacks) used for accent- and
|
|
1649
|
+
* case-insensitive text filtering / sorting / search. Powered by
|
|
1650
|
+
* `Intl.Collator` with `sensitivity: 'base'`, so "cafe", "Café"
|
|
1651
|
+
* and "CAFÉ" all match "cafe" without strain. Defaults to the
|
|
1652
|
+
* browser's locale.
|
|
1653
|
+
*/
|
|
1654
|
+
filterLocale?: string | ReadonlyArray<string>;
|
|
1655
|
+
};
|
|
1656
|
+
|
|
1657
|
+
/**
|
|
1658
|
+
* The grid's single localization surface (see {@link Props.localization}):
|
|
1659
|
+
* `locale` handles the data (filter matching + number/date formatting) and
|
|
1660
|
+
* `text` handles the UI strings.
|
|
1661
|
+
*/
|
|
1662
|
+
export type GridLocalization = {
|
|
1663
|
+
/** BCP-47 tag(s) for filter matching + number / date formatting. */
|
|
1664
|
+
locale?: string | ReadonlyArray<string>;
|
|
1665
|
+
/** Overrides for the grid's own UI strings. */
|
|
1666
|
+
text?: Partial<GridMessages>;
|
|
1667
|
+
};
|
|
1668
|
+
|
|
1669
|
+
export type SelectionPoint = { rowIndex: number; colIndex: number };
|
|
1670
|
+
export type SelectionRange = {
|
|
1671
|
+
anchor: SelectionPoint | null;
|
|
1672
|
+
focus: SelectionPoint | null;
|
|
1673
|
+
};
|
|
1674
|
+
export type CellEditState = {
|
|
1675
|
+
rowId: string;
|
|
1676
|
+
columnId: string;
|
|
1677
|
+
editorType: CellEditorType;
|
|
1678
|
+
value: unknown;
|
|
1679
|
+
/**
|
|
1680
|
+
* The row's underlying data object, captured when the edit started. The
|
|
1681
|
+
* commit path resolves the row by id first; this is the fallback for when
|
|
1682
|
+
* the row has left the row model mid-edit (a filter typed into the filter
|
|
1683
|
+
* row while an editor is open), so the typed value still lands instead of
|
|
1684
|
+
* being silently dropped.
|
|
1685
|
+
*/
|
|
1686
|
+
rowRef?: unknown;
|
|
1687
|
+
} | null;
|
|
1688
|
+
export type FilterOperator =
|
|
1689
|
+
| "contains"
|
|
1690
|
+
| "notContains"
|
|
1691
|
+
| "equals"
|
|
1692
|
+
| "notEquals"
|
|
1693
|
+
| "startsWith"
|
|
1694
|
+
| "endsWith"
|
|
1695
|
+
| "regex"
|
|
1696
|
+
| "in"
|
|
1697
|
+
| "notIn"
|
|
1698
|
+
| "greaterThan"
|
|
1699
|
+
| "lessThan"
|
|
1700
|
+
| "between"
|
|
1701
|
+
| "isBlank"
|
|
1702
|
+
| "isNotBlank";
|
|
1703
|
+
export type FilterOption = {
|
|
1704
|
+
value: FilterOperator;
|
|
1705
|
+
label: string;
|
|
1706
|
+
iconName: string;
|
|
1707
|
+
};
|
|
1708
|
+
export type MenuPosition = { x: number; y: number };
|