@svgrid/enterprise 3.0.1 → 3.0.3

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 (445) 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 +680 -0
  10. package/dist/SvFormulaBar.svelte.d.ts +69 -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 +263 -54
  18. package/dist/SvPivotDesigner.svelte.d.ts +27 -20
  19. package/dist/SvRibbonIcon.svelte +46 -0
  20. package/dist/SvRibbonIcon.svelte.d.ts +17 -0
  21. package/dist/SvSchemaChart.svelte +4 -2
  22. package/dist/SvSheet.svelte +7914 -0
  23. package/dist/SvSheet.svelte.d.ts +215 -0
  24. package/dist/SvSheetChartSetup.svelte +151 -0
  25. package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
  26. package/dist/SvSheetComment.svelte +283 -0
  27. package/dist/SvSheetComment.svelte.d.ts +22 -0
  28. package/dist/SvSheetConditionalFormat.svelte +159 -0
  29. package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
  30. package/dist/SvSheetDataValidation.svelte +273 -0
  31. package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
  32. package/dist/SvSheetEditRanges.svelte +217 -0
  33. package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
  34. package/dist/SvSheetErrors.svelte +125 -0
  35. package/dist/SvSheetErrors.svelte.d.ts +20 -0
  36. package/dist/SvSheetEvaluate.svelte +133 -0
  37. package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
  38. package/dist/SvSheetFilterMenu.svelte +320 -0
  39. package/dist/SvSheetFilterMenu.svelte.d.ts +22 -0
  40. package/dist/SvSheetFindReplace.svelte +132 -0
  41. package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
  42. package/dist/SvSheetFormatCells.svelte +465 -0
  43. package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
  44. package/dist/SvSheetGoalSeek.svelte +145 -0
  45. package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
  46. package/dist/SvSheetInsertFunction.svelte +149 -0
  47. package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
  48. package/dist/SvSheetIteration.svelte +81 -0
  49. package/dist/SvSheetIteration.svelte.d.ts +10 -0
  50. package/dist/SvSheetLink.svelte +99 -0
  51. package/dist/SvSheetLink.svelte.d.ts +17 -0
  52. package/dist/SvSheetListPicker.svelte +91 -0
  53. package/dist/SvSheetListPicker.svelte.d.ts +10 -0
  54. package/dist/SvSheetManageRules.svelte +187 -0
  55. package/dist/SvSheetManageRules.svelte.d.ts +16 -0
  56. package/dist/SvSheetNameManager.svelte +227 -0
  57. package/dist/SvSheetNameManager.svelte.d.ts +11 -0
  58. package/dist/SvSheetPageSetup.svelte +159 -0
  59. package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
  60. package/dist/SvSheetPasteSpecial.svelte +107 -0
  61. package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
  62. package/dist/SvSheetPivot.svelte +220 -0
  63. package/dist/SvSheetPivot.svelte.d.ts +21 -0
  64. package/dist/SvSheetProtectSheet.svelte +81 -0
  65. package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
  66. package/dist/SvSheetRemoveDuplicates.svelte +152 -0
  67. package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
  68. package/dist/SvSheetRibbon.svelte +1254 -0
  69. package/dist/SvSheetRibbon.svelte.d.ts +34 -0
  70. package/dist/SvSheetSizeDialog.svelte +60 -0
  71. package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
  72. package/dist/SvSheetSort.svelte +218 -0
  73. package/dist/SvSheetSort.svelte.d.ts +28 -0
  74. package/dist/SvSheetSparklines.svelte +135 -0
  75. package/dist/SvSheetSparklines.svelte.d.ts +14 -0
  76. package/dist/SvSheetTable.svelte +160 -0
  77. package/dist/SvSheetTable.svelte.d.ts +24 -0
  78. package/dist/SvSheetTabs.svelte +571 -0
  79. package/dist/SvSheetTabs.svelte.d.ts +50 -0
  80. package/dist/SvSheetTabs.test-harness.svelte.d.ts +17 -0
  81. package/dist/SvSheetTabs.test-harness.svelte.js +22 -0
  82. package/dist/SvSheetTextToColumns.svelte +172 -0
  83. package/dist/SvSheetTextToColumns.svelte.d.ts +13 -0
  84. package/dist/SvSheetValidationAlert.svelte +85 -0
  85. package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
  86. package/dist/advanced-filter-enable.js +1 -1
  87. package/dist/alerts/alert-engine.d.ts +6 -0
  88. package/dist/alerts/alert-engine.js +21 -4
  89. package/dist/alerts/alert-formats.js +2 -0
  90. package/dist/alerts/alert-types.d.ts +1 -1
  91. package/dist/alerts.d.ts +1 -1
  92. package/dist/alerts.js +2 -2
  93. package/dist/board.js +2 -2
  94. package/dist/bulk-edit.d.ts +3 -1
  95. package/dist/bulk-edit.js +1 -1
  96. package/dist/cdn/svgrid-enterprise.svelte-external.js +43538 -6539
  97. package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
  98. package/dist/designer/assets/SvChartMenu-BDoeqGz6.js +1 -0
  99. package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
  100. package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
  101. package/dist/designer/assets/SvDateTimePicker-DCPg7WGN.js +1 -0
  102. package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
  103. package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
  104. package/dist/designer/assets/SvGridChart-Cy1ATrWh.js +3 -0
  105. package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
  106. package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
  107. package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
  108. package/dist/designer/assets/SvGridChartPanel-CATdVc9X.js +4 -0
  109. package/dist/designer/assets/{SvGridChartView-DUc-1RUf.css → SvGridChartView-7msfnWZT.css} +1 -1
  110. package/dist/designer/assets/SvGridChartView-CmsZtCED.js +1 -0
  111. package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
  112. package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
  113. package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
  114. package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
  115. package/dist/designer/assets/SvTabs-2mHC6oaz.js +1 -0
  116. package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
  117. package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
  118. package/dist/designer/assets/chart-Cn7MnNqA.js +1 -0
  119. package/dist/designer/assets/chart-export-B6bkQ3X8.js +11 -0
  120. package/dist/designer/assets/chart-export-pdf-BbA28-gt.js +11 -0
  121. package/dist/designer/assets/chart-panel-messages-Dz7PTIqT.js +1 -0
  122. package/dist/designer/assets/chart-summary-BD1qYB2R.js +1 -0
  123. package/dist/designer/assets/chart-trend-B8xr5LuD.js +1 -0
  124. package/dist/designer/assets/chart-validate-BMqM-qkF.js +1 -0
  125. package/dist/designer/assets/column-resize-BYDzR1Ve.js +1 -0
  126. package/dist/designer/assets/date-format-B8JbEtIG.js +1 -0
  127. package/dist/designer/assets/date-format-DKS-z0xS.css +1 -0
  128. package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
  129. package/dist/designer/assets/editor-contract-Bpoa7A5g.js +1 -0
  130. package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
  131. package/dist/designer/assets/focus-trap-V2-6Fy9I.js +1 -0
  132. package/dist/designer/assets/{index-C_a9Cj8Y.js → index-D5bVbuzI.js} +318 -315
  133. package/dist/designer/assets/index-_JVFxt02.css +1 -0
  134. package/dist/designer/assets/list-option-BP_dWS66.js +1 -0
  135. package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
  136. package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
  137. package/dist/designer/assets/src-CITpcm6b.js +1 -0
  138. package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
  139. package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
  140. package/dist/designer/index.html +29 -19
  141. package/dist/export-pdf.d.ts +164 -0
  142. package/dist/export-pdf.js +346 -15
  143. package/dist/export.js +25 -10
  144. package/dist/gantt/SvGridGantt.svelte +2890 -0
  145. package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
  146. package/dist/gantt/gantt-config.d.ts +73 -0
  147. package/dist/gantt/gantt-config.js +1 -0
  148. package/dist/gantt/gantt-critical-path.d.ts +67 -0
  149. package/dist/gantt/gantt-critical-path.js +207 -0
  150. package/dist/gantt/gantt-model.d.ts +257 -0
  151. package/dist/gantt/gantt-model.js +651 -0
  152. package/dist/gantt/gantt-resources.d.ts +59 -0
  153. package/dist/gantt/gantt-resources.js +71 -0
  154. package/dist/gantt/gantt.d.ts +7 -0
  155. package/dist/gantt/gantt.js +36 -0
  156. package/dist/gantt/index.d.ts +15 -0
  157. package/dist/gantt/index.js +22 -0
  158. package/dist/gantt/timeline-arrows.d.ts +102 -0
  159. package/dist/gantt/timeline-arrows.js +181 -0
  160. package/dist/import.d.ts +2 -2
  161. package/dist/import.js +1 -1
  162. package/dist/index.d.ts +93 -3
  163. package/dist/index.js +107 -3
  164. package/dist/install.js +13 -1
  165. package/dist/license-core.d.ts +17 -1
  166. package/dist/license-core.js +16 -5
  167. package/dist/license.d.ts +18 -2
  168. package/dist/license.js +71 -6
  169. package/dist/node/studio.js +203 -9
  170. package/dist/pivot-chart.d.ts +25 -1
  171. package/dist/pivot-chart.js +25 -69
  172. package/dist/pivot-enable.js +2 -2
  173. package/dist/scheduler-dependencies.d.ts +35 -0
  174. package/dist/scheduler-dependencies.js +36 -1
  175. package/dist/scheduler.js +2 -2
  176. package/dist/selection-bar.js +2 -2
  177. package/dist/server/SvGroupCell.svelte +213 -0
  178. package/dist/server/SvGroupCell.svelte.d.ts +62 -0
  179. package/dist/server/SvRowGroupPanel.svelte +322 -0
  180. package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
  181. package/dist/server/enable.d.ts +17 -0
  182. package/dist/server/enable.js +49 -0
  183. package/dist/server/index.d.ts +22 -0
  184. package/dist/server/index.js +24 -0
  185. package/dist/server/messages.d.ts +45 -0
  186. package/dist/server/messages.js +35 -0
  187. package/dist/server/server-group-model.d.ts +104 -0
  188. package/dist/server/server-group-model.js +272 -0
  189. package/dist/server/server-pivot.d.ts +46 -0
  190. package/dist/server/server-pivot.js +57 -0
  191. package/dist/server/server-row-model.d.ts +547 -0
  192. package/dist/server/server-row-model.js +1551 -0
  193. package/dist/server/server-selection.d.ts +99 -0
  194. package/dist/server/server-selection.js +215 -0
  195. package/dist/server/svgrid-adapter.d.ts +155 -0
  196. package/dist/server/svgrid-adapter.js +202 -0
  197. package/dist/sheet/address.d.ts +43 -0
  198. package/dist/sheet/address.js +81 -0
  199. package/dist/sheet/ast.d.ts +138 -0
  200. package/dist/sheet/ast.js +70 -0
  201. package/dist/sheet/auto-filter.d.ts +120 -0
  202. package/dist/sheet/auto-filter.js +295 -0
  203. package/dist/sheet/autocomplete.d.ts +51 -0
  204. package/dist/sheet/autocomplete.js +248 -0
  205. package/dist/sheet/cell-images.d.ts +39 -0
  206. package/dist/sheet/cell-images.js +90 -0
  207. package/dist/sheet/cell-types.d.ts +58 -0
  208. package/dist/sheet/cell-types.js +96 -0
  209. package/dist/sheet/coerce.d.ts +71 -0
  210. package/dist/sheet/coerce.js +289 -0
  211. package/dist/sheet/commands.d.ts +89 -0
  212. package/dist/sheet/commands.js +230 -0
  213. package/dist/sheet/comments.d.ts +63 -0
  214. package/dist/sheet/comments.js +131 -0
  215. package/dist/sheet/conditional-formats.d.ts +167 -0
  216. package/dist/sheet/conditional-formats.js +341 -0
  217. package/dist/sheet/csv.d.ts +32 -0
  218. package/dist/sheet/csv.js +158 -0
  219. package/dist/sheet/culture.d.ts +87 -0
  220. package/dist/sheet/culture.js +247 -0
  221. package/dist/sheet/delta.d.ts +102 -0
  222. package/dist/sheet/delta.js +203 -0
  223. package/dist/sheet/deps.d.ts +104 -0
  224. package/dist/sheet/deps.js +274 -0
  225. package/dist/sheet/document.d.ts +252 -0
  226. package/dist/sheet/document.js +465 -0
  227. package/dist/sheet/edit-keys.d.ts +14 -0
  228. package/dist/sheet/edit-keys.js +40 -0
  229. package/dist/sheet/engine.d.ts +67 -0
  230. package/dist/sheet/engine.js +19 -0
  231. package/dist/sheet/entry.d.ts +35 -0
  232. package/dist/sheet/entry.js +226 -0
  233. package/dist/sheet/error-check.d.ts +49 -0
  234. package/dist/sheet/error-check.js +83 -0
  235. package/dist/sheet/evaluate-steps.d.ts +48 -0
  236. package/dist/sheet/evaluate-steps.js +196 -0
  237. package/dist/sheet/evaluate.d.ts +128 -0
  238. package/dist/sheet/evaluate.js +1049 -0
  239. package/dist/sheet/filter-files.d.ts +37 -0
  240. package/dist/sheet/filter-files.js +465 -0
  241. package/dist/sheet/find-replace.d.ts +62 -0
  242. package/dist/sheet/find-replace.js +152 -0
  243. package/dist/sheet/format-store.d.ts +114 -0
  244. package/dist/sheet/format-store.js +243 -0
  245. package/dist/sheet/freeze.d.ts +54 -0
  246. package/dist/sheet/freeze.js +58 -0
  247. package/dist/sheet/from-rows.d.ts +14 -0
  248. package/dist/sheet/from-rows.js +50 -0
  249. package/dist/sheet/function-catalog.d.ts +10 -0
  250. package/dist/sheet/function-catalog.js +385 -0
  251. package/dist/sheet/functions.d.ts +28 -0
  252. package/dist/sheet/functions.js +634 -0
  253. package/dist/sheet/goal-seek.d.ts +73 -0
  254. package/dist/sheet/goal-seek.js +153 -0
  255. package/dist/sheet/index.d.ts +80 -0
  256. package/dist/sheet/index.js +80 -0
  257. package/dist/sheet/links.d.ts +57 -0
  258. package/dist/sheet/links.js +174 -0
  259. package/dist/sheet/merges.d.ts +71 -0
  260. package/dist/sheet/merges.js +137 -0
  261. package/dist/sheet/messages.d.ts +778 -0
  262. package/dist/sheet/messages.js +806 -0
  263. package/dist/sheet/names.d.ts +31 -0
  264. package/dist/sheet/names.js +87 -0
  265. package/dist/sheet/navigate.d.ts +52 -0
  266. package/dist/sheet/navigate.js +135 -0
  267. package/dist/sheet/number-format.d.ts +110 -0
  268. package/dist/sheet/number-format.js +905 -0
  269. package/dist/sheet/objects.d.ts +106 -0
  270. package/dist/sheet/objects.js +149 -0
  271. package/dist/sheet/ods-document.d.ts +44 -0
  272. package/dist/sheet/ods-document.js +1275 -0
  273. package/dist/sheet/open-file.d.ts +26 -0
  274. package/dist/sheet/open-file.js +56 -0
  275. package/dist/sheet/outline.d.ts +82 -0
  276. package/dist/sheet/outline.js +228 -0
  277. package/dist/sheet/packs/array.d.ts +16 -0
  278. package/dist/sheet/packs/array.js +172 -0
  279. package/dist/sheet/packs/database.d.ts +42 -0
  280. package/dist/sheet/packs/database.js +142 -0
  281. package/dist/sheet/packs/engineering.d.ts +2 -0
  282. package/dist/sheet/packs/engineering.js +296 -0
  283. package/dist/sheet/packs/financial.d.ts +5 -0
  284. package/dist/sheet/packs/financial.js +220 -0
  285. package/dist/sheet/packs/math-stats.d.ts +2 -0
  286. package/dist/sheet/packs/math-stats.js +372 -0
  287. package/dist/sheet/packs/special.d.ts +44 -0
  288. package/dist/sheet/packs/special.js +187 -0
  289. package/dist/sheet/packs/stats-dist.d.ts +2 -0
  290. package/dist/sheet/packs/stats-dist.js +785 -0
  291. package/dist/sheet/packs/text-date.d.ts +2 -0
  292. package/dist/sheet/packs/text-date.js +332 -0
  293. package/dist/sheet/packs/trig.d.ts +2 -0
  294. package/dist/sheet/packs/trig.js +73 -0
  295. package/dist/sheet/page-setup.d.ts +73 -0
  296. package/dist/sheet/page-setup.js +73 -0
  297. package/dist/sheet/palette.d.ts +19 -0
  298. package/dist/sheet/palette.js +84 -0
  299. package/dist/sheet/parse.d.ts +13 -0
  300. package/dist/sheet/parse.js +140 -0
  301. package/dist/sheet/paste-special.d.ts +186 -0
  302. package/dist/sheet/paste-special.js +601 -0
  303. package/dist/sheet/pivot-range.d.ts +160 -0
  304. package/dist/sheet/pivot-range.js +333 -0
  305. package/dist/sheet/presence.d.ts +73 -0
  306. package/dist/sheet/presence.js +79 -0
  307. package/dist/sheet/print.d.ts +104 -0
  308. package/dist/sheet/print.js +169 -0
  309. package/dist/sheet/protection.d.ts +75 -0
  310. package/dist/sheet/protection.js +101 -0
  311. package/dist/sheet/rects.d.ts +45 -0
  312. package/dist/sheet/rects.js +112 -0
  313. package/dist/sheet/refs.d.ts +130 -0
  314. package/dist/sheet/refs.js +413 -0
  315. package/dist/sheet/ribbon-icons.d.ts +31 -0
  316. package/dist/sheet/ribbon-icons.js +536 -0
  317. package/dist/sheet/ribbon.d.ts +173 -0
  318. package/dist/sheet/ribbon.js +1054 -0
  319. package/dist/sheet/sheet-kinds.d.ts +74 -0
  320. package/dist/sheet/sheet-kinds.js +91 -0
  321. package/dist/sheet/shortcuts.d.ts +174 -0
  322. package/dist/sheet/shortcuts.js +674 -0
  323. package/dist/sheet/sort.d.ts +51 -0
  324. package/dist/sheet/sort.js +107 -0
  325. package/dist/sheet/sparklines.d.ts +111 -0
  326. package/dist/sheet/sparklines.js +204 -0
  327. package/dist/sheet/structure.d.ts +87 -0
  328. package/dist/sheet/structure.js +166 -0
  329. package/dist/sheet/table-styles.d.ts +74 -0
  330. package/dist/sheet/table-styles.js +152 -0
  331. package/dist/sheet/tables.d.ts +89 -0
  332. package/dist/sheet/tables.js +178 -0
  333. package/dist/sheet/tokenize.d.ts +71 -0
  334. package/dist/sheet/tokenize.js +355 -0
  335. package/dist/sheet/transforms.d.ts +76 -0
  336. package/dist/sheet/transforms.js +154 -0
  337. package/dist/sheet/validation.d.ts +108 -0
  338. package/dist/sheet/validation.js +278 -0
  339. package/dist/sheet/workbook.d.ts +217 -0
  340. package/dist/sheet/workbook.js +1120 -0
  341. package/dist/sheet/xls-cfb.d.ts +32 -0
  342. package/dist/sheet/xls-cfb.js +290 -0
  343. package/dist/sheet/xls-document.d.ts +10 -0
  344. package/dist/sheet/xls-document.js +1243 -0
  345. package/dist/sheet/xls-formula.d.ts +40 -0
  346. package/dist/sheet/xls-formula.js +569 -0
  347. package/dist/sheet/xlsx-document.d.ts +108 -0
  348. package/dist/sheet/xlsx-document.js +1849 -0
  349. package/dist/sheet/xlsx-drawing.d.ts +99 -0
  350. package/dist/sheet/xlsx-drawing.js +420 -0
  351. package/dist/sheet-enable.d.ts +6 -0
  352. package/dist/sheet-enable.js +45 -0
  353. package/dist/sheet-text.d.ts +7 -0
  354. package/dist/sheet-text.js +29 -0
  355. package/dist/sources/auth-supabase.js +2 -2
  356. package/dist/sources/realtime-supabase.js +2 -2
  357. package/dist/sources/rest.d.ts +6 -2
  358. package/dist/sources/rest.js +42 -7
  359. package/dist/sources/supabase.d.ts +10 -1
  360. package/dist/sources/supabase.js +73 -40
  361. package/dist/studio/emit-project.js +14 -1
  362. package/dist/studio/index.js +1 -1
  363. package/dist/studio/project.d.ts +11 -2
  364. package/dist/studio/project.js +5 -2
  365. package/dist/studio/ui-components.generated.js +170 -3
  366. package/dist/sveltekit/in-memory.d.ts +2 -2
  367. package/dist/sveltekit/in-memory.js +125 -4
  368. package/dist/sveltekit/index.d.ts +1 -1
  369. package/dist/sveltekit/index.js +1 -1
  370. package/dist/sveltekit/query-plan.d.ts +50 -4
  371. package/dist/sveltekit/query-plan.js +25 -3
  372. package/dist/sveltekit/sql-source.d.ts +6 -0
  373. package/dist/sveltekit/sql-source.js +34 -6
  374. package/dist/sveltekit/sql.d.ts +31 -0
  375. package/dist/sveltekit/sql.js +135 -25
  376. package/dist/sveltekit/transport.d.ts +10 -2
  377. package/dist/sveltekit/transport.js +30 -6
  378. package/dist/upgrade-prompt.d.ts +1 -1
  379. package/dist/version.d.ts +1 -1
  380. package/dist/version.js +1 -1
  381. package/dist/watermark.js +35 -2
  382. package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
  383. package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
  384. package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
  385. package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
  386. package/dist/wc/SvField-B_kurx_P.js +149 -0
  387. package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
  388. package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
  389. package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
  390. package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
  391. package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
  392. package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
  393. package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
  394. package/dist/wc/SvModal-DrfOYYyX.js +189 -0
  395. package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
  396. package/dist/wc/chart-6OXlybVT.js +4341 -0
  397. package/dist/wc/chart-export-CeSADGfi.js +135 -0
  398. package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
  399. package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
  400. package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
  401. package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
  402. package/dist/wc/client-DQIzjDBG.js +3064 -0
  403. package/dist/wc/column-resize-DUPgynvc.js +101 -0
  404. package/dist/wc/date-format-DS-z_h9v.js +1130 -0
  405. package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
  406. package/dist/wc/editor-contract-peBDxir_.js +22 -0
  407. package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
  408. package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
  409. package/dist/wc/list-option-DrRyivWp.js +82 -0
  410. package/dist/wc/popover-WsGlvtQv.js +69 -0
  411. package/dist/wc/positioning-BiKLfu1E.js +112 -0
  412. package/dist/wc/react.d.ts +41 -0
  413. package/dist/wc/react.js +90 -0
  414. package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
  415. package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
  416. package/dist/wc/row-resize-limG_N1z.js +111 -0
  417. package/dist/wc/sv-sheet-element.d.ts +97 -0
  418. package/dist/wc/sv-sheet-element.js +44213 -0
  419. package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
  420. package/dist/wc/validate-BqDthkNr.js +88 -0
  421. package/dist/wc/vue.d.ts +31 -0
  422. package/dist/wc/vue.js +75 -0
  423. package/package.json +36 -6
  424. package/dist/designer/assets/GridMenus-B1JtIN21.js +0 -8
  425. package/dist/designer/assets/SvDateRangeInput-CjO7nn_x.js +0 -1
  426. package/dist/designer/assets/SvDateTimePicker-ByBD_ov6.js +0 -1
  427. package/dist/designer/assets/SvField-YDLipR6O.css +0 -1
  428. package/dist/designer/assets/SvField-cj1PFNgZ.js +0 -1
  429. package/dist/designer/assets/SvGridCellEditor-0W1L2hJ1.js +0 -2
  430. package/dist/designer/assets/SvGridChart-DBOR4xcz.js +0 -2
  431. package/dist/designer/assets/SvGridChart-fkMWeh1J.css +0 -1
  432. package/dist/designer/assets/SvGridChartPanel-symrhNnR.js +0 -11
  433. package/dist/designer/assets/SvGridChartView-BmRxq6mU.js +0 -1
  434. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
  435. package/dist/designer/assets/SvListBox-1oUF6Iav.js +0 -110
  436. package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
  437. package/dist/designer/assets/chart-DXFganU8.js +0 -1
  438. package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
  439. package/dist/designer/assets/date-format-DGagAqRc.css +0 -1
  440. package/dist/designer/assets/date-format-onlYDsrY.js +0 -1
  441. package/dist/designer/assets/easing-zaypKrr0.js +0 -3
  442. package/dist/designer/assets/index-k2stW6L8.css +0 -1
  443. package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
  444. package/dist/designer/assets/src-D9p27OGC.js +0 -58
  445. package/dist/designer/assets/validate-h-aslRV9.js +0 -1
@@ -2,37 +2,66 @@ export function planToSql(plan, dialect = {}) {
2
2
  const q = dialect.quote ?? '"';
3
3
  const useIlike = dialect.ilike ?? false;
4
4
  const params = [];
5
- const ph = () => {
6
- if (dialect.placeholders === '$')
7
- return `$${params.length}`;
8
- if (dialect.placeholders === '@')
9
- return `@p${params.length}`;
10
- return '?';
11
- };
12
- const bind = (v) => {
13
- params.push(v);
14
- return ph();
15
- };
16
5
  const columnFor = dialect.column ?? ((f) => f);
17
6
  const id = (field) => {
18
7
  const c = columnFor(field);
19
8
  return `${q}${c.replace(new RegExp(q, 'g'), q + q)}${q}`;
20
9
  };
21
- const like = (field, pattern) => {
22
- const p = bind(pattern);
23
- return useIlike ? `${id(field)} ILIKE ${p}` : `LOWER(${id(field)}) LIKE LOWER(${p})`;
10
+ // The planner whitelists function names; this is the second lock on the
11
+ // same door, since an aggregate name is pasted into the statement raw.
12
+ const aggName = (fn) => {
13
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(fn))
14
+ throw new Error(`planToSql: "${fn}" is not an aggregate function name`);
15
+ return fn.toUpperCase();
24
16
  };
25
- const clauses = [];
26
- for (const pred of plan.where) {
27
- clauses.push(predicateSql(pred, { id, bind, like }));
28
- }
29
- if (plan.search && plan.search.fields.length > 0) {
30
- const term = `%${plan.search.term}%`;
31
- const ors = plan.search.fields.map((f) => like(f, term));
32
- clauses.push(`(${ors.join(' OR ')})`);
17
+ /**
18
+ * Render predicates + search into one WHERE body, binding into `into`.
19
+ * Placeholder numbering follows that array, so a second call with a fresh
20
+ * array (the grand total) starts from $1 again.
21
+ */
22
+ const buildWhere = (preds, into) => {
23
+ const ph = () => {
24
+ if (dialect.placeholders === '$')
25
+ return `$${into.length}`;
26
+ if (dialect.placeholders === '@')
27
+ return `@p${into.length}`;
28
+ return '?';
29
+ };
30
+ const bind = (v) => {
31
+ into.push(v);
32
+ return ph();
33
+ };
34
+ const like = (field, pattern) => {
35
+ const p = bind(pattern);
36
+ return useIlike ? `${id(field)} ILIKE ${p}` : `LOWER(${id(field)}) LIKE LOWER(${p})`;
37
+ };
38
+ const clauses = [];
39
+ for (const pred of preds)
40
+ clauses.push(predicateSql(pred, { id, bind, like }));
41
+ if (plan.search && plan.search.fields.length > 0) {
42
+ const term = `%${plan.search.term}%`;
43
+ const ors = plan.search.fields.map((f) => like(f, term));
44
+ clauses.push(`(${ors.join(' OR ')})`);
45
+ }
46
+ return clauses.join(' AND ');
47
+ };
48
+ const where = buildWhere(plan.where, params);
49
+ // A grouped level can only order by what it produces - the key and the
50
+ // aggregates (under pivot only the key, the aggregates being split per
51
+ // pivot key); a leaf column there is a SQL error. With nothing left the
52
+ // key orders the groups, so paging over them is deterministic. Same rule
53
+ // as the in-memory reference.
54
+ let order = plan.orderBy;
55
+ if (plan.groupBy) {
56
+ const produced = new Set([
57
+ plan.groupBy,
58
+ ...(plan.pivotBy?.length ? [] : (plan.aggregations ?? []).map((a) => a.field)),
59
+ ]);
60
+ order = order.filter((o) => produced.has(o.field));
61
+ if (order.length === 0)
62
+ order = [{ field: plan.groupBy, desc: false }];
33
63
  }
34
- const where = clauses.join(' AND ');
35
- const orderBy = plan.orderBy.map((o) => `${id(o.field)} ${o.desc ? 'DESC' : 'ASC'}`).join(', ');
64
+ const orderBy = order.map((o) => `${id(o.field)} ${o.desc ? 'DESC' : 'ASC'}`).join(', ');
36
65
  // ---- Grouping ----------------------------------------------------------
37
66
  // `plan.groupBy` is a single column: the grid asks one level at a time and
38
67
  // sends the chosen path as ordinary predicates, so there is never a
@@ -44,13 +73,89 @@ export function planToSql(plan, dialect = {}) {
44
73
  for (const agg of plan.aggregations ?? []) {
45
74
  // COUNT(*) rather than COUNT(col) so the tally counts rows in the group
46
75
  // rather than non-null values of one column.
47
- const expr = agg.fn === 'count' ? 'COUNT(*)' : `${agg.fn.toUpperCase()}(${id(agg.field)})`;
76
+ const expr = agg.fn === 'count' ? 'COUNT(*)' : `${aggName(agg.fn)}(${id(agg.field)})`;
48
77
  // Aliased back to the source column name: that is the key the grid reads
49
78
  // the aggregate from on the group row.
50
79
  parts.push(`${expr} AS ${id(agg.field)}`);
51
80
  }
81
+ // What opening the group would show, for the badge beside its key: the
82
+ // distinct keys of the next level, or the rows when this is the innermost
83
+ // group level. Always emitted; a caller that does not want the extra
84
+ // aggregate can drop the alias from the list.
85
+ parts.push(plan.childGroupBy
86
+ ? `COUNT(DISTINCT ${id(plan.childGroupBy)}) AS ${id('childCount')}`
87
+ : `COUNT(*) AS ${id('childCount')}`);
52
88
  select = parts.join(', ');
53
89
  }
90
+ // The grand total aggregates over everything the FILTERS admit, so the
91
+ // group path (the trailing `pathPredicates` entries of `where`, per
92
+ // planQuery) is left out.
93
+ let grandTotalSelect = '';
94
+ let grandTotalWhereText = '';
95
+ const grandTotalParams = [];
96
+ if (plan.grandTotal) {
97
+ grandTotalSelect = (plan.aggregations ?? [])
98
+ .map((agg) => {
99
+ const expr = agg.fn === 'count' ? 'COUNT(*)' : `${aggName(agg.fn)}(${id(agg.field)})`;
100
+ return `${expr} AS ${id(agg.field)}`;
101
+ })
102
+ .join(', ');
103
+ const filtersOnly = plan.where.slice(0, plan.where.length - (plan.pathPredicates ?? 0));
104
+ const body = buildWhere(filtersOnly, grandTotalParams);
105
+ grandTotalWhereText = body ? `WHERE ${body}` : '';
106
+ }
107
+ // ---- Pivot ------------------------------------------------------------
108
+ let pivotKeysSelect = '';
109
+ let pivotSelect = () => ({ select: '', fields: [], grandTotalSelect: '' });
110
+ if (plan.groupBy && plan.pivotBy?.length) {
111
+ const pivotCols = plan.pivotBy;
112
+ const keyList = pivotCols
113
+ .map((c) => (columnFor(c) === c ? id(c) : `${id(c)} AS ${q}${c}${q}`))
114
+ .join(', ');
115
+ pivotKeysSelect = `DISTINCT ${keyList}`;
116
+ pivotSelect = (keyRows) => {
117
+ // Key paths in plain string order, so the field list (and the
118
+ // columns the grid builds from it) is the same whatever order the
119
+ // distinct-keys query returned - and the same as the reference.
120
+ const pathOf = (row) => pivotCols.map((c) => String(row[c] ?? '')).join('_');
121
+ keyRows = [...keyRows].sort((a, b) => {
122
+ const x = pathOf(a);
123
+ const y = pathOf(b);
124
+ return x < y ? -1 : x > y ? 1 : 0;
125
+ });
126
+ const groupCol = id(plan.groupBy);
127
+ const parts = [groupCol];
128
+ const totals = [];
129
+ const fields = [];
130
+ for (const keyRow of keyRows) {
131
+ const path = pivotCols.map((c) => String(keyRow[c] ?? ''));
132
+ // The key path as an inline condition. Values are quoted as string
133
+ // literals with doubled quotes; a caller with typed columns can
134
+ // rewrite through `pivotSelect` itself.
135
+ const cond = pivotCols
136
+ .map((c, i) => `${id(c)} = '${path[i].replace(/'/g, "''")}'`)
137
+ .join(' AND ');
138
+ for (const agg of plan.aggregations ?? []) {
139
+ const field = `${path.join('_')}_${agg.field}`;
140
+ const inner = agg.fn === 'count' ? '1' : id(agg.field);
141
+ const fn = agg.fn === 'count' ? 'COUNT' : aggName(agg.fn);
142
+ const expr = `${fn}(CASE WHEN ${cond} THEN ${inner} END) AS ${id(field)}`;
143
+ parts.push(expr);
144
+ totals.push(expr);
145
+ fields.push(field);
146
+ }
147
+ }
148
+ // The plain aggregates too: the row total beside the per-key cells,
149
+ // which is what a Total column group reads.
150
+ for (const agg of plan.aggregations ?? []) {
151
+ const expr = agg.fn === 'count' ? 'COUNT(*)' : `${aggName(agg.fn)}(${id(agg.field)})`;
152
+ parts.push(`${expr} AS ${id(agg.field)}`);
153
+ totals.push(`${expr} AS ${id(agg.field)}`);
154
+ }
155
+ parts.push(`COUNT(*) AS ${id('childCount')}`);
156
+ return { select: parts.join(', '), fields, grandTotalSelect: totals.join(', ') };
157
+ };
158
+ }
54
159
  // A grouped total is the number of distinct keys, not of underlying rows.
55
160
  const countText = plan.groupBy
56
161
  ? `COUNT(DISTINCT ${id(plan.groupBy)})`
@@ -67,6 +172,11 @@ export function planToSql(plan, dialect = {}) {
67
172
  groupBy,
68
173
  groupByText: groupBy ? `GROUP BY ${groupBy}` : '',
69
174
  countText,
175
+ grandTotalSelect,
176
+ grandTotalWhereText,
177
+ grandTotalParams,
178
+ pivotKeysSelect,
179
+ pivotSelect,
70
180
  };
71
181
  }
72
182
  function predicateSql(pred, ctx) {
@@ -23,7 +23,7 @@
23
23
  * const source = createKitDataSource({ endpoint: '/api/customers' })
24
24
  * const controller = createServerDataSource(source, { onChange: ... })
25
25
  */
26
- import type { RowData, ServerDataSource, ServerRequest } from '@svgrid/grid';
26
+ import type { RowData, ServerDataSource, ServerFilterModel, ServerRequest, ServerSelectionRule } from '@svgrid/grid';
27
27
  import type { EntitySchema } from '../schema.js';
28
28
  import type { WritableDataSource } from './types.js';
29
29
  /** Wire protocol: the single JSON body shape the client POSTs and the server dispatches on. */
@@ -43,6 +43,14 @@ export type KitMessage<TData> = {
43
43
  kind: 'mutate';
44
44
  op: 'delete';
45
45
  id: string;
46
+ }
47
+ /** A bulk edit by rule: every row the filter and the selection name. */
48
+ | {
49
+ kind: 'mutate';
50
+ op: 'updateWhere';
51
+ filterModel: ServerFilterModel;
52
+ patch: Partial<TData>;
53
+ selection: ServerSelectionRule;
46
54
  };
47
55
  type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
48
56
  export type KitDataSourceOptions = {
@@ -54,7 +62,7 @@ export type KitDataSourceOptions = {
54
62
  */
55
63
  fetch?: FetchLike;
56
64
  };
57
- export declare function createKitDataSource<TData extends RowData>(options: KitDataSourceOptions): WritableDataSource<TData>;
65
+ export declare function createKitDataSource<TData extends RowData>(options: KitDataSourceOptions): WritableDataSource<TData> & Required<Pick<ServerDataSource<TData>, 'updateWhere'>>;
58
66
  /** The CRUD action a Kit message maps to (`query` -> `read`). */
59
67
  export type KitAction = 'read' | 'create' | 'update' | 'delete';
60
68
  /** Context passed to the `authorize` guard before every op. */
@@ -7,11 +7,12 @@ function jsonResponse(data, status = 200) {
7
7
  }
8
8
  export function createKitDataSource(options) {
9
9
  const doFetch = options.fetch ?? ((i, init) => fetch(i, init));
10
- async function post(body) {
10
+ async function post(body, signal) {
11
11
  const res = await doFetch(options.endpoint, {
12
12
  method: 'POST',
13
13
  headers: { 'content-type': 'application/json' },
14
14
  body: JSON.stringify(body),
15
+ ...(signal ? { signal } : {}),
15
16
  });
16
17
  if (!res.ok) {
17
18
  const detail = await res.text().catch(() => '');
@@ -20,13 +21,15 @@ export function createKitDataSource(options) {
20
21
  return (await res.json());
21
22
  }
22
23
  return {
23
- getRows: (request) => post({ kind: 'query', request }),
24
+ // The abort signal rides on the fetch, not in the body.
25
+ getRows: ({ signal, ...request }) => post({ kind: 'query', request }, signal),
24
26
  createRow: (input) => post({ kind: 'mutate', op: 'create', input }),
25
27
  updateRow: (id, patch) => post({ kind: 'mutate', op: 'update', id, patch }),
26
28
  deleteRow: (id) => post({ kind: 'mutate', op: 'delete', id }).then(() => undefined),
29
+ updateWhere: (filterModel, patch, selection) => post({ kind: 'mutate', op: 'updateWhere', filterModel, patch, selection }).then((r) => r.count),
27
30
  };
28
31
  }
29
- const actionOf = (msg) => msg.kind === 'query' ? 'read' : msg.op;
32
+ const actionOf = (msg) => msg.kind === 'query' ? 'read' : msg.op === 'updateWhere' ? 'update' : msg.op;
30
33
  export function createKitHandlers(options) {
31
34
  const { source, authorize, validate, audit, hooks, scope } = options;
32
35
  const idField = options.schema.idField ?? options.schema.fields.find((f) => f.primaryKey)?.field ?? 'id';
@@ -66,18 +69,18 @@ export function createKitHandlers(options) {
66
69
  return jsonResponse({ error: 'forbidden' }, 403);
67
70
  }
68
71
  // Validate create / update payloads BEFORE the source. 422 on field errors.
69
- if (validate && msg.kind === 'mutate' && (msg.op === 'create' || msg.op === 'update')) {
72
+ if (validate && msg.kind === 'mutate' && msg.op !== 'delete') {
70
73
  const values = (msg.op === 'create' ? msg.input : msg.patch);
71
74
  let errors;
72
75
  if (validate === true) {
73
76
  const all = await validateAll(options.schema, values);
74
77
  // On update, only the supplied fields are validated (a patch omits the rest).
75
- errors = msg.op === 'update'
78
+ errors = msg.op !== 'create'
76
79
  ? Object.fromEntries(Object.keys(values).filter((k) => all[k]).map((k) => [k, all[k]]))
77
80
  : all;
78
81
  }
79
82
  else {
80
- errors = await validate({ action: msg.op, values, event: { request, locals: event?.locals } });
83
+ errors = await validate({ action: msg.op === 'create' ? 'create' : 'update', values, event: { request, locals: event?.locals } });
81
84
  }
82
85
  if (errors && Object.keys(errors).length) {
83
86
  return jsonResponse({ error: 'validation failed', fieldErrors: errors }, 422);
@@ -191,6 +194,27 @@ export function createKitHandlers(options) {
191
194
  await fireAudit({ action: 'update', id: msg.id, values: patch, result: row, event: evt });
192
195
  return jsonResponse(row);
193
196
  }
197
+ if (msg.op === 'updateWhere') {
198
+ if (!source.updateWhere)
199
+ return jsonResponse({ error: 'updateWhere not supported' }, 405);
200
+ // The scope narrows the rule the same way it narrows a query, and
201
+ // the patch cannot move rows out of it.
202
+ let filterModel = msg.filterModel;
203
+ let patch = msg.patch;
204
+ if (activeScope) {
205
+ filterModel = {
206
+ ...filterModel,
207
+ columns: {
208
+ ...(filterModel.columns ?? {}),
209
+ [activeScope.field]: { operator: 'equals', value: String(activeScope.value) },
210
+ },
211
+ };
212
+ patch = { ...patch, [activeScope.field]: activeScope.value };
213
+ }
214
+ const count = await source.updateWhere(filterModel, patch, msg.selection);
215
+ await fireAudit({ action: 'update', id: null, values: patch, event: evt });
216
+ return jsonResponse({ count });
217
+ }
194
218
  if (msg.op === 'delete') {
195
219
  if (!source.deleteRow)
196
220
  return jsonResponse({ error: 'delete not supported' }, 405);
@@ -1,5 +1,5 @@
1
1
  /** Human-readable labels for the Pro surfaces that gate behind a license. */
2
- export type EnterpriseFeatureLabel = 'Export' | 'Import' | 'Print' | 'AI assistant' | 'Pivot' | 'Studio';
2
+ export type EnterpriseFeatureLabel = 'Export' | 'Import' | 'Print' | 'AI assistant' | 'Pivot' | 'Server-side row model' | 'Spreadsheet' | 'Studio';
3
3
  /**
4
4
  * Show the contextual upgrade prompt for `feature`. No-ops if one has already
5
5
  * been shown this session, a card is already up, or we're on the server. Safe
package/dist/version.d.ts CHANGED
@@ -10,4 +10,4 @@
10
10
  *
11
11
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
12
12
  */
13
- export declare const SVGRID_VERSION = "3.0.0";
13
+ export declare const SVGRID_VERSION = "3.0.3";
package/dist/version.js CHANGED
@@ -10,4 +10,4 @@
10
10
  *
11
11
  * `version.test.ts` asserts this matches `package.json`, so the two cannot drift.
12
12
  */
13
- export const SVGRID_VERSION = '3.0.0';
13
+ export const SVGRID_VERSION = '3.0.3';
package/dist/watermark.js CHANGED
@@ -1,4 +1,4 @@
1
- // Soft-gate UX for unlicensed @svgrid/enterprise use. Shows a small clickable
1
+ // Evaluation UX for unlicensed @svgrid/enterprise use. Shows a small clickable
2
2
  // "www.svgrid.com" watermark in the bottom-right corner of every SvGrid on
3
3
  // the page, which fades out after 5 seconds, and emits a one-time console
4
4
  // nudge. Hard errors (revoked / bad-prefix keys) still throw via license.ts -
@@ -70,7 +70,32 @@ function attachToAllGrids() {
70
70
  document
71
71
  .querySelectorAll(`[${WATERMARK_ATTR}="fixed"]`)
72
72
  .forEach((el) => el.remove());
73
- grids.forEach(attachWatermarkTo);
73
+ const hosts = new Set();
74
+ grids.forEach((grid) => {
75
+ const host = watermarkHost(grid);
76
+ if (host)
77
+ hosts.add(host);
78
+ });
79
+ hosts.forEach(attachWatermarkTo);
80
+ }
81
+ /**
82
+ * Where the watermark for a matched grid actually hangs.
83
+ *
84
+ * The selector above matches the grid's root container AND the `role="grid"`
85
+ * element inside it, which is the TABLE. A link is not a legal child of a
86
+ * table, and `role="grid"` allows only rows under it, so appending there is
87
+ * invalid HTML and an axe `aria-required-children` violation on every
88
+ * unlicensed grid. So: the grid's own root when the match sits inside one,
89
+ * otherwise the nearest ancestor outside the table's content model.
90
+ */
91
+ function watermarkHost(grid) {
92
+ const root = grid.closest('.sv-grid-root');
93
+ if (root)
94
+ return root;
95
+ let host = grid;
96
+ while (host && /^(TABLE|THEAD|TBODY|TFOOT|TR|COLGROUP)$/.test(host.tagName))
97
+ host = host.parentElement;
98
+ return host;
74
99
  }
75
100
  function attachWatermarkTo(grid) {
76
101
  // Show the watermark once per grid. The marker survives the fade-out so the
@@ -118,6 +143,14 @@ function scheduleFadeOut(el) {
118
143
  return;
119
144
  }
120
145
  window.setTimeout(() => {
146
+ // Five seconds is a long time in a teardown. The environment can go
147
+ // away between these two timers - a jsdom test finishing, a page
148
+ // unloading - and reaching for `window` then throws where the guard
149
+ // above was put precisely to avoid it. Same check, second chance.
150
+ if (typeof window === 'undefined') {
151
+ el.remove();
152
+ return;
153
+ }
121
154
  el.style.opacity = '0';
122
155
  window.setTimeout(() => el.remove(), FADE_MS);
123
156
  }, VISIBLE_MS);