@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
@@ -0,0 +1,215 @@
1
+ /**
2
+ * The spreadsheet shell: everything between the ribbon and the sheet tabs.
3
+ *
4
+ * SvSheetRibbon Home / Insert / Formulas / Data
5
+ * SvFormulaBar Name Box + fx, showing the RAW text of the active cell
6
+ * SvGrid A..Z column headers over the built-in 1..N gutter
7
+ * SvSheetTabs sheet tabs
8
+ * status bar Sum / Average / Count of the selection, as Excel has
9
+ *
10
+ * Composition, not a second grid. Every part here already existed and was
11
+ * being re-assembled by hand in four separate demos; the value of the
12
+ * component is that the wiring BETWEEN them is done once and correctly -
13
+ * the formula bar shows the raw text rather than the computed value, the
14
+ * format store is keyed by row id so sorting cannot strand formatting, the
15
+ * ribbon and the keyboard run the same actions, and the tab strip is told
16
+ * when a shortcut moved the active sheet.
17
+ *
18
+ * <SvSheet workbook={wb} />
19
+ *
20
+ * That is the whole required API. Everything else is opt-out.
21
+ */
22
+ import { type SvGridApi, type TableFeatures } from '@svgrid/grid';
23
+ import type { GridCommandContext } from '@svgrid/grid/shortcuts';
24
+ import type { Workbook, SheetData } from './sheet/workbook.js';
25
+ import { type SheetDocument, type SheetState, type SheetChangeReason } from './sheet/document.js';
26
+ import { type CellFormatEntry } from './sheet/format-store.js';
27
+ import { type SheetPresence } from './sheet/presence.js';
28
+ import { type SheetLocalization } from './sheet/messages.js';
29
+ import { type GridSheetSpec } from './sheet/sheet-kinds.js';
30
+ import { type Rect } from './sheet/rects.js';
31
+ import type { RibbonActionId } from './sheet/ribbon.js';
32
+ /**
33
+ * A grid row carries the RAW text of every cell on it, keyed by column
34
+ * letter, as well as its position.
35
+ *
36
+ * It would be tempting to keep the values only in the workbook and let the
37
+ * cell snippet read them, since the snippet is what paints. That does not
38
+ * work, and not only for rendering: the grid's own machinery reads
39
+ * `row[field]`, so an empty row object means `cmd.getCellValue` returns
40
+ * undefined for every cell, and then Ctrl+Arrow thinks the sheet is blank,
41
+ * AutoSum finds no run to total, and the inline editor has nothing to open
42
+ * on. The workbook stays authoritative; this is its projection.
43
+ */
44
+ type SheetRow = {
45
+ id: string;
46
+ index: number;
47
+ } & Record<string, string | number>;
48
+ type SheetApi = SvGridApi<TableFeatures, SheetRow>;
49
+ type Props = {
50
+ /**
51
+ * The document to edit: the workbook plus everything a sheet keeps beside
52
+ * its cells (formats, sizes, hidden lines, frozen panes, comments). Build
53
+ * one with `createSheetDocument` to save it, restore it or listen to it
54
+ * outside the component; without it the shell makes its own from
55
+ * `workbook` or `data` and hands it back through `onReady`.
56
+ */
57
+ document?: SheetDocument;
58
+ /** The workbook to edit. One is created from `data` when absent. */
59
+ workbook?: Workbook;
60
+ /** Seed sheets, when not supplying a workbook. */
61
+ data?: ReadonlyArray<SheetData>;
62
+ /**
63
+ * Tabs that are a bound table rather than a cell grid, by name.
64
+ *
65
+ * Each one keeps records instead of cells and renders as a grid, and
66
+ * its records are projected into the workbook's cells, so
67
+ * `=SUM(Orders!D2:D99)` on a cell tab reads it like any other sheet.
68
+ * A name here that `data` does not list is added as a new tab.
69
+ */
70
+ gridSheets?: Record<string, GridSheetSpec>;
71
+ /** Minimum grid size, so a sparse sheet still looks like a sheet. */
72
+ rows?: number;
73
+ columns?: number;
74
+ /**
75
+ * Grid viewport height in pixels, or `'100%'` to fill the parent.
76
+ *
77
+ * The chrome around the grid - ribbon, formula bar, tabs, status bar -
78
+ * is about 290px tall, so a fixed grid height is a fixed component
79
+ * height with that added on. In a flex column that is too tall for the
80
+ * space, the tab strip is what gets pushed under whatever comes next.
81
+ * With `'100%'` the component is a flex item that fills its column and
82
+ * the grid takes whatever the chrome leaves.
83
+ */
84
+ height?: number | '100%';
85
+ /** Default column width. */
86
+ columnWidth?: number;
87
+ /** Row height in pixels. Excel's is 20 at 100%; 22 fits the grid's 13px font. */
88
+ rowHeight?: number;
89
+ /**
90
+ * `theme` (the default) paints the shell with the host's `--sg-*`
91
+ * tokens, so it follows whatever theme the app around it runs, as the
92
+ * grid does. `excel` pins Excel's own palette and geometry, light or
93
+ * dark with the page, for an app that wants it to read as Excel
94
+ * whatever the theme.
95
+ */
96
+ look?: 'excel' | 'theme';
97
+ /**
98
+ * Per-column overrides, keyed by column letter: `{ A: 150 }`.
99
+ *
100
+ * A sheet's first column usually holds labels and the rest hold numbers,
101
+ * so one width for all of them truncates the only column that needs the
102
+ * room. Columns stay drag-resizable either way.
103
+ */
104
+ columnWidths?: Readonly<Record<string, number>>;
105
+ /**
106
+ * Cell formats to start with, keyed by A1 address: `{ B2: { bold: true },
107
+ * 'E13': { numFmt: '0.0%' } }`.
108
+ *
109
+ * A bare address formats the sheet that is active when the shell mounts.
110
+ * Qualify it to reach another sheet, the way a formula would:
111
+ * `{ 'Orders!F2': { numFmt: '$#,##0.00' }, "'Price list'!C2": ... }`.
112
+ * Formats are per sheet, as they are in Excel; a fill on Summary!C5 says
113
+ * nothing about Orders!C5.
114
+ *
115
+ * Without this the sheet can only be formatted by hand after it loads,
116
+ * which makes it impossible to ship a document that opens looking the way
117
+ * it was saved. Applied once at mount; after that the stores own it.
118
+ */
119
+ formats?: Readonly<Record<string, CellFormatEntry>>;
120
+ /**
121
+ * Kept for the applications that passed it: the shell answers Insert >
122
+ * Table and Insert > Chart itself now, so nothing has to be listed
123
+ * here. An application that wants its own can still take either over
124
+ * through `onAction`.
125
+ *
126
+ * @deprecated Both buttons are always on.
127
+ */
128
+ extras?: ReadonlyArray<'insert-table' | 'insert-chart'>;
129
+ /**
130
+ * The shell's language: `text` overrides any of its strings (the
131
+ * ribbon's, the dialogs', the status bar's; see `SheetMessages`) and
132
+ * `locale` formats the status bar's numbers and the grid's own
133
+ * matching. Unset keys stay English, so a partial map is fine.
134
+ */
135
+ localization?: SheetLocalization;
136
+ /**
137
+ * Who signs a comment: the name a new comment and a reply carry, the
138
+ * way Excel signs a threaded comment with the signed-in user. Unset,
139
+ * a new comment is a plain note and a reply carries its time alone.
140
+ */
141
+ commentAuthor?: string;
142
+ /** Hide any part of the chrome. */
143
+ showRibbon?: boolean;
144
+ showFormulaBar?: boolean;
145
+ showTabs?: boolean;
146
+ showStatusBar?: boolean;
147
+ /**
148
+ * Every action the ribbon, the cell menu, the formula bar and the
149
+ * shortcuts raise. The shell has a dialog of its own for Find and
150
+ * Replace, Paste Special, Format Cells and Insert Function; a handler
151
+ * that returns `true` has taken the action over and the shell's dialog
152
+ * stays closed, so an application can put its own in their place.
153
+ */
154
+ onAction?: (action: RibbonActionId, cmd: GridCommandContext) => void | boolean;
155
+ /**
156
+ * A button drawn in a cell was pressed. `action` is the region's own
157
+ * `action`, or its id when it has none, so a sheet can tell one column
158
+ * of buttons from another.
159
+ */
160
+ onCellAction?: (event: {
161
+ row: number;
162
+ col: number;
163
+ action: string;
164
+ sheet: string;
165
+ }) => void;
166
+ onReady?: (api: SheetApi, document: SheetDocument) => void;
167
+ /**
168
+ * Something the user did landed in the document: a cell, a format, a
169
+ * size, a hidden line, a frozen pane, a sheet, a comment, or a structural
170
+ * edit. Called once per tick with every reason since the last call, so a
171
+ * paste of forty cells is one call; the natural place for an autosave
172
+ * (`getState()`, debounced). Undo and redo report too.
173
+ */
174
+ onChange?: (reasons: ReadonlyArray<SheetChangeReason>) => void;
175
+ /**
176
+ * Other people on this workbook: each one's sheet, selection, name and
177
+ * colour, drawn over the cells as a coloured box with a tag.
178
+ *
179
+ * Presence is not part of the document and is never saved: a cursor
180
+ * belongs to a session. It comes in as a prop so the transport stays
181
+ * the application's, and `createDeltaStream` carries it for an
182
+ * application that wants one wire for both.
183
+ */
184
+ presence?: ReadonlyArray<SheetPresence>;
185
+ /**
186
+ * Where THIS user is, every time it moves: the sheet, the selection and
187
+ * the active cell. What an application broadcasts as its own presence.
188
+ */
189
+ onPresence?: (me: {
190
+ sheet: string;
191
+ rect: Rect;
192
+ active: {
193
+ row: number;
194
+ col: number;
195
+ };
196
+ }) => void;
197
+ };
198
+ declare const SvSheet: import("svelte").Component<Props, {
199
+ getState: () => SheetState;
200
+ setState: (state: SheetState) => void;
201
+ open: (file: Blob & {
202
+ name?: string;
203
+ }) => Promise<void>;
204
+ toXlsx: () => Promise<Blob>;
205
+ toOds: () => Promise<Blob>;
206
+ toXls: () => Blob;
207
+ toCsv: () => string;
208
+ printHtml: () => string;
209
+ print: () => void;
210
+ newWorkbook: () => void;
211
+ refresh: () => void;
212
+ act: (action: RibbonActionId) => void;
213
+ }, "">;
214
+ type SvSheet = ReturnType<typeof SvSheet>;
215
+ export default SvSheet;
@@ -0,0 +1,151 @@
1
+ <script lang="ts">
2
+ /**
3
+ * Excel's Chart Design tab, as the one dialog the sheet needs: the chart
4
+ * type, its title, whether the range's first row and column are labels,
5
+ * whether a series is a column of the range or a row, and stacking.
6
+ * Opened by a double-click on a chart or by Chart Setup on the ribbon
7
+ * while one is selected. Delete removes the chart.
8
+ */
9
+ import { useSheetText } from './sheet-text'
10
+ import { SvModal } from '@svgrid/grid'
11
+ import {
12
+ SHEET_CHART_TYPES, SHEET_CHART_TRENDS, copyObject,
13
+ type SheetChartObject, type SheetChartType, type SheetChartTrend,
14
+ } from './sheet/objects'
15
+ import { colToLetters } from './sheet/address'
16
+
17
+ type Props = {
18
+ open?: boolean
19
+ /** The chart as it stands. */
20
+ chart: SheetChartObject
21
+ /**
22
+ * The series it is drawing, by the labels the range gives them: what
23
+ * the secondary-axis list offers. The dialog has the chart, not the
24
+ * cells, so the shell reads them off the drawing.
25
+ */
26
+ seriesLabels?: ReadonlyArray<string>
27
+ onApply: (chart: SheetChartObject) => void
28
+ onDelete: () => void
29
+ onClose?: () => void
30
+ }
31
+
32
+ let { open = $bindable(false), chart, seriesLabels = [], onApply, onDelete, onClose }: Props = $props()
33
+ const t = useSheetText()
34
+
35
+ let type = $state<SheetChartType>('bar')
36
+ let title = $state('')
37
+ let headers = $state(true)
38
+ let series = $state<'columns' | 'rows'>('columns')
39
+ let stacked = $state(false)
40
+ let trend = $state<SheetChartTrend | ''>('')
41
+ let secondary = $state('')
42
+ let first = $state<HTMLSelectElement | null>(null)
43
+
44
+ $effect(() => {
45
+ if (!open) return
46
+ type = chart.type
47
+ title = chart.title ?? ''
48
+ headers = chart.headers
49
+ series = chart.series
50
+ stacked = Boolean(chart.stacked)
51
+ trend = chart.trend ?? ''
52
+ secondary = chart.secondary ?? ''
53
+ queueMicrotask(() => first?.focus())
54
+ })
55
+
56
+ const rangeText = $derived.by(() => {
57
+ const [r1, c1, r2, c2] = chart.range
58
+ return `${colToLetters(c1)}${r1 + 1}:${colToLetters(c2)}${r2 + 1}`
59
+ })
60
+ /** Stacking means nothing on a pie or a scatter. */
61
+ const stackable = $derived(type === 'bar' || type === 'area' || type === 'line')
62
+ /** A pie has one axis and no trend to draw over it. */
63
+ const twoAxes = $derived(type !== 'pie')
64
+
65
+ function ok() {
66
+ const next = copyObject(chart) as SheetChartObject
67
+ next.type = type
68
+ next.headers = headers
69
+ next.series = series
70
+ if (title.trim()) next.title = title.trim()
71
+ else delete next.title
72
+ if (stacked && stackable) next.stacked = true
73
+ else delete next.stacked
74
+ // A pie has one axis and no line to trend, so neither setting survives
75
+ // a change to one: keeping a hidden setting is how a dialog lies.
76
+ if (trend && twoAxes) next.trend = trend
77
+ else delete next.trend
78
+ // A second axis means nothing on a pie, and nothing for a series that
79
+ // is no longer there.
80
+ if (secondary && twoAxes && seriesLabels.includes(secondary)) next.secondary = secondary
81
+ else delete next.secondary
82
+ open = false
83
+ onApply(next)
84
+ onClose?.()
85
+ }
86
+
87
+ function close() {
88
+ open = false
89
+ onClose?.()
90
+ }
91
+ </script>
92
+
93
+ <SvModal bind:open onClose={onClose} title={t('chartSetup.title')} size="sm">
94
+ <form class="sv-sheet-dialog" onsubmit={(e) => { e.preventDefault(); ok() }}>
95
+ <div class="where">{t('chartSetup.range', { range: rangeText })}</div>
96
+ <label class="field">
97
+ <span>{t('chartSetup.type')}</span>
98
+ <select bind:this={first} bind:value={type}>
99
+ {#each SHEET_CHART_TYPES as kind (kind)}<option value={kind}>{t(`chartSetup.type.${kind}`)}</option>{/each}
100
+ </select>
101
+ </label>
102
+ <label class="field">
103
+ <span>{t('chartSetup.chartTitle')}</span>
104
+ <input type="text" bind:value={title} spellcheck="false" placeholder={t('chartSetup.titlePlaceholder')} />
105
+ </label>
106
+ <label class="field">
107
+ <span>{t('chartSetup.series')}</span>
108
+ <select bind:value={series}>
109
+ <option value="columns">{t('chartSetup.series.columns')}</option>
110
+ <option value="rows">{t('chartSetup.series.rows')}</option>
111
+ </select>
112
+ </label>
113
+ {#if twoAxes}
114
+ <label class="field">
115
+ <span>{t('chartSetup.trend')}</span>
116
+ <select bind:value={trend}>
117
+ <option value="">{t('chartSetup.trend.none')}</option>
118
+ {#each SHEET_CHART_TRENDS as kind (kind)}<option value={kind}>{t(`chartSetup.trend.${kind}`)}</option>{/each}
119
+ </select>
120
+ </label>
121
+ {#if seriesLabels.length > 1}
122
+ <label class="field">
123
+ <span>{t('chartSetup.secondary')}</span>
124
+ <select bind:value={secondary}>
125
+ <option value="">{t('chartSetup.secondary.none')}</option>
126
+ {#each seriesLabels as label (label)}<option value={label}>{label}</option>{/each}
127
+ </select>
128
+ </label>
129
+ {/if}
130
+ {/if}
131
+ <div class="checks">
132
+ <label class="check"><input type="checkbox" bind:checked={headers} /> {t('chartSetup.headers')}</label>
133
+ {#if stackable}
134
+ <label class="check"><input type="checkbox" bind:checked={stacked} /> {t('chartSetup.stacked')}</label>
135
+ {/if}
136
+ </div>
137
+ <p class="hint">{t('chartSetup.hint')}</p>
138
+ </form>
139
+ {#snippet footer()}
140
+ <div class="sv-sheet-dialog-buttons">
141
+ <button type="button" class="btn" onclick={() => { open = false; onDelete() }}>{t('delete')}</button>
142
+ <span class="spacer"></span>
143
+ <button type="button" class="btn primary" onclick={ok}>{t('ok')}</button>
144
+ <button type="button" class="btn" onclick={close}>{t('cancel')}</button>
145
+ </div>
146
+ {/snippet}
147
+ </SvModal>
148
+
149
+ <style>
150
+ .spacer { flex: 1; }
151
+ </style>
@@ -0,0 +1,18 @@
1
+ import { type SheetChartObject } from './sheet/objects.js';
2
+ type Props = {
3
+ open?: boolean;
4
+ /** The chart as it stands. */
5
+ chart: SheetChartObject;
6
+ /**
7
+ * The series it is drawing, by the labels the range gives them: what
8
+ * the secondary-axis list offers. The dialog has the chart, not the
9
+ * cells, so the shell reads them off the drawing.
10
+ */
11
+ seriesLabels?: ReadonlyArray<string>;
12
+ onApply: (chart: SheetChartObject) => void;
13
+ onDelete: () => void;
14
+ onClose?: () => void;
15
+ };
16
+ declare const SvSheetChartSetup: import("svelte").Component<Props, {}, "open">;
17
+ type SvSheetChartSetup = ReturnType<typeof SvSheetChartSetup>;
18
+ export default SvSheetChartSetup;
@@ -0,0 +1,283 @@
1
+ <script lang="ts">
2
+ /**
3
+ * The comment box: Excel's note editor for a new comment, and its
4
+ * threaded comment card once one is there. New: a textarea over the
5
+ * text, Save, and the text kept whatever closes the box (Escape and a
6
+ * click elsewhere included), which is why every keystroke is reported
7
+ * through `onDraft` and the shell saves the draft on dismissal;
8
+ * Ctrl+Enter saves too. Existing: the first entry with its author and
9
+ * time, the replies under it, Edit and Delete on each, a reply box,
10
+ * and Resolve / Reopen in the head. Replies, edits and the resolved
11
+ * state go out whole through `onUpdate`; the first text through
12
+ * `onSave`, as before; Delete removes the thread. The shell mounts it
13
+ * inside the popover anchored to the cell.
14
+ */
15
+ import { useSheetText } from './sheet-text'
16
+ import type { CommentThread, CommentEntry } from './sheet/comments'
17
+
18
+ type Props = {
19
+ /** The comment as it is, null for a new one. */
20
+ thread: CommentThread | null
21
+ /** The first text as it stands, the draft the box opens on. */
22
+ text: string
23
+ /** A1 of the cell, for the heading. */
24
+ address: string
25
+ /** Who signs a reply, when the application says. */
26
+ author?: string
27
+ /** For the times. */
28
+ locale?: string
29
+ /** Every change of the first text, so the shell can keep it on dismissal. */
30
+ onDraft: (text: string) => void
31
+ onSave: (text: string) => void
32
+ onDelete: () => void
33
+ /** A reply, an edited or deleted reply, or Resolve / Reopen: the whole thread as it should be. */
34
+ onUpdate: (thread: CommentThread) => void
35
+ }
36
+
37
+ let { thread, text, address, author, locale, onDraft, onSave, onDelete, onUpdate }: Props = $props()
38
+ const t = useSheetText()
39
+
40
+ let draft = $state('')
41
+ let editingRoot = $state(false)
42
+ let reply = $state('')
43
+ let editingReply = $state<number | null>(null)
44
+ let replyDraft = $state('')
45
+ let box = $state<HTMLTextAreaElement | null>(null)
46
+ let replyBox = $state<HTMLTextAreaElement | null>(null)
47
+
48
+ $effect(() => {
49
+ draft = text
50
+ editingRoot = false
51
+ editingReply = null
52
+ reply = ''
53
+ queueMicrotask(() => {
54
+ const target = thread ? replyBox : box
55
+ if (!target) return
56
+ target.focus()
57
+ target.setSelectionRange(target.value.length, target.value.length)
58
+ })
59
+ })
60
+
61
+ const composing = $derived(!thread || editingRoot)
62
+
63
+ function when(at: string | undefined): string {
64
+ if (!at) return ''
65
+ const ms = Date.parse(at)
66
+ if (!Number.isFinite(ms)) return ''
67
+ try {
68
+ return new Date(ms).toLocaleString(locale, { dateStyle: 'medium', timeStyle: 'short' })
69
+ } catch {
70
+ return new Date(ms).toLocaleString(undefined, { dateStyle: 'medium', timeStyle: 'short' })
71
+ }
72
+ }
73
+
74
+ const stamp = (): Pick<CommentEntry, 'author' | 'at'> => ({ ...(author ? { author } : {}), at: new Date().toISOString() })
75
+
76
+ function saveRoot() {
77
+ editingRoot = false
78
+ onSave(draft)
79
+ }
80
+
81
+ function postReply() {
82
+ const body = reply.trim()
83
+ if (!thread || !body) return
84
+ onUpdate({ ...thread, replies: [...(thread.replies ?? []), { text: body, ...stamp() }] })
85
+ reply = ''
86
+ }
87
+
88
+ function saveReply(index: number) {
89
+ if (!thread) return
90
+ const body = replyDraft.trim()
91
+ const replies = (thread.replies ?? []).map((r, i) => (i === index ? { ...r, text: body } : r)).filter((r) => r.text)
92
+ editingReply = null
93
+ onUpdate({ ...thread, replies })
94
+ }
95
+
96
+ function deleteReply(index: number) {
97
+ if (!thread) return
98
+ onUpdate({ ...thread, replies: (thread.replies ?? []).filter((_, i) => i !== index) })
99
+ }
100
+
101
+ function setResolved(resolved: boolean) {
102
+ if (!thread) return
103
+ const next = { ...thread }
104
+ if (resolved) next.resolved = true
105
+ else delete next.resolved
106
+ onUpdate(next)
107
+ }
108
+
109
+ function onKeyDown(event: KeyboardEvent) {
110
+ if (event.key !== 'Enter' || !(event.ctrlKey || event.metaKey)) return
111
+ event.preventDefault()
112
+ const target = event.target
113
+ if (target === replyBox) postReply()
114
+ else if (editingReply !== null) saveReply(editingReply)
115
+ else if (composing) saveRoot()
116
+ }
117
+ </script>
118
+
119
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
120
+ <div class="sv-sheet-comment" class:threaded={!!thread} role="dialog" tabindex="-1" aria-label={t('commentOn', { address })} onkeydown={onKeyDown}>
121
+ <div class="head">
122
+ <span>{address}</span>
123
+ {#if thread}
124
+ {#if thread.resolved}
125
+ <span class="badge">{t('commentResolved')}</span>
126
+ <button type="button" class="link" onclick={() => setResolved(false)}>{t('commentReopen')}</button>
127
+ {:else}
128
+ <button type="button" class="link" onclick={() => setResolved(true)}>{t('commentResolve')}</button>
129
+ {/if}
130
+ {/if}
131
+ </div>
132
+ {#if composing}
133
+ <textarea
134
+ bind:this={box}
135
+ bind:value={draft}
136
+ oninput={() => onDraft(draft)}
137
+ rows="4"
138
+ aria-label={t('comment')}
139
+ placeholder={t('commentPlaceholder')}
140
+ spellcheck="false"
141
+ ></textarea>
142
+ <div class="sv-sheet-dialog-buttons">
143
+ <span class="keys">{t('commentSaves')}</span>
144
+ <button type="button" class="btn primary" onclick={saveRoot}>{t('save')}</button>
145
+ {#if thread}
146
+ <button type="button" class="btn" onclick={() => { draft = text; onDraft(text); editingRoot = false }}>{t('cancel')}</button>
147
+ {:else if text}
148
+ <button type="button" class="btn" onclick={onDelete}>{t('delete')}</button>
149
+ {/if}
150
+ </div>
151
+ {:else if thread}
152
+ <div class="entry root">
153
+ <div class="who">
154
+ {#if thread.author}<span class="author">{thread.author}</span>{/if}
155
+ {#if thread.at}<span class="when">{when(thread.at)}</span>{/if}
156
+ </div>
157
+ <div class="text">{thread.text}</div>
158
+ <div class="actions">
159
+ <button type="button" class="link" onclick={() => { editingRoot = true; queueMicrotask(() => box?.focus()) }}>{t('commentEdit')}</button>
160
+ <button type="button" class="link" onclick={onDelete}>{t('delete')}</button>
161
+ </div>
162
+ </div>
163
+ {#each thread.replies ?? [] as entry, i (i)}
164
+ <div class="entry reply">
165
+ <div class="who">
166
+ {#if entry.author}<span class="author">{entry.author}</span>{/if}
167
+ {#if entry.at}<span class="when">{when(entry.at)}</span>{/if}
168
+ </div>
169
+ {#if editingReply === i}
170
+ <textarea bind:value={replyDraft} rows="3" aria-label={t('commentReply')} spellcheck="false"></textarea>
171
+ <div class="actions">
172
+ <button type="button" class="link" onclick={() => saveReply(i)}>{t('save')}</button>
173
+ <button type="button" class="link" onclick={() => (editingReply = null)}>{t('cancel')}</button>
174
+ </div>
175
+ {:else}
176
+ <div class="text">{entry.text}</div>
177
+ <div class="actions">
178
+ <button type="button" class="link" onclick={() => { editingReply = i; replyDraft = entry.text }}>{t('commentEdit')}</button>
179
+ <button type="button" class="link" onclick={() => deleteReply(i)}>{t('delete')}</button>
180
+ </div>
181
+ {/if}
182
+ </div>
183
+ {/each}
184
+ {#if !thread.resolved}
185
+ <textarea
186
+ bind:this={replyBox}
187
+ bind:value={reply}
188
+ rows="2"
189
+ aria-label={t('commentReply')}
190
+ placeholder={t('commentReplyPlaceholder')}
191
+ spellcheck="false"
192
+ ></textarea>
193
+ <div class="sv-sheet-dialog-buttons">
194
+ <span class="keys">{t('commentPosts')}</span>
195
+ <button type="button" class="btn primary" onclick={postReply} disabled={!reply.trim()}>{t('commentReply')}</button>
196
+ </div>
197
+ {/if}
198
+ {/if}
199
+ </div>
200
+
201
+ <style>
202
+ .sv-sheet-comment {
203
+ display: flex;
204
+ flex-direction: column;
205
+ gap: 6px;
206
+ width: 260px;
207
+ padding: 8px;
208
+ font-size: 12px;
209
+ color: var(--sg-fg, #242424);
210
+ }
211
+ .sv-sheet-comment.threaded {
212
+ width: 300px;
213
+ max-height: 360px;
214
+ overflow-y: auto;
215
+ }
216
+ .head {
217
+ display: flex;
218
+ align-items: center;
219
+ gap: 8px;
220
+ font-weight: 600;
221
+ color: var(--sg-muted, #616161);
222
+ }
223
+ .head .link { margin-left: auto; }
224
+ .badge {
225
+ padding: 1px 6px;
226
+ font-size: 11px;
227
+ font-weight: 600;
228
+ color: var(--sg-on-accent, #fff);
229
+ background: var(--sg-accent, #107c41);
230
+ border-radius: 9px;
231
+ }
232
+ .keys {
233
+ margin-right: auto;
234
+ font-size: 11px;
235
+ color: var(--sg-muted, #616161);
236
+ }
237
+ .entry {
238
+ display: flex;
239
+ flex-direction: column;
240
+ gap: 3px;
241
+ padding: 6px 0;
242
+ border-top: 1px solid var(--sg-border, #e5e5e5);
243
+ }
244
+ .entry.root { border-top: 0; padding-top: 0; }
245
+ .entry.reply { padding-left: 12px; }
246
+ .who {
247
+ display: flex;
248
+ gap: 8px;
249
+ align-items: baseline;
250
+ font-size: 11px;
251
+ color: var(--sg-muted, #616161);
252
+ }
253
+ .author { font-weight: 600; color: var(--sg-fg, #242424); }
254
+ .text { white-space: pre-wrap; overflow-wrap: anywhere; }
255
+ .actions { display: flex; gap: 10px; }
256
+ .link {
257
+ padding: 0;
258
+ font: inherit;
259
+ font-size: 11px;
260
+ color: var(--sg-accent, #107c41);
261
+ background: none;
262
+ border: 0;
263
+ cursor: pointer;
264
+ }
265
+ .link:hover { text-decoration: underline; }
266
+ textarea {
267
+ width: 100%;
268
+ box-sizing: border-box;
269
+ resize: vertical;
270
+ min-height: 40px;
271
+ padding: 6px 8px;
272
+ font: inherit;
273
+ line-height: 1.4;
274
+ color: inherit;
275
+ background: var(--sg-bg, #fff);
276
+ border: 1px solid var(--sg-border, #d1d1d1);
277
+ border-radius: 3px;
278
+ }
279
+ textarea:focus-visible {
280
+ outline: 2px solid var(--sg-focus-ring, var(--sg-accent, #107c41));
281
+ outline-offset: -1px;
282
+ }
283
+ </style>
@@ -0,0 +1,22 @@
1
+ import type { CommentThread } from './sheet/comments.js';
2
+ type Props = {
3
+ /** The comment as it is, null for a new one. */
4
+ thread: CommentThread | null;
5
+ /** The first text as it stands, the draft the box opens on. */
6
+ text: string;
7
+ /** A1 of the cell, for the heading. */
8
+ address: string;
9
+ /** Who signs a reply, when the application says. */
10
+ author?: string;
11
+ /** For the times. */
12
+ locale?: string;
13
+ /** Every change of the first text, so the shell can keep it on dismissal. */
14
+ onDraft: (text: string) => void;
15
+ onSave: (text: string) => void;
16
+ onDelete: () => void;
17
+ /** A reply, an edited or deleted reply, or Resolve / Reopen: the whole thread as it should be. */
18
+ onUpdate: (thread: CommentThread) => void;
19
+ };
20
+ declare const SvSheetComment: import("svelte").Component<Props, {}, "">;
21
+ type SvSheetComment = ReturnType<typeof SvSheetComment>;
22
+ export default SvSheetComment;