@svgrid/enterprise 3.0.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/LICENSE +94 -24
  2. package/README.md +36 -4
  3. package/dist/SvAdvancedFilter.svelte +1 -1
  4. package/dist/SvAlertsManager.svelte +2 -1
  5. package/dist/SvBoard.svelte +2 -1
  6. package/dist/SvExportMenu.svelte +4 -1
  7. package/dist/SvExportMenu.svelte.d.ts +0 -13
  8. package/dist/SvExpressionEditor.svelte +3 -3
  9. package/dist/SvFormulaBar.svelte +94 -20
  10. package/dist/SvFormulaBar.svelte.d.ts +7 -0
  11. package/dist/SvGridAlerts.svelte +49 -9
  12. package/dist/SvGridBoard.svelte +13 -8
  13. package/dist/SvGridBulkEditDrawer.svelte +26 -2
  14. package/dist/SvGridEditPanel.svelte +3 -0
  15. package/dist/SvGridScheduler.svelte +69 -40
  16. package/dist/SvGridSelectionBar.svelte +10 -3
  17. package/dist/SvPivotDesigner.svelte +198 -40
  18. package/dist/SvPivotDesigner.svelte.d.ts +27 -20
  19. package/dist/SvSheet.svelte +4043 -243
  20. package/dist/SvSheet.svelte.d.ts +76 -3
  21. package/dist/SvSheetChartSetup.svelte +151 -0
  22. package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
  23. package/dist/SvSheetComment.svelte +216 -31
  24. package/dist/SvSheetComment.svelte.d.ts +11 -11
  25. package/dist/SvSheetConditionalFormat.svelte +28 -31
  26. package/dist/SvSheetDataValidation.svelte +66 -42
  27. package/dist/SvSheetEditRanges.svelte +217 -0
  28. package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
  29. package/dist/SvSheetErrors.svelte +125 -0
  30. package/dist/SvSheetErrors.svelte.d.ts +20 -0
  31. package/dist/SvSheetEvaluate.svelte +133 -0
  32. package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
  33. package/dist/SvSheetFilterMenu.svelte +137 -34
  34. package/dist/SvSheetFilterMenu.svelte.d.ts +5 -0
  35. package/dist/SvSheetFindReplace.svelte +19 -19
  36. package/dist/SvSheetFormatCells.svelte +125 -81
  37. package/dist/SvSheetGoalSeek.svelte +17 -16
  38. package/dist/SvSheetInsertFunction.svelte +15 -13
  39. package/dist/SvSheetIteration.svelte +81 -0
  40. package/dist/SvSheetIteration.svelte.d.ts +10 -0
  41. package/dist/SvSheetLink.svelte +99 -0
  42. package/dist/SvSheetLink.svelte.d.ts +17 -0
  43. package/dist/SvSheetListPicker.svelte +4 -2
  44. package/dist/SvSheetListPicker.svelte.d.ts +0 -6
  45. package/dist/SvSheetManageRules.svelte +20 -18
  46. package/dist/SvSheetNameManager.svelte +17 -15
  47. package/dist/SvSheetPageSetup.svelte +159 -0
  48. package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
  49. package/dist/SvSheetPasteSpecial.svelte +22 -20
  50. package/dist/SvSheetPivot.svelte +220 -0
  51. package/dist/SvSheetPivot.svelte.d.ts +21 -0
  52. package/dist/SvSheetProtectSheet.svelte +81 -0
  53. package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
  54. package/dist/SvSheetRemoveDuplicates.svelte +13 -10
  55. package/dist/SvSheetRibbon.svelte +104 -51
  56. package/dist/SvSheetSizeDialog.svelte +4 -2
  57. package/dist/SvSheetSort.svelte +218 -0
  58. package/dist/SvSheetSort.svelte.d.ts +28 -0
  59. package/dist/SvSheetSparklines.svelte +135 -0
  60. package/dist/SvSheetSparklines.svelte.d.ts +14 -0
  61. package/dist/SvSheetTable.svelte +160 -0
  62. package/dist/SvSheetTable.svelte.d.ts +24 -0
  63. package/dist/SvSheetTabs.svelte +161 -31
  64. package/dist/SvSheetTabs.svelte.d.ts +22 -8
  65. package/dist/SvSheetTextToColumns.svelte +20 -20
  66. package/dist/SvSheetValidationAlert.svelte +8 -6
  67. package/dist/advanced-filter-enable.js +1 -1
  68. package/dist/alerts/alert-engine.d.ts +6 -0
  69. package/dist/alerts/alert-engine.js +21 -4
  70. package/dist/alerts/alert-formats.js +2 -0
  71. package/dist/alerts/alert-types.d.ts +1 -1
  72. package/dist/alerts.d.ts +1 -1
  73. package/dist/alerts.js +2 -2
  74. package/dist/board.js +2 -2
  75. package/dist/bulk-edit.d.ts +3 -1
  76. package/dist/bulk-edit.js +1 -1
  77. package/dist/cdn/svgrid-enterprise.svelte-external.js +39827 -16429
  78. package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
  79. package/dist/designer/assets/{SvChartMenu-D9hEeHar.js → SvChartMenu-BDoeqGz6.js} +1 -1
  80. package/dist/designer/assets/{SvDateTimePicker-DARvKUL2.js → SvDateTimePicker-DCPg7WGN.js} +1 -1
  81. package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
  82. package/dist/designer/assets/{SvGridChart-B8j1SSy3.js → SvGridChart-Cy1ATrWh.js} +2 -2
  83. package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
  84. package/dist/designer/assets/{SvGridChartPanel-pT6ITc2P.js → SvGridChartPanel-CATdVc9X.js} +3 -3
  85. package/dist/designer/assets/{SvGridChartView-bg281UA1.js → SvGridChartView-CmsZtCED.js} +1 -1
  86. package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
  87. package/dist/designer/assets/{SvTabs-UFCMTHXS.js → SvTabs-2mHC6oaz.js} +1 -1
  88. package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
  89. package/dist/designer/assets/{chart-cIPUsbM5.js → chart-Cn7MnNqA.js} +1 -1
  90. package/dist/designer/assets/{chart-panel-messages-DtTxpBUU.js → chart-panel-messages-Dz7PTIqT.js} +1 -1
  91. package/dist/designer/assets/{chart-summary-Czu_5epb.js → chart-summary-BD1qYB2R.js} +1 -1
  92. package/dist/designer/assets/{chart-trend-D5I5VEe8.js → chart-trend-B8xr5LuD.js} +1 -1
  93. package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
  94. package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
  95. package/dist/designer/assets/{focus-trap-CAreAhlU.js → focus-trap-V2-6Fy9I.js} +1 -1
  96. package/dist/designer/assets/{index-DwU7CAMm.js → index-BSjv6Qec.js} +317 -315
  97. package/dist/designer/assets/index-_JVFxt02.css +1 -0
  98. package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
  99. package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
  100. package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
  101. package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
  102. package/dist/designer/index.html +17 -16
  103. package/dist/export-pdf.d.ts +75 -0
  104. package/dist/export-pdf.js +216 -15
  105. package/dist/export.js +10 -2
  106. package/dist/gantt/SvGridGantt.svelte +2890 -0
  107. package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
  108. package/dist/gantt/gantt-config.d.ts +73 -0
  109. package/dist/gantt/gantt-config.js +1 -0
  110. package/dist/gantt/gantt-critical-path.d.ts +67 -0
  111. package/dist/gantt/gantt-critical-path.js +207 -0
  112. package/dist/gantt/gantt-model.d.ts +257 -0
  113. package/dist/gantt/gantt-model.js +651 -0
  114. package/dist/gantt/gantt-resources.d.ts +59 -0
  115. package/dist/gantt/gantt-resources.js +71 -0
  116. package/dist/gantt/gantt.d.ts +7 -0
  117. package/dist/gantt/gantt.js +36 -0
  118. package/dist/gantt/index.d.ts +15 -0
  119. package/dist/gantt/index.js +22 -0
  120. package/dist/gantt/timeline-arrows.d.ts +102 -0
  121. package/dist/gantt/timeline-arrows.js +181 -0
  122. package/dist/import.d.ts +2 -2
  123. package/dist/import.js +1 -1
  124. package/dist/index.d.ts +34 -7
  125. package/dist/index.js +44 -7
  126. package/dist/install.js +8 -1
  127. package/dist/license-core.d.ts +17 -1
  128. package/dist/license-core.js +16 -5
  129. package/dist/license.d.ts +18 -2
  130. package/dist/license.js +71 -6
  131. package/dist/node/studio.js +140 -8
  132. package/dist/pivot-enable.js +2 -2
  133. package/dist/scheduler-dependencies.d.ts +35 -0
  134. package/dist/scheduler-dependencies.js +36 -1
  135. package/dist/scheduler.js +2 -2
  136. package/dist/selection-bar.js +2 -2
  137. package/dist/server/SvGroupCell.svelte +213 -0
  138. package/dist/server/SvGroupCell.svelte.d.ts +62 -0
  139. package/dist/server/SvRowGroupPanel.svelte +322 -0
  140. package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
  141. package/dist/server/enable.d.ts +17 -0
  142. package/dist/server/enable.js +49 -0
  143. package/dist/server/index.d.ts +22 -0
  144. package/dist/server/index.js +24 -0
  145. package/dist/server/messages.d.ts +45 -0
  146. package/dist/server/messages.js +35 -0
  147. package/dist/server/server-group-model.d.ts +104 -0
  148. package/dist/server/server-group-model.js +272 -0
  149. package/dist/server/server-pivot.d.ts +46 -0
  150. package/dist/server/server-pivot.js +57 -0
  151. package/dist/server/server-row-model.d.ts +547 -0
  152. package/dist/server/server-row-model.js +1551 -0
  153. package/dist/server/server-selection.d.ts +99 -0
  154. package/dist/server/server-selection.js +215 -0
  155. package/dist/server/svgrid-adapter.d.ts +155 -0
  156. package/dist/server/svgrid-adapter.js +202 -0
  157. package/dist/sheet/ast.d.ts +45 -1
  158. package/dist/sheet/ast.js +14 -0
  159. package/dist/sheet/auto-filter.d.ts +58 -4
  160. package/dist/sheet/auto-filter.js +159 -11
  161. package/dist/sheet/autocomplete.d.ts +9 -0
  162. package/dist/sheet/autocomplete.js +90 -4
  163. package/dist/sheet/cell-images.d.ts +39 -0
  164. package/dist/sheet/cell-images.js +90 -0
  165. package/dist/sheet/cell-types.d.ts +58 -0
  166. package/dist/sheet/cell-types.js +96 -0
  167. package/dist/sheet/coerce.d.ts +40 -0
  168. package/dist/sheet/coerce.js +170 -3
  169. package/dist/sheet/comments.d.ts +43 -9
  170. package/dist/sheet/comments.js +85 -27
  171. package/dist/sheet/conditional-formats.d.ts +29 -6
  172. package/dist/sheet/conditional-formats.js +37 -12
  173. package/dist/sheet/csv.d.ts +32 -0
  174. package/dist/sheet/csv.js +158 -0
  175. package/dist/sheet/culture.d.ts +87 -0
  176. package/dist/sheet/culture.js +247 -0
  177. package/dist/sheet/delta.d.ts +102 -0
  178. package/dist/sheet/delta.js +203 -0
  179. package/dist/sheet/deps.d.ts +45 -1
  180. package/dist/sheet/deps.js +77 -2
  181. package/dist/sheet/document.d.ts +106 -4
  182. package/dist/sheet/document.js +204 -3
  183. package/dist/sheet/engine.d.ts +67 -0
  184. package/dist/sheet/engine.js +19 -0
  185. package/dist/sheet/entry.d.ts +8 -4
  186. package/dist/sheet/entry.js +171 -21
  187. package/dist/sheet/error-check.d.ts +49 -0
  188. package/dist/sheet/error-check.js +83 -0
  189. package/dist/sheet/evaluate-steps.d.ts +48 -0
  190. package/dist/sheet/evaluate-steps.js +196 -0
  191. package/dist/sheet/evaluate.d.ts +67 -0
  192. package/dist/sheet/evaluate.js +725 -13
  193. package/dist/sheet/filter-files.d.ts +37 -0
  194. package/dist/sheet/filter-files.js +465 -0
  195. package/dist/sheet/format-store.d.ts +15 -0
  196. package/dist/sheet/format-store.js +11 -1
  197. package/dist/sheet/from-rows.d.ts +14 -0
  198. package/dist/sheet/from-rows.js +50 -0
  199. package/dist/sheet/function-catalog.d.ts +1 -1
  200. package/dist/sheet/function-catalog.js +296 -5
  201. package/dist/sheet/functions.js +363 -91
  202. package/dist/sheet/index.d.ts +35 -8
  203. package/dist/sheet/index.js +35 -8
  204. package/dist/sheet/links.d.ts +57 -0
  205. package/dist/sheet/links.js +174 -0
  206. package/dist/sheet/messages.d.ts +778 -0
  207. package/dist/sheet/messages.js +806 -0
  208. package/dist/sheet/number-format.d.ts +52 -5
  209. package/dist/sheet/number-format.js +465 -68
  210. package/dist/sheet/objects.d.ts +106 -0
  211. package/dist/sheet/objects.js +149 -0
  212. package/dist/sheet/ods-document.d.ts +44 -0
  213. package/dist/sheet/ods-document.js +1275 -0
  214. package/dist/sheet/open-file.d.ts +26 -0
  215. package/dist/sheet/open-file.js +56 -0
  216. package/dist/sheet/outline.d.ts +82 -0
  217. package/dist/sheet/outline.js +228 -0
  218. package/dist/sheet/packs/array.d.ts +16 -0
  219. package/dist/sheet/packs/array.js +172 -0
  220. package/dist/sheet/packs/database.d.ts +42 -0
  221. package/dist/sheet/packs/database.js +142 -0
  222. package/dist/sheet/packs/engineering.d.ts +2 -0
  223. package/dist/sheet/packs/engineering.js +296 -0
  224. package/dist/sheet/packs/financial.d.ts +5 -0
  225. package/dist/sheet/packs/financial.js +220 -0
  226. package/dist/sheet/packs/math-stats.d.ts +2 -0
  227. package/dist/sheet/packs/math-stats.js +372 -0
  228. package/dist/sheet/packs/special.d.ts +44 -0
  229. package/dist/sheet/packs/special.js +187 -0
  230. package/dist/sheet/packs/stats-dist.d.ts +2 -0
  231. package/dist/sheet/packs/stats-dist.js +785 -0
  232. package/dist/sheet/packs/text-date.d.ts +2 -0
  233. package/dist/sheet/packs/text-date.js +332 -0
  234. package/dist/sheet/packs/trig.d.ts +2 -0
  235. package/dist/sheet/packs/trig.js +73 -0
  236. package/dist/sheet/page-setup.d.ts +73 -0
  237. package/dist/sheet/page-setup.js +73 -0
  238. package/dist/sheet/parse.js +42 -10
  239. package/dist/sheet/paste-special.d.ts +22 -0
  240. package/dist/sheet/paste-special.js +14 -5
  241. package/dist/sheet/pivot-range.d.ts +160 -0
  242. package/dist/sheet/pivot-range.js +333 -0
  243. package/dist/sheet/presence.d.ts +73 -0
  244. package/dist/sheet/presence.js +79 -0
  245. package/dist/sheet/print.d.ts +104 -0
  246. package/dist/sheet/print.js +169 -0
  247. package/dist/sheet/protection.d.ts +55 -1
  248. package/dist/sheet/protection.js +55 -2
  249. package/dist/sheet/rects.d.ts +1 -1
  250. package/dist/sheet/refs.d.ts +48 -0
  251. package/dist/sheet/refs.js +155 -8
  252. package/dist/sheet/ribbon-icons.d.ts +1 -1
  253. package/dist/sheet/ribbon-icons.js +186 -0
  254. package/dist/sheet/ribbon.d.ts +1 -1
  255. package/dist/sheet/ribbon.js +324 -23
  256. package/dist/sheet/sheet-kinds.d.ts +74 -0
  257. package/dist/sheet/sheet-kinds.js +91 -0
  258. package/dist/sheet/shortcuts.d.ts +13 -3
  259. package/dist/sheet/shortcuts.js +63 -12
  260. package/dist/sheet/sort.d.ts +51 -0
  261. package/dist/sheet/sort.js +107 -0
  262. package/dist/sheet/sparklines.d.ts +111 -0
  263. package/dist/sheet/sparklines.js +204 -0
  264. package/dist/sheet/table-styles.d.ts +74 -0
  265. package/dist/sheet/table-styles.js +152 -0
  266. package/dist/sheet/tables.d.ts +19 -0
  267. package/dist/sheet/tables.js +31 -0
  268. package/dist/sheet/tokenize.d.ts +18 -1
  269. package/dist/sheet/tokenize.js +60 -9
  270. package/dist/sheet/validation.d.ts +16 -0
  271. package/dist/sheet/validation.js +37 -0
  272. package/dist/sheet/workbook.d.ts +148 -3
  273. package/dist/sheet/workbook.js +742 -31
  274. package/dist/sheet/xls-cfb.d.ts +32 -0
  275. package/dist/sheet/xls-cfb.js +290 -0
  276. package/dist/sheet/xls-document.d.ts +10 -0
  277. package/dist/sheet/xls-document.js +1243 -0
  278. package/dist/sheet/xls-formula.d.ts +40 -0
  279. package/dist/sheet/xls-formula.js +569 -0
  280. package/dist/sheet/xlsx-document.d.ts +108 -0
  281. package/dist/sheet/xlsx-document.js +1849 -0
  282. package/dist/sheet/xlsx-drawing.d.ts +99 -0
  283. package/dist/sheet/xlsx-drawing.js +420 -0
  284. package/dist/sheet-enable.js +6 -7
  285. package/dist/sheet-text.d.ts +7 -0
  286. package/dist/sheet-text.js +29 -0
  287. package/dist/sources/auth-supabase.js +2 -2
  288. package/dist/sources/realtime-supabase.js +2 -2
  289. package/dist/sources/rest.d.ts +6 -2
  290. package/dist/sources/rest.js +42 -7
  291. package/dist/sources/supabase.d.ts +10 -1
  292. package/dist/sources/supabase.js +73 -40
  293. package/dist/studio/emit-project.js +14 -1
  294. package/dist/studio/index.js +1 -1
  295. package/dist/studio/project.d.ts +11 -2
  296. package/dist/studio/project.js +5 -2
  297. package/dist/studio/ui-components.generated.js +107 -2
  298. package/dist/sveltekit/in-memory.d.ts +2 -2
  299. package/dist/sveltekit/in-memory.js +125 -4
  300. package/dist/sveltekit/index.d.ts +1 -1
  301. package/dist/sveltekit/index.js +1 -1
  302. package/dist/sveltekit/query-plan.d.ts +50 -4
  303. package/dist/sveltekit/query-plan.js +25 -3
  304. package/dist/sveltekit/sql-source.d.ts +6 -0
  305. package/dist/sveltekit/sql-source.js +34 -6
  306. package/dist/sveltekit/sql.d.ts +31 -0
  307. package/dist/sveltekit/sql.js +135 -25
  308. package/dist/sveltekit/transport.d.ts +10 -2
  309. package/dist/sveltekit/transport.js +30 -6
  310. package/dist/upgrade-prompt.d.ts +1 -1
  311. package/dist/version.d.ts +1 -1
  312. package/dist/version.js +1 -1
  313. package/dist/watermark.js +35 -2
  314. package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
  315. package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
  316. package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
  317. package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
  318. package/dist/wc/SvField-B_kurx_P.js +149 -0
  319. package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
  320. package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
  321. package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
  322. package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
  323. package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
  324. package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
  325. package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
  326. package/dist/wc/SvModal-DrfOYYyX.js +189 -0
  327. package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
  328. package/dist/wc/chart-6OXlybVT.js +4341 -0
  329. package/dist/wc/chart-export-CeSADGfi.js +135 -0
  330. package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
  331. package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
  332. package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
  333. package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
  334. package/dist/wc/client-DQIzjDBG.js +3064 -0
  335. package/dist/wc/column-resize-DUPgynvc.js +101 -0
  336. package/dist/wc/date-format-DS-z_h9v.js +1130 -0
  337. package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
  338. package/dist/wc/editor-contract-peBDxir_.js +22 -0
  339. package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
  340. package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
  341. package/dist/wc/list-option-DrRyivWp.js +82 -0
  342. package/dist/wc/popover-WsGlvtQv.js +69 -0
  343. package/dist/wc/positioning-BiKLfu1E.js +112 -0
  344. package/dist/wc/react.d.ts +41 -0
  345. package/dist/wc/react.js +90 -0
  346. package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
  347. package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
  348. package/dist/wc/row-resize-limG_N1z.js +111 -0
  349. package/dist/wc/sv-sheet-element.d.ts +97 -0
  350. package/dist/wc/sv-sheet-element.js +44213 -0
  351. package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
  352. package/dist/wc/validate-BqDthkNr.js +88 -0
  353. package/dist/wc/vue.d.ts +31 -0
  354. package/dist/wc/vue.js +75 -0
  355. package/package.json +30 -5
  356. package/dist/designer/assets/GridMenus-BlsvL_aU.js +0 -8
  357. package/dist/designer/assets/SvGridCellEditor-C7uQXYds.js +0 -4
  358. package/dist/designer/assets/SvGridChartBuilder-kvyIU_Rl.js +0 -1
  359. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
  360. package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
  361. package/dist/designer/assets/index-CMFgAoVV.css +0 -1
  362. package/dist/designer/assets/row-resize-DLktcqUK.js +0 -1
  363. package/dist/designer/assets/src-EdI3Xqds.js +0 -58
  364. package/dist/designer/assets/validate-h-aslRV9.js +0 -1
@@ -1,8 +1,8 @@
1
- import { applyFormat, toggleFormat, preset, autoSum, structural, clearFormats, getFormatTarget, getWorkbook, withFormatUndo, nudgeFontSize, activeEntry, FONT_SIZES, DEFAULT_FONT_SIZE, applyBorders, formatAllowed, raiseRibbonAction, } from './shortcuts.js';
1
+ import { applyFormat, toggleFormat, preset, autoSum, structural, clearFormats, newSheet, getFormatTarget, getWorkbook, withFormatUndo, nudgeFontSize, activeEntry, FONT_SIZES, DEFAULT_FONT_SIZE, applyBorders, formatAllowed, raiseRibbonAction, } from './shortcuts.js';
2
2
  export { FONT_SIZES, applyBorders } from './shortcuts.js';
3
- import { insertRows, deleteRows, getStructureTarget } from './structure.js';
3
+ import { insertRows, deleteRows, insertColumns, deleteColumns, getStructureTarget } from './structure.js';
4
4
  import { fillDown, fillRight, targetRect } from './commands.js';
5
- import { FORMAT_PRESETS, formatCategory } from './number-format.js';
5
+ import { FORMAT_PRESETS, FORMAT_CATEGORY_PATTERNS, formatCategory, accountingParts, accountingPattern, formatWithPattern } from './number-format.js';
6
6
  import { ALL_COLOURS } from './palette.js';
7
7
  // ---------------------------------------------------------------------------
8
8
  // Shared predicates
@@ -87,6 +87,21 @@ function alignItem(align, title) {
87
87
  isEnabled: canFormat,
88
88
  };
89
89
  }
90
+ /** Excel's Top / Middle / Bottom Align. The middle is the sheet's default,
91
+ * so its button clears the field rather than storing it, and reads as on
92
+ * for a cell that has no vertical alignment of its own. */
93
+ function valignItem(valign, title) {
94
+ return {
95
+ id: `valign-${valign}`,
96
+ label: '≡',
97
+ icon: `valign-${valign}`,
98
+ title,
99
+ kind: 'toggle',
100
+ run: (cmd) => applyFormat(cmd, { valign: valign === 'center' ? undefined : valign }),
101
+ isOn: (cmd) => everyCellHas(cmd, (entry) => valign === 'center' ? entry?.valign === undefined || entry?.valign === 'center' : entry?.valign === valign),
102
+ isEnabled: canFormat,
103
+ };
104
+ }
90
105
  function presetItem(id, label, title, name, keys) {
91
106
  const run = preset(name);
92
107
  return {
@@ -110,7 +125,10 @@ function fromCommand(command) {
110
125
  *
111
126
  * Reads the active cell's current pattern rather than assuming one, so
112
127
  * pressing it on a currency cell keeps the currency and only moves the point.
113
- * A cell with no pattern starts from General, which Excel treats as 0 decimals.
128
+ * A cell with no pattern is General, and Excel moves from the decimals the
129
+ * value SHOWS there, not from zero: Increase on 3.14159 goes to six places,
130
+ * not down to one, and Decrease actually trims a place. Only when the cell is
131
+ * empty, or its value is not a number, does General behave like `0`.
114
132
  */
115
133
  function nudgeDecimals(delta) {
116
134
  return (cmd) => {
@@ -123,10 +141,31 @@ function nudgeDecimals(delta) {
123
141
  const current = rowId != null && columnId != null
124
142
  ? target.store.get(rowId, columnId)?.numFmt
125
143
  : undefined;
126
- const next = withDecimals(current ?? '0', delta);
144
+ let next;
145
+ if (current) {
146
+ next = withDecimals(current, delta);
147
+ }
148
+ else {
149
+ // General: start from what the value displays, so the point moves the
150
+ // way Excel's does rather than resetting to a single place.
151
+ const count = generalDecimals(active.rowIndex, active.colIndex) + delta;
152
+ next = count < 0 || count > 30 ? null : count === 0 ? '0' : `0.${'0'.repeat(count)}`;
153
+ }
127
154
  return next === null ? false : applyFormat(cmd, { numFmt: next });
128
155
  };
129
156
  }
157
+ /** The decimals a General cell currently shows, so Increase/Decrease Decimal
158
+ * moves from there. Zero for a blank cell or a non-numeric value. */
159
+ function generalDecimals(row, col) {
160
+ const wb = getWorkbook();
161
+ if (!wb)
162
+ return 0;
163
+ const value = wb.getValue(wb.active, row, col);
164
+ if (typeof value !== 'number' || !Number.isFinite(value))
165
+ return 0;
166
+ const dot = formatWithPattern(value, 'General').indexOf('.');
167
+ return dot < 0 ? 0 : formatWithPattern(value, 'General').length - dot - 1;
168
+ }
130
169
  /**
131
170
  * Move the decimal count of a number-format pattern by `delta`.
132
171
  *
@@ -141,9 +180,17 @@ export function withDecimals(pattern, delta) {
141
180
  // first half would leave a sheet where -1234.5 printed to a different
142
181
  // precision than 1234.5. Excel moves both, so this does too.
143
182
  //
183
+ // An accounting pattern is rebuilt from its parts rather than edited:
184
+ // its zero section carries a `"-"??` whose question marks count the
185
+ // decimals too.
186
+ const accounting = accountingParts(pattern);
187
+ if (accounting) {
188
+ const next = accounting.decimals + delta;
189
+ return next < 0 || next > 30 ? null : accountingPattern(accounting.symbol, next);
190
+ }
144
191
  // A quoted literal can contain a semicolon, which would make splitting on
145
192
  // ';' cut a section in half, so a pattern with quotes declines instead of
146
- // being mangled. Nothing in FORMAT_PRESETS has one.
193
+ // being mangled. Nothing else in FORMAT_PRESETS has one.
147
194
  if (pattern.includes('"'))
148
195
  return null;
149
196
  const sections = pattern.split(';');
@@ -197,6 +244,7 @@ const NUMBER_FORMATS = [
197
244
  { value: 'general', label: 'General' },
198
245
  { value: 'number', label: 'Number' },
199
246
  { value: 'currency', label: 'Currency' },
247
+ { value: 'accounting', label: 'Accounting' },
200
248
  { value: 'percent', label: 'Percentage' },
201
249
  { value: 'date', label: 'Date' },
202
250
  { value: 'time', label: 'Time' },
@@ -216,6 +264,118 @@ const BORDER_OPTIONS = [
216
264
  // The tabs
217
265
  // ---------------------------------------------------------------------------
218
266
  const small = (row, item) => ({ ...item, row });
267
+ /**
268
+ * Excel's File tab, the part of it a document in a page can do: New, Open
269
+ * an .xlsx from disk, Save as .xlsx, and the active sheet as CSV. Every
270
+ * entry is raised for the shell, and through it for the host, so an app
271
+ * that keeps its workbooks on a server takes Open and Save over with
272
+ * `onAction` and the buttons still read as Excel's.
273
+ */
274
+ const FILE = {
275
+ id: 'file',
276
+ label: 'File',
277
+ groups: [
278
+ {
279
+ id: 'file-new',
280
+ icon: 'file-new',
281
+ label: 'New',
282
+ items: [
283
+ { id: 'file-new', label: 'New', title: 'New: start an empty workbook', icon: 'file-new', kind: 'button', size: 'large', emits: 'file-new' },
284
+ ],
285
+ },
286
+ {
287
+ id: 'file-open',
288
+ icon: 'file-open',
289
+ label: 'Open',
290
+ items: [
291
+ { id: 'file-open', label: 'Open', title: 'Open an .xlsx, .xls, .ods or .csv file', keys: 'Ctrl+O', icon: 'file-open', kind: 'button', size: 'large', emits: 'file-open' },
292
+ ],
293
+ },
294
+ {
295
+ id: 'file-save',
296
+ icon: 'file-save',
297
+ label: 'Save',
298
+ items: [
299
+ { id: 'file-save-xlsx', label: 'Save As', title: 'Save the workbook as an .xlsx file', keys: 'Ctrl+S', icon: 'file-save', kind: 'button', size: 'large', emits: 'file-save-xlsx' },
300
+ { id: 'file-save-ods', label: 'Save As ODS', title: 'Save the workbook as an .ods file, which LibreOffice Calc opens', icon: 'file-save', kind: 'button', size: 'large', emits: 'file-save-ods' },
301
+ { id: 'file-save-xls', label: 'Save As XLS', title: 'Save the workbook as an .xls file, which Excel 97-2003 opens', icon: 'file-save', kind: 'button', size: 'large', emits: 'file-save-xls' },
302
+ { id: 'file-export-csv', label: 'Export CSV', title: 'Export the active sheet as CSV', icon: 'file-csv', kind: 'button', size: 'large', emits: 'file-export-csv' },
303
+ ],
304
+ },
305
+ {
306
+ id: 'file-print',
307
+ icon: 'print',
308
+ label: 'Print',
309
+ items: [
310
+ { id: 'file-print', label: 'Print', title: 'Print the active sheet as its Page Layout says', keys: 'Ctrl+P', icon: 'print', kind: 'button', size: 'large', emits: 'file-print' },
311
+ ],
312
+ },
313
+ ],
314
+ };
315
+ /**
316
+ * Excel's Page Layout tab, the part with something behind it: Page Setup
317
+ * (Margins, Orientation, Size, Print Area, Print Titles, with the dialog
318
+ * on the launcher) and Sheet Options (whether gridlines and headings
319
+ * print). Raised rather than run here: the shell keeps the setup per
320
+ * sheet in the document, and File > Print reads it.
321
+ */
322
+ const PAGE_LAYOUT = {
323
+ id: 'page-layout',
324
+ label: 'Page Layout',
325
+ groups: [
326
+ {
327
+ id: 'page-setup',
328
+ icon: 'page-setup',
329
+ label: 'Page Setup',
330
+ launcher: 'page-setup',
331
+ items: [
332
+ {
333
+ id: 'margins', label: 'Margins', title: 'Margins', icon: 'margins', kind: 'dropdown', size: 'large',
334
+ options: [
335
+ { value: 'normal', label: 'Normal', emits: 'margins-normal', toggle: true },
336
+ { value: 'narrow', label: 'Narrow', emits: 'margins-narrow', toggle: true },
337
+ { value: 'wide', label: 'Wide', emits: 'margins-wide', toggle: true },
338
+ ],
339
+ },
340
+ {
341
+ id: 'orientation', label: 'Orientation', title: 'Orientation', icon: 'orientation', kind: 'dropdown', size: 'large',
342
+ options: [
343
+ { value: 'portrait', label: 'Portrait', emits: 'page-portrait', toggle: true },
344
+ { value: 'landscape', label: 'Landscape', emits: 'page-landscape', toggle: true },
345
+ ],
346
+ },
347
+ {
348
+ id: 'paper', label: 'Size', title: 'Page Size', icon: 'paper', kind: 'dropdown', size: 'large',
349
+ options: [
350
+ { value: 'letter', label: 'Letter', emits: 'paper-letter', toggle: true },
351
+ { value: 'legal', label: 'Legal', emits: 'paper-legal', toggle: true },
352
+ { value: 'tabloid', label: 'Tabloid', emits: 'paper-tabloid', toggle: true },
353
+ { value: 'a3', label: 'A3', emits: 'paper-a3', toggle: true },
354
+ { value: 'a4', label: 'A4', emits: 'paper-a4', toggle: true },
355
+ { value: 'a5', label: 'A5', emits: 'paper-a5', toggle: true },
356
+ ],
357
+ },
358
+ {
359
+ id: 'print-area', label: 'Print Area', title: 'Print Area', icon: 'print-area', kind: 'dropdown', size: 'large',
360
+ options: [
361
+ { value: 'set', label: 'Set Print Area', emits: 'print-area-set' },
362
+ { value: 'clear', label: 'Clear Print Area', emits: 'print-area-clear' },
363
+ ],
364
+ },
365
+ { id: 'print-titles', label: 'Print Titles', title: 'Print Titles: rows to repeat at the top of every page', icon: 'print-titles', kind: 'button', size: 'large', emits: 'print-titles' },
366
+ ],
367
+ },
368
+ {
369
+ id: 'sheet-options',
370
+ icon: 'gridlines',
371
+ label: 'Sheet Options',
372
+ items: [
373
+ small(1, { id: 'print-gridlines', label: 'Print Gridlines', title: 'Print the gridlines', icon: 'gridlines', kind: 'toggle', wide: true, emits: 'print-gridlines' }),
374
+ small(2, { id: 'print-headings', label: 'Print Headings', title: 'Print the row numbers and column letters', icon: 'headings', kind: 'toggle', wide: true, emits: 'print-headings' }),
375
+ ],
376
+ },
377
+ ],
378
+ };
219
379
  const HOME = {
220
380
  id: 'home',
221
381
  label: 'Home',
@@ -251,7 +411,15 @@ const HOME = {
251
411
  small(1, {
252
412
  id: 'cut', label: 'Cut', title: 'Cut', keys: 'Ctrl+X', icon: 'cut', kind: 'button',
253
413
  isEnabled: hasTarget,
254
- run: (cmd) => { void cmd.cut(); return true; },
414
+ // Raised, so a spreadsheet shell can give it Excel's meaning: the
415
+ // cells stay where they are until the paste lands. A host that
416
+ // answers nothing falls back to the grid's cut, which clears now.
417
+ run: (cmd) => {
418
+ if (raiseRibbonAction('cut', cmd))
419
+ return true;
420
+ void cmd.cut();
421
+ return true;
422
+ },
255
423
  }),
256
424
  small(2, {
257
425
  id: 'copy', label: 'Copy', title: 'Copy', keys: 'Ctrl+C', icon: 'copy', kind: 'button',
@@ -324,6 +492,9 @@ const HOME = {
324
492
  layout: 'flow',
325
493
  launcher: 'format-cells',
326
494
  items: [
495
+ small(1, valignItem('top', 'Top Align')),
496
+ small(1, valignItem('center', 'Middle Align')),
497
+ small(1, valignItem('bottom', 'Bottom Align')),
327
498
  small(1, {
328
499
  id: 'wrap', label: 'Wrap Text', title: 'Wrap Text', icon: 'wrap', kind: 'toggle', wide: true,
329
500
  run: (cmd) => toggleWrap(cmd),
@@ -367,11 +538,12 @@ const HOME = {
367
538
  current: (cmd) => {
368
539
  const fmt = activeEntry(cmd)?.numFmt;
369
540
  const { category } = formatCategory(fmt);
370
- return category === 'custom' ? fmt ?? 'general' : category;
541
+ return category === 'custom' || category === 'special' ? fmt ?? 'general' : category;
371
542
  },
372
- run: (cmd, value) => applyFormat(cmd, { numFmt: FORMAT_PRESETS[value] }),
543
+ run: (cmd, value) => applyFormat(cmd, { numFmt: FORMAT_CATEGORY_PATTERNS[value] }),
373
544
  }),
374
- small(2, presetItem('fmt-currency', '$', 'Accounting Number Format', 'currency', 'Ctrl+Shift+4')),
545
+ // Excel's $ button applies Accounting; Ctrl+Shift+4 is Currency.
546
+ small(2, presetItem('fmt-currency', '$', 'Accounting Number Format', 'accounting')),
375
547
  small(2, presetItem('fmt-percent', '%', 'Percent Style', 'percent', 'Ctrl+Shift+5')),
376
548
  small(2, presetItem('fmt-number', ',', 'Comma Style', 'number', 'Ctrl+Shift+1')),
377
549
  small(2, {
@@ -389,19 +561,36 @@ const HOME = {
389
561
  icon: 'table',
390
562
  label: 'Cells',
391
563
  items: [
564
+ // Excel's split buttons: the face takes the selection's axis (a
565
+ // whole column inserts columns, anything else rows, which is what
566
+ // Excel does with a cell selected), and the arrow spells the axis
567
+ // out, so a column can be inserted from a cell without selecting
568
+ // the column first.
392
569
  small(1, {
393
570
  id: 'insert', label: 'Insert', title: 'Insert Cells', keys: 'Ctrl+Shift++',
394
- icon: 'insert-cells', kind: 'button', wide: true,
395
- // A plain cell is ambiguous for the keystroke, which declines; the
396
- // button behaves as Excel's does with a cell selected and inserts
397
- // a row, shifting the sheet down.
398
- run: (cmd) => structural(cmd, 'insert') || insertRows(cmd),
571
+ icon: 'insert-cells', kind: 'dropdown', split: true, wide: true,
572
+ run: (cmd, value) => value === 'rows' ? insertRows(cmd)
573
+ : value === 'columns' ? insertColumns(cmd)
574
+ : value === 'sheet' ? newSheet()
575
+ : structural(cmd, 'insert') || insertRows(cmd),
576
+ options: [
577
+ { value: 'rows', label: 'Insert Sheet Rows' },
578
+ { value: 'columns', label: 'Insert Sheet Columns' },
579
+ { value: 'sheet', label: 'Insert Sheet', keys: 'Shift+F11' },
580
+ ],
399
581
  isEnabled: canRestructure,
400
582
  }),
401
583
  small(2, {
402
584
  id: 'delete', label: 'Delete', title: 'Delete Cells', keys: 'Ctrl+-',
403
- icon: 'delete-cells', kind: 'button', wide: true,
404
- run: (cmd) => structural(cmd, 'delete') || deleteRows(cmd),
585
+ icon: 'delete-cells', kind: 'dropdown', split: true, wide: true,
586
+ run: (cmd, value) => value === 'rows' ? deleteRows(cmd)
587
+ : value === 'columns' ? deleteColumns(cmd)
588
+ : structural(cmd, 'delete') || deleteRows(cmd),
589
+ options: [
590
+ { value: 'rows', label: 'Delete Sheet Rows' },
591
+ { value: 'columns', label: 'Delete Sheet Columns' },
592
+ { value: 'sheet', label: 'Delete Sheet', emits: 'delete-sheet' },
593
+ ],
405
594
  isEnabled: canRestructure,
406
595
  }),
407
596
  // Excel's Format menu: Cell Size, Visibility, and Format Cells at
@@ -457,6 +646,8 @@ const HOME = {
457
646
  { value: 'cf-color-scale-3', label: 'Green - Yellow - Red Color Scale', icon: 'cf-scale', emits: 'cf-color-scale-3' },
458
647
  { value: 'cf-color-scale-2', label: 'Green - White Color Scale', icon: 'cf-scale', emits: 'cf-color-scale-2' },
459
648
  { value: 'cf-icon-set', label: 'Icon Set (3 Arrows)', icon: 'cf-icons', emits: 'cf-icon-set' },
649
+ { value: 'n', label: 'New Rule', heading: true },
650
+ { value: 'cf-formula', label: 'Use a Formula...', icon: 'cf-formula', emits: 'cf-formula' },
460
651
  { value: 'c', label: 'Clear Rules', heading: true },
461
652
  { value: 'cf-clear-selection', label: 'Clear Rules from Selected Cells', emits: 'cf-clear-selection' },
462
653
  { value: 'cf-clear-sheet', label: 'Clear Rules from Entire Sheet', emits: 'cf-clear-sheet' },
@@ -474,15 +665,17 @@ const HOME = {
474
665
  // Undo and Redo open the group as a column of two small icons, the
475
666
  // way Cut and Copy stand beside Paste; the owner wanted them here
476
667
  // rather than in a group of their own.
668
+ // Raised rather than run: a step made on another sheet is undone
669
+ // THERE, which means switching sheets first, and only the shell can.
477
670
  small(1, {
478
671
  id: 'undo', label: 'Undo', title: 'Undo', keys: 'Ctrl+Z', icon: 'undo', kind: 'button',
479
672
  isEnabled: (cmd) => cmd.api.canUndo(),
480
- run: (cmd) => cmd.api.undo(),
673
+ emits: 'undo',
481
674
  }),
482
675
  small(2, {
483
676
  id: 'redo', label: 'Redo', title: 'Redo', keys: 'Ctrl+Y', icon: 'redo', kind: 'button',
484
677
  isEnabled: (cmd) => cmd.api.canRedo(),
485
- run: (cmd) => cmd.api.redo(),
678
+ emits: 'redo',
486
679
  }),
487
680
  small(1, {
488
681
  id: 'autosum', label: 'AutoSum', title: 'AutoSum', keys: 'Alt+=',
@@ -522,7 +715,14 @@ const INSERT = {
522
715
  icon: 'table',
523
716
  label: 'Tables',
524
717
  items: [
718
+ // Excel's Tables group leads with PivotTable, and Refresh sits beside
719
+ // the pair for the pivot the cursor is in.
720
+ { id: 'pivot-table', label: 'PivotTable', title: 'Summarise the selected block', icon: 'pivot', kind: 'button', size: 'large', emits: 'insert-pivot' },
525
721
  { id: 'table', label: 'Table', title: 'Format the selection as a table', keys: 'Ctrl+T', icon: 'table', kind: 'button', size: 'large', emits: 'insert-table' },
722
+ small(1, { id: 'pivot-refresh', label: 'Refresh', title: 'Rebuild the PivotTable here from its source', icon: 'calculate', kind: 'button', wide: true, emits: 'refresh-pivot' }),
723
+ small(1, { id: 'pivot-details', label: 'Show Details', title: 'Show Details: the source rows behind the number in this PivotTable cell, on a sheet of their own', icon: 'pivot', kind: 'button', wide: true, emits: 'pivot-details' }),
724
+ small(2, { id: 'table-remove', label: 'To Range', title: 'Convert the table here back to ordinary cells', icon: 'delete-cells', kind: 'button', wide: true, emits: 'remove-table' }),
725
+ small(3, { id: 'table-style', label: 'Table Styles', title: 'Pick the look of the table the cursor is in', icon: 'table', kind: 'button', wide: true, emits: 'table-style' }),
526
726
  ],
527
727
  },
528
728
  {
@@ -531,6 +731,54 @@ const INSERT = {
531
731
  label: 'Charts',
532
732
  items: [
533
733
  { id: 'chart', label: 'Chart', title: 'Chart the selected range', icon: 'chart', kind: 'button', size: 'large', emits: 'insert-chart' },
734
+ small(1, { id: 'chart-setup', label: 'Setup', title: 'Chart: type, title, labels and series', icon: 'chart-setup', kind: 'button', wide: true, emits: 'chart-setup' }),
735
+ small(2, { id: 'delete-object', label: 'Delete', title: 'Delete the selected chart or picture', icon: 'delete-cells', kind: 'button', wide: true, emits: 'delete-object' }),
736
+ ],
737
+ },
738
+ {
739
+ // Excel's Sparklines group: the three kinds, each opening the Create
740
+ // Sparklines dialog on the selection, and Clear for the group under it.
741
+ id: 'sparklines',
742
+ icon: 'sparkline-line',
743
+ label: 'Sparklines',
744
+ items: [
745
+ { id: 'sparkline-line', label: 'Line', title: 'A line sparkline in each cell of a range', icon: 'sparkline-line', kind: 'button', size: 'large', emits: 'sparkline-line' },
746
+ { id: 'sparkline-column', label: 'Column', title: 'A column sparkline in each cell of a range', icon: 'sparkline-column', kind: 'button', size: 'large', emits: 'sparkline-column' },
747
+ { id: 'sparkline-winloss', label: 'Win/Loss', title: 'A win/loss sparkline in each cell of a range', icon: 'sparkline-winloss', kind: 'button', size: 'large', emits: 'sparkline-winloss' },
748
+ small(1, { id: 'sparkline-setup', label: 'Edit', title: 'The sparkline group here: its ranges, kind and colours', icon: 'chart-setup', kind: 'button', wide: true, emits: 'sparkline-setup' }),
749
+ small(2, { id: 'sparkline-clear', label: 'Clear', title: 'Clear the sparklines in the selection', icon: 'delete-cells', kind: 'button', wide: true, emits: 'clear-sparklines' }),
750
+ ],
751
+ },
752
+ {
753
+ // Excel's Links group: one dialog for the address, the text and the tip,
754
+ // and Remove Link beside it.
755
+ id: 'links',
756
+ icon: 'link',
757
+ label: 'Links',
758
+ items: [
759
+ { id: 'link', label: 'Link', title: 'Link this cell to a page or an address', keys: 'Ctrl+K', icon: 'link', kind: 'button', size: 'large', emits: 'insert-link' },
760
+ small(1, { id: 'unlink', label: 'Remove', title: 'Remove the link from the selection', icon: 'unlink', kind: 'button', wide: true, emits: 'remove-link' }),
761
+ ],
762
+ },
763
+ {
764
+ id: 'illustrations',
765
+ icon: 'picture',
766
+ label: 'Illustrations',
767
+ items: [
768
+ { id: 'picture', label: 'Picture', title: 'Put a picture on the sheet', icon: 'picture', kind: 'button', size: 'large', emits: 'insert-picture' },
769
+ ],
770
+ },
771
+ {
772
+ // Excel's Insert > Checkbox, with the two other controls a data-entry
773
+ // sheet asks for beside it. Each draws the cell as a control; the
774
+ // cell's own value is still what it means.
775
+ id: 'controls',
776
+ icon: 'checkbox',
777
+ label: 'Controls',
778
+ items: [
779
+ { id: 'insert-checkbox', label: 'Checkbox', title: 'Draw the selected cells as checkboxes, over TRUE and FALSE', icon: 'checkbox', kind: 'button', size: 'large', emits: 'insert-checkbox' },
780
+ small(2, { id: 'insert-cell-button', label: 'Button', title: 'Draw the selected cells as buttons', icon: 'cell-button', kind: 'button', emits: 'insert-cell-button' }),
781
+ small(2, { id: 'clear-cell-type', label: 'Clear Control', title: 'Draw the selected cells as ordinary cells again', icon: 'clear-formats', kind: 'button', emits: 'clear-cell-type' }),
534
782
  ],
535
783
  },
536
784
  {
@@ -605,7 +853,12 @@ const FORMULAS = {
605
853
  icon: 'show-formulas',
606
854
  label: 'Formula Auditing',
607
855
  items: [
856
+ small(1, { id: 'trace-precedents', label: 'Trace Precedents', title: 'Trace Precedents: arrows from the cells the active formula reads; again for the next level', icon: 'trace-precedents', kind: 'button', wide: true, emits: 'trace-precedents' }),
857
+ small(2, { id: 'trace-dependents', label: 'Trace Dependents', title: 'Trace Dependents: arrows to the formulas that read the active cell; again for the next level', icon: 'trace-dependents', kind: 'button', wide: true, emits: 'trace-dependents' }),
858
+ small(3, { id: 'remove-arrows', label: 'Remove Arrows', title: 'Remove Arrows', icon: 'remove-arrows', kind: 'button', wide: true, emits: 'remove-arrows' }),
608
859
  small(1, { id: 'show-formulas', label: 'Show Formulas', title: 'Show formulas instead of their results', keys: 'Ctrl+`', icon: 'show-formulas', kind: 'toggle', wide: true, emits: 'toggle-formulas' }),
860
+ small(2, { id: 'evaluate-formula', label: 'Evaluate Formula', title: 'Evaluate Formula: work the active cell out one part at a time', icon: 'evaluate-formula', kind: 'button', wide: true, emits: 'evaluate-formula' }),
861
+ small(3, { id: 'error-checking', label: 'Error Checking', title: 'Error Checking: walk the cells on this sheet that report an error, and the formulas that break their column\'s pattern', icon: 'error-checking', kind: 'button', wide: true, emits: 'error-checking' }),
609
862
  ],
610
863
  },
611
864
  {
@@ -615,6 +868,7 @@ const FORMULAS = {
615
868
  items: [
616
869
  { id: 'recalc', label: 'Calculate Now', title: 'Recalculate the workbook', keys: 'F9', icon: 'calculate', kind: 'button', size: 'large', emits: 'recalculate' },
617
870
  small(1, { id: 'goal-seek-f', label: 'Goal Seek', title: 'Goal Seek', icon: 'goal-seek', kind: 'button', wide: true, emits: 'goal-seek' }),
871
+ small(2, { id: 'calc-options', label: 'Calculation Options', title: 'Iterative calculation: let a circular reference settle instead of showing #CYCLE!', icon: 'calculate', kind: 'button', wide: true, emits: 'calc-options' }),
618
872
  ],
619
873
  },
620
874
  ],
@@ -630,6 +884,7 @@ const DATA = {
630
884
  items: [
631
885
  small(1, { id: 'sort-asc', label: 'Sort A to Z', title: 'Sort A to Z', icon: 'sort-asc', kind: 'button', emits: 'sort-asc' }),
632
886
  small(2, { id: 'sort-desc', label: 'Sort Z to A', title: 'Sort Z to A', icon: 'sort-desc', kind: 'button', emits: 'sort-desc' }),
887
+ { id: 'sort-custom', label: 'Sort', title: 'Sort: by several columns, each its own way', icon: 'sort', kind: 'button', size: 'large', emits: 'sort-custom' },
633
888
  { id: 'filter-data', label: 'Filter', title: 'Filter', keys: 'Ctrl+Shift+L', icon: 'filter', kind: 'toggle', size: 'large', emits: 'toggle-filter' },
634
889
  ],
635
890
  },
@@ -640,7 +895,17 @@ const DATA = {
640
895
  items: [
641
896
  { id: 'text-to-columns', label: 'Text to Columns', title: 'Split the selected column on a delimiter', icon: 'text-to-columns', kind: 'button', size: 'large', emits: 'text-to-columns' },
642
897
  { id: 'remove-duplicates', label: 'Remove Duplicates', title: 'Remove duplicate rows', icon: 'remove-duplicates', kind: 'button', size: 'large', emits: 'remove-duplicates' },
643
- { id: 'data-validation', label: 'Data Validation', title: 'Data Validation: what may be typed into the selected cells', icon: 'validation', kind: 'button', size: 'large', emits: 'data-validation' },
898
+ // Excel's menu: the dialog, then Circle Invalid Data and Clear
899
+ // Validation Circles, each raised for the shell.
900
+ {
901
+ id: 'data-validation', label: 'Data Validation', title: 'Data Validation: what may be typed into the selected cells',
902
+ icon: 'validation', kind: 'dropdown', size: 'large',
903
+ options: [
904
+ { value: 'data-validation', label: 'Data Validation...', emits: 'data-validation' },
905
+ { value: 'circle-invalid', label: 'Circle Invalid Data', emits: 'circle-invalid' },
906
+ { value: 'clear-circles', label: 'Clear Validation Circles', emits: 'clear-circles' },
907
+ ],
908
+ },
644
909
  ],
645
910
  },
646
911
  {
@@ -651,6 +916,36 @@ const DATA = {
651
916
  { id: 'goal-seek', label: 'Goal Seek', title: 'Change one input until a formula hits a target', icon: 'goal-seek', kind: 'button', size: 'large', emits: 'goal-seek' },
652
917
  ],
653
918
  },
919
+ {
920
+ id: 'outline',
921
+ icon: 'group-rows',
922
+ label: 'Outline',
923
+ items: [
924
+ // Excel's Group and Ungroup are split buttons whose face acts on
925
+ // rows; the ribbon model forbids a dropdown that emits its own
926
+ // face, so each is a menu whose first entry is the face's action.
927
+ {
928
+ id: 'group', label: 'Group', title: 'Group the selected rows or columns',
929
+ icon: 'group-rows', kind: 'dropdown', size: 'large', wide: true,
930
+ options: [
931
+ { value: 'group-rows', label: 'Group Rows', keys: 'Alt+Shift+Right', emits: 'group-rows' },
932
+ { value: 'group-cols', label: 'Group Columns', emits: 'group-cols' },
933
+ { value: 'auto-outline', label: 'Auto Outline', emits: 'auto-outline' },
934
+ ],
935
+ },
936
+ {
937
+ id: 'ungroup', label: 'Ungroup', title: 'Ungroup the selected rows or columns',
938
+ icon: 'ungroup-rows', kind: 'dropdown', size: 'large', wide: true,
939
+ options: [
940
+ { value: 'ungroup-rows', label: 'Ungroup Rows', keys: 'Alt+Shift+Left', emits: 'ungroup-rows' },
941
+ { value: 'ungroup-cols', label: 'Ungroup Columns', emits: 'ungroup-cols' },
942
+ { value: 'clear-outline', label: 'Clear Outline', emits: 'clear-outline' },
943
+ ],
944
+ },
945
+ small(2, { id: 'show-detail', label: 'Show Detail', title: 'Expand the group at the selection', icon: 'show-detail', kind: 'button', emits: 'show-detail' }),
946
+ small(2, { id: 'hide-detail', label: 'Hide Detail', title: 'Collapse the group at the selection', icon: 'hide-detail', kind: 'button', emits: 'hide-detail' }),
947
+ ],
948
+ },
654
949
  ],
655
950
  };
656
951
  function toggleWrap(cmd) {
@@ -671,8 +966,10 @@ function toggleWrap(cmd) {
671
966
  * the sheet's notes: New Comment opens the editor on the active cell (and
672
967
  * edits the one there), Delete, Previous and Next walk them, Show All
673
968
  * Comments lists them. Protect Sheet and Unprotect Sheet are one slot, the
674
- * shell leaving off whichever does not apply. There is no password, as the
675
- * sheet documents.
969
+ * shell leaving off whichever does not apply; Protect Sheet opens Excel's
970
+ * dialog with its "allow all users to" list, and Allow Edit Ranges names
971
+ * the blocks that stay editable. There is no password, as the sheet
972
+ * documents.
676
973
  */
677
974
  const REVIEW = {
678
975
  id: 'review',
@@ -703,6 +1000,10 @@ const REVIEW = {
703
1000
  id: 'unprotect-sheet', label: 'Unprotect Sheet', title: 'Unprotect Sheet',
704
1001
  icon: 'unprotect', kind: 'button', size: 'large', emits: 'unprotect-sheet',
705
1002
  },
1003
+ {
1004
+ id: 'allow-edit-ranges', label: 'Allow Edit Ranges', title: 'Allow Users to Edit Ranges: blocks that take an edit while the sheet is protected',
1005
+ icon: 'edit-ranges', kind: 'button', size: 'large', emits: 'allow-edit-ranges',
1006
+ },
706
1007
  ],
707
1008
  },
708
1009
  ],
@@ -746,7 +1047,7 @@ const VIEW = {
746
1047
  },
747
1048
  ],
748
1049
  };
749
- export const RIBBON_TABS = [HOME, INSERT, FORMULAS, DATA, REVIEW, VIEW];
1050
+ export const RIBBON_TABS = [FILE, HOME, INSERT, PAGE_LAYOUT, FORMULAS, DATA, REVIEW, VIEW];
750
1051
  /** Every item across every tab, for tests and for a command palette. */
751
1052
  export function ribbonItems() {
752
1053
  return RIBBON_TABS.flatMap((tab) => tab.groups.flatMap((group) => group.items));
@@ -0,0 +1,74 @@
1
+ /**
2
+ * What kind of thing a sheet tab is.
3
+ *
4
+ * A workbook's tabs have always been cell grids. A `grid` tab is the other
5
+ * thing a business workbook wants: a data-bound table, backed by records
6
+ * rather than by cells, sorted and filtered and edited as a grid rather
7
+ * than as a sheet.
8
+ *
9
+ * The trick that makes this cheap rather than a second engine: **a grid
10
+ * sheet PROJECTS its records into the workbook's cells.** The records are
11
+ * the truth, and after every change they are written into the same
12
+ * `string[][]` a cell sheet keeps, header row included. So
13
+ * `=SUM(Orders!D2:D99)` on a cell sheet reads a grid sheet with no new
14
+ * machinery at all: the formula engine, the dependency graph, the file
15
+ * writers and the printer never learn that this tab is different.
16
+ *
17
+ * The projection runs through `setRaw`, which ignores a write that changes
18
+ * nothing, so editing one field of one record rewrites one cell and
19
+ * recalculates what depended on it, not the sheet.
20
+ *
21
+ * What a grid sheet deliberately does NOT do: hold a formula of its own.
22
+ * Its cells are a rendering of its records, so anything typed into them
23
+ * would be overwritten by the next projection. A sheet that needs formulas
24
+ * beside the data is a cell sheet reading the grid one across.
25
+ */
26
+ import { type SheetField } from './from-rows.js';
27
+ export type SheetKind = 'cells' | 'grid';
28
+ /** One column of a grid sheet, as the sheet describes it. */
29
+ export type GridSheetField = SheetField & {
30
+ /** Narrow the editor and the alignment, as the grid's own columns do. */
31
+ type?: 'text' | 'number' | 'date' | 'boolean';
32
+ width?: number;
33
+ editable?: boolean;
34
+ };
35
+ export type GridSheetSpec = {
36
+ fields: GridSheetField[];
37
+ /** The records. A grid sheet's truth; the cells are made from these. */
38
+ rows: Array<Record<string, unknown>>;
39
+ /** Rows may be edited in place. Off by default, as a report would want. */
40
+ editable?: boolean;
41
+ /** A totals row under the records, summing every numeric column. */
42
+ totals?: boolean;
43
+ };
44
+ export declare const emptyGridSheet: () => GridSheetSpec;
45
+ /** The cells a grid sheet stands for: the header, the records, the totals. */
46
+ export declare function projectGridSheet(spec: GridSheetSpec): string[][];
47
+ /**
48
+ * Where a record sits in the projection.
49
+ *
50
+ * Row 0 is the header, so record `i` is at row `i + 1`. Kept as a function
51
+ * rather than inlined so the offset is named in one place: getting it
52
+ * wrong reads the header as a record and is silent.
53
+ */
54
+ export declare const rowOfRecord: (index: number) => number;
55
+ export declare const recordOfRow: (row: number) => number;
56
+ /** Is this row of the projection a record, rather than a header or total? */
57
+ export declare const isRecordRow: (spec: GridSheetSpec, row: number) => boolean;
58
+ /**
59
+ * A field's column in the projection, or -1.
60
+ *
61
+ * Matched on the field name rather than the label, since two columns may
62
+ * share a label and the name is what the record is keyed by.
63
+ */
64
+ export declare const columnOfField: (spec: GridSheetSpec, field: string) => number;
65
+ /** A deep-enough copy for a document snapshot. */
66
+ export declare const copyGridSheet: (spec: GridSheetSpec) => GridSheetSpec;
67
+ /**
68
+ * A value typed into a grid sheet, coerced to the field's type.
69
+ *
70
+ * The grid hands back whatever its editor produced, which for a number
71
+ * column typed into by hand is a string. Storing that would make the
72
+ * record's shape depend on how it was edited, so it is narrowed here once.
73
+ */
74
+ export declare function coerceFieldValue(field: GridSheetField, value: unknown): unknown;