@svgrid/grid 1.2.22 → 1.2.24

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 (263) hide show
  1. package/dist/GridFooter.svelte +34 -20
  2. package/dist/GridFooter.svelte.d.ts +8 -0
  3. package/dist/SvAutoComplete.svelte +89 -0
  4. package/dist/SvAutoComplete.svelte.d.ts +16 -0
  5. package/dist/SvButton.svelte +97 -0
  6. package/dist/SvButton.svelte.d.ts +23 -0
  7. package/dist/SvCalendar.svelte +409 -0
  8. package/dist/SvCalendar.svelte.d.ts +52 -0
  9. package/dist/SvCheckBox.svelte +82 -0
  10. package/dist/SvCheckBox.svelte.d.ts +19 -0
  11. package/dist/SvColorInput.svelte +160 -0
  12. package/dist/SvColorInput.svelte.d.ts +15 -0
  13. package/dist/SvComboBox.svelte +108 -0
  14. package/dist/SvComboBox.svelte.d.ts +15 -0
  15. package/dist/SvCountryInput.svelte +125 -0
  16. package/dist/SvCountryInput.svelte.d.ts +14 -0
  17. package/dist/SvDateTimePicker.svelte +265 -0
  18. package/dist/SvDateTimePicker.svelte.d.ts +38 -0
  19. package/dist/SvDropDownList.svelte +120 -0
  20. package/dist/SvDropDownList.svelte.d.ts +15 -0
  21. package/dist/SvForm.svelte +147 -0
  22. package/dist/SvForm.svelte.d.ts +29 -0
  23. package/dist/SvGauge.svelte +97 -0
  24. package/dist/SvGauge.svelte.d.ts +26 -0
  25. package/dist/SvGrid.controller.svelte.d.ts +16 -2
  26. package/dist/SvGrid.controller.svelte.js +63 -8
  27. package/dist/SvGrid.css +84 -31
  28. package/dist/SvGrid.helpers.d.ts +4 -0
  29. package/dist/SvGrid.helpers.js +40 -12
  30. package/dist/SvGrid.svelte +84 -5
  31. package/dist/SvGrid.types.d.ts +36 -0
  32. package/dist/SvGridDropdown.svelte +16 -30
  33. package/dist/SvGridDropdown.svelte.d.ts +4 -0
  34. package/dist/SvListBox.svelte +89 -0
  35. package/dist/SvListBox.svelte.d.ts +22 -0
  36. package/dist/SvMaskedInput.svelte +66 -0
  37. package/dist/SvMaskedInput.svelte.d.ts +15 -0
  38. package/dist/SvNumberInput.svelte +116 -0
  39. package/dist/SvNumberInput.svelte.d.ts +18 -0
  40. package/dist/SvPasswordInput.svelte +100 -0
  41. package/dist/SvPasswordInput.svelte.d.ts +18 -0
  42. package/dist/SvPhoneInput.svelte +87 -0
  43. package/dist/SvPhoneInput.svelte.d.ts +19 -0
  44. package/dist/SvRadioGroup.svelte +85 -0
  45. package/dist/SvRadioGroup.svelte.d.ts +20 -0
  46. package/dist/SvRating.svelte +91 -0
  47. package/dist/SvRating.svelte.d.ts +18 -0
  48. package/dist/SvRepeatButton.svelte +89 -0
  49. package/dist/SvRepeatButton.svelte.d.ts +21 -0
  50. package/dist/SvSlider.svelte +155 -0
  51. package/dist/SvSlider.svelte.d.ts +20 -0
  52. package/dist/SvSwitchButton.svelte +87 -0
  53. package/dist/SvSwitchButton.svelte.d.ts +14 -0
  54. package/dist/SvTabs.svelte +109 -0
  55. package/dist/SvTabs.svelte.d.ts +26 -0
  56. package/dist/SvTagsInput.svelte +70 -0
  57. package/dist/SvTagsInput.svelte.d.ts +14 -0
  58. package/dist/SvTimePicker.svelte +201 -0
  59. package/dist/SvTimePicker.svelte.d.ts +30 -0
  60. package/dist/SvToggleButton.svelte +57 -0
  61. package/dist/SvToggleButton.svelte.d.ts +16 -0
  62. package/dist/SvTree.svelte +131 -0
  63. package/dist/SvTree.svelte.d.ts +27 -0
  64. package/dist/build-api.js +78 -1
  65. package/dist/cdn/svgrid.js +11674 -5907
  66. package/dist/cdn/svgrid.svelte-external.js +10436 -4671
  67. package/dist/cell-render.d.ts +4 -0
  68. package/dist/cell-render.js +35 -1
  69. package/dist/clipboard.js +19 -1
  70. package/dist/collaboration.d.ts +2 -0
  71. package/dist/collaboration.js +4 -0
  72. package/dist/core.d.ts +22 -1
  73. package/dist/countries.d.ts +15 -0
  74. package/dist/countries.js +61 -0
  75. package/dist/createAutocomplete.svelte.d.ts +77 -0
  76. package/dist/createAutocomplete.svelte.js +100 -0
  77. package/dist/createCalendar.svelte.d.ts +192 -0
  78. package/dist/createCalendar.svelte.js +402 -0
  79. package/dist/createCheckbox.svelte.d.ts +45 -0
  80. package/dist/createCheckbox.svelte.js +26 -0
  81. package/dist/createColorInput.svelte.d.ts +67 -0
  82. package/dist/createColorInput.svelte.js +100 -0
  83. package/dist/createCombobox.svelte.d.ts +102 -0
  84. package/dist/createCombobox.svelte.js +171 -0
  85. package/dist/createCountryInput.svelte.d.ts +86 -0
  86. package/dist/createCountryInput.svelte.js +126 -0
  87. package/dist/createDateTimePicker.svelte.d.ts +83 -0
  88. package/dist/createDateTimePicker.svelte.js +202 -0
  89. package/dist/createDropdownList.svelte.d.ts +78 -0
  90. package/dist/createDropdownList.svelte.js +117 -0
  91. package/dist/createGauge.svelte.d.ts +56 -0
  92. package/dist/createGauge.svelte.js +49 -0
  93. package/dist/createListbox.svelte.d.ts +79 -0
  94. package/dist/createListbox.svelte.js +117 -0
  95. package/dist/createMaskedInput.svelte.d.ts +30 -0
  96. package/dist/createMaskedInput.svelte.js +62 -0
  97. package/dist/createNumberInput.svelte.d.ts +72 -0
  98. package/dist/createNumberInput.svelte.js +167 -0
  99. package/dist/createPasswordInput.svelte.d.ts +60 -0
  100. package/dist/createPasswordInput.svelte.js +72 -0
  101. package/dist/createPhoneInput.svelte.d.ts +46 -0
  102. package/dist/createPhoneInput.svelte.js +105 -0
  103. package/dist/createRadioGroup.svelte.d.ts +64 -0
  104. package/dist/createRadioGroup.svelte.js +73 -0
  105. package/dist/createRating.svelte.d.ts +70 -0
  106. package/dist/createRating.svelte.js +85 -0
  107. package/dist/createSlider.svelte.d.ts +71 -0
  108. package/dist/createSlider.svelte.js +123 -0
  109. package/dist/createSwitch.svelte.d.ts +43 -0
  110. package/dist/createSwitch.svelte.js +41 -0
  111. package/dist/createTabs.svelte.d.ts +78 -0
  112. package/dist/createTabs.svelte.js +92 -0
  113. package/dist/createTagsInput.svelte.d.ts +65 -0
  114. package/dist/createTagsInput.svelte.js +93 -0
  115. package/dist/createTimePicker.svelte.d.ts +106 -0
  116. package/dist/createTimePicker.svelte.js +248 -0
  117. package/dist/createToggle.svelte.d.ts +43 -0
  118. package/dist/createToggle.svelte.js +39 -0
  119. package/dist/createTree.svelte.d.ts +96 -0
  120. package/dist/createTree.svelte.js +194 -0
  121. package/dist/datetime/date-core.d.ts +88 -0
  122. package/dist/datetime/date-core.js +165 -0
  123. package/dist/datetime/date-format.d.ts +39 -0
  124. package/dist/datetime/date-format.js +371 -0
  125. package/dist/datetime/date-restrict.d.ts +23 -0
  126. package/dist/datetime/date-restrict.js +50 -0
  127. package/dist/datetime/date-selection.d.ts +25 -0
  128. package/dist/datetime/date-selection.js +94 -0
  129. package/dist/datetime/mask.d.ts +21 -0
  130. package/dist/datetime/mask.js +90 -0
  131. package/dist/editing.d.ts +1 -1
  132. package/dist/editing.js +7 -0
  133. package/dist/editor-contract.d.ts +48 -0
  134. package/dist/editor-contract.js +26 -0
  135. package/dist/editors/cell-editors.d.ts +2 -2
  136. package/dist/editors/cell-editors.js +3 -1
  137. package/dist/export-format.d.ts +178 -0
  138. package/dist/export-format.js +419 -0
  139. package/dist/hyperformula-adapter.d.ts +4 -0
  140. package/dist/hyperformula-adapter.js +15 -6
  141. package/dist/index.d.ts +60 -0
  142. package/dist/index.js +72 -0
  143. package/dist/list-option.d.ts +10 -0
  144. package/dist/list-option.js +7 -0
  145. package/dist/menus.js +18 -2
  146. package/dist/popover.d.ts +48 -0
  147. package/dist/popover.js +65 -0
  148. package/dist/row-resize.d.ts +4 -4
  149. package/dist/row-resize.js +8 -5
  150. package/dist/selection.d.ts +6 -0
  151. package/dist/selection.js +31 -5
  152. package/dist/server-data-source.d.ts +43 -0
  153. package/dist/server-data-source.js +100 -0
  154. package/dist/sparkline.js +8 -4
  155. package/dist/svgrid-wrapper.types.d.ts +26 -1
  156. package/package.json +6 -1
  157. package/src/GridFooter.svelte +34 -20
  158. package/src/SvAutoComplete.svelte +89 -0
  159. package/src/SvButton.svelte +97 -0
  160. package/src/SvCalendar.svelte +409 -0
  161. package/src/SvCalendar.test.ts +211 -0
  162. package/src/SvCheckBox.svelte +82 -0
  163. package/src/SvColorInput.svelte +160 -0
  164. package/src/SvComboBox.svelte +108 -0
  165. package/src/SvCountryInput.svelte +125 -0
  166. package/src/SvDateTimePicker.svelte +265 -0
  167. package/src/SvDateTimePicker.test.ts +136 -0
  168. package/src/SvDropDownList.svelte +120 -0
  169. package/src/SvForm.svelte +147 -0
  170. package/src/SvGauge.svelte +97 -0
  171. package/src/SvGrid.controller.svelte.ts +74 -8
  172. package/src/SvGrid.css +84 -31
  173. package/src/SvGrid.helpers.ts +41 -12
  174. package/src/SvGrid.svelte +84 -5
  175. package/src/SvGrid.types.ts +33 -0
  176. package/src/SvGridDropdown.svelte +16 -30
  177. package/src/SvListBox.svelte +89 -0
  178. package/src/SvMaskedInput.svelte +66 -0
  179. package/src/SvNumberInput.svelte +116 -0
  180. package/src/SvPasswordInput.svelte +100 -0
  181. package/src/SvPhoneInput.svelte +87 -0
  182. package/src/SvRadioGroup.svelte +85 -0
  183. package/src/SvRating.svelte +91 -0
  184. package/src/SvRepeatButton.svelte +89 -0
  185. package/src/SvSlider.svelte +155 -0
  186. package/src/SvSwitchButton.svelte +87 -0
  187. package/src/SvTabs.svelte +109 -0
  188. package/src/SvTagsInput.svelte +70 -0
  189. package/src/SvTimePicker.svelte +201 -0
  190. package/src/SvTimePicker.test.ts +98 -0
  191. package/src/SvToggleButton.svelte +57 -0
  192. package/src/SvTree.svelte +131 -0
  193. package/src/build-api.ts +115 -0
  194. package/src/cell-render.test.ts +38 -0
  195. package/src/cell-render.ts +43 -0
  196. package/src/clipboard.test.ts +18 -0
  197. package/src/clipboard.ts +24 -1
  198. package/src/collaboration.test.ts +30 -0
  199. package/src/collaboration.ts +6 -0
  200. package/src/core.ts +27 -3
  201. package/src/countries.ts +71 -0
  202. package/src/createAutocomplete.svelte.ts +104 -0
  203. package/src/createCalendar.svelte.ts +488 -0
  204. package/src/createCheckbox.svelte.ts +74 -0
  205. package/src/createColorInput.svelte.ts +115 -0
  206. package/src/createCombobox.svelte.ts +158 -0
  207. package/src/createCountryInput.svelte.ts +126 -0
  208. package/src/createDateTimePicker.svelte.ts +216 -0
  209. package/src/createDropdownList.svelte.ts +125 -0
  210. package/src/createGauge.svelte.ts +86 -0
  211. package/src/createListbox.svelte.ts +186 -0
  212. package/src/createMaskedInput.svelte.ts +81 -0
  213. package/src/createNumberInput.svelte.ts +193 -0
  214. package/src/createPasswordInput.svelte.ts +87 -0
  215. package/src/createPhoneInput.svelte.ts +119 -0
  216. package/src/createRadioGroup.svelte.ts +132 -0
  217. package/src/createRating.svelte.ts +145 -0
  218. package/src/createSlider.svelte.ts +160 -0
  219. package/src/createSwitch.svelte.ts +78 -0
  220. package/src/createTabs.svelte.ts +129 -0
  221. package/src/createTagsInput.svelte.ts +98 -0
  222. package/src/createTimePicker.svelte.ts +289 -0
  223. package/src/createToggle.svelte.ts +69 -0
  224. package/src/createTree.svelte.ts +216 -0
  225. package/src/datetime/date-core.test.ts +217 -0
  226. package/src/datetime/date-core.ts +204 -0
  227. package/src/datetime/date-format.test.ts +121 -0
  228. package/src/datetime/date-format.ts +317 -0
  229. package/src/datetime/date-restrict.ts +60 -0
  230. package/src/datetime/date-selection.test.ts +129 -0
  231. package/src/datetime/date-selection.ts +137 -0
  232. package/src/datetime/mask.test.ts +36 -0
  233. package/src/datetime/mask.ts +84 -0
  234. package/src/editing.test.ts +22 -0
  235. package/src/editing.ts +7 -1
  236. package/src/editor-contract.test.ts +32 -0
  237. package/src/editor-contract.ts +60 -0
  238. package/src/editors/cell-editors.ts +7 -1
  239. package/src/export-data-api.test.ts +126 -0
  240. package/src/export-format.test.ts +107 -0
  241. package/src/export-format.ts +598 -0
  242. package/src/hyperformula-adapter.test.ts +35 -1
  243. package/src/hyperformula-adapter.ts +18 -6
  244. package/src/index.ts +110 -0
  245. package/src/list-option.ts +15 -0
  246. package/src/menus.ts +21 -2
  247. package/src/popover.ts +79 -0
  248. package/src/row-resize.test.ts +25 -0
  249. package/src/row-resize.ts +8 -5
  250. package/src/selection.test.ts +36 -4
  251. package/src/selection.ts +30 -9
  252. package/src/server-data-source.test.ts +201 -0
  253. package/src/server-data-source.ts +148 -0
  254. package/src/sparkline.test.ts +9 -0
  255. package/src/sparkline.ts +9 -4
  256. package/src/svgrid-wrapper.types.ts +28 -1
  257. package/src/svgrid.behavior.test.ts +27 -0
  258. package/src/svgrid.new-features.wrapper.test.ts +27 -1
  259. package/src/ui-buttons.test.ts +105 -0
  260. package/src/ui-composite.test.ts +89 -0
  261. package/src/ui-inputs.test.ts +118 -0
  262. package/src/ui-range.test.ts +61 -0
  263. package/src/ui-selection.test.ts +119 -0
@@ -0,0 +1,97 @@
1
+ <script lang="ts">
2
+ /**
3
+ * SvGauge - a radial arc gauge (SVG) that renders a value within [min, max]
4
+ * with optional colored threshold bands, a needle, and a center label. Parity:
5
+ * Smart `smart-gauge` (radial). Display control; theme-driven.
6
+ *
7
+ * The arc/needle geometry + `role="meter"` ARIA live in the headless
8
+ * `createGauge` core; this component is just one styled renderer over it.
9
+ */
10
+ import { createGauge } from './createGauge.svelte'
11
+
12
+ type Band = { from: number; to: number; color: string }
13
+
14
+ type Props = {
15
+ value?: number
16
+ min?: number
17
+ max?: number
18
+ /** Sweep angle in degrees (default 270, a classic dashboard gauge). */
19
+ sweep?: number
20
+ /** Colored threshold bands along the arc. */
21
+ bands?: Band[]
22
+ /** Show the needle. */
23
+ needle?: boolean
24
+ /** Center label (defaults to the formatted value). */
25
+ label?: string
26
+ unit?: string
27
+ size?: number
28
+ thickness?: number
29
+ formatValue?: (v: number) => string
30
+ ariaLabel?: string
31
+ }
32
+
33
+ let {
34
+ value = 0,
35
+ min = 0,
36
+ max = 100,
37
+ sweep = 270,
38
+ bands = [],
39
+ needle = true,
40
+ label,
41
+ unit = '',
42
+ size = 180,
43
+ thickness = 14,
44
+ formatValue,
45
+ ariaLabel,
46
+ }: Props = $props()
47
+
48
+ const gauge = createGauge({
49
+ value: () => value,
50
+ min: () => min,
51
+ max: () => max,
52
+ sweep: () => sweep,
53
+ size: () => size,
54
+ thickness: () => thickness,
55
+ ariaLabel: () => ariaLabel,
56
+ })
57
+ const clamped = $derived(gauge.clamped)
58
+ const cx = $derived(gauge.cx)
59
+ const cy = $derived(gauge.cy)
60
+ const r = $derived(gauge.r)
61
+ const arcPath = (v0: number, v1: number, radius: number) => gauge.arcPath(v0, v1, radius)
62
+ const needleEnd = $derived(gauge.needleEnd)
63
+ const display = $derived(label ?? `${formatValue ? formatValue(clamped) : Math.round(clamped)}${unit}`)
64
+ </script>
65
+
66
+ <div class="sv-gauge" {...gauge.rootProps()}>
67
+ <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size} class="sv-gauge__svg">
68
+ <!-- track -->
69
+ <path d={arcPath(min, max, r)} class="sv-gauge__track" fill="none" stroke-width={thickness} stroke-linecap="round" />
70
+ <!-- bands (or accent fill up to value when no bands) -->
71
+ {#if bands.length}
72
+ {#each bands as band (band.from + '-' + band.to)}
73
+ <path d={arcPath(band.from, band.to, r)} fill="none" stroke={band.color} stroke-width={thickness} stroke-linecap="round" />
74
+ {/each}
75
+ {:else}
76
+ <path d={arcPath(min, clamped, r)} class="sv-gauge__value" fill="none" stroke-width={thickness} stroke-linecap="round" />
77
+ {/if}
78
+ {#if needle}
79
+ <line x1={cx} y1={cy} x2={needleEnd.x} y2={needleEnd.y} class="sv-gauge__needle" stroke-linecap="round" />
80
+ <circle cx={cx} cy={cy} r="5" class="sv-gauge__hub" />
81
+ {/if}
82
+ </svg>
83
+ <div class="sv-gauge__label">{display}</div>
84
+ </div>
85
+
86
+ <style>
87
+ .sv-gauge { position: relative; display: inline-flex; flex-direction: column; align-items: center; color: var(--sg-fg, #0f172a); }
88
+ .sv-gauge__svg { display: block; }
89
+ .sv-gauge__track { stroke: var(--sg-border, #e2e8f0); }
90
+ .sv-gauge__value { stroke: var(--sg-accent, #2563eb); }
91
+ .sv-gauge__needle { stroke: var(--sg-fg, #0f172a); stroke-width: 3; }
92
+ .sv-gauge__hub { fill: var(--sg-fg, #0f172a); }
93
+ .sv-gauge__label {
94
+ position: absolute; left: 0; right: 0; bottom: 22%; text-align: center;
95
+ font-size: 22px; font-weight: 750; font-variant-numeric: tabular-nums;
96
+ }
97
+ </style>
@@ -0,0 +1,26 @@
1
+ type Band = {
2
+ from: number;
3
+ to: number;
4
+ color: string;
5
+ };
6
+ type Props = {
7
+ value?: number;
8
+ min?: number;
9
+ max?: number;
10
+ /** Sweep angle in degrees (default 270, a classic dashboard gauge). */
11
+ sweep?: number;
12
+ /** Colored threshold bands along the arc. */
13
+ bands?: Band[];
14
+ /** Show the needle. */
15
+ needle?: boolean;
16
+ /** Center label (defaults to the formatted value). */
17
+ label?: string;
18
+ unit?: string;
19
+ size?: number;
20
+ thickness?: number;
21
+ formatValue?: (v: number) => string;
22
+ ariaLabel?: string;
23
+ };
24
+ declare const SvGauge: import("svelte").Component<Props, {}, "">;
25
+ type SvGauge = ReturnType<typeof SvGauge>;
26
+ export default SvGauge;
@@ -225,6 +225,10 @@ export declare function createSvGridController<TFeatures extends TableFeatures =
225
225
  readonly sortDirectionByColumn: Record<string, false | "asc" | "desc">;
226
226
  readonly groupingColumns: any;
227
227
  readonly paginationState: any;
228
+ readonly externalPaginationEnabled: boolean;
229
+ readonly paginationTotalRows: number;
230
+ readonly paginationPageIndex: any;
231
+ readonly paginationPageSize: any;
228
232
  readonly getRowColumnValue: (row: Row<TData>, columnId: string) => unknown;
229
233
  readonly allRowsBeforePagination: Row<TData>[];
230
234
  readonly allRows: Row<TData>[];
@@ -327,6 +331,10 @@ export declare function createSvGridController<TFeatures extends TableFeatures =
327
331
  readonly computeRowClass: (row: Row<TData>, rowIndex: number) => string;
328
332
  readonly computeCellClass: (row: Row<TData>, column: Column<TData>) => string;
329
333
  readonly computeCellTooltip: (row: Row<TData>, column: Column<TData>) => string | null;
334
+ readonly computeCellValidity: (row: Row<TData>, column: Column<TData>) => {
335
+ invalid: boolean;
336
+ message: string | null;
337
+ };
330
338
  readonly computeCellNote: (row: Row<TData>, column: Column<TData>) => string | null;
331
339
  readonly getCellDisplayValue: (rowId: string, columnId: string, baseValue: unknown) => any;
332
340
  readonly getColumnAlign: typeof getColumnAlign;
@@ -339,7 +347,7 @@ export declare function createSvGridController<TFeatures extends TableFeatures =
339
347
  readonly computePinnedCellClass: (rowData: TData, column: Column<TData>) => string;
340
348
  readonly isRowSelected: (rowId: string) => boolean;
341
349
  readonly toggleRowSelectionById: (rowId: string) => void;
342
- readonly headerSelectionState: "none" | "all" | "some";
350
+ readonly headerSelectionState: "all" | "none" | "some";
343
351
  readonly toggleSelectAllRows: () => void;
344
352
  userHasActivatedCell: boolean;
345
353
  readonly setActiveCell: (rowIndex: number, colIndex: number) => void;
@@ -372,6 +380,12 @@ export declare function createSvGridController<TFeatures extends TableFeatures =
372
380
  colIndex: any;
373
381
  } | null;
374
382
  readonly isInFillPreview: (rowIndex: number, colIndex: number) => boolean;
383
+ readonly fillMarqueeEdges: (rowIndex: number, colIndex: number) => {
384
+ top: boolean;
385
+ bottom: boolean;
386
+ left: boolean;
387
+ right: boolean;
388
+ } | null;
375
389
  readonly findColumnById: (columnId: string) => any;
376
390
  readonly readCellRaw: (rowIndex: number, columnId: string) => unknown;
377
391
  readonly writeCellRaw: (rowIndex: number, columnId: string, value: unknown) => void;
@@ -408,7 +422,7 @@ export declare function createSvGridController<TFeatures extends TableFeatures =
408
422
  before: unknown;
409
423
  after: unknown;
410
424
  }, direction: "undo" | "redo") => void;
411
- readonly updateEditingCellValue: (value: string) => void;
425
+ readonly updateEditingCellValue: (value: unknown) => void;
412
426
  readonly onEditorKeyDown: (event: KeyboardEvent) => void;
413
427
  readonly focusOnMount: (node: HTMLInputElement | HTMLTextAreaElement) => void;
414
428
  readonly onHeaderSortClick: (event: MouseEvent, columnId: string) => void;
@@ -243,6 +243,10 @@ export function createSvGridController(props) {
243
243
  });
244
244
  let columnVirtualizerVersion = $state(0);
245
245
  let gridStateVersion = $state(0);
246
+ // Bumps only when a row-model-affecting slice changes (see the store
247
+ // subscription below) - the row-model derivation depends on THIS, not the
248
+ // catch-all gridStateVersion, so navigation doesn't rebuild 1M rows.
249
+ let dataStateVersion = $state(0);
246
250
  const selectionColumnWidth = 44;
247
251
  const rowNumberColumnWidth = $derived(props.rowNumberWidth ?? 56);
248
252
  const showRowNumbersEffective = $derived(props.showRowNumbers ?? false);
@@ -391,6 +395,10 @@ export function createSvGridController(props) {
391
395
  // the wrapper records filter state but does not actually filter rows.
392
396
  // svelte-ignore state_referenced_locally
393
397
  const externalFilterEnabled = props.externalFilter === true;
398
+ // Server-side pagination: the footer reads rowCount/pageIndex from props and
399
+ // emits onPaginationChange instead of slicing locally. Controlled by the
400
+ // consumer. Reactive (unlike sort/filter) so pageIndex/rowCount can change.
401
+ const externalPaginationEnabled = $derived(props.externalPagination === true);
394
402
  const passthroughSortedRowModel = ({ rows }) => rows;
395
403
  const grid = createSvGrid({
396
404
  get _features() {
@@ -434,9 +442,34 @@ export function createSvGridController(props) {
434
442
  activeCell: { rowIndex: 0, colIndex: 0, cellId: null },
435
443
  },
436
444
  });
445
+ // `gridStateVersion` bumps on EVERY store change (incl. moving the active
446
+ // cell). `dataStateVersion` bumps ONLY when a slice that actually changes the
447
+ // row model changes (sort / filter / pagination / grouping / expansion /
448
+ // selection) - so the O(rows) row-model derivation does NOT re-run on plain
449
+ // keyboard navigation. Without this, arrow-keying a 1,000,000-row grid re-ran
450
+ // the entire core->filter->sort->group pipeline on every keystroke.
451
+ let prevDataSlices = null;
437
452
  $effect(() => {
438
453
  const unsubscribe = grid.store.subscribe(() => {
439
454
  gridStateVersion += 1;
455
+ const s = grid.getState();
456
+ if (!prevDataSlices ||
457
+ prevDataSlices.sorting !== s.sorting ||
458
+ prevDataSlices.columnFilters !== s.columnFilters ||
459
+ prevDataSlices.pagination !== s.pagination ||
460
+ prevDataSlices.grouping !== s.grouping ||
461
+ prevDataSlices.expanded !== s.expanded ||
462
+ prevDataSlices.rowSelection !== s.rowSelection) {
463
+ dataStateVersion += 1;
464
+ prevDataSlices = {
465
+ sorting: s.sorting,
466
+ columnFilters: s.columnFilters,
467
+ pagination: s.pagination,
468
+ grouping: s.grouping,
469
+ expanded: s.expanded,
470
+ rowSelection: s.rowSelection,
471
+ };
472
+ }
440
473
  });
441
474
  return unsubscribe;
442
475
  });
@@ -707,7 +740,11 @@ export function createSvGridController(props) {
707
740
  * filters reduce the dataset.
708
741
  */
709
742
  const allRowsBeforePagination = $derived.by(() => {
710
- gridStateVersion;
743
+ // Depend on dataStateVersion (row-model-affecting store changes) NOT
744
+ // gridStateVersion - so moving the active cell / selection does not force
745
+ // this O(rows) pipeline to re-run. Filter-input state (globalFilter etc.)
746
+ // and internalData are read below and tracked as their own dependencies.
747
+ dataStateVersion;
711
748
  // Touch internalData + internalColumns so the row model re-derives when
712
749
  // the consumer replaces the data array (e.g. via a "Reset" button).
713
750
  void internalData;
@@ -794,7 +831,8 @@ export function createSvGridController(props) {
794
831
  */
795
832
  const allRows = $derived.by(() => {
796
833
  const rows = allRowsBeforePagination;
797
- if (!paginationEnabled)
834
+ // External pagination: `data` already IS the current page - never slice.
835
+ if (!paginationEnabled || externalPaginationEnabled)
798
836
  return rows;
799
837
  const { pageIndex, pageSize } = paginationState;
800
838
  const start = pageIndex * pageSize;
@@ -802,8 +840,9 @@ export function createSvGridController(props) {
802
840
  });
803
841
  // When a filter reduces the dataset, the stored pageIndex can point beyond
804
842
  // the last valid page. Reset to page 0 so the grid never shows a blank body.
843
+ // Skipped for external pagination, where the consumer owns pageIndex.
805
844
  $effect(() => {
806
- if (!paginationEnabled)
845
+ if (!paginationEnabled || externalPaginationEnabled)
807
846
  return;
808
847
  const { pageIndex, pageSize } = paginationState;
809
848
  const pageCount = Math.ceil(allRowsBeforePagination.length / pageSize);
@@ -811,6 +850,11 @@ export function createSvGridController(props) {
811
850
  grid.setPagination({ pageIndex: 0, pageSize });
812
851
  }
813
852
  });
853
+ // Footer-facing pagination values. In external mode they come from the
854
+ // consumer-controlled props; otherwise from the local row model + state.
855
+ const paginationTotalRows = $derived(externalPaginationEnabled ? (props.rowCount ?? 0) : allRowsBeforePagination.length);
856
+ const paginationPageIndex = $derived(externalPaginationEnabled ? (props.pageIndex ?? 0) : paginationState.pageIndex);
857
+ const paginationPageSize = $derived(externalPaginationEnabled ? (props.pageSize ?? 10) : paginationState.pageSize);
814
858
  const rowSelectionState = $derived.by(() => {
815
859
  gridStateVersion;
816
860
  return grid.getState().rowSelection ?? {};
@@ -1179,9 +1223,14 @@ export function createSvGridController(props) {
1179
1223
  const SUMMARY_DEFER_CELL_LIMIT = 50000;
1180
1224
  let summaryByColumn = $state({});
1181
1225
  $effect(() => {
1182
- // Re-aggregate whenever the visible data, columns, edits, or any
1183
- // state that reorders/filters rows changes.
1184
- gridStateVersion;
1226
+ // Re-aggregate whenever the data / columns / edits change. We depend on
1227
+ // `allRows` / `allColumns` / `editedCellValues` DIRECTLY - not the
1228
+ // catch-all `gridStateVersion` - because that version bumps on EVERY store
1229
+ // change, including moving the active cell or selection. `allRows` stays
1230
+ // referentially stable across those (sort/filter/paginate produce a new
1231
+ // rows array; navigation does not), so this now skips the
1232
+ // O(rows x cols) aggregation on plain keyboard navigation - which was
1233
+ // making arrow-key movement crawl on huge grids (e.g. 1,000,000 rows).
1185
1234
  void editedCellValues;
1186
1235
  const rows = allRows;
1187
1236
  const columns = allColumns;
@@ -1776,6 +1825,10 @@ export function createSvGridController(props) {
1776
1825
  get sortDirectionByColumn() { return sortDirectionByColumn; },
1777
1826
  get groupingColumns() { return groupingColumns; },
1778
1827
  get paginationState() { return paginationState; },
1828
+ get externalPaginationEnabled() { return externalPaginationEnabled; },
1829
+ get paginationTotalRows() { return paginationTotalRows; },
1830
+ get paginationPageIndex() { return paginationPageIndex; },
1831
+ get paginationPageSize() { return paginationPageSize; },
1779
1832
  get getRowColumnValue() { return getRowColumnValue; },
1780
1833
  get allRowsBeforePagination() { return allRowsBeforePagination; },
1781
1834
  get allRows() { return allRows; },
@@ -1841,6 +1894,7 @@ export function createSvGridController(props) {
1841
1894
  get computeRowClass() { return computeRowClass; },
1842
1895
  get computeCellClass() { return computeCellClass; },
1843
1896
  get computeCellTooltip() { return computeCellTooltip; },
1897
+ get computeCellValidity() { return computeCellValidity; },
1844
1898
  get computeCellNote() { return computeCellNote; },
1845
1899
  get getCellDisplayValue() { return getCellDisplayValue; },
1846
1900
  get getColumnAlign() { return getColumnAlign; },
@@ -1876,6 +1930,7 @@ export function createSvGridController(props) {
1876
1930
  get getSelectionRects() { return getSelectionRects; },
1877
1931
  get fillHandleCell() { return fillHandleCell; },
1878
1932
  get isInFillPreview() { return isInFillPreview; },
1933
+ get fillMarqueeEdges() { return fillMarqueeEdges; },
1879
1934
  get findColumnById() { return findColumnById; },
1880
1935
  get readCellRaw() { return readCellRaw; },
1881
1936
  get writeCellRaw() { return writeCellRaw; },
@@ -1969,9 +2024,9 @@ export function createSvGridController(props) {
1969
2024
  const { onGridKeyDown, onWindowKeydown, onHeaderSortClick } = createKeyboard(ctx);
1970
2025
  const { computeSummaries, hasRenderedColumn } = createSummaries(ctx);
1971
2026
  const { updateFilterRow, updateFilterOperator, updateFilterMenuValue, updateFilterMenuValueTo, toggleCheckboxWithKeyboard, isColumnFiltered, closeMenus, openChooseColumns, openColumnMenu, openFilterMenu, openOperatorMenu, sortColumnFromMenu, clearColumnSort, groupByColumnFromMenu, clearGroupingFromMenu, isFacetChecked, toggleFacetValue, isAllFacetsChecked, toggleAllFacets, clearColumnFilter, changePage, goToPage, setPageSize, openContextMenu, closeContextMenu, contextMenuItems, saveComment, removeComment, closeCommentEditor } = createMenus(ctx);
1972
- const { cellConditionalFormat, computeRowClass, computeCellClass, computeCellTooltip, computeCellNote, getColumnEditorOptions, formatListCellValue, formatCellValue, formatPinnedValue, computePinnedCellClass } = createCellRender(ctx);
2027
+ const { cellConditionalFormat, computeRowClass, computeCellClass, computeCellTooltip, computeCellValidity, computeCellNote, getColumnEditorOptions, formatListCellValue, formatCellValue, formatPinnedValue, computePinnedCellClass } = createCellRender(ctx);
1973
2028
  const { isCellEditable, isCellEditableAt, getRowColumnValue, getCellDisplayValue, startEditingWithChar, startEditing, stopEditing, startFullRowEdit, setFullRowDraft, commitFullRowEdit, cancelFullRowEdit, saveEditingCell, applyHistoryStep, updateEditingCellValue, onEditorKeyDown, focusOnMount, onCellDoubleClick, pasteFromClipboard, onGridPaste } = createEditing(ctx);
1974
- const { isRowSelected, toggleRowSelectionById, toggleSelectAllRows, setActiveCell, scrollActiveCellIntoView, setSelection, extendSelection, isCellInSelectedRange, getCellRangeEdges, getSelectionRects, isInFillPreview, findColumnById, onCellPointerDown, onCellPointerEnter, endDragSelection, onWindowPointerMove, onCellClick, emitCellDoubleClick } = createSelection(ctx);
2029
+ const { isRowSelected, toggleRowSelectionById, toggleSelectAllRows, setActiveCell, scrollActiveCellIntoView, setSelection, extendSelection, isCellInSelectedRange, getCellRangeEdges, getSelectionRects, isInFillPreview, fillMarqueeEdges, findColumnById, onCellPointerDown, onCellPointerEnter, endDragSelection, onWindowPointerMove, onCellClick, emitCellDoubleClick } = createSelection(ctx);
1975
2030
  const { cellPinStyle, isColumnPinned, getCurrentColumnOrder, emitColumnOrder, setColumnOrderInternal, applyColumnDrop, onColumnHeaderDragStart, onColumnHeaderDragOver, onColumnHeaderDragLeave, onColumnHeaderDrop, onColumnHeaderDragEnd, pinColumnLeft, pinColumnRight, unpinColumn, toggleColumnVisibleInPanel, moveColumnInPanel, toggleGroupInPanel, getColumnBaseWidth, getColumnWidth, startColumnResize, onColumnResizeMove, endColumnResize, measureText, autosizeColumn, autosizeAllColumns, resetColumns } = createColumns(ctx);
1976
2031
  const { onRowDragStart, onRowDragOver, onRowDragLeave, onRowDrop, onRowsContainerDragOver, onRowsContainerDrop, onRowDragEnd } = createRowDrag(ctx);
1977
2032
  const { register: registerAlignedGrid, broadcastScroll: broadcastAlignedScroll, broadcastWidths: broadcastAlignedWidths } = createAlignedGrids(ctx);
package/dist/SvGrid.css CHANGED
@@ -348,9 +348,13 @@
348
348
  .sv-grid-table tr > :last-child.sv-grid-cell {
349
349
  border-right: 0;
350
350
  }
351
- /* Row hover tint. */
352
- .sv-grid-table tbody tr:hover > .sv-grid-cell {
353
- background: var(--sg-row-hover-bg, #eef2ff);
351
+ /* Row hover tint - opt-in via `enableRowHover` (off by default; the class is
352
+ present unless the grid opts in). Uses `background-color` (not the shorthand)
353
+ so it never resets the fill-marquee `background-image`, and skips selected
354
+ cells so the selection stays visible under a hovered row. */
355
+ .sv-grid-table:not(.sv-grid-no-row-hover)
356
+ tbody tr:hover > .sv-grid-cell:not([data-selected-range="true"]) {
357
+ background-color: var(--sg-row-hover-bg, #eef2ff);
354
358
  }
355
359
  /* Only the active cell + the cell hosting the fill handle become a
356
360
  positioning context (so the absolutely-positioned handle anchors
@@ -441,8 +445,10 @@
441
445
  ),
442
446
  var(--sg-pinned-bg, color-mix(in oklab, var(--sg-header-bg, #f1f5f9) 92%, var(--sg-accent, #2563eb) 8%));
443
447
  }
444
- /* Hovered row keeps the pinned tint distinguishable from the hover. */
445
- .sv-grid-row:hover > .sv-grid-cell[data-pinned] {
448
+ /* Hovered row keeps the pinned tint distinguishable from the hover. Selected
449
+ cells are excluded so the selection stays visible under hover. */
450
+ .sv-grid-table:not(.sv-grid-no-row-hover)
451
+ .sv-grid-row:hover > .sv-grid-cell[data-pinned]:not([data-selected-range="true"]) {
446
452
  background:
447
453
  linear-gradient(
448
454
  color-mix(in srgb, var(--sg-row-hover-bg, #eef2ff) 55%, transparent),
@@ -1062,18 +1068,52 @@ select.sv-grid-fr-editor {
1062
1068
  transform-origin: bottom right;
1063
1069
  }
1064
1070
 
1065
- /* Fill-preview overlay paints an accent border on the cells the user is
1066
- about to fill. Source cells (still in the selection range) keep their
1067
- normal range styling. The border + tint derive from the theme accent
1068
- (`--sg-accent`) so they match each theme instead of a fixed blue;
1069
- `--sg-fill-preview-border` / `--sg-fill-preview-bg` let a theme override
1070
- them directly. */
1071
- .sv-grid-cell[data-fill-preview="true"] {
1072
- box-shadow: inset 0 0 0 2px
1073
- var(--sg-fill-preview-border,
1074
- color-mix(in srgb, var(--sg-accent, #0b63f3) 50%, transparent));
1075
- background: var(--sg-fill-preview-bg,
1076
- color-mix(in srgb, var(--sg-accent, #0b63f3) 8%, transparent));
1071
+ /* Excel-style fill-handle drag marquee: ONE thin dashed rectangle around the
1072
+ whole target range (source + fill-into area), not a thick per-cell border or
1073
+ fill tint. Drawn as four background-image layers on the boundary cells - no
1074
+ `border`, so it paints on the compositor with zero reflow while dragging.
1075
+ `--sg-fill-marquee` overrides the colour (defaults to a theme-aware grey). */
1076
+ /* Step 1 (LOW specificity): default every edge layer to `none`, then light up
1077
+ the edges this cell sits on. These are custom properties, which the
1078
+ `background:` shorthands on selected / zebra cells do NOT reset - so they can
1079
+ safely live at low specificity and just compete with each other by source
1080
+ order (gradient rules come after the defaults, so they win). */
1081
+ .sv-grid-cell[data-fill-top="true"],
1082
+ .sv-grid-cell[data-fill-bottom="true"],
1083
+ .sv-grid-cell[data-fill-left="true"],
1084
+ .sv-grid-cell[data-fill-right="true"] {
1085
+ --sv-fill-top: none;
1086
+ --sv-fill-bottom: none;
1087
+ --sv-fill-left: none;
1088
+ --sv-fill-right: none;
1089
+ /* Match the selection colour (the grid accent) by default. */
1090
+ --sv-fill-color: var(--sg-fill-marquee, var(--sg-accent, #2563eb));
1091
+ }
1092
+ .sv-grid-cell[data-fill-top="true"] {
1093
+ --sv-fill-top: repeating-linear-gradient(to right, var(--sv-fill-color) 0 3px, transparent 3px 6px);
1094
+ }
1095
+ .sv-grid-cell[data-fill-bottom="true"] {
1096
+ --sv-fill-bottom: repeating-linear-gradient(to right, var(--sv-fill-color) 0 3px, transparent 3px 6px);
1097
+ }
1098
+ .sv-grid-cell[data-fill-left="true"] {
1099
+ --sv-fill-left: repeating-linear-gradient(to bottom, var(--sv-fill-color) 0 3px, transparent 3px 6px);
1100
+ }
1101
+ .sv-grid-cell[data-fill-right="true"] {
1102
+ --sv-fill-right: repeating-linear-gradient(to bottom, var(--sv-fill-color) 0 3px, transparent 3px 6px);
1103
+ }
1104
+ /* Step 2 (HIGH specificity, `.sv-grid-table` prefix): compose the resolved edge
1105
+ layers into `background-image` so it beats the `background:` shorthands on
1106
+ selected / zebra / hover cells (which would otherwise reset background-image).
1107
+ The cell keeps its background-COLOR; this only adds the dashed lines on top. */
1108
+ .sv-grid-table .sv-grid-cell[data-fill-top="true"],
1109
+ .sv-grid-table .sv-grid-cell[data-fill-bottom="true"],
1110
+ .sv-grid-table .sv-grid-cell[data-fill-left="true"],
1111
+ .sv-grid-table .sv-grid-cell[data-fill-right="true"] {
1112
+ background-image: var(--sv-fill-top), var(--sv-fill-bottom),
1113
+ var(--sv-fill-left), var(--sv-fill-right);
1114
+ background-repeat: no-repeat;
1115
+ background-size: 100% 2px, 100% 2px, 2px 100%, 2px 100%;
1116
+ background-position: top left, bottom left, top left, top right;
1077
1117
  }
1078
1118
 
1079
1119
  .sv-grid-cell-editing {
@@ -1338,6 +1378,17 @@ select.sv-grid-fr-editor {
1338
1378
  .sv-grid-cell-cf {
1339
1379
  position: relative;
1340
1380
  }
1381
+ /* Declarative cell validation (column `validate` hook). Invalid cells get a
1382
+ * soft red wash and a red inset ring - Handsontable's `htInvalid` look. The
1383
+ * value keeps rendering as-is; the message (if any) shows as the tooltip. */
1384
+ .sv-grid-cell-invalid {
1385
+ background-color: var(--sg-invalid-bg, rgba(239, 68, 68, 0.14)) !important;
1386
+ box-shadow: inset 0 0 0 1px var(--sg-invalid-border, rgba(239, 68, 68, 0.45));
1387
+ color: var(--sg-invalid-fg, #b91c1c);
1388
+ }
1389
+ .sv-grid-cell-invalid.sv-grid-cell-active {
1390
+ box-shadow: inset 0 0 0 2px var(--sg-invalid-border, rgba(239, 68, 68, 0.7));
1391
+ }
1341
1392
  .sv-grid-status-bar {
1342
1393
  display: flex;
1343
1394
  flex-wrap: wrap;
@@ -2103,32 +2154,34 @@ select.sv-grid-fr-editor {
2103
2154
  color: var(--sg-fg, #0f172a);
2104
2155
  font-size: 13px;
2105
2156
  }
2157
+ /* Top-positioned pager: rounded + bordered on the top edge instead. */
2158
+ .sv-grid-pagination-top {
2159
+ border-top: 1px solid var(--sg-border, #e2e8f0);
2160
+ border-bottom: 0;
2161
+ border-radius: var(--sg-radius, 6px) var(--sg-radius, 6px) 0 0;
2162
+ }
2106
2163
  .sv-grid-pagination-pagesize {
2107
2164
  display: inline-flex;
2108
2165
  align-items: center;
2109
2166
  gap: 8px;
2110
2167
  color: var(--sg-muted, #64748b);
2111
2168
  }
2112
- .sv-grid-pagination-pagesize select {
2169
+ .sv-grid-pagination-pagesize-dd {
2170
+ position: relative;
2113
2171
  height: 28px;
2114
- padding: 0 22px 0 8px;
2172
+ min-width: 62px;
2115
2173
  border: 1px solid var(--sg-input-border, #cbd5e1);
2116
2174
  border-radius: 5px;
2117
2175
  background: var(--sg-input-bg, #fff);
2118
- color: var(--sg-fg, #0f172a);
2119
- font: inherit;
2176
+ }
2177
+ .sv-grid-pagination-pagesize-dd .sv-grid-dropdown,
2178
+ .sv-grid-pagination-pagesize-dd .sv-grid-dropdown-trigger {
2179
+ background: transparent;
2180
+ border-radius: 5px;
2120
2181
  font-size: 13px;
2121
- cursor: pointer;
2122
- appearance: none;
2123
- -webkit-appearance: none;
2124
- background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
2125
- linear-gradient(135deg, currentColor 50%, transparent 50%);
2126
- background-position: calc(100% - 12px) 12px, calc(100% - 8px) 12px;
2127
- background-size: 4px 4px, 4px 4px;
2128
- background-repeat: no-repeat;
2182
+ color: var(--sg-fg, #0f172a);
2129
2183
  }
2130
- .sv-grid-pagination-pagesize select:focus {
2131
- outline: none;
2184
+ .sv-grid-pagination-pagesize-dd:focus-within {
2132
2185
  border-color: var(--sg-accent, #2563eb);
2133
2186
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--sg-accent, #2563eb) 30%, transparent);
2134
2187
  }
@@ -12,6 +12,10 @@ export declare function getCellKey(rowId: string, columnId: string): string;
12
12
  export declare function resolveClassList(value: string | ReadonlyArray<string> | Record<string, boolean> | undefined | null): string;
13
13
  export declare function toDateInputValue(value: unknown): string;
14
14
  export declare function toDateTimeLocalInputValue(value: unknown): string;
15
+ /** 'HH:MM[:SS]' string (or Date) to a Date carrying that time (today's date). */
16
+ export declare function timeStringToDate(value: unknown): Date | null;
17
+ /** A Date to an 'HH:MM' string (the `time` editor's stored form). */
18
+ export declare function dateToTimeString(d: Date | null): string | null;
15
19
  export declare function getEditableInputValue(editorType: CellEditorType, value: unknown): string;
16
20
  export declare function getEditorInputType(editorType: CellEditorType): "number" | "date" | "text" | "time" | "password" | "color" | "datetime-local";
17
21
  /** Resolve a stored value to an array form (for list/chips multi-select). */
@@ -57,25 +57,52 @@ export function toDateTimeLocalInputValue(value) {
57
57
  return "";
58
58
  return parsed.toISOString().slice(0, 16);
59
59
  }
60
+ /** Strip the `-native` opt-out suffix so the native-input helpers treat
61
+ * `date-native` exactly like `date` (the rich pickers own the bare types). */
62
+ function baseEditor(editorType) {
63
+ return String(editorType).replace(/-native$/, "");
64
+ }
65
+ /** 'HH:MM[:SS]' string (or Date) to a Date carrying that time (today's date). */
66
+ export function timeStringToDate(value) {
67
+ if (value instanceof Date)
68
+ return value;
69
+ if (typeof value === "string") {
70
+ const m = value.match(/^(\d{1,2}):(\d{2})(?::(\d{2}))?/);
71
+ if (m) {
72
+ const d = new Date();
73
+ d.setHours(Math.min(23, +m[1]), Math.min(59, +m[2]), m[3] ? +m[3] : 0, 0);
74
+ return d;
75
+ }
76
+ }
77
+ return null;
78
+ }
79
+ /** A Date to an 'HH:MM' string (the `time` editor's stored form). */
80
+ export function dateToTimeString(d) {
81
+ if (!d)
82
+ return null;
83
+ return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
84
+ }
60
85
  export function getEditableInputValue(editorType, value) {
61
- if (editorType === "date")
86
+ const base = baseEditor(editorType);
87
+ if (base === "date")
62
88
  return toDateInputValue(value);
63
- if (editorType === "datetime")
89
+ if (base === "datetime")
64
90
  return toDateTimeLocalInputValue(value);
65
91
  return String(value ?? "");
66
92
  }
67
93
  export function getEditorInputType(editorType) {
68
- if (editorType === "number")
94
+ const base = baseEditor(editorType);
95
+ if (base === "number")
69
96
  return "number";
70
- if (editorType === "date")
97
+ if (base === "date")
71
98
  return "date";
72
- if (editorType === "datetime")
99
+ if (base === "datetime")
73
100
  return "datetime-local";
74
- if (editorType === "time")
101
+ if (base === "time")
75
102
  return "time";
76
- if (editorType === "password")
103
+ if (base === "password")
77
104
  return "password";
78
- if (editorType === "color")
105
+ if (base === "color")
79
106
  return "color";
80
107
  return "text";
81
108
  }
@@ -111,13 +138,14 @@ export function colorfulChipStyle(color) {
111
138
  `color: color-mix(in srgb, ${color} 80%, var(--sg-fg, #0f172a));`);
112
139
  }
113
140
  export function getEditorClass(editorType) {
114
- if (editorType === "number")
141
+ const base = baseEditor(editorType);
142
+ if (base === "number")
115
143
  return "sv-grid-cell-editor sv-grid-cell-editor-number";
116
- if (editorType === "date")
144
+ if (base === "date")
117
145
  return "sv-grid-cell-editor sv-grid-cell-editor-date";
118
- if (editorType === "datetime")
146
+ if (base === "datetime")
119
147
  return "sv-grid-cell-editor sv-grid-cell-editor-datetime";
120
- if (editorType === "color")
148
+ if (base === "color")
121
149
  return "sv-grid-cell-editor sv-grid-cell-editor-color";
122
150
  return "sv-grid-cell-editor";
123
151
  }