@svgrid/enterprise 3.0.2 → 3.1.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 (364) hide show
  1. package/LICENSE +94 -24
  2. package/README.md +36 -4
  3. package/dist/SvAdvancedFilter.svelte +1 -1
  4. package/dist/SvAlertsManager.svelte +2 -1
  5. package/dist/SvBoard.svelte +2 -1
  6. package/dist/SvExportMenu.svelte +4 -1
  7. package/dist/SvExportMenu.svelte.d.ts +0 -13
  8. package/dist/SvExpressionEditor.svelte +3 -3
  9. package/dist/SvFormulaBar.svelte +94 -20
  10. package/dist/SvFormulaBar.svelte.d.ts +7 -0
  11. package/dist/SvGridAlerts.svelte +49 -9
  12. package/dist/SvGridBoard.svelte +13 -8
  13. package/dist/SvGridBulkEditDrawer.svelte +26 -2
  14. package/dist/SvGridEditPanel.svelte +3 -0
  15. package/dist/SvGridScheduler.svelte +69 -40
  16. package/dist/SvGridSelectionBar.svelte +10 -3
  17. package/dist/SvPivotDesigner.svelte +198 -40
  18. package/dist/SvPivotDesigner.svelte.d.ts +27 -20
  19. package/dist/SvSheet.svelte +4043 -243
  20. package/dist/SvSheet.svelte.d.ts +76 -3
  21. package/dist/SvSheetChartSetup.svelte +151 -0
  22. package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
  23. package/dist/SvSheetComment.svelte +216 -31
  24. package/dist/SvSheetComment.svelte.d.ts +11 -11
  25. package/dist/SvSheetConditionalFormat.svelte +28 -31
  26. package/dist/SvSheetDataValidation.svelte +66 -42
  27. package/dist/SvSheetEditRanges.svelte +217 -0
  28. package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
  29. package/dist/SvSheetErrors.svelte +125 -0
  30. package/dist/SvSheetErrors.svelte.d.ts +20 -0
  31. package/dist/SvSheetEvaluate.svelte +133 -0
  32. package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
  33. package/dist/SvSheetFilterMenu.svelte +137 -34
  34. package/dist/SvSheetFilterMenu.svelte.d.ts +5 -0
  35. package/dist/SvSheetFindReplace.svelte +19 -19
  36. package/dist/SvSheetFormatCells.svelte +125 -81
  37. package/dist/SvSheetGoalSeek.svelte +17 -16
  38. package/dist/SvSheetInsertFunction.svelte +15 -13
  39. package/dist/SvSheetIteration.svelte +81 -0
  40. package/dist/SvSheetIteration.svelte.d.ts +10 -0
  41. package/dist/SvSheetLink.svelte +99 -0
  42. package/dist/SvSheetLink.svelte.d.ts +17 -0
  43. package/dist/SvSheetListPicker.svelte +4 -2
  44. package/dist/SvSheetListPicker.svelte.d.ts +0 -6
  45. package/dist/SvSheetManageRules.svelte +20 -18
  46. package/dist/SvSheetNameManager.svelte +17 -15
  47. package/dist/SvSheetPageSetup.svelte +159 -0
  48. package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
  49. package/dist/SvSheetPasteSpecial.svelte +22 -20
  50. package/dist/SvSheetPivot.svelte +220 -0
  51. package/dist/SvSheetPivot.svelte.d.ts +21 -0
  52. package/dist/SvSheetProtectSheet.svelte +81 -0
  53. package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
  54. package/dist/SvSheetRemoveDuplicates.svelte +13 -10
  55. package/dist/SvSheetRibbon.svelte +104 -51
  56. package/dist/SvSheetSizeDialog.svelte +4 -2
  57. package/dist/SvSheetSort.svelte +218 -0
  58. package/dist/SvSheetSort.svelte.d.ts +28 -0
  59. package/dist/SvSheetSparklines.svelte +135 -0
  60. package/dist/SvSheetSparklines.svelte.d.ts +14 -0
  61. package/dist/SvSheetTable.svelte +160 -0
  62. package/dist/SvSheetTable.svelte.d.ts +24 -0
  63. package/dist/SvSheetTabs.svelte +161 -31
  64. package/dist/SvSheetTabs.svelte.d.ts +22 -8
  65. package/dist/SvSheetTextToColumns.svelte +20 -20
  66. package/dist/SvSheetValidationAlert.svelte +8 -6
  67. package/dist/advanced-filter-enable.js +1 -1
  68. package/dist/alerts/alert-engine.d.ts +6 -0
  69. package/dist/alerts/alert-engine.js +21 -4
  70. package/dist/alerts/alert-formats.js +2 -0
  71. package/dist/alerts/alert-types.d.ts +1 -1
  72. package/dist/alerts.d.ts +1 -1
  73. package/dist/alerts.js +2 -2
  74. package/dist/board.js +2 -2
  75. package/dist/bulk-edit.d.ts +3 -1
  76. package/dist/bulk-edit.js +1 -1
  77. package/dist/cdn/svgrid-enterprise.svelte-external.js +39827 -16429
  78. package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
  79. package/dist/designer/assets/{SvChartMenu-D9hEeHar.js → SvChartMenu-BDoeqGz6.js} +1 -1
  80. package/dist/designer/assets/{SvDateTimePicker-DARvKUL2.js → SvDateTimePicker-DCPg7WGN.js} +1 -1
  81. package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
  82. package/dist/designer/assets/{SvGridChart-B8j1SSy3.js → SvGridChart-Cy1ATrWh.js} +2 -2
  83. package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
  84. package/dist/designer/assets/{SvGridChartPanel-pT6ITc2P.js → SvGridChartPanel-CATdVc9X.js} +3 -3
  85. package/dist/designer/assets/{SvGridChartView-bg281UA1.js → SvGridChartView-CmsZtCED.js} +1 -1
  86. package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
  87. package/dist/designer/assets/{SvTabs-UFCMTHXS.js → SvTabs-2mHC6oaz.js} +1 -1
  88. package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
  89. package/dist/designer/assets/{chart-cIPUsbM5.js → chart-Cn7MnNqA.js} +1 -1
  90. package/dist/designer/assets/{chart-panel-messages-DtTxpBUU.js → chart-panel-messages-Dz7PTIqT.js} +1 -1
  91. package/dist/designer/assets/{chart-summary-Czu_5epb.js → chart-summary-BD1qYB2R.js} +1 -1
  92. package/dist/designer/assets/{chart-trend-D5I5VEe8.js → chart-trend-B8xr5LuD.js} +1 -1
  93. package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
  94. package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
  95. package/dist/designer/assets/{focus-trap-CAreAhlU.js → focus-trap-V2-6Fy9I.js} +1 -1
  96. package/dist/designer/assets/{index-DwU7CAMm.js → index-BSjv6Qec.js} +317 -315
  97. package/dist/designer/assets/index-_JVFxt02.css +1 -0
  98. package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
  99. package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
  100. package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
  101. package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
  102. package/dist/designer/index.html +17 -16
  103. package/dist/export-pdf.d.ts +75 -0
  104. package/dist/export-pdf.js +216 -15
  105. package/dist/export.js +10 -2
  106. package/dist/gantt/SvGridGantt.svelte +2890 -0
  107. package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
  108. package/dist/gantt/gantt-config.d.ts +73 -0
  109. package/dist/gantt/gantt-config.js +1 -0
  110. package/dist/gantt/gantt-critical-path.d.ts +67 -0
  111. package/dist/gantt/gantt-critical-path.js +207 -0
  112. package/dist/gantt/gantt-model.d.ts +257 -0
  113. package/dist/gantt/gantt-model.js +651 -0
  114. package/dist/gantt/gantt-resources.d.ts +59 -0
  115. package/dist/gantt/gantt-resources.js +71 -0
  116. package/dist/gantt/gantt.d.ts +7 -0
  117. package/dist/gantt/gantt.js +36 -0
  118. package/dist/gantt/index.d.ts +15 -0
  119. package/dist/gantt/index.js +22 -0
  120. package/dist/gantt/timeline-arrows.d.ts +102 -0
  121. package/dist/gantt/timeline-arrows.js +181 -0
  122. package/dist/import.d.ts +2 -2
  123. package/dist/import.js +1 -1
  124. package/dist/index.d.ts +34 -7
  125. package/dist/index.js +44 -7
  126. package/dist/install.js +8 -1
  127. package/dist/license-core.d.ts +17 -1
  128. package/dist/license-core.js +16 -5
  129. package/dist/license.d.ts +18 -2
  130. package/dist/license.js +71 -6
  131. package/dist/node/studio.js +140 -8
  132. package/dist/pivot-enable.js +2 -2
  133. package/dist/scheduler-dependencies.d.ts +35 -0
  134. package/dist/scheduler-dependencies.js +36 -1
  135. package/dist/scheduler.js +2 -2
  136. package/dist/selection-bar.js +2 -2
  137. package/dist/server/SvGroupCell.svelte +213 -0
  138. package/dist/server/SvGroupCell.svelte.d.ts +62 -0
  139. package/dist/server/SvRowGroupPanel.svelte +322 -0
  140. package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
  141. package/dist/server/enable.d.ts +17 -0
  142. package/dist/server/enable.js +49 -0
  143. package/dist/server/index.d.ts +22 -0
  144. package/dist/server/index.js +24 -0
  145. package/dist/server/messages.d.ts +45 -0
  146. package/dist/server/messages.js +35 -0
  147. package/dist/server/server-group-model.d.ts +104 -0
  148. package/dist/server/server-group-model.js +272 -0
  149. package/dist/server/server-pivot.d.ts +46 -0
  150. package/dist/server/server-pivot.js +57 -0
  151. package/dist/server/server-row-model.d.ts +547 -0
  152. package/dist/server/server-row-model.js +1551 -0
  153. package/dist/server/server-selection.d.ts +99 -0
  154. package/dist/server/server-selection.js +215 -0
  155. package/dist/server/svgrid-adapter.d.ts +155 -0
  156. package/dist/server/svgrid-adapter.js +202 -0
  157. package/dist/sheet/ast.d.ts +45 -1
  158. package/dist/sheet/ast.js +14 -0
  159. package/dist/sheet/auto-filter.d.ts +58 -4
  160. package/dist/sheet/auto-filter.js +159 -11
  161. package/dist/sheet/autocomplete.d.ts +9 -0
  162. package/dist/sheet/autocomplete.js +90 -4
  163. package/dist/sheet/cell-images.d.ts +39 -0
  164. package/dist/sheet/cell-images.js +90 -0
  165. package/dist/sheet/cell-types.d.ts +58 -0
  166. package/dist/sheet/cell-types.js +96 -0
  167. package/dist/sheet/coerce.d.ts +40 -0
  168. package/dist/sheet/coerce.js +170 -3
  169. package/dist/sheet/comments.d.ts +43 -9
  170. package/dist/sheet/comments.js +85 -27
  171. package/dist/sheet/conditional-formats.d.ts +29 -6
  172. package/dist/sheet/conditional-formats.js +37 -12
  173. package/dist/sheet/csv.d.ts +32 -0
  174. package/dist/sheet/csv.js +158 -0
  175. package/dist/sheet/culture.d.ts +87 -0
  176. package/dist/sheet/culture.js +247 -0
  177. package/dist/sheet/delta.d.ts +102 -0
  178. package/dist/sheet/delta.js +203 -0
  179. package/dist/sheet/deps.d.ts +45 -1
  180. package/dist/sheet/deps.js +77 -2
  181. package/dist/sheet/document.d.ts +106 -4
  182. package/dist/sheet/document.js +204 -3
  183. package/dist/sheet/engine.d.ts +67 -0
  184. package/dist/sheet/engine.js +19 -0
  185. package/dist/sheet/entry.d.ts +8 -4
  186. package/dist/sheet/entry.js +171 -21
  187. package/dist/sheet/error-check.d.ts +49 -0
  188. package/dist/sheet/error-check.js +83 -0
  189. package/dist/sheet/evaluate-steps.d.ts +48 -0
  190. package/dist/sheet/evaluate-steps.js +196 -0
  191. package/dist/sheet/evaluate.d.ts +67 -0
  192. package/dist/sheet/evaluate.js +725 -13
  193. package/dist/sheet/filter-files.d.ts +37 -0
  194. package/dist/sheet/filter-files.js +465 -0
  195. package/dist/sheet/format-store.d.ts +15 -0
  196. package/dist/sheet/format-store.js +11 -1
  197. package/dist/sheet/from-rows.d.ts +14 -0
  198. package/dist/sheet/from-rows.js +50 -0
  199. package/dist/sheet/function-catalog.d.ts +1 -1
  200. package/dist/sheet/function-catalog.js +296 -5
  201. package/dist/sheet/functions.js +363 -91
  202. package/dist/sheet/index.d.ts +35 -8
  203. package/dist/sheet/index.js +35 -8
  204. package/dist/sheet/links.d.ts +57 -0
  205. package/dist/sheet/links.js +174 -0
  206. package/dist/sheet/messages.d.ts +778 -0
  207. package/dist/sheet/messages.js +806 -0
  208. package/dist/sheet/number-format.d.ts +52 -5
  209. package/dist/sheet/number-format.js +465 -68
  210. package/dist/sheet/objects.d.ts +106 -0
  211. package/dist/sheet/objects.js +149 -0
  212. package/dist/sheet/ods-document.d.ts +44 -0
  213. package/dist/sheet/ods-document.js +1275 -0
  214. package/dist/sheet/open-file.d.ts +26 -0
  215. package/dist/sheet/open-file.js +56 -0
  216. package/dist/sheet/outline.d.ts +82 -0
  217. package/dist/sheet/outline.js +228 -0
  218. package/dist/sheet/packs/array.d.ts +16 -0
  219. package/dist/sheet/packs/array.js +172 -0
  220. package/dist/sheet/packs/database.d.ts +42 -0
  221. package/dist/sheet/packs/database.js +142 -0
  222. package/dist/sheet/packs/engineering.d.ts +2 -0
  223. package/dist/sheet/packs/engineering.js +296 -0
  224. package/dist/sheet/packs/financial.d.ts +5 -0
  225. package/dist/sheet/packs/financial.js +220 -0
  226. package/dist/sheet/packs/math-stats.d.ts +2 -0
  227. package/dist/sheet/packs/math-stats.js +372 -0
  228. package/dist/sheet/packs/special.d.ts +44 -0
  229. package/dist/sheet/packs/special.js +187 -0
  230. package/dist/sheet/packs/stats-dist.d.ts +2 -0
  231. package/dist/sheet/packs/stats-dist.js +785 -0
  232. package/dist/sheet/packs/text-date.d.ts +2 -0
  233. package/dist/sheet/packs/text-date.js +332 -0
  234. package/dist/sheet/packs/trig.d.ts +2 -0
  235. package/dist/sheet/packs/trig.js +73 -0
  236. package/dist/sheet/page-setup.d.ts +73 -0
  237. package/dist/sheet/page-setup.js +73 -0
  238. package/dist/sheet/parse.js +42 -10
  239. package/dist/sheet/paste-special.d.ts +22 -0
  240. package/dist/sheet/paste-special.js +14 -5
  241. package/dist/sheet/pivot-range.d.ts +160 -0
  242. package/dist/sheet/pivot-range.js +333 -0
  243. package/dist/sheet/presence.d.ts +73 -0
  244. package/dist/sheet/presence.js +79 -0
  245. package/dist/sheet/print.d.ts +104 -0
  246. package/dist/sheet/print.js +169 -0
  247. package/dist/sheet/protection.d.ts +55 -1
  248. package/dist/sheet/protection.js +55 -2
  249. package/dist/sheet/rects.d.ts +1 -1
  250. package/dist/sheet/refs.d.ts +48 -0
  251. package/dist/sheet/refs.js +155 -8
  252. package/dist/sheet/ribbon-icons.d.ts +1 -1
  253. package/dist/sheet/ribbon-icons.js +186 -0
  254. package/dist/sheet/ribbon.d.ts +1 -1
  255. package/dist/sheet/ribbon.js +324 -23
  256. package/dist/sheet/sheet-kinds.d.ts +74 -0
  257. package/dist/sheet/sheet-kinds.js +91 -0
  258. package/dist/sheet/shortcuts.d.ts +13 -3
  259. package/dist/sheet/shortcuts.js +63 -12
  260. package/dist/sheet/sort.d.ts +51 -0
  261. package/dist/sheet/sort.js +107 -0
  262. package/dist/sheet/sparklines.d.ts +111 -0
  263. package/dist/sheet/sparklines.js +204 -0
  264. package/dist/sheet/table-styles.d.ts +74 -0
  265. package/dist/sheet/table-styles.js +152 -0
  266. package/dist/sheet/tables.d.ts +19 -0
  267. package/dist/sheet/tables.js +31 -0
  268. package/dist/sheet/tokenize.d.ts +18 -1
  269. package/dist/sheet/tokenize.js +60 -9
  270. package/dist/sheet/validation.d.ts +16 -0
  271. package/dist/sheet/validation.js +37 -0
  272. package/dist/sheet/workbook.d.ts +148 -3
  273. package/dist/sheet/workbook.js +742 -31
  274. package/dist/sheet/xls-cfb.d.ts +32 -0
  275. package/dist/sheet/xls-cfb.js +290 -0
  276. package/dist/sheet/xls-document.d.ts +10 -0
  277. package/dist/sheet/xls-document.js +1243 -0
  278. package/dist/sheet/xls-formula.d.ts +40 -0
  279. package/dist/sheet/xls-formula.js +569 -0
  280. package/dist/sheet/xlsx-document.d.ts +108 -0
  281. package/dist/sheet/xlsx-document.js +1849 -0
  282. package/dist/sheet/xlsx-drawing.d.ts +99 -0
  283. package/dist/sheet/xlsx-drawing.js +420 -0
  284. package/dist/sheet-enable.js +6 -7
  285. package/dist/sheet-text.d.ts +7 -0
  286. package/dist/sheet-text.js +29 -0
  287. package/dist/sources/auth-supabase.js +2 -2
  288. package/dist/sources/realtime-supabase.js +2 -2
  289. package/dist/sources/rest.d.ts +6 -2
  290. package/dist/sources/rest.js +42 -7
  291. package/dist/sources/supabase.d.ts +10 -1
  292. package/dist/sources/supabase.js +73 -40
  293. package/dist/studio/emit-project.js +14 -1
  294. package/dist/studio/index.js +1 -1
  295. package/dist/studio/project.d.ts +11 -2
  296. package/dist/studio/project.js +5 -2
  297. package/dist/studio/ui-components.generated.js +107 -2
  298. package/dist/sveltekit/in-memory.d.ts +2 -2
  299. package/dist/sveltekit/in-memory.js +125 -4
  300. package/dist/sveltekit/index.d.ts +1 -1
  301. package/dist/sveltekit/index.js +1 -1
  302. package/dist/sveltekit/query-plan.d.ts +50 -4
  303. package/dist/sveltekit/query-plan.js +25 -3
  304. package/dist/sveltekit/sql-source.d.ts +6 -0
  305. package/dist/sveltekit/sql-source.js +34 -6
  306. package/dist/sveltekit/sql.d.ts +31 -0
  307. package/dist/sveltekit/sql.js +135 -25
  308. package/dist/sveltekit/transport.d.ts +10 -2
  309. package/dist/sveltekit/transport.js +30 -6
  310. package/dist/upgrade-prompt.d.ts +1 -1
  311. package/dist/version.d.ts +1 -1
  312. package/dist/version.js +1 -1
  313. package/dist/watermark.js +35 -2
  314. package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
  315. package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
  316. package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
  317. package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
  318. package/dist/wc/SvField-B_kurx_P.js +149 -0
  319. package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
  320. package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
  321. package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
  322. package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
  323. package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
  324. package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
  325. package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
  326. package/dist/wc/SvModal-DrfOYYyX.js +189 -0
  327. package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
  328. package/dist/wc/chart-6OXlybVT.js +4341 -0
  329. package/dist/wc/chart-export-CeSADGfi.js +135 -0
  330. package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
  331. package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
  332. package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
  333. package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
  334. package/dist/wc/client-DQIzjDBG.js +3064 -0
  335. package/dist/wc/column-resize-DUPgynvc.js +101 -0
  336. package/dist/wc/date-format-DS-z_h9v.js +1130 -0
  337. package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
  338. package/dist/wc/editor-contract-peBDxir_.js +22 -0
  339. package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
  340. package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
  341. package/dist/wc/list-option-DrRyivWp.js +82 -0
  342. package/dist/wc/popover-WsGlvtQv.js +69 -0
  343. package/dist/wc/positioning-BiKLfu1E.js +112 -0
  344. package/dist/wc/react.d.ts +41 -0
  345. package/dist/wc/react.js +90 -0
  346. package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
  347. package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
  348. package/dist/wc/row-resize-limG_N1z.js +111 -0
  349. package/dist/wc/sv-sheet-element.d.ts +97 -0
  350. package/dist/wc/sv-sheet-element.js +44213 -0
  351. package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
  352. package/dist/wc/validate-BqDthkNr.js +88 -0
  353. package/dist/wc/vue.d.ts +31 -0
  354. package/dist/wc/vue.js +75 -0
  355. package/package.json +30 -5
  356. package/dist/designer/assets/GridMenus-BlsvL_aU.js +0 -8
  357. package/dist/designer/assets/SvGridCellEditor-C7uQXYds.js +0 -4
  358. package/dist/designer/assets/SvGridChartBuilder-kvyIU_Rl.js +0 -1
  359. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
  360. package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
  361. package/dist/designer/assets/index-CMFgAoVV.css +0 -1
  362. package/dist/designer/assets/row-resize-DLktcqUK.js +0 -1
  363. package/dist/designer/assets/src-EdI3Xqds.js +0 -58
  364. package/dist/designer/assets/validate-h-aslRV9.js +0 -1
@@ -24,6 +24,7 @@
24
24
  import { applyAlertEvents, type FlashTarget } from './alerts/alert-engine-attach'
25
25
  import { rulesToConditionalFormats } from './alerts/alert-formats'
26
26
  import { alertStore } from './alerts/alert-store.svelte'
27
+ import { createScheduler, type Schedule } from './scheduling'
27
28
  import {
28
29
  createAlertRules,
29
30
  localStorageAlertRules,
@@ -100,19 +101,37 @@
100
101
  onJump,
101
102
  }: Props = $props()
102
103
 
103
- const manager: AlertRulesManager = createAlertRules(
104
- storageKey ? localStorageAlertRules(storageKey) : memoryAlertRules(),
104
+ // The store is chosen and seeded once, from the props' first values: a
105
+ // storage key does not move at runtime and the seed is only for an empty
106
+ // store.
107
+ const manager: AlertRulesManager = untrack(() =>
108
+ createAlertRules(storageKey ? localStorageAlertRules(storageKey) : memoryAlertRules()),
105
109
  )
106
- // Seed once if the store is empty.
107
- if (initialRules.length && manager.list().length === 0) {
108
- for (const r of initialRules) manager.save(r)
109
- }
110
+ untrack(() => {
111
+ if (initialRules.length && manager.list().length === 0) {
112
+ for (const r of initialRules) manager.save(r)
113
+ }
114
+ })
110
115
 
111
116
  let rules = $state<AlertRule[]>(manager.list())
112
117
  let rulesVersion = $state(0)
113
- let flashFormats = $state<ConditionalFormat<TRow>[]>([])
118
+ // Raw on purpose: a flash is removed by identity 900 ms later, and a deep
119
+ // proxy never equals the object that was pushed, so the flashes never went.
120
+ let flashFormats = $state.raw<ConditionalFormat<TRow>[]>([])
114
121
 
115
- const engine = createAlertEngine<TRow>({ rules, getRowId, getValue, locale })
122
+ // The engine and the observer are built once; `getRowId`, `getValue` and
123
+ // `locale` are props that may change after mount, so they go in as
124
+ // closures and getters that read the current value rather than a copy of
125
+ // the first one.
126
+ const rowIdOf = (row: TRow) => getRowId(row)
127
+ const engine = createAlertEngine<TRow>({
128
+ // The first list; later lists reach the observer through the
129
+ // rulesVersion effect below.
130
+ rules: untrack(() => rules),
131
+ getRowId: rowIdOf,
132
+ get getValue() { return getValue },
133
+ get locale() { return locale },
134
+ })
116
135
 
117
136
  // The observer owns all scheduling + change tracking. It runs evaluation on a
118
137
  // post-paint frame (never inside the grid's render flush) and only clones prev
@@ -132,7 +151,7 @@
132
151
 
133
152
  const observer = createAlertObserver<TRow>({
134
153
  engine,
135
- getRowId,
154
+ getRowId: rowIdOf,
136
155
  schedule: 'raf',
137
156
  onEvents: (events) => {
138
157
  const { flashes } = applyAlertEvents(events, getRowId, { shouldToast: allowToast })
@@ -142,6 +161,27 @@
142
161
 
143
162
  let seededVersion = -1
144
163
 
164
+ // A `scheduled` rule is re-checked on its cron by the enterprise scheduler
165
+ // rather than on a data change: on each fire the pass lists every row the
166
+ // predicate matches at that moment, whether or not anything moved. The
167
+ // scheduler is rebuilt when the rules change, and stopped with the overlay.
168
+ $effect(() => {
169
+ void rulesVersion
170
+ const scheduled = rules.filter((r): r is AlertRule & { trigger: { type: 'scheduled'; schedule: Schedule } } => r.enabled && r.trigger.type === 'scheduled')
171
+ if (scheduled.length === 0) return
172
+ const scheduler = createScheduler({
173
+ schedules: scheduled.map((r) => ({ ...r.trigger.schedule, id: r.id })),
174
+ onFire: (schedule) => {
175
+ const events = engine.evaluateScheduled(schedule.id, untrack(() => data))
176
+ if (events.length === 0) return
177
+ const { flashes } = applyAlertEvents(events, getRowId, { shouldToast: allowToast })
178
+ for (const f of flashes) addFlash(f)
179
+ },
180
+ })
181
+ scheduler.start()
182
+ return () => scheduler.stop()
183
+ })
184
+
145
185
  function addFlash(target: FlashTarget) {
146
186
  const fmt: ConditionalFormat<TRow> = {
147
187
  type: 'rule',
@@ -12,7 +12,7 @@
12
12
  // as a per-row overlay keyed by row id, so consumers write no move code;
13
13
  // `onCardMove` fires purely as a notification for persistence / mirroring
14
14
  // Themes entirely from the grid's `--sg-*` tokens.
15
- import { tick } from "svelte";
15
+ import { tick, untrack } from "svelte";
16
16
  import type {
17
17
  ColumnDef,
18
18
  RowData,
@@ -165,10 +165,11 @@
165
165
  collapsedSwim: { ...collapsedSwim },
166
166
  };
167
167
  }
168
- // Restore once at init (before first paint).
169
- if (board.persistKey && getRowId && typeof localStorage !== "undefined") {
168
+ // Restore once at init (before first paint), from the first persistKey.
169
+ const persistKey = untrack(() => (getRowId ? board.persistKey : undefined));
170
+ if (persistKey && typeof localStorage !== "undefined") {
170
171
  try {
171
- const raw = localStorage.getItem(board.persistKey);
172
+ const raw = localStorage.getItem(persistKey);
172
173
  if (raw) {
173
174
  const s = JSON.parse(raw);
174
175
  laneOf = s.laneOf ?? {};
@@ -1264,6 +1265,8 @@
1264
1265
  style={lane.color ? `--sv-board-accent: ${lane.color};` : undefined}
1265
1266
  aria-label={laneTitle(lane)}
1266
1267
  >
1268
+ <!-- A reorderable lane header is a keyboard handle (Ctrl+arrows move the lane). -->
1269
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
1267
1270
  <!-- svelte-ignore a11y_no_static_element_interactions -->
1268
1271
  <header
1269
1272
  class="sv-board-lane-head"
@@ -1344,7 +1347,9 @@
1344
1347
  <div
1345
1348
  class="sv-board-lane-body"
1346
1349
  class:is-virtual={virtualized}
1347
- role="list"
1350
+ role="listbox"
1351
+ tabindex="-1"
1352
+ aria-multiselectable={board.selectable ? true : undefined}
1348
1353
  class:is-dropover={overLane === lane.id && overSwim === swimId}
1349
1354
  use:trackLane={cellKey(lane.id, swimId)}
1350
1355
  ondragover={(e) => onLaneDragOver(e, lane.id, swimId)}
@@ -1359,7 +1364,7 @@
1359
1364
  <div class="sv-board-drop-marker" aria-hidden="true"></div>
1360
1365
  {/if}
1361
1366
  {@const isEditing = editingKey === key(row)}
1362
- <article
1367
+ <div
1363
1368
  class="sv-board-card"
1364
1369
  class:is-dragging={dragRow === row}
1365
1370
  class:is-grabbed={grabbed === row}
@@ -1367,7 +1372,7 @@
1367
1372
  class:is-flagged={isFlagged(row)}
1368
1373
  class:is-locked={!movable(row)}
1369
1374
  class:is-selected={board.selectable && selected[key(row)]}
1370
- role="listitem"
1375
+ role="option"
1371
1376
  tabindex="0"
1372
1377
  data-card-key={key(row)}
1373
1378
  aria-roledescription="Draggable card"
@@ -1531,7 +1536,7 @@
1531
1536
  {@render commentThread(row)}
1532
1537
  </div>
1533
1538
  {/if}
1534
- </article>
1539
+ </div>
1535
1540
  {/each}
1536
1541
  {#if win.bottom > 0}
1537
1542
  <div style={`height:${win.bottom}px`} aria-hidden="true"></div>
@@ -35,7 +35,17 @@
35
35
 
36
36
  const messages = $derived(ctrl.messages)
37
37
  const columns = $derived(bulkEditableFields(ctrl) as BulkEditField[])
38
- const count = $derived((ctrl.selectionBarTarget?.ids ?? []).length as number)
38
+ const count = $derived(
39
+ ((ctrl.selectionBarCount as number | undefined) ?? (ctrl.selectionBarTarget?.ids ?? []).length) as number,
40
+ )
41
+ // A selection model with `bulkUpdate` owns the write: the rule it stores
42
+ // covers rows this grid never loaded, which writing the loaded cells
43
+ // would silently miss.
44
+ const remoteUpdate = $derived(
45
+ (ctrl.props?.rowSelectionModel?.bulkUpdate ?? null) as
46
+ | ((patch: Record<string, unknown>) => Promise<number>)
47
+ | null,
48
+ )
39
49
 
40
50
  /** A column's editor type mapped onto the form's control vocabulary. */
41
51
  function controlFor(editorType: string, hasOptions: boolean): FormFieldType {
@@ -85,7 +95,8 @@
85
95
  })),
86
96
  )
87
97
 
88
- const fill = (t: string, n: number) => t.replace(/\{count\}/g, String(n))
98
+ const locale = $derived(ctrl.props?.localization?.locale as string | string[] | undefined)
99
+ const fill = (t: string, n: number) => t.replace(/\{count\}/g, n.toLocaleString(locale))
89
100
 
90
101
  function submit(values: Record<string, unknown>) {
91
102
  const byId = new Map(columns.map((c) => [c.id, c]))
@@ -100,6 +111,19 @@
100
111
  if (mixed.has(name) && (raw === '' || raw == null)) continue
101
112
  edits[name] = next
102
113
  }
114
+ if (remoteUpdate) {
115
+ // Keyed by field, not column id: the write goes to the datasource.
116
+ const byField: Record<string, unknown> = {}
117
+ for (const [columnId, value] of Object.entries(edits)) {
118
+ const field = byId.get(columnId)?.field
119
+ if (field) byField[field] = value
120
+ }
121
+ open = false
122
+ void remoteUpdate(byField).then((changed) =>
123
+ onApplied?.({ changed, skipped: 0, fields: Object.keys(byField).length }),
124
+ )
125
+ return
126
+ }
103
127
  const result = applyBulkEdit(ctrl, edits)
104
128
  open = false
105
129
  onApplied?.(result)
@@ -715,6 +715,9 @@
715
715
  (no scrollbar), unlike an in-flow popup. -->
716
716
  <div class="sv-ep-field__dropdown">
717
717
  <SvGridDropdown
718
+ id={`sv-ef-${f.field}`}
719
+ invalid={!!err}
720
+ {describedBy}
718
721
  options={selectOptions(f)}
719
722
  value={values[f.field]}
720
723
  autoOpen={false}
@@ -78,6 +78,7 @@
78
78
  } from "@svgrid/grid";
79
79
  // Scheduler Pro feature models (this package).
80
80
  import { cascade, violations, type SchedulerDependency } from "./scheduler-dependencies";
81
+ import { arrowHeadPath, dependencyArrows, type Arrow } from "./gantt/timeline-arrows";
81
82
  import { expandAssignments, resourceLoad, type SchedulerAssignment } from "./scheduler-assignments";
82
83
  import { columnSummaries } from "./scheduler-summary";
83
84
  import { buildAxis, timeToX, xToTime, resolveZoom, zoomPresets, type Axis, type ZoomLevel } from "./scheduler-axis";
@@ -568,33 +569,18 @@
568
569
  }
569
570
  return { byKey, height: top };
570
571
  });
571
- // SVG path + state for each dependency arrow (elbow connector, pred finish -> succ start).
572
- const tlDepArrows = $derived.by(() => {
573
- if (!isTimeline || !hasDeps) return [] as Array<{ id: string; d: string; bad: boolean; hx: number; hy: number }>;
574
- const rects = tlBarRects.byKey;
575
- const bad = new Set(depViolations.map((d) => d.id));
576
- const out: Array<{ id: string; d: string; bad: boolean; hx: number; hy: number }> = [];
577
- for (const dep of depList) {
578
- const a = rects.get(dep.from);
579
- const b = rects.get(dep.to);
580
- if (!a || !b) continue;
581
- const type = dep.type ?? "FS";
582
- const x1 = type === "SS" || type === "SF" ? a.left : a.right;
583
- const x2 = type === "FF" || type === "SF" ? b.right : b.left;
584
- out.push({ id: dep.id, d: depElbow(x1, a.midY, x2, b.midY), bad: bad.has(dep.id), hx: x2, hy: b.midY });
585
- }
586
- return out;
572
+ // SVG path + state for each dependency arrow (elbow connector, pred finish ->
573
+ // succ start). The geometry lives in ./gantt/timeline-arrows, shared with the
574
+ // Gantt chart so the two views draw the same link the same way.
575
+ const tlDepArrows = $derived.by<Arrow[]>(() => {
576
+ if (!isTimeline || !hasDeps) return [];
577
+ return dependencyArrows(
578
+ tlBarRects.byKey,
579
+ depList,
580
+ new Set(depViolations.map((d) => d.id)),
581
+ tlLaneH,
582
+ );
587
583
  });
588
- // Orthogonal elbow connector between two anchor points; loops around when the
589
- // successor sits left of the predecessor (a backward / violating link).
590
- function depElbow(x1: number, y1: number, x2: number, y2: number): string {
591
- const s = 10;
592
- const p = x1 + s;
593
- if (x2 >= p) return `M${x1},${y1} L${p},${y1} L${p},${y2} L${x2},${y2}`;
594
- const q = x2 - s;
595
- const midY = y2 >= y1 ? y1 + tlLaneH : y1 - tlLaneH;
596
- return `M${x1},${y1} L${p},${y1} L${p},${midY} L${q},${midY} L${q},${y2} L${x2},${y2}`;
597
- }
598
584
  // Cascade successors forward after a move / resize, writing the shifts into the
599
585
  // overlay and reporting them (never mutating source rows).
600
586
  function cascadeDeps(movedKey: string, ns: Date, ne: Date) {
@@ -602,7 +588,9 @@
602
588
  const times = new Map<string, { start: Date; end: Date }>();
603
589
  for (const [k, v] of depTimes) times.set(k, v);
604
590
  times.set(movedKey, { start: ns, end: ne });
605
- const shifts = cascade(times, depList, { snapForward: depSnapForward });
591
+ // Successors only: the moved event stays where it was dropped, and a link
592
+ // it now breaks is drawn as violated rather than the drop being undone.
593
+ const shifts = cascade(times, depList, { from: [movedKey], snapForward: depSnapForward });
606
594
  if (!shifts.size) return;
607
595
  const moves: Array<{ id: string; start: Date; end: Date }> = [];
608
596
  for (const [k, t] of shifts) {
@@ -882,16 +870,45 @@
882
870
  return monthWeekSegments(rowEvents, gridDays[0] ?? anchor);
883
871
  });
884
872
 
885
- const monthWeeks = $derived(monthMatrix(anchor, weekStartsOn, 6));
873
+ // `monthMatrix` returns exactly the rows it is asked for, because the date
874
+ // picker wants a grid that keeps its height as you page through the months.
875
+ // A full-page calendar wants the opposite: September 2026 spans five weeks,
876
+ // and a sixth row of October dates only takes height away from the five that
877
+ // carry the month - enough, at this demo's size, to cost every cell a lane.
878
+ // So trailing rows that are entirely outside the month are dropped. Only
879
+ // trailing rows can be: the first row always holds the 1st.
880
+ const monthWeeks = $derived.by(() => {
881
+ const weeks = monthMatrix(anchor, weekStartsOn, 6);
882
+ let used = weeks.length;
883
+ while (used > 1 && weeks[used - 1]!.every((cell) => !cell.inMonth)) used--;
884
+ return used === weeks.length ? weeks : weeks.slice(0, used);
885
+ });
886
886
  const agenda = $derived(agendaGroups(viewEvents));
887
887
 
888
888
  // --- month spanning-bar layout ---
889
889
  const MONTH_DAYNUM_H = 22; // px reserved at the top of each cell for the date
890
890
  const MONTH_LANE_H = 20; // px per event-bar lane
891
891
  const MONTH_MORE_H = 16; // px reserved for the "+N more" row
892
+ // The floor a week row never shrinks past, fed to the CSS below so the two
893
+ // cannot drift apart. It is the sum above rather than a round number on
894
+ // purpose: it is exactly the height that still shows the date, one lane and
895
+ // the "+N more" that reaches the rest, so every event stays reachable at the
896
+ // floor. It used to be a flat 84, which is taller than six rows of a short
897
+ // body can be - so a month that needs six (August 2026, say) pushed its last
898
+ // row past the bottom of a `overflow: visible` box, and the 31st could not
899
+ // be seen or scrolled to. Rows shrink to fit now, and the body scrolls only
900
+ // if even the floor does not.
901
+ const MONTH_WEEK_MIN_H = MONTH_DAYNUM_H + MONTH_LANE_H + MONTH_MORE_H;
892
902
  let monthBodyH = $state(0);
893
903
  const visibleMonthLanes = $derived.by(() => {
894
- const weekH = monthBodyH / Math.max(1, monthWeeks.length);
904
+ // A week row is `flex: 1 1 0` with that min-height, so its real height is
905
+ // the larger of the two - the rows only divide the body evenly while the
906
+ // body is tall enough for all of them. Dividing unconditionally
907
+ // under-counts the lanes and puts a "+N more" in cells with a whole lane
908
+ // of empty space below it. September 2026 did exactly that: 418px over
909
+ // six rows reads as 69px and one lane, while every row really was 84px
910
+ // and fit two.
911
+ const weekH = Math.max(MONTH_WEEK_MIN_H, monthBodyH / Math.max(1, monthWeeks.length));
895
912
  return Math.max(1, Math.floor((weekH - MONTH_DAYNUM_H - MONTH_MORE_H) / MONTH_LANE_H));
896
913
  });
897
914
  // Events hidden (beyond the visible lanes) that cover a given day column.
@@ -1971,6 +1988,9 @@
1971
1988
  e.preventDefault();
1972
1989
  const s = new Date(ev.start.getTime() + dDay * 86400000 + dMin * 60000);
1973
1990
  const en = new Date(ev.end.getTime() + dDay * 86400000 + dMin * 60000);
1991
+ // The same booking rules as a drag: an arrow key must not land an event
1992
+ // on another one, outside the working hours or on a blocked day.
1993
+ if (bookingBlocked(s, en, ev.resourceId, ev.rowKey, ev.row)) return;
1974
1994
  startOfE[ev.rowKey] = s;
1975
1995
  endOfE[ev.rowKey] = en;
1976
1996
  emitMove({ row: ev.row, start: s, end: en, allDay: ev.allDay, toResource: ev.resourceId });
@@ -3191,9 +3211,9 @@
3191
3211
  {/if}
3192
3212
  {#if zoomOn && proAxisData}
3193
3213
  <div class="sv-sched-slots sv-sched-zoom" role="group" aria-label="Zoom">
3194
- <button type="button" class="sv-sched-btn sv-sched-btn-slot" onclick={() => stepZoom(-1)} aria-label="Zoom in">-</button>
3214
+ <button type="button" class="sv-sched-btn sv-sched-btn-slot" onclick={() => stepZoom(1)} aria-label="Zoom out">-</button>
3195
3215
  <span class="sv-sched-zoom-label">{proAxisData.level?.label ?? "Zoom"}</span>
3196
- <button type="button" class="sv-sched-btn sv-sched-btn-slot" onclick={() => stepZoom(1)} aria-label="Zoom out">+</button>
3216
+ <button type="button" class="sv-sched-btn sv-sched-btn-slot" onclick={() => stepZoom(-1)} aria-label="Zoom in">+</button>
3197
3217
  </div>
3198
3218
  {/if}
3199
3219
  {#each views as v (v)}
@@ -3266,7 +3286,7 @@
3266
3286
  <div class="sv-sched-dow">{wd(dowIdx)}</div>
3267
3287
  {/each}
3268
3288
  </div>
3269
- <div class="sv-sched-monthbody" bind:clientHeight={monthBodyH}>
3289
+ <div class="sv-sched-monthbody" style={`--sv-sched-week-min-h:${MONTH_WEEK_MIN_H}px`} bind:clientHeight={monthBodyH}>
3270
3290
  {#each monthWeeks as week, wi (wi)}
3271
3291
  {@const weekStart = week[0]!.date}
3272
3292
  {@const seg = monthWeekSegments(viewEvents, weekStart)}
@@ -3428,7 +3448,7 @@
3428
3448
  <path
3429
3449
  class="sv-sched-dep-arrow"
3430
3450
  class:sv-sched-dep-bad={arr.bad}
3431
- d={`M${arr.hx},${arr.hy} l-6,-3.5 l0,7 z`}
3451
+ d={arrowHeadPath(arr.hx, arr.hy, arr.dir)}
3432
3452
  />
3433
3453
  {/each}
3434
3454
  </svg>
@@ -4272,8 +4292,16 @@
4272
4292
  border-bottom: 1px solid var(--sg-border, #e5e7eb);
4273
4293
  text-align: right;
4274
4294
  }
4275
- .sv-sched-monthbody { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
4276
- .sv-sched-week { position: relative; display: grid; grid-template-columns: repeat(7, 1fr); flex: 1 1 0; min-height: 84px; }
4295
+ /* `auto`, not `visible`: the rows shrink to fit, so this only ever engages
4296
+ when the body is shorter than the rows' own floor - and then a scrollbar
4297
+ is the difference between a day you can reach and one that is simply
4298
+ painted outside the box. */
4299
+ .sv-sched-monthbody { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow-y: auto; }
4300
+ /* min-height comes from MONTH_WEEK_MIN_H: the lane count reads the same
4301
+ floor, so a change here that did not reach the script would put "+N more"
4302
+ in cells that have room for the bar. The rows are `flex: 1 1 0`, so they
4303
+ grow to fill a tall body and shrink to this floor in a short one. */
4304
+ .sv-sched-week { position: relative; display: grid; grid-template-columns: repeat(7, 1fr); flex: 1 1 0; min-height: var(--sv-sched-week-min-h, 58px); }
4277
4305
  .sv-sched-daycell {
4278
4306
  position: relative;
4279
4307
  border-right: 1px solid var(--sg-border, #e5e7eb);
@@ -5149,14 +5177,15 @@
5149
5177
  .sv-sched-dep-arrow {
5150
5178
  fill: var(--sv-sched-dep, color-mix(in srgb, var(--sg-fg, #1f2937) 45%, transparent));
5151
5179
  }
5152
- .sv-sched-dep-line.sv-sched-dep-bad,
5153
- .sv-sched-dep-arrow.sv-sched-dep-bad {
5154
- stroke: var(--sv-sched-dep-bad, #dc2626);
5155
- fill: var(--sv-sched-dep-bad, #dc2626);
5156
- }
5180
+ /* The line keeps `fill: none` - a fill on the elbow path paints the polygon
5181
+ it encloses, and a violated link showed up as a solid red slab. */
5157
5182
  .sv-sched-dep-line.sv-sched-dep-bad {
5183
+ stroke: var(--sv-sched-dep-bad, #dc2626);
5158
5184
  stroke-dasharray: 4 3;
5159
5185
  }
5186
+ .sv-sched-dep-arrow.sv-sched-dep-bad {
5187
+ fill: var(--sv-sched-dep-bad, #dc2626);
5188
+ }
5160
5189
  /* Resource utilization histogram (Scheduler Pro) - a subtle meter strip at the
5161
5190
  bottom of each resource row, clearly separated from the event lanes above. */
5162
5191
  .sv-sched-hist {
@@ -27,7 +27,13 @@
27
27
  }
28
28
 
29
29
  const target = $derived(ctrl.selectionBarTarget as Target)
30
- const count = $derived(target.ids.length)
30
+ // The count the controller resolved: a selection model that stores the
31
+ // rule knows about rows the grid never loaded, so "1,000,000 selected"
32
+ // is honest even with twenty rows on screen.
33
+ const count = $derived((ctrl.selectionBarCount as number | undefined) ?? target.ids.length)
34
+ // Grouped the way the grid's own numbers are: 1,000,000, not 1000000.
35
+ const locale = $derived(ctrl.props?.localization?.locale as string | string[] | undefined)
36
+ const countText = $derived(count.toLocaleString(locale))
31
37
  const messages = $derived(ctrl.messages)
32
38
  const position = $derived(ctrl.selectionBarPosition as 'top' | 'bottom')
33
39
  const maxVisible = $derived(ctrl.selectionBarMaxVisible as number)
@@ -85,7 +91,7 @@
85
91
  let overflowOpen = $state(false)
86
92
  let barEl = $state<HTMLElement | null>(null)
87
93
 
88
- const fill = (template: string, n: number) => template.replace(/\{count\}/g, String(n))
94
+ const fill = (template: string, n: number) => template.replace(/\{count\}/g, n.toLocaleString(locale))
89
95
  const clearSelection = () => ctrl.grid.setRowSelection(() => ({}))
90
96
 
91
97
  function run(a: Action) {
@@ -138,12 +144,13 @@
138
144
  class="sv-selbar"
139
145
  data-position={position}
140
146
  role="toolbar"
147
+ tabindex="-1"
141
148
  aria-label={messages.selectionBarLabel}
142
149
  aria-orientation="horizontal"
143
150
  onkeydown={onKeydown}
144
151
  >
145
152
  <span class="sv-selbar-count" aria-live="polite">
146
- <span class="sv-selbar-chip">{count}</span>
153
+ <span class="sv-selbar-chip">{countText}</span>
147
154
  <span class="sv-selbar-count-label">{messages.selectionBarCount}</span>
148
155
  </span>
149
156