@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
@@ -1,5 +1,5 @@
1
1
  import { resolveIdField } from '../schema.js';
2
- import { nudgeEnterprise } from '../license.js';
2
+ import { nudgeEnterpriseFor } from '../license.js';
3
3
  import { normalizeFilters } from './filters.js';
4
4
  const encodePredicate = (p) => {
5
5
  if (p.op === 'in')
@@ -48,22 +48,57 @@ function defaultBuildQuery(request) {
48
48
  if (aggs.length)
49
49
  params.aggregate = aggs.map((a) => `${a.fn}:${a.col}`).join(',');
50
50
  }
51
+ // The grid wants a grand-total row it does not have yet. An endpoint that
52
+ // supports it answers with `grandTotal` in the body (the aggregates over
53
+ // the filtered set, path excluded); one that does not simply ignores the
54
+ // flag and the grid shows no total. The aggregate list is sent either
55
+ // way, so a leaf-level request still says what to total.
56
+ if (request.needsGrandTotal) {
57
+ params.grandTotal = '1';
58
+ const aggs = request.aggregations ?? [];
59
+ if (aggs.length && !params.aggregate)
60
+ params.aggregate = aggs.map((a) => `${a.fn}:${a.col}`).join(',');
61
+ }
62
+ // Pivot: the columns whose values become fields, on a grouped request.
63
+ // The endpoint answers with the pivoted fields on each group row and
64
+ // lists them in `pivotResultFields`; see the SQL source for the shape.
65
+ //
66
+ // ?groupBy=region&aggregate=sum:amount&pivot=year,quarter
67
+ if (request.pivotMode && request.pivotBy?.length && params.groupBy) {
68
+ params.pivot = request.pivotBy.join(',');
69
+ }
51
70
  return params;
52
71
  }
53
- function defaultParse(body, response) {
72
+ /**
73
+ * The count when the API sent none: a short block is the last one, so the
74
+ * end is known; a full block says nothing, so the count is unknown (`-1`)
75
+ * and an infinite-scrolling grid discovers the end from a later short
76
+ * block. Claiming `rows.length` would tell a pager there is one page.
77
+ */
78
+ function countWithoutTotal(rows, request) {
79
+ const asked = Math.max(1, request.endRow - request.startRow);
80
+ return rows.length < asked ? request.startRow + rows.length : -1;
81
+ }
82
+ function defaultParse(body, response, request) {
54
83
  if (Array.isArray(body)) {
55
84
  // Total from a Content-Range header (`items 0-9/240`) when present.
56
85
  const range = response.headers.get('content-range');
57
86
  const total = range && /\/(\d+)\s*$/.exec(range);
58
- return { rows: body, rowCount: total ? Number(total[1]) : body.length };
87
+ return { rows: body, rowCount: total ? Number(total[1]) : countWithoutTotal(body, request) };
59
88
  }
60
89
  const b = (body ?? {});
90
+ // `grandTotal` rides along in an envelope body when the endpoint answered
91
+ // the request for one. Absent means "keep what you have", `null` means
92
+ // "there is none" - the same three-way contract as ServerResult.
93
+ const grandTotal = 'grandTotal' in b ? { grandTotal: (b.grandTotal ?? null) } : {};
61
94
  const rows = (b.rows ?? b.data ?? b.items ?? []);
62
- const rowCount = Number(b.rowCount ?? b.total ?? b.count ?? rows.length);
63
- return { rows, rowCount };
95
+ const declared = b.rowCount ?? b.total ?? b.count;
96
+ const rowCount = declared == null ? countWithoutTotal(rows, request) : Number(declared);
97
+ const pivot = Array.isArray(b.pivotResultFields) ? { pivotResultFields: b.pivotResultFields } : {};
98
+ return { rows, rowCount, ...grandTotal, ...pivot };
64
99
  }
65
100
  export function createRestDataSource(config) {
66
- nudgeEnterprise('Studio'); // soft-gate; never blocks
101
+ nudgeEnterpriseFor('studio', 'Studio'); // evaluation nudge; never blocks
67
102
  const doFetch = config.fetch ?? globalThis.fetch;
68
103
  const idField = config.idField ?? (config.schema ? resolveIdField(config.schema) : 'id');
69
104
  const base = config.url.replace(/\/+$/, '');
@@ -86,7 +121,7 @@ export function createRestDataSource(config) {
86
121
  const qs = new URLSearchParams({ ...config.query, ...buildQuery(request) }).toString();
87
122
  const url = qs ? `${base}?${qs}` : base;
88
123
  const { body, res } = (await send(url, { headers: headers() }));
89
- return parse(body, res);
124
+ return parse(body, res, request);
90
125
  },
91
126
  async createRow(input) {
92
127
  const { body } = (await send(base, {
@@ -12,7 +12,7 @@
12
12
  * with `searchColumns`. The primary key comes from the schema (`idField`) and is
13
13
  * stripped from inserts (it's database-generated).
14
14
  */
15
- import type { RowData } from '@svgrid/grid';
15
+ import type { RowData, ServerRequest, ServerResult } from '@svgrid/grid';
16
16
  import { type EntitySchema } from '../schema.js';
17
17
  import type { WritableDataSource } from '../sveltekit/types.js';
18
18
  /** The slice of a `supabase-js` client this adapter needs. */
@@ -29,5 +29,14 @@ export type SupabaseDataSourceConfig<TData extends RowData> = {
29
29
  * schema's text + enum fields.
30
30
  */
31
31
  searchColumns?: string[];
32
+ /**
33
+ * Server-side pivot. PostgREST has no way to turn values into columns, so
34
+ * a pivoted request (`pivotMode` with `pivotBy`) goes to this function
35
+ * instead - typically an RPC (`client.rpc(...)`) that returns the group
36
+ * rows with one field per (pivot key x aggregation) and lists them in
37
+ * `pivotResultFields`; the SQL source documents the shape. Without it a
38
+ * pivoted request is answered as plain grouping, with a warning once.
39
+ */
40
+ pivot?: (request: ServerRequest) => Promise<ServerResult<TData>>;
32
41
  };
33
42
  export declare function createSupabaseDataSource<TData extends RowData>(config: SupabaseDataSourceConfig<TData>): WritableDataSource<TData>;
@@ -1,15 +1,27 @@
1
1
  import { resolveIdField } from '../schema.js';
2
- import { nudgeEnterprise } from '../license.js';
2
+ import { nudgeEnterpriseFor } from '../license.js';
3
3
  import { normalizeFilters } from './filters.js';
4
4
  const sanitize = (term) => term.replace(/[%,()]/g, '');
5
5
  export function createSupabaseDataSource(config) {
6
- nudgeEnterprise('Studio'); // soft-gate; never blocks
6
+ nudgeEnterpriseFor('studio', 'Studio'); // evaluation nudge; never blocks
7
7
  const { client, table, schema } = config;
8
8
  const idField = resolveIdField(schema);
9
9
  const searchColumns = config.searchColumns ??
10
10
  schema.fields.filter((f) => f.type === 'text' || f.type === 'enum').map((f) => String(f.field));
11
+ let warnedPivot = false;
11
12
  return {
12
13
  async getRows(request) {
14
+ // ---- Server-side pivot ----------------------------------------------
15
+ // Only a grouped level pivots; the leaves under a path do not.
16
+ const grouped = (request.groupKeys?.length ?? 0) < (request.groupBy?.length ?? 0);
17
+ if (grouped && request.pivotMode && request.pivotBy?.length) {
18
+ if (config.pivot)
19
+ return config.pivot(request);
20
+ if (!warnedPivot) {
21
+ warnedPivot = true;
22
+ console.warn('[svgrid] createSupabaseDataSource: a pivoted request needs the `pivot` option (an RPC that pivots); answering it as plain grouping.');
23
+ }
24
+ }
13
25
  // ---- Server-side grouping -------------------------------------------
14
26
  // The grid asks one level at a time. The already-chosen path becomes
15
27
  // ordinary `.eq()` filters below; at this level we ask PostgREST for the
@@ -26,50 +38,61 @@ export function createSupabaseDataSource(config) {
26
38
  const groupCols = request.groupBy ?? [];
27
39
  const groupKeys = request.groupKeys ?? [];
28
40
  const groupField = groupKeys.length < groupCols.length ? groupCols[groupKeys.length] : undefined;
41
+ const aggregateSelects = (request.aggregations ?? []).map((a) => a.fn === 'count' ? `${a.col}:count()` : `${a.col}:${a.col}.${a.fn}()`);
42
+ // The innermost group level can say how many rows each group holds
43
+ // (a plain count). Higher levels would need COUNT(DISTINCT next),
44
+ // which PostgREST does not expose, so those group rows carry no
45
+ // childCount and the grid shows no badge for them.
46
+ const innermost = groupField != null && groupKeys.length === groupCols.length - 1;
29
47
  const selectExpr = groupField
30
- ? [
31
- groupField,
32
- ...(request.aggregations ?? []).map((a) => a.fn === 'count' ? `${a.col}:count()` : `${a.col}:${a.col}.${a.fn}()`),
33
- ].join(',')
48
+ ? [groupField, ...aggregateSelects, ...(innermost ? ['childCount:count()'] : [])].join(',')
34
49
  : '*';
35
50
  let q = client.from(table).select(selectExpr, { count: 'exact' });
51
+ // The filters are applied to two queries when a grand total was asked
52
+ // for: the level itself (below, with the group path) and the total
53
+ // (the filters alone). Build them once.
54
+ const applyFilters = (query) => {
55
+ let out = query;
56
+ const { predicates, search } = normalizeFilters(request.filterModel);
57
+ for (const p of predicates) {
58
+ switch (p.op) {
59
+ case 'in':
60
+ out = out.in(p.column, p.values);
61
+ break;
62
+ case 'contains':
63
+ out = out.ilike(p.column, `%${p.value}%`);
64
+ break;
65
+ case 'startsWith':
66
+ out = out.ilike(p.column, `${p.value}%`);
67
+ break;
68
+ case 'eq':
69
+ out = out.eq(p.column, p.value);
70
+ break;
71
+ case 'gt':
72
+ out = out.gt(p.column, p.value);
73
+ break;
74
+ case 'lt':
75
+ out = out.lt(p.column, p.value);
76
+ break;
77
+ case 'between':
78
+ out = out.gte(p.column, p.value).lte(p.column, p.valueTo);
79
+ break;
80
+ case 'isNull':
81
+ out = out.is(p.column, null);
82
+ break;
83
+ }
84
+ }
85
+ if (search && searchColumns.length) {
86
+ const term = sanitize(search);
87
+ out = out.or(searchColumns.map((c) => `${c}.ilike.%${term}%`).join(','));
88
+ }
89
+ return out;
90
+ };
36
91
  // The path constrains the rows before grouping.
37
92
  for (let i = 0; i < groupKeys.length && i < groupCols.length; i += 1) {
38
93
  q = q.eq(groupCols[i], groupKeys[i]);
39
94
  }
40
- const { predicates, search } = normalizeFilters(request.filterModel);
41
- for (const p of predicates) {
42
- switch (p.op) {
43
- case 'in':
44
- q = q.in(p.column, p.values);
45
- break;
46
- case 'contains':
47
- q = q.ilike(p.column, `%${p.value}%`);
48
- break;
49
- case 'startsWith':
50
- q = q.ilike(p.column, `${p.value}%`);
51
- break;
52
- case 'eq':
53
- q = q.eq(p.column, p.value);
54
- break;
55
- case 'gt':
56
- q = q.gt(p.column, p.value);
57
- break;
58
- case 'lt':
59
- q = q.lt(p.column, p.value);
60
- break;
61
- case 'between':
62
- q = q.gte(p.column, p.value).lte(p.column, p.valueTo);
63
- break;
64
- case 'isNull':
65
- q = q.is(p.column, null);
66
- break;
67
- }
68
- }
69
- if (search && searchColumns.length) {
70
- const term = sanitize(search);
71
- q = q.or(searchColumns.map((c) => `${c}.ilike.%${term}%`).join(','));
72
- }
95
+ q = applyFilters(q);
73
96
  // When grouping, only columns the grouped select actually produces can be
74
97
  // ordered on - PostgREST rejects an ORDER BY over a column that is
75
98
  // neither grouped nor aggregated. Fall back to the group key so the
@@ -95,7 +118,17 @@ export function createSupabaseDataSource(config) {
95
118
  const { data, count, error } = await q.range(request.startRow, request.endRow - 1);
96
119
  if (error)
97
120
  throw new Error(error.message);
98
- return { rows: (data ?? []), rowCount: count ?? 0 };
121
+ const result = { rows: (data ?? []), rowCount: count ?? 0 };
122
+ // The grand total: one aggregate-only select over the filtered set,
123
+ // with no group column (so PostgREST returns a single row) and no path.
124
+ if (request.needsGrandTotal && aggregateSelects.length) {
125
+ const total = applyFilters(client.from(table).select(aggregateSelects.join(',')));
126
+ const { data: totalRows, error: totalError } = await total;
127
+ if (totalError)
128
+ throw new Error(totalError.message);
129
+ result.grandTotal = (totalRows?.[0] ?? null);
130
+ }
131
+ return result;
99
132
  },
100
133
  async createRow(input) {
101
134
  const rest = { ...input };
@@ -478,6 +478,17 @@ ${panels}
478
478
  // Dragging a card updates its groupBy value in the local row state (optimistic).
479
479
  return ` <div ${wrapperStyle(block)}${cls}>
480
480
  <SvBoard schema={${schemaVar}} rows={allRows} loading={!allRowsReady} groupBy=${JSON.stringify(cfg.groupBy)} titleField=${JSON.stringify(asText(cfg.titleField))}${badge}${sub}${onOpen} height={${h}} onMove={(id, value) => { allRows = allRows.map((r) => String((r as Record<string, unknown>)[idField]) === String(id) ? ({ ...r, ['${cfg.groupBy}']: value }) : r) }} />
481
+ </div>`;
482
+ }
483
+ case 'sheet': {
484
+ const h = block.height ?? 480;
485
+ // The shell reads `data` once at mount, so it mounts once the rows are in.
486
+ const chosen = cfg.fields?.length ? cfg.fields : entity.fields.map((f) => f.field);
487
+ const specs = chosen.map((field) => ({ field, label: entity.fields.find((f) => f.field === field)?.label ?? field }));
488
+ // Excel's sheet-name rules: none of []:*?/\ and at most 31 characters.
489
+ const sheetName = (entity.label ?? entity.name).replace(/[[\]:*?/\\]/g, ' ').trim().slice(0, 31) || 'Sheet1';
490
+ return ` <div ${wrapperStyle(block, `min-height: ${h}px`)}${cls}>
491
+ {#if allRowsReady}<SvSheet data={[{ name: ${JSON.stringify(sheetName)}, cells: sheetCellsFromRows(${rowsExpr}, ${JSON.stringify(specs)}, { totals: ${cfg.totals ? 'true' : 'false'} }) }]} height={${h}} />{/if}
481
492
  </div>`;
482
493
  }
483
494
  case 'calendar': {
@@ -1981,7 +1992,7 @@ function screenPage(schema, rawSchema, screen, resolve, rawResolve, accessEnable
1981
1992
  const exportApiVars = blocks.filter((b) => b.config.kind === 'grid' && gridHasExport(b.config) && !(codeGrid && b.id === codeGridBlockId)).map((b) => `gridApi_${b.id.replace(/-/g, '_')}`);
1982
1993
  const needsGridApiType = codeGrid || exportApiVars.length > 0;
1983
1994
  // The pivot reads the whole table (like charts / dashboards).
1984
- const needsAllRows = hasAgg || hasMD || hasPivot || hasBoundComponent || hasGroupedGrid || hasTreeGrid || hasSchedulerGrid || has(allBlocks, 'board') || has(allBlocks, 'calendar') || has(allBlocks, 'detail');
1995
+ const needsAllRows = hasAgg || hasMD || hasPivot || hasBoundComponent || hasGroupedGrid || hasTreeGrid || hasSchedulerGrid || has(allBlocks, 'board') || has(allBlocks, 'calendar') || has(allBlocks, 'detail') || has(allBlocks, 'sheet');
1985
1996
  // --- imports ---
1986
1997
  const gridSpecs = [];
1987
1998
  if (needsController)
@@ -2030,6 +2041,8 @@ function screenPage(schema, rawSchema, screen, resolve, rawResolve, accessEnable
2030
2041
  entImports.push('schemaToColumns');
2031
2042
  if (has(allBlocks, 'detail'))
2032
2043
  entImports.push('SvRecordDetail');
2044
+ if (has(allBlocks, 'sheet'))
2045
+ entImports.push('SvSheet', 'sheetCellsFromRows');
2033
2046
  if (has(allBlocks, 'kpi') || has(allBlocks, 'gauge') || hasAggregateBinding)
2034
2047
  entImports.push('reduceValue');
2035
2048
  const kpiCfgs = allBlocks.filter((b) => b.config.kind === 'kpi').map((b) => b.config);
@@ -36,6 +36,6 @@ export { resolveDeployTarget, deployCommands, missingEnvKeys, } from './deploy-c
36
36
  export { runStudioAdd, runStudioAddApp, resolveSchema, resolveSchemas, } from './cli.js';
37
37
  // Re-export the schema surface so consumers get everything from one entry.
38
38
  export { resolveIdField, schemaToColumns, schemaToFormFields, isFieldHidden, linkRelationLabels, pickLabelField, } from '../schema.js';
39
- // Pure license classification, so the Node/MCP generator can soft-gate with the
39
+ // Pure license classification, so the Node/MCP generator can nudge with the
40
40
  // same rules as the browser (see license-core.ts). No DOM, safe in Node.
41
41
  export { checkLicenseKey } from '../license-core.js';
@@ -95,7 +95,7 @@ export type EntityDataSource = MemorySource | RestSource | SqlSource | SupabaseS
95
95
  /** The kinds of block a screen can hold: data-bound (entity-derived) or the
96
96
  * entity-agnostic `'component'` (a UI-kit component from `UI_COMPONENT_REGISTRY`,
97
97
  * usable on any screen, including a freestanding one with no entity). */
98
- export type BlockKind = 'grid' | 'form' | 'chart' | 'dashboard' | 'kpi' | 'gauge' | 'tree' | 'tabs' | 'accordion' | 'master-detail' | 'lookup' | 'pivot' | 'filter' | 'record' | 'board' | 'calendar' | 'detail' | 'component';
98
+ export type BlockKind = 'grid' | 'form' | 'chart' | 'dashboard' | 'kpi' | 'gauge' | 'tree' | 'tabs' | 'accordion' | 'master-detail' | 'lookup' | 'pivot' | 'filter' | 'record' | 'board' | 'calendar' | 'detail' | 'sheet' | 'component';
99
99
  export type GridAlign = 'left' | 'center' | 'right';
100
100
  /** No-code per-column value formatting. Compiles to the grid's `format` (CellFormatConfig):
101
101
  * a raw `1234.5` becomes `$1,234.50` / `42%` / `Jun 27, 2026` without a code renderer. */
@@ -516,6 +516,15 @@ export type DetailConfig = {
516
516
  }[];
517
517
  related?: DetailRelated[];
518
518
  };
519
+ /** The entity's rows on the spreadsheet shell (SvSheet): a header row of field
520
+ * labels, a row per record, and, with `totals`, a SUM row under every numeric
521
+ * column. `fields` narrows and orders the columns (empty = every field). The
522
+ * sheet is Excel over the dataset: formulas, formats, filters and an xlsx out. */
523
+ export type SheetConfig = {
524
+ kind: 'sheet';
525
+ fields?: string[];
526
+ totals?: boolean;
527
+ };
519
528
  /** A UI-kit component (from `UI_COMPONENT_REGISTRY`, keyed by `component`) dropped
520
529
  * onto a screen. Entity-agnostic - works on a freestanding page or mixed onto an
521
530
  * entity-bound screen alike. `props` holds its configured "chrome" values, keyed
@@ -543,7 +552,7 @@ export type ComponentConfig = {
543
552
  name?: string;
544
553
  bindings?: Record<string, ComponentBinding>;
545
554
  };
546
- export type BlockConfig = GridConfig | FormConfig | ChartConfig | KpiConfig | GaugeConfig | TreeConfig | TabsConfig | AccordionConfig | DashboardConfig | MasterDetailConfig | LookupConfig | PivotConfig | FilterPanelConfig | RecordConfig | BoardConfig | CalendarConfig | DetailConfig | ComponentConfig;
555
+ export type BlockConfig = GridConfig | FormConfig | ChartConfig | KpiConfig | GaugeConfig | TreeConfig | TabsConfig | AccordionConfig | DashboardConfig | MasterDetailConfig | LookupConfig | PivotConfig | FilterPanelConfig | RecordConfig | BoardConfig | CalendarConfig | DetailConfig | SheetConfig | ComponentConfig;
547
556
  /** Block kinds allowed inside a Tabs / Accordion container: the controller-free,
548
557
  * `allRows`-driven display blocks (no grid / form / master-detail, which need the
549
558
  * screen controller). `component` covers any UI-kit component added by key. */
@@ -432,6 +432,7 @@ export const blockPalette = [
432
432
  { kind: 'board', label: 'Board' },
433
433
  { kind: 'calendar', label: 'Calendar' },
434
434
  { kind: 'detail', label: 'Detail page' },
435
+ { kind: 'sheet', label: 'Spreadsheet' },
435
436
  { kind: 'filter', label: 'Filter panel' },
436
437
  { kind: 'record', label: 'Record panel' },
437
438
  { kind: 'lookup', label: 'Lookup' },
@@ -538,6 +539,8 @@ export function defaultBlockConfig(kind, entity) {
538
539
  const metrics = nonKey.filter((f) => f.type === 'number').slice(0, 3).map((f) => f.field);
539
540
  return { kind, titleField: titleF, ...(subF ? { subtitleField: subF } : {}), ...(statusF ? { statusField: statusF } : {}), ...(metrics.length ? { metricFields: metrics } : {}) };
540
541
  }
542
+ case 'sheet':
543
+ return { kind, totals: entity.fields.some((f) => f.type === 'number' && !f.primaryKey) };
541
544
  case 'component':
542
545
  // Entity-agnostic - built directly by `addComponentBlock`, never through here.
543
546
  return { kind, component: '', props: {} };
@@ -554,7 +557,7 @@ export function pickFacetFields(entity) {
554
557
  }
555
558
  const facetRank = (t) => (t === 'enum' ? 0 : t === 'boolean' ? 1 : 2);
556
559
  const DEFAULT_SPAN = {
557
- grid: 3, form: 1, chart: 2, dashboard: 3, kpi: 1, gauge: 1, tree: 2, tabs: 3, accordion: 3, 'master-detail': 3, lookup: 1, pivot: 3, filter: 1, record: 1, board: 3, calendar: 3, detail: 3, component: 1,
560
+ grid: 3, form: 1, chart: 2, dashboard: 3, kpi: 1, gauge: 1, tree: 2, tabs: 3, accordion: 3, 'master-detail': 3, lookup: 1, pivot: 3, filter: 1, record: 1, board: 3, calendar: 3, detail: 3, sheet: 3, component: 1,
558
561
  };
559
562
  function makeBlock(kind, entity, taken) {
560
563
  return { id: uid(`${kind}-`, taken), span: DEFAULT_SPAN[kind], config: defaultBlockConfig(kind, entity) };
@@ -1249,7 +1252,7 @@ function dockPaneTitle(block) {
1249
1252
  grid: 'Grid', form: 'Form', chart: 'Chart', dashboard: 'Dashboard', tree: 'Tree', pivot: 'Pivot',
1250
1253
  filter: 'Filters', record: 'Record', detail: 'Detail', board: 'Board', calendar: 'Calendar',
1251
1254
  'master-detail': 'Master / detail', lookup: 'Lookup', tabs: 'Tabs', accordion: 'Accordion',
1252
- kpi: 'KPI', gauge: 'Gauge', component: 'Component',
1255
+ kpi: 'KPI', gauge: 'Gauge', sheet: 'Spreadsheet', component: 'Component',
1253
1256
  };
1254
1257
  return c.label || c.title || c.name || c.component || byKind[c.kind] || 'Panel';
1255
1258
  }
@@ -6583,6 +6583,7 @@ export const GENERATED_UI_SURFACE = {
6583
6583
  "key": "data",
6584
6584
  "label": "Data",
6585
6585
  "type": "json",
6586
+ "description": "The rows to render. Optional only because `rowModel` can supply them instead; a grid with neither renders empty. When both are present `data` wins.",
6586
6587
  "group": "common"
6587
6588
  },
6588
6589
  {
@@ -6605,6 +6606,13 @@ export const GENERATED_UI_SURFACE = {
6605
6606
  "description": "Scheduler / calendar mode. When set, the grid renders its rows as events on a Month / Week / Day / Agenda calendar instead of a table. See .",
6606
6607
  "group": "common"
6607
6608
  },
6609
+ {
6610
+ "key": "gantt",
6611
+ "label": "Gantt",
6612
+ "type": "json",
6613
+ "description": "Gantt mode. When set, the grid renders its rows as a task table beside a time chart: one bar per row by start / end, a work-breakdown tree from `parentField`, and dependency arrows. See . A view of the grid like the board and scheduler; the renderer ships in `@svgrid/enterprise` (call `enableGanttView()`).",
6614
+ "group": "common"
6615
+ },
6608
6616
  {
6609
6617
  "key": "chart",
6610
6618
  "label": "Chart",
@@ -7021,11 +7029,42 @@ export const GENERATED_UI_SURFACE = {
7021
7029
  "description": "Prepend a header row (the column labels) to copied cell ranges, so pasting into Excel / Sheets includes the headers. Applies per copied range.",
7022
7030
  "group": "common"
7023
7031
  },
7032
+ {
7033
+ "key": "processCellForFill",
7034
+ "label": "Process Cell For Fill",
7035
+ "type": "json",
7036
+ "description": "Decide what the fill handle writes into one cell, ahead of the grid's own pattern rules (series, weekdays, \"Item 1\"). Receives the source cell's value and how far the target sits from it; return the value to write, or `undefined` to let the pattern decide. A spreadsheet uses it to move a formula's references by the distance filled, which the pattern rules would otherwise mangle (\"=A1+B1\" reads as \"Item 1\").",
7037
+ "code": true,
7038
+ "group": "advanced"
7039
+ },
7024
7040
  {
7025
7041
  "key": "processCellForClipboard",
7026
7042
  "label": "Process Cell For Clipboard",
7027
7043
  "type": "json",
7028
- "description": "Transform each cell value on its way to the clipboard - e.g. strip currency symbols, expand codes to labels, or redact. Receives the display value plus the row/column context; return the string (or value) to copy.",
7044
+ "code": true,
7045
+ "group": "advanced"
7046
+ },
7047
+ {
7048
+ "key": "includeCollapsedRows",
7049
+ "label": "Include Collapsed Rows",
7050
+ "type": "json",
7051
+ "description": "Whether a collapsed row still takes part in a copy or a fill that spans it. Left out, both skip every collapsed row, which is what \"filter, copy, paste\" needs and what a fill dragged over a filtered list expects: the series runs over the rows that show. A spreadsheet answers per row: a row hidden by hand is copied and filled, as Excel does, while a row a filter folded away is not.",
7052
+ "code": true,
7053
+ "group": "advanced"
7054
+ },
7055
+ {
7056
+ "key": "clipboardHtml",
7057
+ "label": "Clipboard Html",
7058
+ "type": "json",
7059
+ "description": "An HTML rendering of what Ctrl+C copies, written to the clipboard as `text/html` beside the TSV. Excel and Google Sheets read the HTML first, so a table with inline styles pastes into them with its formats, and the same markup can carry what the text cannot (a formula in a `data-` attribute) for a round trip back into a grid that reads it. Called after every cell has been through `processCellForClipboard`, with the rectangles copied and the text about to be written. Return nothing to write text alone. Runs synchronously inside the key press, which is what the clipboard needs.",
7060
+ "code": true,
7061
+ "group": "advanced"
7062
+ },
7063
+ {
7064
+ "key": "processCellFromClipboard",
7065
+ "label": "Process Cell From Clipboard",
7066
+ "type": "json",
7067
+ "description": "Transform each cell on its way IN from the clipboard, before the grid coerces it for the column's editor. Symmetric with `processCellForClipboard`: the pair is what lets a round trip survive. Receives the raw clipboard text for the cell plus where it is landing. Return the value to write, or `undefined` to leave the cell untouched. This is also the seam a feature pack uses to take over a paste entirely: `@svgrid/enterprise`'s paste-special reads the clipboard's `text/html` for formats and formulas and writes through here.",
7029
7068
  "code": true,
7030
7069
  "group": "advanced"
7031
7070
  },
@@ -7036,6 +7075,13 @@ export const GENERATED_UI_SURFACE = {
7036
7075
  "description": "Inline cell editing: F2 or double-click opens an editor in the active cell, Enter commits, Esc cancels. Off by default. A column still needs an `editorType` to pick its editor (text, number, date, checkbox, list, ...); without one it gets a plain text editor. `editable` is the shortcut alias and wins over this.",
7037
7076
  "group": "common"
7038
7077
  },
7078
+ {
7079
+ "key": "editOnSecondClick",
7080
+ "label": "Edit On Second Click",
7081
+ "type": "boolean",
7082
+ "description": "A click on the cell that is already active opens its editor, the way a second click on a selected file name starts renaming it. On by default. A spreadsheet turns it off: Excel edits on double-click or F2 only, and a user clicking the cell they are on to get back to it after a dialog would otherwise find the next shortcut typed into an editor.",
7083
+ "group": "common"
7084
+ },
7039
7085
  {
7040
7086
  "key": "fullRowEditing",
7041
7087
  "label": "Full Row Editing",
@@ -7214,6 +7260,34 @@ export const GENERATED_UI_SURFACE = {
7214
7260
  "description": "Which rows feed the min/max range that `colorScale` / `dataBar` formats scale against. - `filtered` (default): every row that survives the filters, ignoring the page slice. The scale follows what you filtered to but does not shift when you page, so the same value keeps the same colour on page 1 and page 2. - `visible`: only the rows currently on screen. Rescales per page - use it when you want each page's heat map normalized to that page. - `all`: the full unfiltered dataset, for a scale that stays put as you filter.",
7215
7261
  "group": "common"
7216
7262
  },
7263
+ {
7264
+ "key": "rowPlaceholder",
7265
+ "label": "Row Placeholder",
7266
+ "type": "json",
7267
+ "description": "Marks a row as one whose data has not arrived: `\"loading\"` draws a shimmer in every cell, `\"failed\"` draws a full-width \"could not load\" row with a Retry button, and `null` (the default for every row) renders normally. Placeholder rows are inert - not selectable, not editable, and skipped by cell navigation - because there is nothing there to act on yet. `createServerDataSource` in `infinite` mode fills the gaps with rows this recognises, so the usual wiring is `rowPlaceholder={rowPlaceholderState}` (or nothing at all, via `rowModel`).",
7268
+ "code": true,
7269
+ "group": "advanced"
7270
+ },
7271
+ {
7272
+ "key": "rowModel",
7273
+ "label": "Row Model",
7274
+ "type": "json",
7275
+ "description": "Drive the grid from a row model instead of wiring a dozen props. `createServerDataSource` returns one, and so does the Enterprise server-side row model, so server-backed grids become: ```svelte <SvGrid rowModel={ctl} {columns} /> ``` The model supplies `data`, `loading`, `getRowId`, the external sort and filter wiring, the visible range, placeholder rows, group accessors, selection and paging - each one only if it implements that part. A prop written explicitly on the grid always wins, so you can adopt it and still override one piece.",
7276
+ "group": "common"
7277
+ },
7278
+ {
7279
+ "key": "pivotResultColumns",
7280
+ "label": "Pivot Result Columns",
7281
+ "type": "json",
7282
+ "description": "Columns that REPLACE `columns` while set. The server-side row model supplies them in pivot mode - one column per pivoted value, grouped under a header per pivot key - and clears them when pivot mode ends, so `columns` stays the app's own list. Rarely set by hand.",
7283
+ "group": "common"
7284
+ },
7285
+ {
7286
+ "key": "rowSelectionModel",
7287
+ "label": "Row Selection Model",
7288
+ "type": "json",
7289
+ "group": "common"
7290
+ },
7217
7291
  {
7218
7292
  "key": "isDetailRow",
7219
7293
  "label": "Is Detail Row",
@@ -7222,11 +7296,41 @@ export const GENERATED_UI_SURFACE = {
7222
7296
  "code": true,
7223
7297
  "group": "advanced"
7224
7298
  },
7299
+ {
7300
+ "key": "detailRowHeight",
7301
+ "label": "Detail Row Height",
7302
+ "type": "number",
7303
+ "description": "The height of a detail row, in px, or a function of its data. With it the virtualizer can size detail rows, so master-detail works with `virtualization` on (the panel scrolls inside its cell when taller). Without it a detail row is auto height, which needs `virtualization={false}`.",
7304
+ "group": "common"
7305
+ },
7306
+ {
7307
+ "key": "showDetailToggle",
7308
+ "label": "Show Detail Toggle",
7309
+ "type": "boolean",
7310
+ "description": "A row-header column of chevrons that open and close detail rows. It sits with the row-number and selection columns: sticky at the left, no column menu, not resizable, not reorderable, outside the active cell and the selection. The chevron calls `onDetailToggle` (or, on a server row model, the model's own toggle) and reads `isDetailOpen` for its direction; `hasDetail` hides it on rows that have nothing to open. Detail rows themselves get an empty cell.",
7311
+ "group": "common"
7312
+ },
7313
+ {
7314
+ "key": "isDetailOpen",
7315
+ "label": "Is Detail Open",
7316
+ "type": "json",
7317
+ "description": "Whether the detail under a row is open: the chevron's direction and `aria-expanded`.",
7318
+ "code": true,
7319
+ "group": "advanced"
7320
+ },
7321
+ {
7322
+ "key": "hasDetail",
7323
+ "label": "Has Detail",
7324
+ "type": "json",
7325
+ "description": "Whether a row has a detail to open; the chevron is left out where this returns false.",
7326
+ "code": true,
7327
+ "group": "advanced"
7328
+ },
7225
7329
  {
7226
7330
  "key": "serverGroup",
7227
7331
  "label": "Server Group",
7228
7332
  "type": "json",
7229
- "description": "Server-side group / tree keyboard + accessibility, built into the grid. When set, the grid uses the treegrid role and marks matching rows with `aria-level` / `aria-expanded`, and ArrowRight / ArrowLeft expand / collapse the focused group row (no app-level key handling). Pair with `serverGroupRows` + `SvGroupCell` for the visual expander. Every accessor receives the row data.",
7333
+ "description": "Server-side group / tree keyboard + accessibility, built into the grid. When set, the grid uses the treegrid role and marks matching rows with `aria-level` / `aria-expanded`, and ArrowRight / ArrowLeft expand / collapse the focused group row (no app-level key handling). Pair with `serverGroupRows` + `SvGroupCell` from `@svgrid/enterprise` for the visual expander, or drive it from your own tree state. Every accessor receives the row data.",
7230
7334
  "group": "common"
7231
7335
  },
7232
7336
  {
@@ -7244,6 +7348,27 @@ export const GENERATED_UI_SURFACE = {
7244
7348
  "description": "Rows to pin to the TOP of the grid - rendered above the regular rows and sticky-positioned so they stay visible while the user scrolls. Typical use: a \"totals\" or \"headline\" row that should always be in view. Rows are read-only (no inline editing, no row-selection checkbox). They share the column schema with the main grid; field/format/cell/cellClass all apply.",
7245
7349
  "group": "common"
7246
7350
  },
7351
+ {
7352
+ "key": "frozenRows",
7353
+ "label": "Frozen Rows",
7354
+ "type": "number",
7355
+ "description": "Freeze the first N rows: they stay under the header while the body scrolls, and unlike `pinnedTopRows` they are the grid's own rows, still editable, selectable and numbered as rows 1..N. Excel's Freeze Panes, for the row half; the column half is `columnPinning`. Under `virtualization` the frozen rows are always rendered and the window skips them.",
7356
+ "group": "common"
7357
+ },
7358
+ {
7359
+ "key": "stickyGroupRows",
7360
+ "label": "Sticky Group Rows",
7361
+ "type": "boolean",
7362
+ "description": "Keep the group a row belongs to in view: while the rows of an open group scroll past, the group's row (and its parents' rows) stay under the header, the way a section heading stays put in a long list, so a screen deep inside a 60,000-row group still says which group it is. Works for server-side groups (`rowModel` / `serverGroup`), client grouping and tree data. Under `virtualization` the band shows a copy of each ancestor row; without it the rows themselves stick. Off by default.",
7363
+ "group": "common"
7364
+ },
7365
+ {
7366
+ "key": "mergedCells",
7367
+ "label": "Merged Cells",
7368
+ "type": "json",
7369
+ "description": "Merged cells: rectangles drawn as one cell, a spreadsheet's Merge & Center. Each entry is the top-left cell (display indices) and how many rows and columns it covers. The origin's td takes the span and shows the origin's value; the covered cells are not drawn, a selection grows to whole merges, the active cell inside a merge is its origin, and the arrow keys step over a merge as one cell. A merge that crosses the frozen boundary or the rendered window is drawn in parts, one per band. The grid does not write into covered cells on its own; a consumer that merges cells keeps them empty or marks them read-only through the column's `editable`.",
7370
+ "group": "common"
7371
+ },
7247
7372
  {
7248
7373
  "key": "pinnedBottomRows",
7249
7374
  "label": "Pinned Bottom Rows",
@@ -7320,6 +7445,24 @@ export const GENERATED_UI_SURFACE = {
7320
7445
  "prop": "onPaginationChange",
7321
7446
  "description": "Fires when the user changes page or page size while `externalPagination` is on. Fetch that page and update `data` / `rowCount` / `pageIndex`."
7322
7447
  },
7448
+ {
7449
+ "key": "columnResize",
7450
+ "label": "Column Resize",
7451
+ "prop": "onColumnResize",
7452
+ "description": "The user dragged a column's edge (or double-clicked it to autosize). Programmatic `api.setColumnWidth` does not fire it."
7453
+ },
7454
+ {
7455
+ "key": "rowResize",
7456
+ "label": "Row Resize",
7457
+ "prop": "onRowResize",
7458
+ "description": "The user dragged a row's edge, or double-clicked it: `height` is then `null`, the row back at its declared height. Programmatic `api.setRowHeight` does not fire it."
7459
+ },
7460
+ {
7461
+ "key": "pasteClipboard",
7462
+ "label": "Paste Clipboard",
7463
+ "prop": "onPasteClipboard",
7464
+ "description": "Take over a paste. Receives the clipboard's `text/plain` and, when the source put one there, its `text/html` (Excel's carries formats and formulas; a grid's own `clipboardHtml` carries whatever it chose to). Return `true` to say the paste was applied; anything else lets the grid paste the text as it always has. Runs inside one history group, so every `setCellValue` and `recordUndo` the handler makes is one Ctrl+Z. With this set, Ctrl+V lets the browser's own `paste` event through (that is where the unsanitised HTML is), and the async Clipboard API is the fallback for a browser that does not deliver it. `source` says which path the payload came by."
7465
+ },
7323
7466
  {
7324
7467
  "key": "apiReady",
7325
7468
  "label": "Api Ready",
@@ -7336,7 +7479,7 @@ export const GENERATED_UI_SURFACE = {
7336
7479
  "key": "cellSelectionChange",
7337
7480
  "label": "Cell Selection Change",
7338
7481
  "prop": "onCellSelectionChange",
7339
- "description": "Fires whenever the cell-selection rectangle changes (mouse, keyboard, or `api.selectCells()`). `ranges` matches `api.getSelected()` - `[rowStart, colStart, rowEnd, colEnd]` rectangles in grid coords. Empty array when the user clears the selection."
7482
+ "description": "Fires whenever the cell selection changes (mouse, keyboard, or `api.selectCells()`). `ranges` is every selected rectangle, matching `api.getSelected()`: the ones a Ctrl+click committed and the active one last, each `[rowStart, colStart, rowEnd, colEnd]` in grid coords. Empty array when the user clears the selection."
7340
7483
  },
7341
7484
  {
7342
7485
  "key": "sortingChange",
@@ -7404,6 +7547,24 @@ export const GENERATED_UI_SURFACE = {
7404
7547
  "prop": "onScrollBottomReached",
7405
7548
  "description": "Fires once each time the body is scrolled to (within ~32px of) the bottom. Re-arms after the user scrolls back up. The canonical hook for infinite / lazy loading - append more rows to `data` when it fires."
7406
7549
  },
7550
+ {
7551
+ "key": "visibleRangeChange",
7552
+ "label": "Visible Range Change",
7553
+ "prop": "onVisibleRangeChange",
7554
+ "description": "Fires when the range of rows on screen changes, with the first and last row INDEX (not pixels). Coalesced to one call per frame, so it is cheap to wire to something that fetches. This is the hook a block-loading data source needs and `onScrollBottomReached` cannot give it: \"the user is looking at rows 4,000-4,020\" answers which block to fetch and which to keep, while \"they hit the bottom\" only ever means \"append more\". Both are free; use this one with `createServerDataSource({ mode: 'infinite' })`, or let `rowModel` wire it for you. Reports `0, data.length - 1` when virtualization is off, since every row really is rendered."
7555
+ },
7556
+ {
7557
+ "key": "retryRow",
7558
+ "label": "Retry Row",
7559
+ "prop": "onRetryRow",
7560
+ "description": "Called by the Retry button on a `\"failed\"` placeholder row."
7561
+ },
7562
+ {
7563
+ "key": "detailToggle",
7564
+ "label": "Detail Toggle",
7565
+ "prop": "onDetailToggle",
7566
+ "description": "Open or close the detail under a row. The chevron of `showDetailToggle` and Ctrl+Enter on a row call it; you keep the open set and insert or remove the detail row in `data`. A server row model supplies its own (the `rowModel` prop wires `toggleDetail`), so this is the client side."
7567
+ },
7407
7568
  {
7408
7569
  "key": "columnOrderChange",
7409
7570
  "label": "Column Order Change",
@@ -7415,6 +7576,12 @@ export const GENERATED_UI_SURFACE = {
7415
7576
  "label": "Row Drag End",
7416
7577
  "prop": "onRowDragEnd",
7417
7578
  "description": "Fires on the TARGET grid after a managed row drag settles, with the moved row, its landing index, whether it stayed in the same grid, and the source / target grid ids. Use it to mirror the move into your own state (persistence, server sync). The grid has already applied the change to its internal data by the time this fires."
7579
+ },
7580
+ {
7581
+ "key": "rowDrop",
7582
+ "label": "Row Drop",
7583
+ "prop": "onRowDrop",
7584
+ "description": "Take the drop yourself. With this set the grid keeps the drag affordance and the drop indicator but does not touch its data: the handler gets the dragged row, the row it landed on (null for the empty space below the rows) and the side - `before` / `after`, or `into` when it landed on the middle of a group or tree row, which makes it that row's child. The path for a `rowModel`, whose rows the grid does not own: hand the move to the model (`moveRow`) or to your server. Only fires within one grid; a drop from another grid stays managed."
7418
7585
  }
7419
7586
  ]
7420
7587
  }