@svgrid/grid 3.0.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (318) hide show
  1. package/README.md +5 -4
  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 +845 -207
  9. package/dist/SvGrid.css +178 -2
  10. package/dist/SvGrid.svelte +467 -516
  11. package/dist/SvGrid.types.d.ts +315 -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-CLI93jke.js +635 -0
  30. package/dist/cdn/{GridMenus-DhdPF700.js → GridMenus-CwooL3QA.js} +240 -207
  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-B6HXdfHY.js} +10448 -10049
  68. package/dist/cdn/{src-Bugf5XlI.js → src-C6Iowdvs.js} +6908 -6509
  69. package/dist/cdn/svgrid.js +27 -15
  70. package/dist/cdn/svgrid.svelte-external.js +27 -15
  71. package/dist/cdn/validate-CchXzyrX.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/grid-icons.d.ts +2 -2
  143. package/dist/grid-icons.js +2 -2
  144. package/dist/grid-messages.d.ts +12 -3
  145. package/dist/grid-messages.js +7 -0
  146. package/dist/history.d.ts +83 -0
  147. package/dist/history.js +133 -0
  148. package/dist/index.d.ts +27 -10
  149. package/dist/index.js +22 -5
  150. package/dist/keyboard-handlers.js +88 -31
  151. package/dist/keyboard.d.ts +55 -0
  152. package/dist/keyboard.js +132 -0
  153. package/dist/menus.d.ts +3 -1
  154. package/dist/menus.js +7 -2
  155. package/dist/merges.d.ts +97 -0
  156. package/dist/merges.js +147 -0
  157. package/dist/row-model.d.ts +133 -0
  158. package/dist/row-model.js +16 -0
  159. package/dist/row-resize.d.ts +3 -0
  160. package/dist/row-resize.js +14 -0
  161. package/dist/scroll-sync.d.ts +1 -0
  162. package/dist/scroll-sync.js +24 -0
  163. package/dist/selection.d.ts +18 -1
  164. package/dist/selection.js +138 -18
  165. package/dist/server-block-cache.d.ts +214 -0
  166. package/dist/server-block-cache.js +531 -0
  167. package/dist/server-data-source.d.ts +240 -6
  168. package/dist/server-data-source.js +220 -20
  169. package/dist/server.d.ts +13 -0
  170. package/dist/server.js +13 -0
  171. package/dist/shortcut-registry.d.ts +145 -0
  172. package/dist/shortcut-registry.js +44 -0
  173. package/dist/svgrid-wrapper.types.d.ts +213 -22
  174. package/dist/validate.d.ts +2 -0
  175. package/dist/validate.js +8 -3
  176. package/dist/virtualization/virtualizer.js +38 -17
  177. package/package.json +11 -1
  178. package/src/GridMenus.svelte +44 -2
  179. package/src/SvChartMenu.svelte +69 -0
  180. package/src/SvChartPanes.svelte +113 -0
  181. package/src/SvChartPanes.test.ts +66 -0
  182. package/src/SvGrid.controller.svelte.ts +818 -179
  183. package/src/SvGrid.css +178 -2
  184. package/src/SvGrid.svelte +467 -516
  185. package/src/SvGrid.types.ts +293 -11
  186. package/src/SvGridCellEditor.svelte +17 -0
  187. package/src/SvGridChart.svelte +2257 -329
  188. package/src/SvGridChart.test.ts +1419 -1
  189. package/src/SvGridChart.types.ts +336 -0
  190. package/src/SvGridChartBuilder.svelte +323 -0
  191. package/src/SvGridChartPanel.svelte +221 -275
  192. package/src/SvGridChartPickers.svelte +417 -0
  193. package/src/SvGridChartView.svelte +13 -14
  194. package/src/SvModal.svelte +7 -1
  195. package/src/SvModal.test.ts +9 -0
  196. package/src/ai.test.ts +57 -2
  197. package/src/ai.ts +166 -22
  198. package/src/aria.d.ts +11 -0
  199. package/src/build-api.coverage.test.ts +184 -0
  200. package/src/build-api.ts +118 -22
  201. package/src/chart-axes.test.ts +573 -0
  202. package/src/chart-axes.ts +342 -0
  203. package/src/chart-cartesian.ts +1863 -0
  204. package/src/chart-decimate.test.ts +249 -0
  205. package/src/chart-decimate.ts +186 -0
  206. package/src/chart-export-pdf.test.ts +91 -0
  207. package/src/chart-export-pdf.ts +207 -0
  208. package/src/chart-export.test.ts +14 -0
  209. package/src/chart-export.ts +13 -3
  210. package/src/chart-financial.ts +208 -0
  211. package/src/chart-flow.ts +286 -0
  212. package/src/chart-format.ts +67 -0
  213. package/src/chart-grid.ts +179 -0
  214. package/src/chart-hierarchy.ts +135 -0
  215. package/src/chart-indicators.test.ts +443 -0
  216. package/src/chart-indicators.ts +384 -0
  217. package/src/chart-messages.test.ts +21 -0
  218. package/src/chart-messages.ts +184 -0
  219. package/src/chart-motion.test.ts +71 -0
  220. package/src/chart-motion.ts +148 -0
  221. package/src/chart-panel-messages.test.ts +29 -0
  222. package/src/chart-panel-messages.ts +550 -0
  223. package/src/chart-pivot.test.ts +54 -0
  224. package/src/chart-pivot.ts +225 -0
  225. package/src/chart-polar.ts +674 -0
  226. package/src/chart-samples.ts +106 -0
  227. package/src/chart-scale.ts +394 -0
  228. package/src/chart-series-types.test.ts +714 -0
  229. package/src/chart-stats.ts +409 -0
  230. package/src/chart-stream.test.ts +75 -0
  231. package/src/chart-stream.ts +114 -0
  232. package/src/chart-summary.test.ts +90 -0
  233. package/src/chart-summary.ts +197 -0
  234. package/src/chart-sync.svelte.ts +41 -0
  235. package/src/chart-table.test.ts +76 -0
  236. package/src/chart-table.ts +178 -0
  237. package/src/chart-trend.ts +47 -0
  238. package/src/chart-types.ts +1309 -0
  239. package/src/chart-validate.test.ts +100 -0
  240. package/src/chart-validate.ts +247 -0
  241. package/src/chart-zoom.test.ts +137 -0
  242. package/src/chart-zoom.ts +124 -0
  243. package/src/chart.coverage.test.ts +81 -0
  244. package/src/chart.test.ts +56 -3
  245. package/src/chart.ts +557 -2784
  246. package/src/clipboard.test.ts +151 -0
  247. package/src/clipboard.ts +145 -16
  248. package/src/column-resize.ts +7 -1
  249. package/src/columns.ts +2 -0
  250. package/src/command-context.test.ts +200 -0
  251. package/src/command-context.ts +137 -0
  252. package/src/core.rowmodel-cache.test.ts +51 -0
  253. package/src/core.ts +40 -12
  254. package/src/editing.test.ts +281 -3
  255. package/src/editing.ts +264 -38
  256. package/src/fill-patterns.test.ts +35 -0
  257. package/src/fill-patterns.ts +56 -2
  258. package/src/grid-icons.ts +2 -2
  259. package/src/grid-messages.ts +21 -3
  260. package/src/history.test.ts +196 -0
  261. package/src/history.ts +162 -0
  262. package/src/icon-seam.test.ts +5 -6
  263. package/src/index.ts +169 -12
  264. package/src/keyboard-handlers.coverage.test.ts +126 -6
  265. package/src/keyboard-handlers.ts +91 -30
  266. package/src/keyboard-shortcuts.seam.test.ts +200 -0
  267. package/src/keyboard.test.ts +124 -1
  268. package/src/keyboard.ts +142 -0
  269. package/src/menus.test.ts +26 -0
  270. package/src/menus.ts +10 -3
  271. package/src/merges.test.ts +112 -0
  272. package/src/merges.ts +168 -0
  273. package/src/pivot.grid.test.ts +40 -5
  274. package/src/row-model.ts +146 -0
  275. package/src/row-resize.test.ts +44 -0
  276. package/src/row-resize.ts +17 -0
  277. package/src/scroll-sync.test.ts +42 -1
  278. package/src/scroll-sync.ts +25 -0
  279. package/src/selection.multi-range.test.ts +34 -0
  280. package/src/selection.test.ts +33 -2
  281. package/src/selection.ts +143 -21
  282. package/src/server-block-cache.test.ts +645 -0
  283. package/src/server-block-cache.ts +677 -0
  284. package/src/server-data-source.infinite.test.ts +343 -0
  285. package/src/server-data-source.ts +450 -27
  286. package/src/server.ts +47 -0
  287. package/src/shortcut-registry.test.ts +97 -0
  288. package/src/shortcut-registry.ts +181 -0
  289. package/src/svgrid-wrapper.types.ts +184 -13
  290. package/src/svgrid.behavior.test.ts +135 -0
  291. package/src/svgrid.charting.test.ts +513 -3
  292. package/src/svgrid.context-menu.test.ts +31 -0
  293. package/src/svgrid.new-features.wrapper.test.ts +10 -3
  294. package/src/svgrid.row-model-prop.svelte.test.ts +352 -0
  295. package/src/svgrid.row-model-seam.svelte.test.ts +289 -0
  296. package/src/validate.test.ts +10 -0
  297. package/src/validate.ts +10 -3
  298. package/src/virtualization/virtualizer.ts +39 -17
  299. package/dist/SvGroupCell.svelte +0 -141
  300. package/dist/SvGroupCell.svelte.d.ts +0 -49
  301. package/dist/SvRowGroupPanel.svelte +0 -186
  302. package/dist/SvRowGroupPanel.svelte.d.ts +0 -25
  303. package/dist/cdn/GridMenus-CHOMnW-c.js +0 -602
  304. package/dist/cdn/SvDateTimePicker-CCbDZNZB.js +0 -816
  305. package/dist/cdn/SvGridChart-1PMSp2LZ.js +0 -1481
  306. package/dist/cdn/SvGridChart-D02avhyr.js +0 -1480
  307. package/dist/cdn/SvGridChartPanel-DJnViOv4.js +0 -834
  308. package/dist/cdn/SvGridChartPanel-vPTNerFZ.js +0 -810
  309. package/dist/cdn/SvGridChartView-C--HhdUo.js +0 -56
  310. package/dist/cdn/SvGridChartView-KyyFG-wY.js +0 -55
  311. package/dist/cdn/chart-DLg3_zTQ.js +0 -1652
  312. package/dist/cdn/validate-_CDJzgIo.js +0 -75
  313. package/dist/server-group-model.d.ts +0 -98
  314. package/dist/server-group-model.js +0 -263
  315. package/src/SvGroupCell.svelte +0 -141
  316. package/src/SvRowGroupPanel.svelte +0 -186
  317. package/src/server-group-model.test.ts +0 -294
  318. package/src/server-group-model.ts +0 -370
@@ -1,6 +1,7 @@
1
1
  // Type definitions extracted from SvGrid.svelte. These are compile-time
2
2
  // only - moving them out keeps the component's <script> focused on logic.
3
3
  import type { Snippet } from "svelte";
4
+ import type { GridRowModel } from "./row-model";
4
5
  import type {
5
6
  CellEditorType,
6
7
  ColumnDef,
@@ -11,6 +12,7 @@ import type {
11
12
  import type { ConditionalFormat } from "./conditional-formatting";
12
13
  import type { GroupDisplayType } from "./group-display";
13
14
  import type { GridMessages } from "./grid-messages";
15
+ import type { ChartMessages } from "./chart-messages";
14
16
  import type { GridIconName, GridIcons } from "./grid-icons";
15
17
  import type { GridPivotConfig } from "./pivot-view.svelte";
16
18
  import type { GridPredicateExpr } from "./filtering/predicate-expr";
@@ -68,9 +70,22 @@ import type {
68
70
  ChartType,
69
71
  ChartSpec,
70
72
  ChartAnnotation,
73
+ ChartReducer,
71
74
  ChartReferenceLine,
72
75
  ChartValueFormat,
73
76
  } from "./chart";
77
+ import type { ChartRangePreset } from "./chart-zoom";
78
+ import type { ChartAnimateConfig, ChartContextTarget, ChartZoomConfig } from "./SvGridChart.types";
79
+
80
+ /** What the chart panel's lifecycle events carry. */
81
+ export type ChartPanelInfo = {
82
+ /** Tab index in the panel's strip. */
83
+ index: number;
84
+ title: string;
85
+ type: ChartType;
86
+ /** The spec the panel is rendering, or null while it cannot build one. */
87
+ spec: ChartSpec | null;
88
+ };
74
89
 
75
90
  /** One aggregated bucket returned by a server-side `getAggregate`. */
76
91
  export type ChartAggregateBucket = { category: string; series?: string; value: number };
@@ -79,7 +94,7 @@ export type ChartAggregateRequest = {
79
94
  dimension: string | undefined;
80
95
  measure: string | null;
81
96
  series?: string;
82
- reduce: "sum" | "avg" | "count";
97
+ reduce: ChartReducer;
83
98
  filterModel: Record<string, unknown>;
84
99
  };
85
100
 
@@ -107,7 +122,7 @@ export type ChartingConfig<TData extends RowData = RowData> = {
107
122
  series?: string;
108
123
  /** Measure column, or several for a multi-series chart. */
109
124
  measures?: string | string[];
110
- reduce?: "sum" | "avg" | "count";
125
+ reduce?: ChartReducer;
111
126
  stacked?: boolean;
112
127
  stacked100?: boolean;
113
128
  /** Per-series-label type override (combo). */
@@ -116,7 +131,10 @@ export type ChartingConfig<TData extends RowData = RowData> = {
116
131
  seriesAxes?: Record<string, "left" | "right">;
117
132
  referenceLines?: ChartReferenceLine[];
118
133
  averageLine?: boolean;
119
- trend?: "sma" | "ema" | "linear";
134
+ /** An overlay on every series: a 7-point moving average, or a regression
135
+ * (`linear`, `poly` for a quadratic, `exp`, `log`, `power`) whose
136
+ * R-squared the tooltip reads. */
137
+ trend?: "sma" | "ema" | "linear" | "poly" | "exp" | "log" | "power";
120
138
  annotations?: ChartAnnotation[];
121
139
  yScale?: "linear" | "log";
122
140
  timeAxis?: boolean;
@@ -137,10 +155,37 @@ export type ChartingConfig<TData extends RowData = RowData> = {
137
155
  otherLabel?: string;
138
156
  sort?: "value-desc" | "value-asc" | "category" | "none";
139
157
  dataLabels?: boolean;
140
- zoom?: boolean;
158
+ /** Zooming: `true` for drag-to-zoom, or an object choosing wheel, pinch,
159
+ * pan and the axes (see `ChartZoomConfig`). The window survives tab
160
+ * switches and round-trips through `getChartsState`. */
161
+ zoom?: boolean | ChartZoomConfig;
141
162
  brush?: boolean;
163
+ /** Range buttons (1W / 1M / 3M / 6M / YTD / 1Y / All, or your own) when the
164
+ * dimension is a date. */
165
+ rangePresets?: boolean | ChartRangePreset[];
166
+ /** Share crosshair and zoom with other charts on the page (any `SvChart`
167
+ * with the same `syncGroup`). */
168
+ syncGroup?: string;
169
+ /** All chart tabs of this grid share one zoom window: zoom in one tab and
170
+ * the others open at the same range. */
171
+ syncTabs?: boolean;
172
+ /** Right-click menu on the chart: `true` for the built-in items, your own
173
+ * `MenuItem`s appended after them, or a function of the clicked point. */
174
+ contextMenu?: boolean | MenuItem[] | ((target: ChartContextTarget) => MenuItem[]);
175
+ /** Motion: `true` for the default data-update tween, or an object choosing
176
+ * the enter effect and duration. */
177
+ animate?: boolean | ChartAnimateConfig;
178
+ /** Translations for the chart's own strings (toolbar, menu, legend hints,
179
+ * what it says to assistive technology); the panel passes them to every
180
+ * chart it draws. See `ChartMessages`. */
181
+ localeText?: Partial<ChartMessages>;
142
182
  /** Show the chart's PNG/SVG export toolbar. */
143
183
  export?: boolean;
184
+ /** A chart tab was added (the first one counts, once the panel opens). */
185
+ onChartCreated?: (info: ChartPanelInfo) => void;
186
+ /** The active chart's spec changed: a picker, the builder, a filter, an
187
+ * edit, new rows. Debounced to one call per burst of changes. */
188
+ onChartChanged?: (info: ChartPanelInfo) => void;
144
189
  /** Escape hatch: build a fully custom ChartSpec from the (scoped) rows. */
145
190
  buildSpec?: (rows: TData[]) => ChartSpec | null;
146
191
  /** Server-side aggregation: chart the whole dataset, not just loaded rows. */
@@ -212,17 +257,42 @@ export type ContextMenuTarget<TData extends RowData = RowData> = {
212
257
  * "chart"`. The `"chart"` item (chart the selected range) is only shown when
213
258
  * `charting` is enabled; it is appended to the default menu automatically.
214
259
  */
260
+ /**
261
+ * An icon of your own for a context-menu item: path data on a 16 x 16 grid,
262
+ * drawn in the text colour with a 1.4px round stroke (`fill` for a solid
263
+ * part, `width` and `dash` to vary the stroke). The same shape a
264
+ * spreadsheet ribbon's icon set uses, so one set serves both.
265
+ */
266
+ export type ContextMenuIcon = {
267
+ paths: ReadonlyArray<{ d: string; fill?: boolean; width?: number; dash?: string }>;
268
+ };
269
+
215
270
  export type ContextMenuItem<TData extends RowData = RowData> =
216
271
  | string
217
272
  | {
218
273
  key: string;
219
- label: string;
274
+ /**
275
+ * The text. An object whose `key` names a built-in (`copy`, `cut`,
276
+ * `paste`, `clear`, `row_above`, `row_below`, `remove_row`,
277
+ * `remove_col`, `comment`, `chart`) keeps the built-in's own label
278
+ * when this is omitted.
279
+ */
280
+ label?: string;
281
+ /**
282
+ * A glyph before the label: one of the grid's icons by name, or path
283
+ * data of your own. Items without one keep the gutter, so the labels
284
+ * line up.
285
+ */
286
+ icon?: GridIconName | ContextMenuIcon;
220
287
  /** Hide the item entirely for this target. */
221
288
  hidden?: (target: ContextMenuTarget<TData>) => boolean;
222
289
  /** Render the item greyed-out and non-clickable for this target. */
223
290
  disabled?: (target: ContextMenuTarget<TData>) => boolean;
224
- /** Invoked on click. The menu closes afterwards. */
225
- action: (target: ContextMenuTarget<TData>) => void;
291
+ /**
292
+ * Invoked on click. The menu closes afterwards. Omit it on a built-in
293
+ * key to keep what the built-in does and only give it an icon.
294
+ */
295
+ action?: (target: ContextMenuTarget<TData>) => void;
226
296
  };
227
297
 
228
298
  /** What a {@link SelectionBarAction} is handed when it runs. */
@@ -416,7 +486,7 @@ export type ChartViewConfig<
416
486
  /** Pivot dimension: one series per distinct value of this field. */
417
487
  series?: keyof TData & string;
418
488
  /** Aggregation when several rows share a category. Default `'sum'`. */
419
- reduce?: "sum" | "avg" | "count";
489
+ reduce?: ChartReducer;
420
490
  /** Stack bar / area series instead of grouping them. */
421
491
  stacked?: boolean;
422
492
  /** Stack to 100% (implies `stacked`). */
@@ -1044,7 +1114,13 @@ export type SchedulerConfig<
1044
1114
  };
1045
1115
 
1046
1116
  export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> = {
1047
- data: ReadonlyArray<TData>;
1117
+ /**
1118
+ * The rows to render.
1119
+ *
1120
+ * Optional only because `rowModel` can supply them instead; a grid with
1121
+ * neither renders empty. When both are present `data` wins.
1122
+ */
1123
+ data?: ReadonlyArray<TData>;
1048
1124
  columns: Array<ColumnDef<TFeatures, TData>>;
1049
1125
  /**
1050
1126
  * Kanban board mode. When set, the grid renders its rows as cards in
@@ -1556,6 +1632,17 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
1556
1632
  * that leaves this off never fetches that code.
1557
1633
  */
1558
1634
  columnResize?: boolean;
1635
+ /**
1636
+ * The user dragged a column's edge (or double-clicked it to autosize).
1637
+ * Programmatic `api.setColumnWidth` does not fire it.
1638
+ */
1639
+ onColumnResize?: (event: { columnId: string; width: number }) => void;
1640
+ /**
1641
+ * The user dragged a row's edge, or double-clicked it: `height` is then
1642
+ * `null`, the row back at its declared height. Programmatic
1643
+ * `api.setRowHeight` does not fire it.
1644
+ */
1645
+ onRowResize?: (event: { rowIndex: number; height: number | null }) => void;
1559
1646
  /**
1560
1647
  * Make the grid usable on narrow screens. When the grid's own width drops
1561
1648
  * below the breakpoint (default `640`px), pinned columns are un-pinned so the
@@ -1618,6 +1705,22 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
1618
1705
  * currency symbols, expand codes to labels, or redact. Receives the display
1619
1706
  * value plus the row/column context; return the string (or value) to copy.
1620
1707
  */
1708
+ /**
1709
+ * Decide what the fill handle writes into one cell, ahead of the grid's
1710
+ * own pattern rules (series, weekdays, "Item 1"). Receives the source
1711
+ * cell's value and how far the target sits from it; return the value to
1712
+ * write, or `undefined` to let the pattern decide. A spreadsheet uses it
1713
+ * to move a formula's references by the distance filled, which the
1714
+ * pattern rules would otherwise mangle ("=A1+B1" reads as "Item 1").
1715
+ */
1716
+ processCellForFill?: (params: {
1717
+ /** The source cell's value the target cycles back to. */
1718
+ value: unknown;
1719
+ /** Rows and columns from that source cell to the target. */
1720
+ delta: { rows: number; cols: number };
1721
+ rowIndex: number;
1722
+ columnId: string;
1723
+ }) => unknown;
1621
1724
  processCellForClipboard?: (params: {
1622
1725
  value: unknown;
1623
1726
  column: unknown;
@@ -1625,6 +1728,60 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
1625
1728
  rowIndex: number;
1626
1729
  columnId: string;
1627
1730
  }) => unknown;
1731
+ /**
1732
+ * An HTML rendering of what Ctrl+C copies, written to the clipboard as
1733
+ * `text/html` beside the TSV. Excel and Google Sheets read the HTML
1734
+ * first, so a table with inline styles pastes into them with its formats,
1735
+ * and the same markup can carry what the text cannot (a formula in a
1736
+ * `data-` attribute) for a round trip back into a grid that reads it.
1737
+ * Called after every cell has been through `processCellForClipboard`,
1738
+ * with the rectangles copied and the text about to be written. Return
1739
+ * nothing to write text alone. Runs synchronously inside the key press,
1740
+ * which is what the clipboard needs.
1741
+ */
1742
+ clipboardHtml?: (params: {
1743
+ rects: ReadonlyArray<{ minRow: number; maxRow: number; minCol: number; maxCol: number }>;
1744
+ text: string;
1745
+ }) => string | null | undefined;
1746
+ /**
1747
+ * Take over a paste. Receives the clipboard's `text/plain` and, when the
1748
+ * source put one there, its `text/html` (Excel's carries formats and
1749
+ * formulas; a grid's own `clipboardHtml` carries whatever it chose to).
1750
+ * Return `true` to say the paste was applied; anything else lets the grid
1751
+ * paste the text as it always has. Runs inside one history group, so
1752
+ * every `setCellValue` and `recordUndo` the handler makes is one Ctrl+Z.
1753
+ *
1754
+ * With this set, Ctrl+V lets the browser's own `paste` event through
1755
+ * (that is where the unsanitised HTML is), and the async Clipboard API is
1756
+ * the fallback for a browser that does not deliver it. `source` says
1757
+ * which path the payload came by.
1758
+ */
1759
+ onPasteClipboard?: (payload: {
1760
+ text: string;
1761
+ html: string | null;
1762
+ source: "event" | "async";
1763
+ }) => boolean | void;
1764
+ /**
1765
+ * Transform each cell on its way IN from the clipboard, before the grid
1766
+ * coerces it for the column's editor. Symmetric with
1767
+ * `processCellForClipboard`: the pair is what lets a round trip survive.
1768
+ *
1769
+ * Receives the raw clipboard text for the cell plus where it is landing.
1770
+ * Return the value to write, or `undefined` to leave the cell untouched.
1771
+ *
1772
+ * This is also the seam a feature pack uses to take over a paste entirely:
1773
+ * `@svgrid/enterprise`'s paste-special reads the clipboard's `text/html`
1774
+ * for formats and formulas and writes through here.
1775
+ */
1776
+ processCellFromClipboard?: (params: {
1777
+ /** The raw text from the clipboard for this cell. */
1778
+ text: string;
1779
+ /** What the grid would have written after its own coercion. */
1780
+ parsedValue: unknown;
1781
+ row: TData;
1782
+ rowIndex: number;
1783
+ columnId: string;
1784
+ }) => unknown;
1628
1785
  /**
1629
1786
  * Inline cell editing: F2 or double-click opens an editor in the active cell,
1630
1787
  * Enter commits, Esc cancels. Off by default.
@@ -1634,6 +1791,14 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
1634
1791
  * `editable` is the shortcut alias and wins over this.
1635
1792
  */
1636
1793
  enableInlineEditing?: boolean;
1794
+ /**
1795
+ * A click on the cell that is already active opens its editor, the way a
1796
+ * second click on a selected file name starts renaming it. On by default.
1797
+ * A spreadsheet turns it off: Excel edits on double-click or F2 only, and
1798
+ * a user clicking the cell they are on to get back to it after a dialog
1799
+ * would otherwise find the next shortcut typed into an editor.
1800
+ */
1801
+ editOnSecondClick?: boolean;
1637
1802
  /**
1638
1803
  * Full-row editing. When `true`, starting an edit puts the WHOLE row into
1639
1804
  * edit mode - every editable cell shows an inline editor at once - and a
@@ -1941,6 +2106,99 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
1941
2106
  scrollHeight: number;
1942
2107
  clientHeight: number;
1943
2108
  }) => void;
2109
+ /**
2110
+ * Fires when the range of rows on screen changes, with the first and last
2111
+ * row INDEX (not pixels). Coalesced to one call per frame, so it is cheap
2112
+ * to wire to something that fetches.
2113
+ *
2114
+ * This is the hook a block-loading data source needs and
2115
+ * `onScrollBottomReached` cannot give it: "the user is looking at rows
2116
+ * 4,000-4,020" answers which block to fetch and which to keep, while
2117
+ * "they hit the bottom" only ever means "append more". Both are free; use
2118
+ * this one with `createServerDataSource({ mode: 'infinite' })`, or let
2119
+ * `rowModel` wire it for you.
2120
+ *
2121
+ * Reports `0, data.length - 1` when virtualization is off, since every row
2122
+ * really is rendered.
2123
+ */
2124
+ onVisibleRangeChange?: (range: {
2125
+ startIndex: number;
2126
+ endIndex: number;
2127
+ }) => void;
2128
+ /**
2129
+ * Marks a row as one whose data has not arrived: `"loading"` draws a
2130
+ * shimmer in every cell, `"failed"` draws a full-width "could not load"
2131
+ * row with a Retry button, and `null` (the default for every row) renders
2132
+ * normally.
2133
+ *
2134
+ * Placeholder rows are inert - not selectable, not editable, and skipped
2135
+ * by cell navigation - because there is nothing there to act on yet.
2136
+ *
2137
+ * `createServerDataSource` in `infinite` mode fills the gaps with rows this
2138
+ * recognises, so the usual wiring is `rowPlaceholder={rowPlaceholderState}`
2139
+ * (or nothing at all, via `rowModel`).
2140
+ */
2141
+ rowPlaceholder?: (row: TData, rowIndex: number) => "loading" | "failed" | null;
2142
+ /** Called by the Retry button on a `"failed"` placeholder row. */
2143
+ onRetryRow?: (row: TData, rowIndex: number) => void;
2144
+ /**
2145
+ * Hand selection over to an external model.
2146
+ *
2147
+ * The grid normally tracks selection as a record of the row ids it has
2148
+ * seen, which is right until the rows it has seen are a window onto a
2149
+ * million on a server: "select all" then means 20 ticked checkboxes rather
2150
+ * than a million, and the header checkbox cannot honestly say `all`. A
2151
+ * model that stores the RULE ("everything except these three") can answer
2152
+ * both, so when this is set the header checkbox, the row checkboxes and
2153
+ * `api.selectAllRows()` all route through it instead.
2154
+ *
2155
+ * `@svgrid/enterprise` ships one for the server-side row model; this is the
2156
+ * seam it plugs into.
2157
+ */
2158
+ /**
2159
+ * Drive the grid from a row model instead of wiring a dozen props.
2160
+ *
2161
+ * `createServerDataSource` returns one, and so does the Enterprise
2162
+ * server-side row model, so server-backed grids become:
2163
+ *
2164
+ * ```svelte
2165
+ * <SvGrid rowModel={ctl} {columns} />
2166
+ * ```
2167
+ *
2168
+ * The model supplies `data`, `loading`, `getRowId`, the external sort
2169
+ * and filter wiring, the visible range, placeholder rows, group
2170
+ * accessors, selection and paging - each one only if it implements that
2171
+ * part. A prop written explicitly on the grid always wins, so you can
2172
+ * adopt it and still override one piece.
2173
+ */
2174
+ rowModel?: GridRowModel<TData>;
2175
+ /**
2176
+ * Columns that REPLACE `columns` while set. The server-side row model
2177
+ * supplies them in pivot mode - one column per pivoted value, grouped
2178
+ * under a header per pivot key - and clears them when pivot mode ends,
2179
+ * so `columns` stays the app's own list. Rarely set by hand.
2180
+ */
2181
+ pivotResultColumns?: Array<ColumnDef<TFeatures, TData>> | null;
2182
+ rowSelectionModel?: {
2183
+ isSelected: (rowId: string, row: TData) => boolean;
2184
+ /** Whether the header checkbox shows empty, indeterminate, or ticked. */
2185
+ headerState: () => "none" | "some" | "all";
2186
+ toggle: (rowId: string, row: TData, next: boolean) => void;
2187
+ /** The header checkbox: select or clear everything, loaded or not. */
2188
+ toggleAll: (next: boolean) => void;
2189
+ /**
2190
+ * How many rows the rule selects, counting the ones the grid never
2191
+ * loaded; `null` when it cannot say. The selection bar shows this
2192
+ * instead of counting ticked rows on screen.
2193
+ */
2194
+ selectedCount?: () => number | null;
2195
+ /**
2196
+ * Apply one patch to every selected row, loaded or not. When present,
2197
+ * the bulk-edit drawer sends its edits here instead of writing the
2198
+ * loaded cells. Resolves with how many rows changed.
2199
+ */
2200
+ bulkUpdate?: (patch: Record<string, unknown>) => Promise<number>;
2201
+ };
1944
2202
  /**
1945
2203
  * Marks a row as an expandable "detail row". When this returns true the
1946
2204
  * grid renders that row as a SINGLE full-width cell (colspan across every
@@ -1961,8 +2219,10 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
1961
2219
  * Server-side group / tree keyboard + accessibility, built into the grid. When
1962
2220
  * set, the grid uses the treegrid role and marks matching rows with
1963
2221
  * `aria-level` / `aria-expanded`, and ArrowRight / ArrowLeft expand / collapse
1964
- * the focused group row (no app-level key handling). Pair with `serverGroupRows`
1965
- * + `SvGroupCell` for the visual expander. Every accessor receives the row data.
2222
+ * the focused group row (no app-level key handling). Pair with
2223
+ * `serverGroupRows` + `SvGroupCell` from `@svgrid/enterprise` for the visual
2224
+ * expander, or drive it from your own tree state. Every accessor receives the
2225
+ * row data.
1966
2226
  */
1967
2227
  serverGroup?: {
1968
2228
  /** Whether a row is an expandable group / branch. */
@@ -1991,6 +2251,28 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
1991
2251
  * main grid; field/format/cell/cellClass all apply.
1992
2252
  */
1993
2253
  pinnedTopRows?: ReadonlyArray<TData>;
2254
+ /**
2255
+ * Freeze the first N rows: they stay under the header while the body
2256
+ * scrolls, and unlike `pinnedTopRows` they are the grid's own rows,
2257
+ * still editable, selectable and numbered as rows 1..N. Excel's Freeze
2258
+ * Panes, for the row half; the column half is `columnPinning`. Under
2259
+ * `virtualization` the frozen rows are always rendered and the window
2260
+ * skips them.
2261
+ */
2262
+ frozenRows?: number;
2263
+ /**
2264
+ * Merged cells: rectangles drawn as one cell, a spreadsheet's Merge &
2265
+ * Center. Each entry is the top-left cell (display indices) and how many
2266
+ * rows and columns it covers. The origin's td takes the span and shows
2267
+ * the origin's value; the covered cells are not drawn, a selection grows
2268
+ * to whole merges, the active cell inside a merge is its origin, and the
2269
+ * arrow keys step over a merge as one cell. A merge that crosses the
2270
+ * frozen boundary or the rendered window is drawn in parts, one per
2271
+ * band. The grid does not write into covered cells on its own; a
2272
+ * consumer that merges cells keeps them empty or marks them read-only
2273
+ * through the column's `editable`.
2274
+ */
2275
+ mergedCells?: ReadonlyArray<{ rowIndex: number; colIndex: number; rowSpan: number; colSpan: number }>;
1994
2276
  /**
1995
2277
  * Rows to pin to the BOTTOM of the grid - rendered below the regular
1996
2278
  * rows and sticky-positioned (sticks to the bottom of the viewport
@@ -715,6 +715,23 @@
715
715
  {@const _reg = getCellEditor(String(ctrl.editingCell?.editorType))!}
716
716
  {@const CustomCellEditor = _reg.component}
717
717
  <CustomCellEditor {...resolveEditorProps(_reg, buildRegisteredEditorContext())} />
718
+ {:else if (ctrl.editingCell?.editorType ?? "text") === "text" && column?.columnDef.editorMultiline}
719
+ <!-- The text editor with room for line breaks: Alt+Enter inserts one
720
+ (handled in onEditorKeyDown), Enter commits like the input's, and
721
+ the height follows the lines. -->
722
+ <textarea
723
+ use:focusOnMount
724
+ class="sv-grid-cell-editor sv-grid-cell-editor-text sv-grid-cell-editor-multiline"
725
+ rows={Math.max(1, String(ctrl.editingCell?.value ?? "").split("\n").length)}
726
+ value={String(ctrl.editingCell?.value ?? "")}
727
+ oninput={(event) => {
728
+ const area = event.currentTarget as HTMLTextAreaElement;
729
+ area.rows = Math.max(1, area.value.split("\n").length);
730
+ updateEditingCellValue(area.value);
731
+ }}
732
+ onblur={() => saveEditingCell()}
733
+ onkeydown={onEditorKeyDown}
734
+ ></textarea>
718
735
  {:else}
719
736
  {@const editorType = ctrl.editingCell?.editorType ?? "text"}
720
737
  {@const isNumberEditor = getCellEditorInputType(editorType) === "text" &&