@svgrid/grid 3.0.3 → 3.0.5

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.
Files changed (325) hide show
  1. package/README.md +6 -5
  2. package/dist/GridMenus.svelte +44 -2
  3. package/dist/SvChartMenu.svelte +69 -0
  4. package/dist/SvChartMenu.svelte.d.ts +11 -0
  5. package/dist/SvChartPanes.svelte +113 -0
  6. package/dist/SvChartPanes.svelte.d.ts +20 -0
  7. package/dist/SvGrid.controller.svelte.d.ts +122 -41
  8. package/dist/SvGrid.controller.svelte.js +846 -207
  9. package/dist/SvGrid.css +178 -2
  10. package/dist/SvGrid.svelte +717 -720
  11. package/dist/SvGrid.types.d.ts +566 -12
  12. package/dist/SvGridCellEditor.svelte +17 -0
  13. package/dist/SvGridChart.svelte +2257 -329
  14. package/dist/SvGridChart.svelte.d.ts +6 -106
  15. package/dist/SvGridChart.types.d.ts +338 -0
  16. package/dist/SvGridChart.types.js +1 -0
  17. package/dist/SvGridChartBuilder.svelte +323 -0
  18. package/dist/SvGridChartBuilder.svelte.d.ts +34 -0
  19. package/dist/SvGridChartPanel.svelte +221 -275
  20. package/dist/SvGridChartPickers.svelte +417 -0
  21. package/dist/SvGridChartPickers.svelte.d.ts +70 -0
  22. package/dist/SvGridChartView.svelte +13 -14
  23. package/dist/SvModal.svelte +7 -1
  24. package/dist/SvModal.svelte.d.ts +5 -0
  25. package/dist/ai.d.ts +40 -8
  26. package/dist/ai.js +135 -24
  27. package/dist/aria.d.ts +11 -0
  28. package/dist/build-api.js +119 -28
  29. package/dist/cdn/GridMenus-CID62rlI.js +636 -0
  30. package/dist/cdn/GridMenus-DLL-qZeu.js +635 -0
  31. package/dist/cdn/SvChartMenu-Bl6PBbkT.js +58 -0
  32. package/dist/cdn/SvChartMenu-FBSMINA6.js +59 -0
  33. package/dist/cdn/{SvDateRangeInput-DMLKmGEc.js → SvDateRangeInput-BeU_TkbQ.js} +15 -14
  34. package/dist/cdn/{SvDateRangeInput-CaOuMs8O.js → SvDateRangeInput-yX8vzleW.js} +38 -37
  35. package/dist/cdn/{SvDateTimePicker-sonaH0oh.js → SvDateTimePicker-DQwt4UAs.js} +139 -180
  36. package/dist/cdn/SvDateTimePicker-vNU6bZ-q.js +775 -0
  37. package/dist/cdn/{SvGridCellEditor-CjEJMJKc.js → SvGridCellEditor-B1p-vCK5.js} +188 -178
  38. package/dist/cdn/{SvGridCellEditor-BWnTi2N7.js → SvGridCellEditor-D_0q4xAu.js} +98 -88
  39. package/dist/cdn/SvGridChart-C3EWAZaM.js +3574 -0
  40. package/dist/cdn/SvGridChart-DzLkSwCH.js +3572 -0
  41. package/dist/cdn/SvGridChartBuilder-BE2T1ykB.js +783 -0
  42. package/dist/cdn/SvGridChartBuilder-CfII62sZ.js +784 -0
  43. package/dist/cdn/SvGridChartPanel-CCX5_Wgd.js +675 -0
  44. package/dist/cdn/SvGridChartPanel-xf4sWVTo.js +699 -0
  45. package/dist/cdn/SvGridChartView-CfuXmY5I.js +48 -0
  46. package/dist/cdn/SvGridChartView-DYwabQWj.js +47 -0
  47. package/dist/cdn/SvMenuList-CLN8OuIK.js +452 -0
  48. package/dist/cdn/SvMenuList-DkGhNKjf.js +451 -0
  49. package/dist/cdn/SvModal-BAE-pjZX.js +396 -0
  50. package/dist/cdn/SvModal-CIZWCcad.js +397 -0
  51. package/dist/cdn/chart-Dz7SqMXH.js +4341 -0
  52. package/dist/cdn/chart-export-BXqueeWJ.js +135 -0
  53. package/dist/cdn/chart-export-pdf-DONFUnNY.js +110 -0
  54. package/dist/cdn/chart-panel-messages-CUbf2R4i.js +1052 -0
  55. package/dist/cdn/chart-panel-messages-CmNrMdsr.js +1053 -0
  56. package/dist/cdn/chart-summary-BJW_tg_X.js +138 -0
  57. package/dist/cdn/chart-trend-CaN9mDEV.js +50 -0
  58. package/dist/cdn/chart-validate-HcOVFAfJ.js +188 -0
  59. package/dist/cdn/{column-resize-DsfNXMom.js → column-resize-DpmOLfRp.js} +3 -3
  60. package/dist/cdn/{date-format-BnnHlqGw.js → date-format-CtquV-p3.js} +583 -603
  61. package/dist/cdn/{date-format-BNii4zeD.js → date-format-D6KFzU_W.js} +347 -367
  62. package/dist/cdn/dismissable-DAHetSNk.js +44 -0
  63. package/dist/cdn/editor-contract-LXgQJAgd.js +22 -0
  64. package/dist/cdn/focus-trap-BBOQYBma.js +65 -0
  65. package/dist/cdn/{row-resize-BRcimkUT.js → row-resize-niQCp040.js} +44 -36
  66. package/dist/cdn/server-block-cache-CGoWz-87.js +237 -0
  67. package/dist/cdn/{src-D6XvA1Ij.js → src-Bklofsad.js} +10615 -10155
  68. package/dist/cdn/{src-Bugf5XlI.js → src-jcFMkBnN.js} +7111 -6651
  69. package/dist/cdn/svgrid.js +27 -15
  70. package/dist/cdn/svgrid.svelte-external.js +27 -15
  71. package/dist/cdn/validate-C7Rn_Bns.js +76 -0
  72. package/dist/chart-axes.d.ts +53 -0
  73. package/dist/chart-axes.js +351 -0
  74. package/dist/chart-cartesian.d.ts +88 -0
  75. package/dist/chart-cartesian.js +1862 -0
  76. package/dist/chart-decimate.d.ts +51 -0
  77. package/dist/chart-decimate.js +199 -0
  78. package/dist/chart-export-pdf.d.ts +47 -0
  79. package/dist/chart-export-pdf.js +187 -0
  80. package/dist/chart-export.d.ts +2 -1
  81. package/dist/chart-export.js +18 -3
  82. package/dist/chart-financial.d.ts +91 -0
  83. package/dist/chart-financial.js +175 -0
  84. package/dist/chart-flow.d.ts +10 -0
  85. package/dist/chart-flow.js +298 -0
  86. package/dist/chart-format.d.ts +18 -0
  87. package/dist/chart-format.js +65 -0
  88. package/dist/chart-grid.d.ts +8 -0
  89. package/dist/chart-grid.js +190 -0
  90. package/dist/chart-hierarchy.d.ts +17 -0
  91. package/dist/chart-hierarchy.js +146 -0
  92. package/dist/chart-indicators.d.ts +115 -0
  93. package/dist/chart-indicators.js +389 -0
  94. package/dist/chart-messages.d.ts +95 -0
  95. package/dist/chart-messages.js +92 -0
  96. package/dist/chart-motion.d.ts +16 -0
  97. package/dist/chart-motion.js +141 -0
  98. package/dist/chart-panel-messages.d.ts +265 -0
  99. package/dist/chart-panel-messages.js +285 -0
  100. package/dist/chart-pivot.d.ts +87 -0
  101. package/dist/chart-pivot.js +156 -0
  102. package/dist/chart-polar.d.ts +25 -0
  103. package/dist/chart-polar.js +700 -0
  104. package/dist/chart-samples.d.ts +16 -0
  105. package/dist/chart-samples.js +153 -0
  106. package/dist/chart-scale.d.ts +113 -0
  107. package/dist/chart-scale.js +405 -0
  108. package/dist/chart-stats.d.ts +111 -0
  109. package/dist/chart-stats.js +419 -0
  110. package/dist/chart-stream.d.ts +45 -0
  111. package/dist/chart-stream.js +91 -0
  112. package/dist/chart-summary.d.ts +27 -0
  113. package/dist/chart-summary.js +205 -0
  114. package/dist/chart-sync.svelte.d.ts +32 -0
  115. package/dist/chart-sync.svelte.js +23 -0
  116. package/dist/chart-table.d.ts +35 -0
  117. package/dist/chart-table.js +165 -0
  118. package/dist/chart-trend.d.ts +19 -0
  119. package/dist/chart-trend.js +61 -0
  120. package/dist/chart-types.d.ts +1456 -0
  121. package/dist/chart-types.js +6 -0
  122. package/dist/chart-validate.d.ts +43 -0
  123. package/dist/chart-validate.js +272 -0
  124. package/dist/chart-zoom.d.ts +40 -0
  125. package/dist/chart-zoom.js +145 -0
  126. package/dist/chart.d.ts +186 -865
  127. package/dist/chart.js +460 -2204
  128. package/dist/clipboard.d.ts +1 -0
  129. package/dist/clipboard.js +137 -18
  130. package/dist/column-resize.d.ts +3 -0
  131. package/dist/column-resize.js +4 -1
  132. package/dist/columns.js +3 -0
  133. package/dist/command-context.d.ts +19 -0
  134. package/dist/command-context.js +116 -0
  135. package/dist/core.d.ts +7 -0
  136. package/dist/core.js +36 -13
  137. package/dist/createPopoverSelect.svelte.d.ts +2 -2
  138. package/dist/editing.d.ts +2 -8
  139. package/dist/editing.js +272 -33
  140. package/dist/fill-patterns.d.ts +0 -5
  141. package/dist/fill-patterns.js +56 -2
  142. package/dist/gantt-view.svelte.d.ts +24 -0
  143. package/dist/gantt-view.svelte.js +13 -0
  144. package/dist/grid-icons.d.ts +2 -2
  145. package/dist/grid-icons.js +2 -2
  146. package/dist/grid-messages.d.ts +16 -3
  147. package/dist/grid-messages.js +10 -0
  148. package/dist/history.d.ts +83 -0
  149. package/dist/history.js +133 -0
  150. package/dist/index.d.ts +29 -10
  151. package/dist/index.js +23 -5
  152. package/dist/keyboard-handlers.js +88 -31
  153. package/dist/keyboard.d.ts +55 -0
  154. package/dist/keyboard.js +132 -0
  155. package/dist/menus.d.ts +3 -1
  156. package/dist/menus.js +7 -2
  157. package/dist/merges.d.ts +97 -0
  158. package/dist/merges.js +147 -0
  159. package/dist/row-model.d.ts +133 -0
  160. package/dist/row-model.js +16 -0
  161. package/dist/row-resize.d.ts +3 -0
  162. package/dist/row-resize.js +14 -0
  163. package/dist/scroll-sync.d.ts +1 -0
  164. package/dist/scroll-sync.js +24 -0
  165. package/dist/selection.d.ts +18 -1
  166. package/dist/selection.js +138 -18
  167. package/dist/server-block-cache.d.ts +214 -0
  168. package/dist/server-block-cache.js +531 -0
  169. package/dist/server-data-source.d.ts +240 -6
  170. package/dist/server-data-source.js +220 -20
  171. package/dist/server.d.ts +13 -0
  172. package/dist/server.js +13 -0
  173. package/dist/shortcut-registry.d.ts +145 -0
  174. package/dist/shortcut-registry.js +44 -0
  175. package/dist/svgrid-wrapper.types.d.ts +213 -22
  176. package/dist/validate.d.ts +4 -0
  177. package/dist/validate.js +21 -3
  178. package/dist/virtualization/virtualizer.js +38 -17
  179. package/package.json +11 -1
  180. package/src/GridMenus.svelte +44 -2
  181. package/src/SvChartMenu.svelte +69 -0
  182. package/src/SvChartPanes.svelte +113 -0
  183. package/src/SvChartPanes.test.ts +66 -0
  184. package/src/SvGrid.controller.svelte.ts +819 -179
  185. package/src/SvGrid.css +178 -2
  186. package/src/SvGrid.svelte +717 -720
  187. package/src/SvGrid.types.ts +564 -11
  188. package/src/SvGridCellEditor.svelte +17 -0
  189. package/src/SvGridChart.svelte +2257 -329
  190. package/src/SvGridChart.test.ts +1419 -1
  191. package/src/SvGridChart.types.ts +336 -0
  192. package/src/SvGridChartBuilder.svelte +323 -0
  193. package/src/SvGridChartPanel.svelte +221 -275
  194. package/src/SvGridChartPickers.svelte +417 -0
  195. package/src/SvGridChartView.svelte +13 -14
  196. package/src/SvModal.svelte +7 -1
  197. package/src/SvModal.test.ts +9 -0
  198. package/src/ai.test.ts +57 -2
  199. package/src/ai.ts +166 -22
  200. package/src/aria.d.ts +11 -0
  201. package/src/build-api.coverage.test.ts +184 -0
  202. package/src/build-api.ts +118 -22
  203. package/src/chart-axes.test.ts +573 -0
  204. package/src/chart-axes.ts +342 -0
  205. package/src/chart-cartesian.ts +1863 -0
  206. package/src/chart-decimate.test.ts +249 -0
  207. package/src/chart-decimate.ts +186 -0
  208. package/src/chart-export-pdf.test.ts +91 -0
  209. package/src/chart-export-pdf.ts +207 -0
  210. package/src/chart-export.test.ts +14 -0
  211. package/src/chart-export.ts +13 -3
  212. package/src/chart-financial.ts +208 -0
  213. package/src/chart-flow.ts +286 -0
  214. package/src/chart-format.ts +67 -0
  215. package/src/chart-grid.ts +179 -0
  216. package/src/chart-hierarchy.ts +135 -0
  217. package/src/chart-indicators.test.ts +443 -0
  218. package/src/chart-indicators.ts +384 -0
  219. package/src/chart-messages.test.ts +21 -0
  220. package/src/chart-messages.ts +184 -0
  221. package/src/chart-motion.test.ts +71 -0
  222. package/src/chart-motion.ts +148 -0
  223. package/src/chart-panel-messages.test.ts +29 -0
  224. package/src/chart-panel-messages.ts +550 -0
  225. package/src/chart-pivot.test.ts +54 -0
  226. package/src/chart-pivot.ts +225 -0
  227. package/src/chart-polar.ts +674 -0
  228. package/src/chart-samples.ts +106 -0
  229. package/src/chart-scale.ts +394 -0
  230. package/src/chart-series-types.test.ts +714 -0
  231. package/src/chart-stats.ts +409 -0
  232. package/src/chart-stream.test.ts +75 -0
  233. package/src/chart-stream.ts +114 -0
  234. package/src/chart-summary.test.ts +90 -0
  235. package/src/chart-summary.ts +197 -0
  236. package/src/chart-sync.svelte.ts +41 -0
  237. package/src/chart-table.test.ts +76 -0
  238. package/src/chart-table.ts +178 -0
  239. package/src/chart-trend.ts +47 -0
  240. package/src/chart-types.ts +1309 -0
  241. package/src/chart-validate.test.ts +100 -0
  242. package/src/chart-validate.ts +247 -0
  243. package/src/chart-zoom.test.ts +137 -0
  244. package/src/chart-zoom.ts +124 -0
  245. package/src/chart.coverage.test.ts +81 -0
  246. package/src/chart.test.ts +56 -3
  247. package/src/chart.ts +557 -2784
  248. package/src/clipboard.test.ts +151 -0
  249. package/src/clipboard.ts +145 -16
  250. package/src/column-resize.ts +7 -1
  251. package/src/columns.ts +2 -0
  252. package/src/command-context.test.ts +200 -0
  253. package/src/command-context.ts +137 -0
  254. package/src/core.rowmodel-cache.test.ts +51 -0
  255. package/src/core.ts +40 -12
  256. package/src/editing.test.ts +281 -3
  257. package/src/editing.ts +264 -38
  258. package/src/fill-patterns.test.ts +35 -0
  259. package/src/fill-patterns.ts +56 -2
  260. package/src/gantt-stub.test.svelte +38 -0
  261. package/src/gantt-view.svelte.ts +35 -0
  262. package/src/grid-icons.ts +2 -2
  263. package/src/grid-messages.ts +28 -3
  264. package/src/history.test.ts +196 -0
  265. package/src/history.ts +162 -0
  266. package/src/icon-seam.test.ts +5 -6
  267. package/src/index.ts +186 -12
  268. package/src/keyboard-handlers.coverage.test.ts +126 -6
  269. package/src/keyboard-handlers.ts +91 -30
  270. package/src/keyboard-shortcuts.seam.test.ts +200 -0
  271. package/src/keyboard.test.ts +124 -1
  272. package/src/keyboard.ts +142 -0
  273. package/src/menus.test.ts +26 -0
  274. package/src/menus.ts +10 -3
  275. package/src/merges.test.ts +112 -0
  276. package/src/merges.ts +168 -0
  277. package/src/pivot.grid.test.ts +40 -5
  278. package/src/row-model.ts +146 -0
  279. package/src/row-resize.test.ts +44 -0
  280. package/src/row-resize.ts +17 -0
  281. package/src/scroll-sync.test.ts +42 -1
  282. package/src/scroll-sync.ts +25 -0
  283. package/src/selection.multi-range.test.ts +34 -0
  284. package/src/selection.test.ts +33 -2
  285. package/src/selection.ts +143 -21
  286. package/src/server-block-cache.test.ts +645 -0
  287. package/src/server-block-cache.ts +677 -0
  288. package/src/server-data-source.infinite.test.ts +343 -0
  289. package/src/server-data-source.ts +450 -27
  290. package/src/server.ts +47 -0
  291. package/src/shortcut-registry.test.ts +97 -0
  292. package/src/shortcut-registry.ts +181 -0
  293. package/src/svgrid-wrapper.types.ts +184 -13
  294. package/src/svgrid.behavior.test.ts +135 -0
  295. package/src/svgrid.charting.test.ts +513 -3
  296. package/src/svgrid.context-menu.test.ts +31 -0
  297. package/src/svgrid.gantt-seam.test.ts +199 -0
  298. package/src/svgrid.new-features.wrapper.test.ts +10 -3
  299. package/src/svgrid.row-model-prop.svelte.test.ts +352 -0
  300. package/src/svgrid.row-model-seam.svelte.test.ts +289 -0
  301. package/src/svgrid.upsell-license.test.ts +7 -4
  302. package/src/validate.test.ts +29 -0
  303. package/src/validate.ts +28 -3
  304. package/src/virtualization/virtualizer.ts +39 -17
  305. package/dist/SvGroupCell.svelte +0 -141
  306. package/dist/SvGroupCell.svelte.d.ts +0 -49
  307. package/dist/SvRowGroupPanel.svelte +0 -186
  308. package/dist/SvRowGroupPanel.svelte.d.ts +0 -25
  309. package/dist/cdn/GridMenus-CHOMnW-c.js +0 -602
  310. package/dist/cdn/GridMenus-DhdPF700.js +0 -603
  311. package/dist/cdn/SvDateTimePicker-CCbDZNZB.js +0 -816
  312. package/dist/cdn/SvGridChart-1PMSp2LZ.js +0 -1481
  313. package/dist/cdn/SvGridChart-D02avhyr.js +0 -1480
  314. package/dist/cdn/SvGridChartPanel-DJnViOv4.js +0 -834
  315. package/dist/cdn/SvGridChartPanel-vPTNerFZ.js +0 -810
  316. package/dist/cdn/SvGridChartView-C--HhdUo.js +0 -56
  317. package/dist/cdn/SvGridChartView-KyyFG-wY.js +0 -55
  318. package/dist/cdn/chart-DLg3_zTQ.js +0 -1652
  319. package/dist/cdn/validate-_CDJzgIo.js +0 -75
  320. package/dist/server-group-model.d.ts +0 -98
  321. package/dist/server-group-model.js +0 -263
  322. package/src/SvGroupCell.svelte +0 -141
  323. package/src/SvRowGroupPanel.svelte +0 -186
  324. package/src/server-group-model.test.ts +0 -294
  325. package/src/server-group-model.ts +0 -370
package/src/index.ts CHANGED
@@ -86,6 +86,7 @@ export { registerBoardView, getBoardView, hasBoardView } from './board-view.svel
86
86
  export type {
87
87
  SelectionBarAction,
88
88
  SelectionBarTarget,
89
+ ContextMenuIcon,
89
90
  ContextMenuItem,
90
91
  ContextMenuTarget,
91
92
  } from './SvGrid.types'
@@ -120,6 +121,23 @@ export type {
120
121
  SchedulerOccurrenceChangeEvent,
121
122
  } from './SvGrid.types'
122
123
  export { registerSchedulerView, getSchedulerView, hasSchedulerView } from './scheduler-view.svelte'
124
+ // Gantt view. Same split as the scheduler: the `gantt` prop and its config
125
+ // types live in the free grid, the RENDERER ships in @svgrid/enterprise and
126
+ // registers itself through this seam (see gantt-view.svelte.ts). Unlike the
127
+ // scheduler, the Gantt's layout model lives in enterprise too - only the
128
+ // renderer reads it.
129
+ export type {
130
+ GanttConfig,
131
+ GanttDrawerConfig,
132
+ GanttTaskMoveEvent,
133
+ GanttTaskResizeEvent,
134
+ GanttProgressChangeEvent,
135
+ GanttTaskCommitEvent,
136
+ GanttDependency,
137
+ GanttDependencyType,
138
+ GanttZoom,
139
+ } from './SvGrid.types'
140
+ export { registerGanttView, getGanttView, hasGanttView } from './gantt-view.svelte'
123
141
  // Bulk-action bar over the row selection. Prop + types free, renderer Pro.
124
142
  export { registerSelectionBarView, getSelectionBarView, hasSelectionBarView } from './selection-bar-view.svelte'
125
143
  // Chart view. The `chart` prop + its config live in the free grid AND so does the
@@ -529,8 +547,32 @@ export { default as SvGridChartPanel } from './SvGridChartPanel.svelte'
529
547
  // unprefixed siblings SvGauge / SvSparkline. The `SvGrid*` names remain exported
530
548
  // as aliases so existing imports keep working.
531
549
  export { default as SvChart } from './SvGridChart.svelte'
550
+ export type {
551
+ SvChartProps,
552
+ ChartRenderContext,
553
+ ChartTooltipContext,
554
+ ChartTooltipRow,
555
+ ChartLegendItemContext,
556
+ ChartLegendPosition,
557
+ ChartZoomConfig,
558
+ ChartAnimateConfig,
559
+ ChartContextTarget,
560
+ ChartHoverPoint,
561
+ } from './SvGridChart.types'
562
+ export {
563
+ wheelWindow,
564
+ panWindow,
565
+ pinchWindow,
566
+ presetWindow,
567
+ nearestIndexByTime,
568
+ type ChartRangePreset,
569
+ } from './chart-zoom'
570
+ export { interpolateGeometry } from './chart-motion'
571
+ export { drillTree, pathTo } from './chart-hierarchy'
572
+ export { syncGroupState, publishSyncHover, publishSyncZoom, type ChartSyncState } from './chart-sync.svelte'
532
573
  export { default as SvChartPanel } from './SvGridChartPanel.svelte'
533
- export type { ChartingConfig, ChartAggregateRequest, ChartAggregateBucket } from './SvGrid.types'
574
+ export { default as SvChartPanes } from './SvChartPanes.svelte'
575
+ export type { ChartingConfig, ChartAggregateRequest, ChartAggregateBucket, ChartPanelInfo } from './SvGrid.types'
534
576
  export type { GridLocalization } from './SvGrid.types'
535
577
  export {
536
578
  buildChart,
@@ -538,17 +580,72 @@ export {
538
580
  rowsToChartSpec,
539
581
  rowsToBoxSpec,
540
582
  rowsToDirectSpec,
583
+ rowsToScatterSpec,
584
+ rowsToGaugeSpec,
585
+ rowsToHistogramSpec,
586
+ rowsToRangeSpec,
587
+ paretoSpec,
588
+ specToTreemap,
589
+ specToCalendar,
590
+ specToSankey,
591
+ binValues,
592
+ heikinAshi,
593
+ resampleOhlc,
594
+ rowsToOhlcSpec,
595
+ guessOhlcColumns,
596
+ splitPanelIndicators,
597
+ applyChartFormat,
598
+ CHART_RESPONSIVE_PRESETS,
599
+ type ChartFormatState,
600
+ type OhlcColumns,
601
+ type ChartPanelIndicator,
602
+ bollingerBands,
603
+ rsi,
604
+ macd,
605
+ vwap,
606
+ atr,
607
+ stochastic,
608
+ wma,
609
+ obv,
610
+ indicatorPane,
611
+ type ChartIndicatorSpec,
612
+ arcPath,
613
+ streamBaseline,
541
614
  boxStats,
542
615
  sliceChartWindow,
616
+ matchResponsiveRules,
617
+ resolveResponsive,
618
+ chartStyleVars,
543
619
  chartScales,
544
620
  ordinalDateTicks,
545
621
  niceScale,
546
622
  niceLogScale,
547
623
  linearTrend,
624
+ linearFit,
625
+ polynomialFit,
626
+ exponentialFit,
627
+ logarithmicFit,
628
+ powerFit,
629
+ rSquared,
630
+ pearson,
631
+ type RegressionFit,
548
632
  simpleMovingAverage,
549
633
  exponentialMovingAverage,
550
634
  computeOverlay,
635
+ computeOverlayFit,
636
+ regressionFit,
637
+ overlayName,
551
638
  buildLinePath,
639
+ layoutDataLabels,
640
+ markerPath,
641
+ decimateSpec,
642
+ pickCategories,
643
+ lttb,
644
+ minMaxIndices,
645
+ reduceValues,
646
+ percentile,
647
+ bucketStart,
648
+ PER_CATEGORY_SERIES_KEYS,
552
649
  sampleGradient,
553
650
  pickContrastText,
554
651
  DEFAULT_PALETTE,
@@ -566,6 +663,9 @@ export {
566
663
  type ChartLine,
567
664
  type ChartLinePoint,
568
665
  type ChartPieSlice,
666
+ type ChartResponsiveRule,
667
+ type ChartStyle,
668
+ type ChartSeriesLabel,
569
669
  type ChartSelection,
570
670
  type ChartReferenceLine,
571
671
  type ChartRefLineGeo,
@@ -587,6 +687,28 @@ export {
587
687
  type ChartSankeyLink,
588
688
  type ChartValueFormat,
589
689
  type TreeNode,
690
+ type ChartAxisConfig,
691
+ type ChartReferenceBand,
692
+ type ChartRefBandGeo,
693
+ type ChartMarker,
694
+ type ChartMarkerShape,
695
+ type ChartDataLabelConfig,
696
+ type ChartDataLabel,
697
+ type ChartDecimateConfig,
698
+ type ChartReducer,
699
+ type ChartTimeBucket,
700
+ type ChartFrame,
701
+ type ChartLineStyle,
702
+ type ChartBins,
703
+ type ChartStem,
704
+ type ChartArc,
705
+ type ChartChordRibbon,
706
+ type ChartBullet,
707
+ type ChartZoomWindow,
708
+ type ChartPointRef,
709
+ type ChartDrawing,
710
+ type ChartDrawingKind,
711
+ type ChartDrawingGeo,
590
712
  } from './chart'
591
713
  export {
592
714
  chartToSvgString,
@@ -598,6 +720,7 @@ export {
598
720
  downloadChartCsv,
599
721
  type ChartExportOptions,
600
722
  } from './chart-export'
723
+ export { chartToPdfBlob, downloadChartPdf, printChart, buildChartPdf, type ChartPdfOptions } from './chart-export-pdf'
601
724
  export {
602
725
  buildSparkline,
603
726
  toSparklineValues,
@@ -648,9 +771,11 @@ export {
648
771
  export {
649
772
  createServerDataSource,
650
773
  type ServerDataSource,
774
+ type ServerSelectionRule,
651
775
  type ServerRequest,
652
776
  type ServerResult,
653
777
  type ServerController,
778
+ type ServerControllerOptions,
654
779
  type ServerState,
655
780
  type ServerSortModel,
656
781
  type ServerFilterModel,
@@ -660,19 +785,26 @@ export {
660
785
  type ServerMoreRow,
661
786
  type ServerFooterRow,
662
787
  type ServerSkeletonRow,
788
+ type ServerGrandTotalRow,
789
+ type ServerPlaceholderRow,
663
790
  type ServerDisplayRow,
664
791
  } from './server-data-source'
665
792
  export {
666
- createServerGroupModel,
667
- serverGroupRows,
668
- serverGroupNav,
669
- type ServerGroupController,
670
- type ServerGroupControllerOptions,
671
- type ServerGroupState,
672
- type ServerGroupGridRow,
673
- } from './server-group-model'
674
- export { default as SvGroupCell } from './SvGroupCell.svelte'
675
- export { default as SvRowGroupPanel } from './SvRowGroupPanel.svelte'
793
+ createBlockCache,
794
+ createRowPlaceholder,
795
+ rowPlaceholderState,
796
+ type BlockCache,
797
+ type BlockCacheOptions,
798
+ type BlockCacheState,
799
+ type BlockFetchResult,
800
+ type BlockState,
801
+ } from './server-block-cache'
802
+ export {
803
+ toServerFilterColumns,
804
+ type GridRowModel,
805
+ type GridFilterState,
806
+ type GridRowModelSort,
807
+ } from './row-model'
676
808
  export {
677
809
  createNamedViews,
678
810
  memoryViews,
@@ -705,7 +837,33 @@ export {
705
837
  defaultGridMessages,
706
838
  resolveGridMessages,
707
839
  type GridMessages,
840
+ type GridChromeMessages,
708
841
  } from './grid-messages'
842
+ export {
843
+ defaultChartMessages,
844
+ resolveChartMessages,
845
+ chartMessage,
846
+ type ChartMessages,
847
+ } from './chart-messages'
848
+ export {
849
+ defaultChartPanelMessages,
850
+ resolveChartPanelMessages,
851
+ chartPanelMessage,
852
+ type GridChartPanelMessages,
853
+ } from './chart-panel-messages'
854
+ export {
855
+ validateChartSpec,
856
+ warnChartSpec,
857
+ nearestKey as nearestChartKey,
858
+ CHART_TYPES,
859
+ KNOWN_SPEC_KEYS,
860
+ KNOWN_SERIES_KEYS,
861
+ type ChartDiagnostic,
862
+ } from './chart-validate'
863
+ export { chartSummary, type ChartSummaryOptions } from './chart-summary'
864
+ export { appendPoints, type ChartPoint, type AppendPointsOptions } from './chart-stream'
865
+ export { pivotResultToChartSpec, pivotChartType, pivotFilterColumn, type PivotResultChartOptions, type PivotResultLike } from './chart-pivot'
866
+ export { chartSpecToTable, type ChartTable, type ChartTableColumn } from './chart-table'
709
867
  export {
710
868
  GRID_ICON_GLYPHS,
711
869
  GRID_ICON_NAMES,
@@ -723,7 +881,19 @@ export {
723
881
  type GroupPaginationOptions,
724
882
  type GroupPaginationResult,
725
883
  } from './group-display'
726
- export { getKeyboardIntent, getNextActiveCell, type GridKeyboardIntent } from './keyboard'
884
+ export { getKeyboardIntent, getNextActiveCell, getEntryStep, pastCollapsed, type GridKeyboardIntent, type EntryIntent, type EntryRect, type EntryStep, type Collapsed } from './keyboard'
885
+ export { buildMergeIndex, mergeAt, isCovered, originOf, endOf, expandRectToMerges, stepPastMerge, mergeDrawAt, type MergedCell, type MergeIndex, type MergeRect, type MergeDraw } from './merges'
886
+ // The fill handle's series (2, 4, 6; Jan, Feb; dates by the day), for a host
887
+ // that wants to show what a fill will write before it lands.
888
+ export { buildFillPattern } from './fill-patterns'
889
+ export {
890
+ registerGridShortcuts,
891
+ hasGridShortcuts,
892
+ clearGridShortcuts,
893
+ type GridShortcutHandler,
894
+ type GridCommandContext,
895
+ } from './shortcut-registry'
896
+ export type { HistoryStep } from './history'
727
897
  export { createVirtualizer } from './virtualization/virtualizer'
728
898
  export { createSvelteVirtualizer } from './virtualization/svelte-virtualizer.svelte'
729
899
  export { createColumnVirtualizer } from './virtualization/column-virtualizer'
@@ -733,6 +903,10 @@ export type {
733
903
  SvGridFilterOperator,
734
904
  SvGridViewState,
735
905
  SvGridWrapperProps,
906
+ SvGridSelectedRange,
907
+ SvGridCellCoords,
908
+ ChartTabSnapshot,
909
+ SavedChart,
736
910
  } from './svgrid-wrapper.types'
737
911
  export {
738
912
  parseEditorValue,
@@ -54,6 +54,10 @@ function makeCtx(overrides: Partial<any> = {}) {
54
54
  extendSelection: vi.fn(),
55
55
  setSelection: vi.fn(),
56
56
  closeMenus: vi.fn(),
57
+ tabRunOrigin: null,
58
+ activeRangeRect: () => null,
59
+ isRowCollapsed: () => false,
60
+ collapsedColumns: {},
57
61
  ...overrides,
58
62
  }
59
63
  ctx._state = state
@@ -344,12 +348,32 @@ describe('onGridKeyDown / navigation', () => {
344
348
  expect(ctx.extendSelection).not.toHaveBeenCalled()
345
349
  })
346
350
 
347
- it('Shift+ArrowRight extends the selection rectangle', () => {
348
- const ctx = navCtx()
351
+ it('Shift+ArrowRight extends the selection rectangle and leaves the active cell', () => {
352
+ const ctx = navCtx({
353
+ selectionRange: { anchor: { rowIndex: 1, colIndex: 1 }, focus: { rowIndex: 1, colIndex: 1 } },
354
+ })
349
355
  const { onGridKeyDown } = createKeyboard(ctx)
350
356
  onGridKeyDown(rootKeyEvent({ key: 'ArrowRight', shiftKey: true }))
351
- expect(ctx.setActiveCell).toHaveBeenCalledWith(1, 2)
357
+ expect(ctx.setActiveCell).not.toHaveBeenCalled()
352
358
  expect(ctx.extendSelection).toHaveBeenCalledWith(1, 2)
359
+ expect(ctx.scrollActiveCellIntoView).toHaveBeenCalledWith(1, 2)
360
+ expect(ctx.setSelection).not.toHaveBeenCalled()
361
+ })
362
+
363
+ it('Shift+Home, Shift+PageDown and Ctrl+Shift+Home grow the range to where the plain key goes', () => {
364
+ const ctx = navCtx({
365
+ selectionRange: { anchor: { rowIndex: 1, colIndex: 1 }, focus: { rowIndex: 3, colIndex: 2 } },
366
+ })
367
+ const { onGridKeyDown } = createKeyboard(ctx)
368
+ onGridKeyDown(rootKeyEvent({ key: 'Home', shiftKey: true }))
369
+ expect(ctx.extendSelection).toHaveBeenLastCalledWith(3, 0)
370
+ onGridKeyDown(rootKeyEvent({ key: 'Home', shiftKey: true, ctrlKey: true }))
371
+ expect(ctx.extendSelection).toHaveBeenLastCalledWith(0, 0)
372
+ onGridKeyDown(rootKeyEvent({ key: 'PageDown', shiftKey: true }))
373
+ const [row, col] = ctx.extendSelection.mock.lastCall
374
+ expect(col).toBe(2)
375
+ expect(row).toBeGreaterThan(3)
376
+ expect(ctx.setActiveCell).not.toHaveBeenCalled()
353
377
  expect(ctx.setSelection).not.toHaveBeenCalled()
354
378
  })
355
379
 
@@ -364,13 +388,109 @@ describe('onGridKeyDown / navigation', () => {
364
388
  expect(ctx.setSelection).toHaveBeenCalledWith(1, 0)
365
389
  })
366
390
 
367
- it('Shift+Enter (moveUp) DOES extend the selection (arrow-family intent)', () => {
391
+ it('Shift+Arrow grows from the far corner of the range, not from the active cell', () => {
392
+ const ctx = navCtx({
393
+ selectionRange: { anchor: { rowIndex: 1, colIndex: 1 }, focus: { rowIndex: 3, colIndex: 2 } },
394
+ })
395
+ const { onGridKeyDown } = createKeyboard(ctx)
396
+ onGridKeyDown(rootKeyEvent({ key: 'ArrowDown', shiftKey: true }))
397
+ expect(ctx.extendSelection).toHaveBeenCalledWith(4, 2)
398
+ expect(ctx.setActiveCell).not.toHaveBeenCalled()
399
+ })
400
+
401
+ it('Shift+Arrow with nothing anchored anchors at the active cell first', () => {
402
+ const ctx = navCtx({ selectionRange: { anchor: null, focus: null } })
403
+ const { onGridKeyDown } = createKeyboard(ctx)
404
+ onGridKeyDown(rootKeyEvent({ key: 'ArrowDown', shiftKey: true }))
405
+ expect(ctx.setSelection).toHaveBeenCalledWith(1, 1)
406
+ expect(ctx.extendSelection).toHaveBeenCalledWith(2, 1)
407
+ })
408
+
409
+ it('Shift+Arrow moves the active cell when cell selection is off', () => {
410
+ const ctx = navCtx({ enableCellSelectionEffective: false })
411
+ const { onGridKeyDown } = createKeyboard(ctx)
412
+ onGridKeyDown(rootKeyEvent({ key: 'ArrowDown', shiftKey: true }))
413
+ expect(ctx.setActiveCell).toHaveBeenCalledWith(2, 1)
414
+ expect(ctx.extendSelection).not.toHaveBeenCalled()
415
+ })
416
+
417
+ it('Ctrl+V with onPasteClipboard leaves the key to the browser and arms the async fallback', () => {
418
+ const arm = vi.fn()
419
+ const ctx = navCtx({ props: { rowHeight: 30, onPasteClipboard: () => true }, armPasteFallback: arm, pasteFromClipboard: vi.fn() })
420
+ const { onGridKeyDown } = createKeyboard(ctx)
421
+ const ev = rootKeyEvent({ key: 'v', ctrlKey: true })
422
+ onGridKeyDown(ev)
423
+ expect(ev.defaultPrevented).toBe(false)
424
+ expect(arm).toHaveBeenCalledTimes(1)
425
+ expect(ctx.pasteFromClipboard).not.toHaveBeenCalled()
426
+ })
427
+
428
+ it('Shift+Enter moves up without extending the selection', () => {
429
+ // Shift+Enter shares the moveUp intent with Shift+ArrowUp, and used to
430
+ // grow the range like the arrow does. In Excel it only reverses Enter.
368
431
  const ctx = navCtx()
369
432
  const { onGridKeyDown } = createKeyboard(ctx)
370
433
  onGridKeyDown(rootKeyEvent({ key: 'Enter', shiftKey: true }))
371
- // Enter+shift -> moveUp, which is in the extend set.
372
434
  expect(ctx.setActiveCell).toHaveBeenCalledWith(0, 1)
373
- expect(ctx.extendSelection).toHaveBeenCalledWith(0, 1)
435
+ expect(ctx.setSelection).toHaveBeenCalledWith(0, 1)
436
+ expect(ctx.extendSelection).not.toHaveBeenCalled()
437
+ })
438
+
439
+ it('Enter after a run of Tabs goes down from the column the run began in', () => {
440
+ const ctx = navCtx({ state: { activeCell: { rowIndex: 0, colIndex: 0, cellId: null } } })
441
+ // The fake setActiveCell does what the real one does: forgets the run.
442
+ ctx.setActiveCell = vi.fn((r: number, c: number) => {
443
+ const prev = ctx._state.activeCell
444
+ if (!prev || prev.rowIndex !== r || prev.colIndex !== c) ctx.tabRunOrigin = null
445
+ ctx._state.activeCell = { rowIndex: r, colIndex: c, cellId: null }
446
+ })
447
+ const { onGridKeyDown } = createKeyboard(ctx)
448
+ onGridKeyDown(rootKeyEvent({ key: 'Tab' }))
449
+ onGridKeyDown(rootKeyEvent({ key: 'Tab' }))
450
+ expect(ctx._state.activeCell).toMatchObject({ rowIndex: 0, colIndex: 2 })
451
+ expect(ctx.tabRunOrigin).toBe(0)
452
+ onGridKeyDown(rootKeyEvent({ key: 'Enter' }))
453
+ expect(ctx._state.activeCell).toMatchObject({ rowIndex: 1, colIndex: 0 })
454
+ expect(ctx.tabRunOrigin).toBe(null)
455
+ expect(ctx.setSelection).toHaveBeenLastCalledWith(1, 0)
456
+ })
457
+
458
+ it('an arrow between the Tabs ends the run', () => {
459
+ const ctx = navCtx({ state: { activeCell: { rowIndex: 0, colIndex: 0, cellId: null } } })
460
+ ctx.setActiveCell = vi.fn((r: number, c: number) => {
461
+ const prev = ctx._state.activeCell
462
+ if (!prev || prev.rowIndex !== r || prev.colIndex !== c) ctx.tabRunOrigin = null
463
+ ctx._state.activeCell = { rowIndex: r, colIndex: c, cellId: null }
464
+ })
465
+ const { onGridKeyDown } = createKeyboard(ctx)
466
+ onGridKeyDown(rootKeyEvent({ key: 'Tab' }))
467
+ onGridKeyDown(rootKeyEvent({ key: 'ArrowRight' }))
468
+ expect(ctx.tabRunOrigin).toBe(null)
469
+ onGridKeyDown(rootKeyEvent({ key: 'Enter' }))
470
+ expect(ctx._state.activeCell).toMatchObject({ rowIndex: 1, colIndex: 2 })
471
+ })
472
+
473
+ it('Enter and Tab stay inside a selected block and keep the selection', () => {
474
+ const ctx = navCtx({
475
+ state: { activeCell: { rowIndex: 1, colIndex: 1, cellId: null } },
476
+ activeRangeRect: () => ({ minRow: 1, maxRow: 2, minCol: 1, maxCol: 2 }),
477
+ })
478
+ ctx.setActiveCell = vi.fn((r: number, c: number) => {
479
+ const prev = ctx._state.activeCell
480
+ if (!prev || prev.rowIndex !== r || prev.colIndex !== c) ctx.tabRunOrigin = null
481
+ ctx._state.activeCell = { rowIndex: r, colIndex: c, cellId: null }
482
+ })
483
+ const { onGridKeyDown } = createKeyboard(ctx)
484
+ onGridKeyDown(rootKeyEvent({ key: 'Enter' }))
485
+ expect(ctx._state.activeCell).toMatchObject({ rowIndex: 2, colIndex: 1 })
486
+ onGridKeyDown(rootKeyEvent({ key: 'Enter' }))
487
+ expect(ctx._state.activeCell).toMatchObject({ rowIndex: 1, colIndex: 2 })
488
+ onGridKeyDown(rootKeyEvent({ key: 'Tab' }))
489
+ expect(ctx._state.activeCell).toMatchObject({ rowIndex: 2, colIndex: 1 })
490
+ onGridKeyDown(rootKeyEvent({ key: 'Tab', shiftKey: true }))
491
+ expect(ctx._state.activeCell).toMatchObject({ rowIndex: 1, colIndex: 2 })
492
+ expect(ctx.setSelection).not.toHaveBeenCalled()
493
+ expect(ctx.extendSelection).not.toHaveBeenCalled()
374
494
  })
375
495
 
376
496
  it('Tab moves right and wraps using getNextActiveCell', () => {
@@ -7,7 +7,11 @@ import {
7
7
  } from "./index";
8
8
  import "./sv-grid-scrollbar";
9
9
 
10
- import { getKeyboardIntent, getNextActiveCell } from "./keyboard";
10
+ import { getKeyboardIntent, getNextActiveCell, getEntryStep, pastCollapsed } from "./keyboard";
11
+ import { stepPastMerge } from "./merges";
12
+ import { hasGridShortcuts, runGridShortcuts } from "./shortcut-registry";
13
+ import { undoHistory, redoHistory } from "./history";
14
+ import { buildCommandContext } from "./command-context";
11
15
 
12
16
  export function createKeyboard<
13
17
  TFeatures extends TableFeatures = TableFeatures,
@@ -16,7 +20,21 @@ export function createKeyboard<
16
20
  function onGridKeyDown(event: KeyboardEvent) {
17
21
  // Only the grid root drives navigation - keys on header buttons, menus,
18
22
  // or the cell editor are handled by those controls themselves.
23
+ //
24
+ // The command chain runs AFTER this guard, not before. Running it first
25
+ // meant a key typed into a filter-row input reached the sheet commands,
26
+ // so Ctrl+A or Ctrl+D while filtering mutated grid cells. The editor has
27
+ // its own chain call in editing.ts, which is what Alt+Enter needs.
19
28
  if (event.target !== event.currentTarget) return;
29
+
30
+ // Registered commands get the key BEFORE the grid interprets it. That is
31
+ // how @svgrid/enterprise binds Ctrl+Arrow, Ctrl+D and the rest without
32
+ // widening the closed GridKeyboardIntent union, which is public API. A
33
+ // grid with nothing registered pays one array-length read.
34
+ if (hasGridShortcuts() && runGridShortcuts(event, buildCommandContext(ctx, false))) {
35
+ return;
36
+ }
37
+
20
38
  if (ctx.editingCell) return;
21
39
 
22
40
  if ((event.ctrlKey || event.metaKey) && !event.altKey) {
@@ -27,6 +45,14 @@ export function createKeyboard<
27
45
  return;
28
46
  }
29
47
  if (lower === "v") {
48
+ // A consumer taking the paste over wants the browser's own `paste`
49
+ // event, which carries the clipboard's HTML unsanitised; the key is
50
+ // left alone and the async API is armed as the fallback for a
51
+ // browser that never delivers the event to a non-editable element.
52
+ if (ctx.props.onPasteClipboard) {
53
+ ctx.armPasteFallback();
54
+ return;
55
+ }
30
56
  // Secure context: read via the async Clipboard API and swallow the
31
57
  // key. Insecure context (no navigator.clipboard): DON'T preventDefault
32
58
  // so the browser delivers a native `paste` event to `onGridPaste`.
@@ -45,26 +71,12 @@ export function createKeyboard<
45
71
  // and Ctrl+Y both redo. Mirrors VSCode / Sheets / Excel.
46
72
  if (lower === "z" && !event.shiftKey) {
47
73
  event.preventDefault()
48
- if (ctx.historyPtr >= 0) {
49
- const step = ctx.history[ctx.historyPtr]
50
- if (step) {
51
- ctx.applyHistoryStep(step, 'undo')
52
- ctx.historyPtr -= 1
53
- ctx.historyVersion += 1
54
- }
55
- }
74
+ undoHistory(ctx)
56
75
  return
57
76
  }
58
77
  if ((lower === "z" && event.shiftKey) || lower === "y") {
59
78
  event.preventDefault()
60
- if (ctx.historyPtr < ctx.history.length - 1) {
61
- const step = ctx.history[ctx.historyPtr + 1]
62
- if (step) {
63
- ctx.applyHistoryStep(step, 'redo')
64
- ctx.historyPtr += 1
65
- ctx.historyVersion += 1
66
- }
67
- }
79
+ redoHistory(ctx)
68
80
  return
69
81
  }
70
82
  // Ctrl+F opens the find overlay.
@@ -204,25 +216,74 @@ export function createKeyboard<
204
216
  const usable = Math.max(0, clientHeight - headerHeight)
205
217
  return Math.max(1, Math.floor(usable / Math.max(rowHeight, 1)) - 1)
206
218
  }
207
- const next = getNextActiveCell(current, intent, {
219
+ const bounds = {
208
220
  maxRow: Math.max(ctx.allRows.length - 1, 0),
209
221
  maxCol: Math.max(ctx.allColumns.length - 1, 0),
210
- pageSize: pageStep(),
211
- });
212
- ctx.setActiveCell(next.rowIndex, next.colIndex);
213
- ctx.scrollActiveCellIntoView(next.rowIndex, next.colIndex);
214
- // Shift extends the selection ONLY for arrow keys (Excel-style).
215
- // Shift+Enter / Shift+Tab just change direction; they don't grow the
216
- // range, otherwise hammering Shift+Tab to backspace through a row
217
- // would paint a creeping rectangle behind the cursor.
218
- const shouldExtend =
222
+ };
223
+ // Collapsed rows and columns are stepped over, as a sheet's hidden ones.
224
+ const collapsed = {
225
+ isRowCollapsed: (i: number) => ctx.isRowCollapsed(i) as boolean,
226
+ isColumnCollapsed: (i: number) => !!ctx.collapsedColumns[ctx.allColumns[i]?.id],
227
+ };
228
+ // Enter and Tab are entry keys: they remember a Tab run and stay inside
229
+ // a selected block (getEntryStep). ArrowDown shares the moveDown intent
230
+ // and is a plain move, hence the key check.
231
+ if (
232
+ (event.key === "Enter" || event.key === "Tab") &&
233
+ (intent === "moveDown" || intent === "moveUp" || intent === "tabNext" || intent === "tabPrev")
234
+ ) {
235
+ const step = getEntryStep(current, intent, {
236
+ ...bounds,
237
+ tabOrigin: ctx.tabRunOrigin,
238
+ range: ctx.activeRangeRect(),
239
+ collapsed,
240
+ });
241
+ const landed = stepPastMerge(ctx.mergeIndex, current, step.cell, bounds);
242
+ ctx.setActiveCell(landed.rowIndex, landed.colIndex);
243
+ ctx.tabRunOrigin = step.tabOrigin;
244
+ ctx.scrollActiveCellIntoView(landed.rowIndex, landed.colIndex);
245
+ if (!step.withinRange) ctx.setSelection(landed.rowIndex, landed.colIndex);
246
+ return;
247
+ }
248
+ // Shift+Arrow grows the range from its far corner, and the active cell
249
+ // stays where it is, as in Excel: it is the cell the formula bar shows
250
+ // and the one the next keystroke edits. Shift+Home, Shift+End,
251
+ // Shift+PageUp / PageDown and Ctrl+Shift+Home / End grow it the same
252
+ // way, to where the plain key would have moved. Shift+Enter and
253
+ // Shift+Tab never come this way (they are entry keys, above), so
254
+ // hammering Shift+Tab back through a row cannot paint a creeping
255
+ // rectangle. A grid without cell selection has no range to grow and
256
+ // moves the active cell instead.
257
+ const extending =
219
258
  event.shiftKey &&
259
+ ctx.enableCellSelectionEffective !== false &&
220
260
  (intent === "moveLeft" ||
221
261
  intent === "moveRight" ||
222
262
  intent === "moveUp" ||
223
- intent === "moveDown");
224
- if (shouldExtend) ctx.extendSelection(next.rowIndex, next.colIndex);
225
- else ctx.setSelection(next.rowIndex, next.colIndex);
263
+ intent === "moveDown" ||
264
+ intent === "rowStart" ||
265
+ intent === "rowEnd" ||
266
+ intent === "pageUp" ||
267
+ intent === "pageDown" ||
268
+ intent === "gridStart" ||
269
+ intent === "gridEnd");
270
+ if (extending) {
271
+ const anchored = !!ctx.selectionRange?.anchor;
272
+ if (!anchored) ctx.setSelection(current.rowIndex, current.colIndex);
273
+ const from = anchored ? ctx.selectionRange.focus ?? current : current;
274
+ const next = stepPastMerge(ctx.mergeIndex, from, pastCollapsed(from, getNextActiveCell(from, intent, { ...bounds, pageSize: pageStep() }), bounds, collapsed), bounds);
275
+ ctx.extendSelection(next.rowIndex, next.colIndex);
276
+ // Scroll along the axis of the key only, as Excel does: Shift+Right
277
+ // brings the new column into view without moving the rows, so a
278
+ // whole-column selection (its far corner on the last row) stays put.
279
+ const sideways = intent === "moveLeft" || intent === "moveRight" || intent === "rowStart" || intent === "rowEnd";
280
+ ctx.scrollActiveCellIntoView(sideways ? current.rowIndex : next.rowIndex, sideways ? next.colIndex : current.colIndex);
281
+ return;
282
+ }
283
+ const next = stepPastMerge(ctx.mergeIndex, current, pastCollapsed(current, getNextActiveCell(current, intent, { ...bounds, pageSize: pageStep() }), bounds, collapsed), bounds);
284
+ ctx.setActiveCell(next.rowIndex, next.colIndex);
285
+ ctx.scrollActiveCellIntoView(next.rowIndex, next.colIndex);
286
+ ctx.setSelection(next.rowIndex, next.colIndex);
226
287
  }
227
288
 
228
289
  function onWindowKeydown(event: KeyboardEvent) {