@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.
- package/LICENSE +94 -24
- package/README.md +36 -4
- package/dist/SvAdvancedFilter.svelte +1 -1
- package/dist/SvAlertsManager.svelte +2 -1
- package/dist/SvBoard.svelte +2 -1
- package/dist/SvExportMenu.svelte +4 -1
- package/dist/SvExportMenu.svelte.d.ts +0 -13
- package/dist/SvExpressionEditor.svelte +3 -3
- package/dist/SvFormulaBar.svelte +680 -0
- package/dist/SvFormulaBar.svelte.d.ts +69 -0
- package/dist/SvGridAlerts.svelte +49 -9
- package/dist/SvGridBoard.svelte +13 -8
- package/dist/SvGridBulkEditDrawer.svelte +26 -2
- package/dist/SvGridEditPanel.svelte +3 -0
- package/dist/SvGridScheduler.svelte +69 -40
- package/dist/SvGridSelectionBar.svelte +10 -3
- package/dist/SvPivotDesigner.svelte +263 -54
- package/dist/SvPivotDesigner.svelte.d.ts +27 -20
- package/dist/SvRibbonIcon.svelte +46 -0
- package/dist/SvRibbonIcon.svelte.d.ts +17 -0
- package/dist/SvSchemaChart.svelte +4 -2
- package/dist/SvSheet.svelte +7914 -0
- package/dist/SvSheet.svelte.d.ts +215 -0
- package/dist/SvSheetChartSetup.svelte +151 -0
- package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
- package/dist/SvSheetComment.svelte +283 -0
- package/dist/SvSheetComment.svelte.d.ts +22 -0
- package/dist/SvSheetConditionalFormat.svelte +159 -0
- package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
- package/dist/SvSheetDataValidation.svelte +273 -0
- package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
- package/dist/SvSheetEditRanges.svelte +217 -0
- package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
- package/dist/SvSheetErrors.svelte +125 -0
- package/dist/SvSheetErrors.svelte.d.ts +20 -0
- package/dist/SvSheetEvaluate.svelte +133 -0
- package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
- package/dist/SvSheetFilterMenu.svelte +320 -0
- package/dist/SvSheetFilterMenu.svelte.d.ts +22 -0
- package/dist/SvSheetFindReplace.svelte +132 -0
- package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
- package/dist/SvSheetFormatCells.svelte +465 -0
- package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
- package/dist/SvSheetGoalSeek.svelte +145 -0
- package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
- package/dist/SvSheetInsertFunction.svelte +149 -0
- package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
- package/dist/SvSheetIteration.svelte +81 -0
- package/dist/SvSheetIteration.svelte.d.ts +10 -0
- package/dist/SvSheetLink.svelte +99 -0
- package/dist/SvSheetLink.svelte.d.ts +17 -0
- package/dist/SvSheetListPicker.svelte +91 -0
- package/dist/SvSheetListPicker.svelte.d.ts +10 -0
- package/dist/SvSheetManageRules.svelte +187 -0
- package/dist/SvSheetManageRules.svelte.d.ts +16 -0
- package/dist/SvSheetNameManager.svelte +227 -0
- package/dist/SvSheetNameManager.svelte.d.ts +11 -0
- package/dist/SvSheetPageSetup.svelte +159 -0
- package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
- package/dist/SvSheetPasteSpecial.svelte +107 -0
- package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
- package/dist/SvSheetPivot.svelte +220 -0
- package/dist/SvSheetPivot.svelte.d.ts +21 -0
- package/dist/SvSheetProtectSheet.svelte +81 -0
- package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
- package/dist/SvSheetRemoveDuplicates.svelte +152 -0
- package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
- package/dist/SvSheetRibbon.svelte +1254 -0
- package/dist/SvSheetRibbon.svelte.d.ts +34 -0
- package/dist/SvSheetSizeDialog.svelte +60 -0
- package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
- package/dist/SvSheetSort.svelte +218 -0
- package/dist/SvSheetSort.svelte.d.ts +28 -0
- package/dist/SvSheetSparklines.svelte +135 -0
- package/dist/SvSheetSparklines.svelte.d.ts +14 -0
- package/dist/SvSheetTable.svelte +160 -0
- package/dist/SvSheetTable.svelte.d.ts +24 -0
- package/dist/SvSheetTabs.svelte +571 -0
- package/dist/SvSheetTabs.svelte.d.ts +50 -0
- package/dist/SvSheetTabs.test-harness.svelte.d.ts +17 -0
- package/dist/SvSheetTabs.test-harness.svelte.js +22 -0
- package/dist/SvSheetTextToColumns.svelte +172 -0
- package/dist/SvSheetTextToColumns.svelte.d.ts +13 -0
- package/dist/SvSheetValidationAlert.svelte +85 -0
- package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
- package/dist/advanced-filter-enable.js +1 -1
- package/dist/alerts/alert-engine.d.ts +6 -0
- package/dist/alerts/alert-engine.js +21 -4
- package/dist/alerts/alert-formats.js +2 -0
- package/dist/alerts/alert-types.d.ts +1 -1
- package/dist/alerts.d.ts +1 -1
- package/dist/alerts.js +2 -2
- package/dist/board.js +2 -2
- package/dist/bulk-edit.d.ts +3 -1
- package/dist/bulk-edit.js +1 -1
- package/dist/cdn/svgrid-enterprise.svelte-external.js +43538 -6539
- package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
- package/dist/designer/assets/SvChartMenu-BDoeqGz6.js +1 -0
- package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
- package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
- package/dist/designer/assets/SvDateTimePicker-DCPg7WGN.js +1 -0
- package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
- package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
- package/dist/designer/assets/SvGridChart-Cy1ATrWh.js +3 -0
- package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
- package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
- package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
- package/dist/designer/assets/SvGridChartPanel-CATdVc9X.js +4 -0
- package/dist/designer/assets/{SvGridChartView-DUc-1RUf.css → SvGridChartView-7msfnWZT.css} +1 -1
- package/dist/designer/assets/SvGridChartView-CmsZtCED.js +1 -0
- package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
- package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
- package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
- package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
- package/dist/designer/assets/SvTabs-2mHC6oaz.js +1 -0
- package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
- package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
- package/dist/designer/assets/chart-Cn7MnNqA.js +1 -0
- package/dist/designer/assets/chart-export-B6bkQ3X8.js +11 -0
- package/dist/designer/assets/chart-export-pdf-BbA28-gt.js +11 -0
- package/dist/designer/assets/chart-panel-messages-Dz7PTIqT.js +1 -0
- package/dist/designer/assets/chart-summary-BD1qYB2R.js +1 -0
- package/dist/designer/assets/chart-trend-B8xr5LuD.js +1 -0
- package/dist/designer/assets/chart-validate-BMqM-qkF.js +1 -0
- package/dist/designer/assets/column-resize-BYDzR1Ve.js +1 -0
- package/dist/designer/assets/date-format-B8JbEtIG.js +1 -0
- package/dist/designer/assets/date-format-DKS-z0xS.css +1 -0
- package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
- package/dist/designer/assets/editor-contract-Bpoa7A5g.js +1 -0
- package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
- package/dist/designer/assets/focus-trap-V2-6Fy9I.js +1 -0
- package/dist/designer/assets/{index-C_a9Cj8Y.js → index-D5bVbuzI.js} +318 -315
- package/dist/designer/assets/index-_JVFxt02.css +1 -0
- package/dist/designer/assets/list-option-BP_dWS66.js +1 -0
- package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
- package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
- package/dist/designer/assets/src-CITpcm6b.js +1 -0
- package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
- package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
- package/dist/designer/index.html +29 -19
- package/dist/export-pdf.d.ts +164 -0
- package/dist/export-pdf.js +346 -15
- package/dist/export.js +25 -10
- package/dist/gantt/SvGridGantt.svelte +2890 -0
- package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
- package/dist/gantt/gantt-config.d.ts +73 -0
- package/dist/gantt/gantt-config.js +1 -0
- package/dist/gantt/gantt-critical-path.d.ts +67 -0
- package/dist/gantt/gantt-critical-path.js +207 -0
- package/dist/gantt/gantt-model.d.ts +257 -0
- package/dist/gantt/gantt-model.js +651 -0
- package/dist/gantt/gantt-resources.d.ts +59 -0
- package/dist/gantt/gantt-resources.js +71 -0
- package/dist/gantt/gantt.d.ts +7 -0
- package/dist/gantt/gantt.js +36 -0
- package/dist/gantt/index.d.ts +15 -0
- package/dist/gantt/index.js +22 -0
- package/dist/gantt/timeline-arrows.d.ts +102 -0
- package/dist/gantt/timeline-arrows.js +181 -0
- package/dist/import.d.ts +2 -2
- package/dist/import.js +1 -1
- package/dist/index.d.ts +93 -3
- package/dist/index.js +107 -3
- package/dist/install.js +13 -1
- package/dist/license-core.d.ts +17 -1
- package/dist/license-core.js +16 -5
- package/dist/license.d.ts +18 -2
- package/dist/license.js +71 -6
- package/dist/node/studio.js +203 -9
- package/dist/pivot-chart.d.ts +25 -1
- package/dist/pivot-chart.js +25 -69
- package/dist/pivot-enable.js +2 -2
- package/dist/scheduler-dependencies.d.ts +35 -0
- package/dist/scheduler-dependencies.js +36 -1
- package/dist/scheduler.js +2 -2
- package/dist/selection-bar.js +2 -2
- package/dist/server/SvGroupCell.svelte +213 -0
- package/dist/server/SvGroupCell.svelte.d.ts +62 -0
- package/dist/server/SvRowGroupPanel.svelte +322 -0
- package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
- package/dist/server/enable.d.ts +17 -0
- package/dist/server/enable.js +49 -0
- package/dist/server/index.d.ts +22 -0
- package/dist/server/index.js +24 -0
- package/dist/server/messages.d.ts +45 -0
- package/dist/server/messages.js +35 -0
- package/dist/server/server-group-model.d.ts +104 -0
- package/dist/server/server-group-model.js +272 -0
- package/dist/server/server-pivot.d.ts +46 -0
- package/dist/server/server-pivot.js +57 -0
- package/dist/server/server-row-model.d.ts +547 -0
- package/dist/server/server-row-model.js +1551 -0
- package/dist/server/server-selection.d.ts +99 -0
- package/dist/server/server-selection.js +215 -0
- package/dist/server/svgrid-adapter.d.ts +155 -0
- package/dist/server/svgrid-adapter.js +202 -0
- package/dist/sheet/address.d.ts +43 -0
- package/dist/sheet/address.js +81 -0
- package/dist/sheet/ast.d.ts +138 -0
- package/dist/sheet/ast.js +70 -0
- package/dist/sheet/auto-filter.d.ts +120 -0
- package/dist/sheet/auto-filter.js +295 -0
- package/dist/sheet/autocomplete.d.ts +51 -0
- package/dist/sheet/autocomplete.js +248 -0
- package/dist/sheet/cell-images.d.ts +39 -0
- package/dist/sheet/cell-images.js +90 -0
- package/dist/sheet/cell-types.d.ts +58 -0
- package/dist/sheet/cell-types.js +96 -0
- package/dist/sheet/coerce.d.ts +71 -0
- package/dist/sheet/coerce.js +289 -0
- package/dist/sheet/commands.d.ts +89 -0
- package/dist/sheet/commands.js +230 -0
- package/dist/sheet/comments.d.ts +63 -0
- package/dist/sheet/comments.js +131 -0
- package/dist/sheet/conditional-formats.d.ts +167 -0
- package/dist/sheet/conditional-formats.js +341 -0
- package/dist/sheet/csv.d.ts +32 -0
- package/dist/sheet/csv.js +158 -0
- package/dist/sheet/culture.d.ts +87 -0
- package/dist/sheet/culture.js +247 -0
- package/dist/sheet/delta.d.ts +102 -0
- package/dist/sheet/delta.js +203 -0
- package/dist/sheet/deps.d.ts +104 -0
- package/dist/sheet/deps.js +274 -0
- package/dist/sheet/document.d.ts +252 -0
- package/dist/sheet/document.js +465 -0
- package/dist/sheet/edit-keys.d.ts +14 -0
- package/dist/sheet/edit-keys.js +40 -0
- package/dist/sheet/engine.d.ts +67 -0
- package/dist/sheet/engine.js +19 -0
- package/dist/sheet/entry.d.ts +35 -0
- package/dist/sheet/entry.js +226 -0
- package/dist/sheet/error-check.d.ts +49 -0
- package/dist/sheet/error-check.js +83 -0
- package/dist/sheet/evaluate-steps.d.ts +48 -0
- package/dist/sheet/evaluate-steps.js +196 -0
- package/dist/sheet/evaluate.d.ts +128 -0
- package/dist/sheet/evaluate.js +1049 -0
- package/dist/sheet/filter-files.d.ts +37 -0
- package/dist/sheet/filter-files.js +465 -0
- package/dist/sheet/find-replace.d.ts +62 -0
- package/dist/sheet/find-replace.js +152 -0
- package/dist/sheet/format-store.d.ts +114 -0
- package/dist/sheet/format-store.js +243 -0
- package/dist/sheet/freeze.d.ts +54 -0
- package/dist/sheet/freeze.js +58 -0
- package/dist/sheet/from-rows.d.ts +14 -0
- package/dist/sheet/from-rows.js +50 -0
- package/dist/sheet/function-catalog.d.ts +10 -0
- package/dist/sheet/function-catalog.js +385 -0
- package/dist/sheet/functions.d.ts +28 -0
- package/dist/sheet/functions.js +634 -0
- package/dist/sheet/goal-seek.d.ts +73 -0
- package/dist/sheet/goal-seek.js +153 -0
- package/dist/sheet/index.d.ts +80 -0
- package/dist/sheet/index.js +80 -0
- package/dist/sheet/links.d.ts +57 -0
- package/dist/sheet/links.js +174 -0
- package/dist/sheet/merges.d.ts +71 -0
- package/dist/sheet/merges.js +137 -0
- package/dist/sheet/messages.d.ts +778 -0
- package/dist/sheet/messages.js +806 -0
- package/dist/sheet/names.d.ts +31 -0
- package/dist/sheet/names.js +87 -0
- package/dist/sheet/navigate.d.ts +52 -0
- package/dist/sheet/navigate.js +135 -0
- package/dist/sheet/number-format.d.ts +110 -0
- package/dist/sheet/number-format.js +905 -0
- package/dist/sheet/objects.d.ts +106 -0
- package/dist/sheet/objects.js +149 -0
- package/dist/sheet/ods-document.d.ts +44 -0
- package/dist/sheet/ods-document.js +1275 -0
- package/dist/sheet/open-file.d.ts +26 -0
- package/dist/sheet/open-file.js +56 -0
- package/dist/sheet/outline.d.ts +82 -0
- package/dist/sheet/outline.js +228 -0
- package/dist/sheet/packs/array.d.ts +16 -0
- package/dist/sheet/packs/array.js +172 -0
- package/dist/sheet/packs/database.d.ts +42 -0
- package/dist/sheet/packs/database.js +142 -0
- package/dist/sheet/packs/engineering.d.ts +2 -0
- package/dist/sheet/packs/engineering.js +296 -0
- package/dist/sheet/packs/financial.d.ts +5 -0
- package/dist/sheet/packs/financial.js +220 -0
- package/dist/sheet/packs/math-stats.d.ts +2 -0
- package/dist/sheet/packs/math-stats.js +372 -0
- package/dist/sheet/packs/special.d.ts +44 -0
- package/dist/sheet/packs/special.js +187 -0
- package/dist/sheet/packs/stats-dist.d.ts +2 -0
- package/dist/sheet/packs/stats-dist.js +785 -0
- package/dist/sheet/packs/text-date.d.ts +2 -0
- package/dist/sheet/packs/text-date.js +332 -0
- package/dist/sheet/packs/trig.d.ts +2 -0
- package/dist/sheet/packs/trig.js +73 -0
- package/dist/sheet/page-setup.d.ts +73 -0
- package/dist/sheet/page-setup.js +73 -0
- package/dist/sheet/palette.d.ts +19 -0
- package/dist/sheet/palette.js +84 -0
- package/dist/sheet/parse.d.ts +13 -0
- package/dist/sheet/parse.js +140 -0
- package/dist/sheet/paste-special.d.ts +186 -0
- package/dist/sheet/paste-special.js +601 -0
- package/dist/sheet/pivot-range.d.ts +160 -0
- package/dist/sheet/pivot-range.js +333 -0
- package/dist/sheet/presence.d.ts +73 -0
- package/dist/sheet/presence.js +79 -0
- package/dist/sheet/print.d.ts +104 -0
- package/dist/sheet/print.js +169 -0
- package/dist/sheet/protection.d.ts +75 -0
- package/dist/sheet/protection.js +101 -0
- package/dist/sheet/rects.d.ts +45 -0
- package/dist/sheet/rects.js +112 -0
- package/dist/sheet/refs.d.ts +130 -0
- package/dist/sheet/refs.js +413 -0
- package/dist/sheet/ribbon-icons.d.ts +31 -0
- package/dist/sheet/ribbon-icons.js +536 -0
- package/dist/sheet/ribbon.d.ts +173 -0
- package/dist/sheet/ribbon.js +1054 -0
- package/dist/sheet/sheet-kinds.d.ts +74 -0
- package/dist/sheet/sheet-kinds.js +91 -0
- package/dist/sheet/shortcuts.d.ts +174 -0
- package/dist/sheet/shortcuts.js +674 -0
- package/dist/sheet/sort.d.ts +51 -0
- package/dist/sheet/sort.js +107 -0
- package/dist/sheet/sparklines.d.ts +111 -0
- package/dist/sheet/sparklines.js +204 -0
- package/dist/sheet/structure.d.ts +87 -0
- package/dist/sheet/structure.js +166 -0
- package/dist/sheet/table-styles.d.ts +74 -0
- package/dist/sheet/table-styles.js +152 -0
- package/dist/sheet/tables.d.ts +89 -0
- package/dist/sheet/tables.js +178 -0
- package/dist/sheet/tokenize.d.ts +71 -0
- package/dist/sheet/tokenize.js +355 -0
- package/dist/sheet/transforms.d.ts +76 -0
- package/dist/sheet/transforms.js +154 -0
- package/dist/sheet/validation.d.ts +108 -0
- package/dist/sheet/validation.js +278 -0
- package/dist/sheet/workbook.d.ts +217 -0
- package/dist/sheet/workbook.js +1120 -0
- package/dist/sheet/xls-cfb.d.ts +32 -0
- package/dist/sheet/xls-cfb.js +290 -0
- package/dist/sheet/xls-document.d.ts +10 -0
- package/dist/sheet/xls-document.js +1243 -0
- package/dist/sheet/xls-formula.d.ts +40 -0
- package/dist/sheet/xls-formula.js +569 -0
- package/dist/sheet/xlsx-document.d.ts +108 -0
- package/dist/sheet/xlsx-document.js +1849 -0
- package/dist/sheet/xlsx-drawing.d.ts +99 -0
- package/dist/sheet/xlsx-drawing.js +420 -0
- package/dist/sheet-enable.d.ts +6 -0
- package/dist/sheet-enable.js +45 -0
- package/dist/sheet-text.d.ts +7 -0
- package/dist/sheet-text.js +29 -0
- package/dist/sources/auth-supabase.js +2 -2
- package/dist/sources/realtime-supabase.js +2 -2
- package/dist/sources/rest.d.ts +6 -2
- package/dist/sources/rest.js +42 -7
- package/dist/sources/supabase.d.ts +10 -1
- package/dist/sources/supabase.js +73 -40
- package/dist/studio/emit-project.js +14 -1
- package/dist/studio/index.js +1 -1
- package/dist/studio/project.d.ts +11 -2
- package/dist/studio/project.js +5 -2
- package/dist/studio/ui-components.generated.js +170 -3
- package/dist/sveltekit/in-memory.d.ts +2 -2
- package/dist/sveltekit/in-memory.js +125 -4
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/dist/sveltekit/query-plan.d.ts +50 -4
- package/dist/sveltekit/query-plan.js +25 -3
- package/dist/sveltekit/sql-source.d.ts +6 -0
- package/dist/sveltekit/sql-source.js +34 -6
- package/dist/sveltekit/sql.d.ts +31 -0
- package/dist/sveltekit/sql.js +135 -25
- package/dist/sveltekit/transport.d.ts +10 -2
- package/dist/sveltekit/transport.js +30 -6
- package/dist/upgrade-prompt.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/watermark.js +35 -2
- package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
- package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
- package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
- package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
- package/dist/wc/SvField-B_kurx_P.js +149 -0
- package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
- package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
- package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
- package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
- package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
- package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
- package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
- package/dist/wc/SvModal-DrfOYYyX.js +189 -0
- package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
- package/dist/wc/chart-6OXlybVT.js +4341 -0
- package/dist/wc/chart-export-CeSADGfi.js +135 -0
- package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
- package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
- package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
- package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
- package/dist/wc/client-DQIzjDBG.js +3064 -0
- package/dist/wc/column-resize-DUPgynvc.js +101 -0
- package/dist/wc/date-format-DS-z_h9v.js +1130 -0
- package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
- package/dist/wc/editor-contract-peBDxir_.js +22 -0
- package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
- package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
- package/dist/wc/list-option-DrRyivWp.js +82 -0
- package/dist/wc/popover-WsGlvtQv.js +69 -0
- package/dist/wc/positioning-BiKLfu1E.js +112 -0
- package/dist/wc/react.d.ts +41 -0
- package/dist/wc/react.js +90 -0
- package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
- package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
- package/dist/wc/row-resize-limG_N1z.js +111 -0
- package/dist/wc/sv-sheet-element.d.ts +97 -0
- package/dist/wc/sv-sheet-element.js +44213 -0
- package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
- package/dist/wc/validate-BqDthkNr.js +88 -0
- package/dist/wc/vue.d.ts +31 -0
- package/dist/wc/vue.js +75 -0
- package/package.json +36 -6
- package/dist/designer/assets/GridMenus-B1JtIN21.js +0 -8
- package/dist/designer/assets/SvDateRangeInput-CjO7nn_x.js +0 -1
- package/dist/designer/assets/SvDateTimePicker-ByBD_ov6.js +0 -1
- package/dist/designer/assets/SvField-YDLipR6O.css +0 -1
- package/dist/designer/assets/SvField-cj1PFNgZ.js +0 -1
- package/dist/designer/assets/SvGridCellEditor-0W1L2hJ1.js +0 -2
- package/dist/designer/assets/SvGridChart-DBOR4xcz.js +0 -2
- package/dist/designer/assets/SvGridChart-fkMWeh1J.css +0 -1
- package/dist/designer/assets/SvGridChartPanel-symrhNnR.js +0 -11
- package/dist/designer/assets/SvGridChartView-BmRxq6mU.js +0 -1
- package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
- package/dist/designer/assets/SvListBox-1oUF6Iav.js +0 -110
- package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
- package/dist/designer/assets/chart-DXFganU8.js +0 -1
- package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
- package/dist/designer/assets/date-format-DGagAqRc.css +0 -1
- package/dist/designer/assets/date-format-onlYDsrY.js +0 -1
- package/dist/designer/assets/easing-zaypKrr0.js +0 -3
- package/dist/designer/assets/index-k2stW6L8.css +0 -1
- package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
- package/dist/designer/assets/src-D9p27OGC.js +0 -58
- package/dist/designer/assets/validate-h-aslRV9.js +0 -1
|
@@ -0,0 +1,1054 @@
|
|
|
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
|
+
export { FONT_SIZES, applyBorders } from './shortcuts.js';
|
|
3
|
+
import { insertRows, deleteRows, insertColumns, deleteColumns, getStructureTarget } from './structure.js';
|
|
4
|
+
import { fillDown, fillRight, targetRect } from './commands.js';
|
|
5
|
+
import { FORMAT_PRESETS, FORMAT_CATEGORY_PATTERNS, formatCategory, accountingParts, accountingPattern, formatWithPattern } from './number-format.js';
|
|
6
|
+
import { ALL_COLOURS } from './palette.js';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Shared predicates
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/** True when there is at least one cell to act on. */
|
|
11
|
+
function hasTarget(cmd) {
|
|
12
|
+
return targetRect(cmd) !== null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The rectangles an action should write to: the selection when there is one,
|
|
16
|
+
* otherwise the active cell alone.
|
|
17
|
+
*
|
|
18
|
+
* The same fallback `applyFormat` makes, so a button with nothing
|
|
19
|
+
* range-selected behaves like the key it mirrors rather than declining.
|
|
20
|
+
*/
|
|
21
|
+
function rectsOf(cmd) {
|
|
22
|
+
if (cmd.ranges.length)
|
|
23
|
+
return cmd.ranges;
|
|
24
|
+
const rect = targetRect(cmd);
|
|
25
|
+
return rect ? [rect] : [];
|
|
26
|
+
}
|
|
27
|
+
/** Formatting needs somewhere to write. Without a store the keyboard
|
|
28
|
+
* bindings decline, so the buttons grey out for the same reason. */
|
|
29
|
+
function canFormat(cmd) {
|
|
30
|
+
const target = getFormatTarget();
|
|
31
|
+
if (!target || !hasTarget(cmd))
|
|
32
|
+
return false;
|
|
33
|
+
return target.guard?.(rectsOf(cmd)) !== false;
|
|
34
|
+
}
|
|
35
|
+
/** Insert and Delete grey out where the sheet refuses structural edits. */
|
|
36
|
+
function canRestructure() {
|
|
37
|
+
const target = getStructureTarget();
|
|
38
|
+
return !target || target.canApply?.({ kind: 'insertRows', at: 0, count: 1 }) !== false;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Whether every cell in the selection already carries `field`.
|
|
42
|
+
*
|
|
43
|
+
* Excel's own rule for a toggle button's pressed state, and the same rule
|
|
44
|
+
* `store.toggle` uses to decide which way the next press goes - so the button
|
|
45
|
+
* lights up exactly when pressing it would turn the attribute OFF.
|
|
46
|
+
*/
|
|
47
|
+
function everyCellHas(cmd, test) {
|
|
48
|
+
const target = getFormatTarget();
|
|
49
|
+
if (!target)
|
|
50
|
+
return false;
|
|
51
|
+
const rects = rectsOf(cmd);
|
|
52
|
+
if (!rects.length)
|
|
53
|
+
return false;
|
|
54
|
+
let seen = 0;
|
|
55
|
+
for (const [minRow, minCol, maxRow, maxCol] of rects) {
|
|
56
|
+
for (let r = minRow; r <= maxRow; r += 1) {
|
|
57
|
+
for (let c = minCol; c <= maxCol; c += 1) {
|
|
58
|
+
const rowId = target.lookup.rowIdAt(r);
|
|
59
|
+
const columnId = target.lookup.columnIdAt(c);
|
|
60
|
+
if (rowId == null || columnId == null)
|
|
61
|
+
continue;
|
|
62
|
+
seen += 1;
|
|
63
|
+
if (!test(target.store.get(rowId, columnId)))
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return seen > 0;
|
|
69
|
+
}
|
|
70
|
+
function styleToggle(field) {
|
|
71
|
+
return {
|
|
72
|
+
kind: 'toggle',
|
|
73
|
+
run: (cmd) => toggleFormat(cmd, field),
|
|
74
|
+
isOn: (cmd) => everyCellHas(cmd, (entry) => entry?.[field] === true),
|
|
75
|
+
isEnabled: canFormat,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function alignItem(align, title) {
|
|
79
|
+
return {
|
|
80
|
+
id: `align-${align}`,
|
|
81
|
+
label: '≡',
|
|
82
|
+
icon: `align-${align}`,
|
|
83
|
+
title,
|
|
84
|
+
kind: 'toggle',
|
|
85
|
+
run: (cmd) => applyFormat(cmd, { align }),
|
|
86
|
+
isOn: (cmd) => everyCellHas(cmd, (entry) => entry?.align === align),
|
|
87
|
+
isEnabled: canFormat,
|
|
88
|
+
};
|
|
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
|
+
}
|
|
105
|
+
function presetItem(id, label, title, name, keys) {
|
|
106
|
+
const run = preset(name);
|
|
107
|
+
return {
|
|
108
|
+
id,
|
|
109
|
+
label,
|
|
110
|
+
title,
|
|
111
|
+
keys,
|
|
112
|
+
kind: 'toggle',
|
|
113
|
+
run: (cmd) => run(cmd, new KeyboardEvent('keydown')),
|
|
114
|
+
isOn: (cmd) => everyCellHas(cmd, (entry) => entry?.numFmt === FORMAT_PRESETS[name]),
|
|
115
|
+
isEnabled: canFormat,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/** A command written for the keymap, adapted to a button. The event is only
|
|
119
|
+
* there because `SheetCommand` takes one; none of these read it. */
|
|
120
|
+
function fromCommand(command) {
|
|
121
|
+
return (cmd) => command(cmd, new KeyboardEvent('keydown'));
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Excel's Increase/Decrease Decimal.
|
|
125
|
+
*
|
|
126
|
+
* Reads the active cell's current pattern rather than assuming one, so
|
|
127
|
+
* pressing it on a currency cell keeps the currency and only moves the point.
|
|
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`.
|
|
132
|
+
*/
|
|
133
|
+
function nudgeDecimals(delta) {
|
|
134
|
+
return (cmd) => {
|
|
135
|
+
const target = getFormatTarget();
|
|
136
|
+
const active = cmd.activeCell;
|
|
137
|
+
if (!target || !active)
|
|
138
|
+
return false;
|
|
139
|
+
const rowId = target.lookup.rowIdAt(active.rowIndex);
|
|
140
|
+
const columnId = target.lookup.columnIdAt(active.colIndex);
|
|
141
|
+
const current = rowId != null && columnId != null
|
|
142
|
+
? target.store.get(rowId, columnId)?.numFmt
|
|
143
|
+
: undefined;
|
|
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
|
+
}
|
|
154
|
+
return next === null ? false : applyFormat(cmd, { numFmt: next });
|
|
155
|
+
};
|
|
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
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Move the decimal count of a number-format pattern by `delta`.
|
|
171
|
+
*
|
|
172
|
+
* Exported because it is the fiddly part and deserves its own tests: the
|
|
173
|
+
* pattern can have a prefix and a suffix (`$#,##0.00`, `0.0%`), can have no
|
|
174
|
+
* decimal section at all, and must not go below zero or run away past the 30
|
|
175
|
+
* places Excel allows.
|
|
176
|
+
*/
|
|
177
|
+
export function withDecimals(pattern, delta) {
|
|
178
|
+
// Every section moves together. The currency preset is
|
|
179
|
+
// '$#,##0.00;($#,##0.00)' - positives and negatives - and moving only the
|
|
180
|
+
// first half would leave a sheet where -1234.5 printed to a different
|
|
181
|
+
// precision than 1234.5. Excel moves both, so this does too.
|
|
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
|
+
}
|
|
191
|
+
// A quoted literal can contain a semicolon, which would make splitting on
|
|
192
|
+
// ';' cut a section in half, so a pattern with quotes declines instead of
|
|
193
|
+
// being mangled. Nothing else in FORMAT_PRESETS has one.
|
|
194
|
+
if (pattern.includes('"'))
|
|
195
|
+
return null;
|
|
196
|
+
const sections = pattern.split(';');
|
|
197
|
+
const moved = [];
|
|
198
|
+
for (const section of sections) {
|
|
199
|
+
const next = sectionWithDecimals(section, delta);
|
|
200
|
+
// All or nothing: a partial rewrite is the very thing this guards.
|
|
201
|
+
if (next === null)
|
|
202
|
+
return null;
|
|
203
|
+
moved.push(next);
|
|
204
|
+
}
|
|
205
|
+
return moved.join(';');
|
|
206
|
+
}
|
|
207
|
+
function sectionWithDecimals(section, delta) {
|
|
208
|
+
const dot = section.indexOf('.');
|
|
209
|
+
const places = dot < 0 ? 0 : countLeading(section.slice(dot + 1), '0');
|
|
210
|
+
const next = places + delta;
|
|
211
|
+
if (next < 0 || next > 30)
|
|
212
|
+
return null;
|
|
213
|
+
const head = dot < 0 ? section : section.slice(0, dot);
|
|
214
|
+
const tail = dot < 0 ? '' : section.slice(dot + 1 + places);
|
|
215
|
+
return next === 0 ? head + tail : `${head}.${'0'.repeat(next)}${tail}`;
|
|
216
|
+
}
|
|
217
|
+
function countLeading(text, ch) {
|
|
218
|
+
let n = 0;
|
|
219
|
+
while (n < text.length && text[n] === ch)
|
|
220
|
+
n += 1;
|
|
221
|
+
return n;
|
|
222
|
+
}
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
// Fonts, sizes, borders
|
|
225
|
+
// ---------------------------------------------------------------------------
|
|
226
|
+
/**
|
|
227
|
+
* The fonts a spreadsheet user reaches for, with the stacks that make each
|
|
228
|
+
* render on a machine that lacks it. The empty value is the theme's own
|
|
229
|
+
* font, which is what "Default" means here and what a fresh cell has.
|
|
230
|
+
*/
|
|
231
|
+
export const FONT_FAMILIES = [
|
|
232
|
+
{ value: '', label: 'Default' },
|
|
233
|
+
{ value: 'Aptos, "Aptos Narrow", "Segoe UI", sans-serif', label: 'Aptos' },
|
|
234
|
+
{ value: 'Calibri, Carlito, "Segoe UI", sans-serif', label: 'Calibri' },
|
|
235
|
+
{ value: 'Arial, Helvetica, sans-serif', label: 'Arial' },
|
|
236
|
+
{ value: '"Segoe UI", system-ui, sans-serif', label: 'Segoe UI' },
|
|
237
|
+
{ value: 'Verdana, Geneva, sans-serif', label: 'Verdana' },
|
|
238
|
+
{ value: 'Georgia, "Times New Roman", serif', label: 'Georgia' },
|
|
239
|
+
{ value: '"Times New Roman", Times, serif', label: 'Times New Roman' },
|
|
240
|
+
{ value: '"Courier New", Courier, monospace', label: 'Courier New' },
|
|
241
|
+
{ value: 'ui-monospace, Menlo, Consolas, monospace', label: 'Consolas' },
|
|
242
|
+
];
|
|
243
|
+
const NUMBER_FORMATS = [
|
|
244
|
+
{ value: 'general', label: 'General' },
|
|
245
|
+
{ value: 'number', label: 'Number' },
|
|
246
|
+
{ value: 'currency', label: 'Currency' },
|
|
247
|
+
{ value: 'accounting', label: 'Accounting' },
|
|
248
|
+
{ value: 'percent', label: 'Percentage' },
|
|
249
|
+
{ value: 'date', label: 'Date' },
|
|
250
|
+
{ value: 'time', label: 'Time' },
|
|
251
|
+
{ value: 'scientific', label: 'Scientific' },
|
|
252
|
+
];
|
|
253
|
+
const BORDER_OPTIONS = [
|
|
254
|
+
{ value: 'bottom', label: 'Bottom Border', icon: 'border-bottom' },
|
|
255
|
+
{ value: 'top', label: 'Top Border', icon: 'border-top' },
|
|
256
|
+
{ value: 'left', label: 'Left Border', icon: 'border-left' },
|
|
257
|
+
{ value: 'right', label: 'Right Border', icon: 'border-right' },
|
|
258
|
+
{ value: 'none', label: 'No Border', icon: 'border-none' },
|
|
259
|
+
{ value: 'all', label: 'All Borders', icon: 'border-all' },
|
|
260
|
+
{ value: 'outside', label: 'Outside Borders', icon: 'border-outside' },
|
|
261
|
+
{ value: 'thick-bottom', label: 'Thick Bottom Border', icon: 'border-thick-bottom' },
|
|
262
|
+
];
|
|
263
|
+
// ---------------------------------------------------------------------------
|
|
264
|
+
// The tabs
|
|
265
|
+
// ---------------------------------------------------------------------------
|
|
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
|
+
};
|
|
379
|
+
const HOME = {
|
|
380
|
+
id: 'home',
|
|
381
|
+
label: 'Home',
|
|
382
|
+
groups: [
|
|
383
|
+
{
|
|
384
|
+
id: 'clipboard',
|
|
385
|
+
icon: 'paste',
|
|
386
|
+
label: 'Clipboard',
|
|
387
|
+
launcher: 'paste-special',
|
|
388
|
+
items: [
|
|
389
|
+
// Excel's Clipboard group: the large Paste, and beside it Cut, Copy and
|
|
390
|
+
// Format Painter as icons alone, which is how Excel draws them at
|
|
391
|
+
// every width but the widest. Paste is a split button: the face
|
|
392
|
+
// pastes, the arrow opens the paste kinds with Paste Special... last.
|
|
393
|
+
{
|
|
394
|
+
id: 'paste', label: 'Paste', title: 'Paste', keys: 'Ctrl+V', icon: 'paste',
|
|
395
|
+
kind: 'dropdown', split: true, size: 'large',
|
|
396
|
+
run: (cmd) => { void cmd.paste(); return true; },
|
|
397
|
+
options: [
|
|
398
|
+
{ value: 'paste', label: 'Paste', keys: 'Ctrl+V', icon: 'paste' },
|
|
399
|
+
{ value: 'paste-formulas', label: 'Formulas', emits: 'paste-formulas' },
|
|
400
|
+
{ value: 'paste-values', label: 'Values', emits: 'paste-values' },
|
|
401
|
+
{ value: 'paste-formats', label: 'Formatting', emits: 'paste-formats' },
|
|
402
|
+
{ value: 'paste-transpose', label: 'Transpose', emits: 'paste-transpose' },
|
|
403
|
+
{ value: 'paste-special', label: 'Paste Special...', keys: 'Ctrl+Shift+V', emits: 'paste-special' },
|
|
404
|
+
],
|
|
405
|
+
},
|
|
406
|
+
// The same copy and cut as Ctrl+C and Ctrl+X: the selection, cell
|
|
407
|
+
// by cell through the sheet's clipboard hook. They went through the
|
|
408
|
+
// api's copyToClipboard, which is the export, and put the whole
|
|
409
|
+
// sheet with its column letters on the clipboard whatever was
|
|
410
|
+
// selected; Cut then blanked the selection by hand.
|
|
411
|
+
small(1, {
|
|
412
|
+
id: 'cut', label: 'Cut', title: 'Cut', keys: 'Ctrl+X', icon: 'cut', kind: 'button',
|
|
413
|
+
isEnabled: hasTarget,
|
|
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
|
+
},
|
|
423
|
+
}),
|
|
424
|
+
small(2, {
|
|
425
|
+
id: 'copy', label: 'Copy', title: 'Copy', keys: 'Ctrl+C', icon: 'copy', kind: 'button',
|
|
426
|
+
isEnabled: hasTarget,
|
|
427
|
+
run: (cmd) => { cmd.copy(); return true; },
|
|
428
|
+
}),
|
|
429
|
+
// Raised: the shell holds the copied formats and paints them onto the
|
|
430
|
+
// next selection. The button reads pressed while it is armed.
|
|
431
|
+
small(3, {
|
|
432
|
+
id: 'format-painter', label: 'Format Painter', title: 'Format Painter',
|
|
433
|
+
icon: 'format-painter', kind: 'button', emits: 'format-painter',
|
|
434
|
+
}),
|
|
435
|
+
],
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
id: 'font',
|
|
439
|
+
icon: 'font',
|
|
440
|
+
label: 'Font',
|
|
441
|
+
layout: 'flow',
|
|
442
|
+
launcher: 'format-cells',
|
|
443
|
+
items: [
|
|
444
|
+
small(1, {
|
|
445
|
+
id: 'font-family', label: 'Font', title: 'Font', kind: 'select',
|
|
446
|
+
options: FONT_FAMILIES, isEnabled: canFormat,
|
|
447
|
+
current: (cmd) => activeEntry(cmd)?.fontFamily ?? '',
|
|
448
|
+
run: (cmd, value) => applyFormat(cmd, { fontFamily: value || undefined }),
|
|
449
|
+
}),
|
|
450
|
+
small(1, {
|
|
451
|
+
id: 'font-size', label: 'Size', title: 'Font Size', kind: 'select',
|
|
452
|
+
options: FONT_SIZES.map((n) => ({ value: String(n), label: String(n) })),
|
|
453
|
+
isEnabled: canFormat,
|
|
454
|
+
current: (cmd) => String(activeEntry(cmd)?.fontSize ?? DEFAULT_FONT_SIZE),
|
|
455
|
+
run: (cmd, value) => applyFormat(cmd, { fontSize: Number(value) === DEFAULT_FONT_SIZE ? undefined : Number(value) }),
|
|
456
|
+
}),
|
|
457
|
+
small(1, {
|
|
458
|
+
id: 'font-grow', label: 'A', title: 'Increase Font Size', keys: 'Ctrl+Shift+>',
|
|
459
|
+
icon: 'font-grow', kind: 'button', isEnabled: canFormat, run: fromCommand(nudgeFontSize(1)),
|
|
460
|
+
}),
|
|
461
|
+
small(1, {
|
|
462
|
+
id: 'font-shrink', label: 'A', title: 'Decrease Font Size', keys: 'Ctrl+Shift+<',
|
|
463
|
+
icon: 'font-shrink', kind: 'button', isEnabled: canFormat, run: fromCommand(nudgeFontSize(-1)),
|
|
464
|
+
}),
|
|
465
|
+
small(2, { id: 'bold', label: 'B', title: 'Bold', keys: 'Ctrl+B', ...styleToggle('bold') }),
|
|
466
|
+
small(2, { id: 'italic', label: 'I', title: 'Italic', keys: 'Ctrl+I', ...styleToggle('italic') }),
|
|
467
|
+
small(2, { id: 'underline', label: 'U', title: 'Underline', keys: 'Ctrl+U', ...styleToggle('underline') }),
|
|
468
|
+
small(2, { id: 'strike', label: 'S', title: 'Strikethrough', keys: 'Ctrl+5', ...styleToggle('strike') }),
|
|
469
|
+
small(2, {
|
|
470
|
+
id: 'borders', label: 'Borders', title: 'Borders', icon: 'borders', kind: 'menu',
|
|
471
|
+
options: BORDER_OPTIONS, isEnabled: canFormat,
|
|
472
|
+
run: (cmd, value) => applyBorders(cmd, (value || 'bottom')),
|
|
473
|
+
}),
|
|
474
|
+
small(2, {
|
|
475
|
+
id: 'fill', label: 'Fill Color', title: 'Fill Color', icon: 'fill-colour', kind: 'menu',
|
|
476
|
+
palette: true, none: { value: 'transparent', label: 'No Fill' }, initial: '#FFFF00',
|
|
477
|
+
options: ALL_COLOURS, isEnabled: canFormat,
|
|
478
|
+
run: (cmd, value) => applyFormat(cmd, { fill: !value || value === 'transparent' ? undefined : value }),
|
|
479
|
+
}),
|
|
480
|
+
small(2, {
|
|
481
|
+
id: 'text-colour', label: 'A', title: 'Font Color', icon: 'font-colour', kind: 'menu',
|
|
482
|
+
palette: true, none: { value: 'inherit', label: 'Automatic' }, initial: '#FF0000',
|
|
483
|
+
options: ALL_COLOURS, isEnabled: canFormat,
|
|
484
|
+
run: (cmd, value) => applyFormat(cmd, { color: !value || value === 'inherit' ? undefined : value }),
|
|
485
|
+
}),
|
|
486
|
+
],
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
id: 'alignment',
|
|
490
|
+
icon: 'align-center',
|
|
491
|
+
label: 'Alignment',
|
|
492
|
+
layout: 'flow',
|
|
493
|
+
launcher: 'format-cells',
|
|
494
|
+
items: [
|
|
495
|
+
small(1, valignItem('top', 'Top Align')),
|
|
496
|
+
small(1, valignItem('center', 'Middle Align')),
|
|
497
|
+
small(1, valignItem('bottom', 'Bottom Align')),
|
|
498
|
+
small(1, {
|
|
499
|
+
id: 'wrap', label: 'Wrap Text', title: 'Wrap Text', icon: 'wrap', kind: 'toggle', wide: true,
|
|
500
|
+
run: (cmd) => toggleWrap(cmd),
|
|
501
|
+
isOn: (cmd) => everyCellHas(cmd, (entry) => entry?.wrap === true),
|
|
502
|
+
isEnabled: canFormat,
|
|
503
|
+
}),
|
|
504
|
+
small(2, alignItem('left', 'Align Left')),
|
|
505
|
+
small(2, alignItem('center', 'Center')),
|
|
506
|
+
small(2, alignItem('right', 'Align Right')),
|
|
507
|
+
// Excel's split button: the face merges and centres, the arrow
|
|
508
|
+
// opens the kinds. Raised for the shell, which keeps the merges
|
|
509
|
+
// per sheet and hands them to the grid.
|
|
510
|
+
small(3, {
|
|
511
|
+
id: 'merge', label: 'Merge & Center', title: 'Merge & Center', icon: 'merge',
|
|
512
|
+
kind: 'dropdown', split: true, wide: true, lit: 'merge-center',
|
|
513
|
+
// Greyed on a protected sheet, as Excel's is: merging is a format.
|
|
514
|
+
isEnabled: canFormat,
|
|
515
|
+
run: (cmd) => raiseRibbonAction('merge-center', cmd),
|
|
516
|
+
options: [
|
|
517
|
+
{ value: 'merge-center', label: 'Merge & Center', icon: 'merge', emits: 'merge-center' },
|
|
518
|
+
{ value: 'merge-across', label: 'Merge Across', emits: 'merge-across' },
|
|
519
|
+
{ value: 'merge-cells', label: 'Merge Cells', emits: 'merge-cells' },
|
|
520
|
+
{ value: 'unmerge-cells', label: 'Unmerge Cells', icon: 'unmerge', emits: 'unmerge-cells' },
|
|
521
|
+
],
|
|
522
|
+
}),
|
|
523
|
+
],
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
id: 'number',
|
|
527
|
+
icon: 'number',
|
|
528
|
+
label: 'Number',
|
|
529
|
+
layout: 'flow',
|
|
530
|
+
launcher: 'format-cells',
|
|
531
|
+
items: [
|
|
532
|
+
small(1, {
|
|
533
|
+
id: 'num-format', label: 'General', title: 'Number Format', kind: 'select',
|
|
534
|
+
options: NUMBER_FORMATS, isEnabled: canFormat,
|
|
535
|
+
// The category, not the exact pattern: a typed 12% carries 0%,
|
|
536
|
+
// and Excel's combo calls that Percentage too. A pattern outside
|
|
537
|
+
// every category shows as itself.
|
|
538
|
+
current: (cmd) => {
|
|
539
|
+
const fmt = activeEntry(cmd)?.numFmt;
|
|
540
|
+
const { category } = formatCategory(fmt);
|
|
541
|
+
return category === 'custom' || category === 'special' ? fmt ?? 'general' : category;
|
|
542
|
+
},
|
|
543
|
+
run: (cmd, value) => applyFormat(cmd, { numFmt: FORMAT_CATEGORY_PATTERNS[value] }),
|
|
544
|
+
}),
|
|
545
|
+
// Excel's $ button applies Accounting; Ctrl+Shift+4 is Currency.
|
|
546
|
+
small(2, presetItem('fmt-currency', '$', 'Accounting Number Format', 'accounting')),
|
|
547
|
+
small(2, presetItem('fmt-percent', '%', 'Percent Style', 'percent', 'Ctrl+Shift+5')),
|
|
548
|
+
small(2, presetItem('fmt-number', ',', 'Comma Style', 'number', 'Ctrl+Shift+1')),
|
|
549
|
+
small(2, {
|
|
550
|
+
id: 'dec-more', label: '.00', title: 'Increase Decimal', icon: 'dec-more', kind: 'button',
|
|
551
|
+
isEnabled: canFormat, run: nudgeDecimals(1),
|
|
552
|
+
}),
|
|
553
|
+
small(2, {
|
|
554
|
+
id: 'dec-less', label: '.0', title: 'Decrease Decimal', icon: 'dec-less', kind: 'button',
|
|
555
|
+
isEnabled: canFormat, run: nudgeDecimals(-1),
|
|
556
|
+
}),
|
|
557
|
+
],
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
id: 'cells',
|
|
561
|
+
icon: 'table',
|
|
562
|
+
label: 'Cells',
|
|
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.
|
|
569
|
+
small(1, {
|
|
570
|
+
id: 'insert', label: 'Insert', title: 'Insert Cells', keys: 'Ctrl+Shift++',
|
|
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
|
+
],
|
|
581
|
+
isEnabled: canRestructure,
|
|
582
|
+
}),
|
|
583
|
+
small(2, {
|
|
584
|
+
id: 'delete', label: 'Delete', title: 'Delete Cells', keys: 'Ctrl+-',
|
|
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
|
+
],
|
|
594
|
+
isEnabled: canRestructure,
|
|
595
|
+
}),
|
|
596
|
+
// Excel's Format menu: Cell Size, Visibility, and Format Cells at
|
|
597
|
+
// the end. Each entry is raised for the shell, which owns the size
|
|
598
|
+
// dialogs and keeps hidden lines per sheet.
|
|
599
|
+
small(3, {
|
|
600
|
+
id: 'format', label: 'Format', title: 'Format', icon: 'format-cells', kind: 'dropdown', wide: true,
|
|
601
|
+
options: [
|
|
602
|
+
{ value: 'cell-size', label: 'Cell Size', heading: true },
|
|
603
|
+
{ value: 'row-height', label: 'Row Height...', emits: 'row-height' },
|
|
604
|
+
{ value: 'autofit-rows', label: 'AutoFit Row Height', emits: 'autofit-rows' },
|
|
605
|
+
{ value: 'column-width', label: 'Column Width...', emits: 'column-width' },
|
|
606
|
+
{ value: 'autofit-columns', label: 'AutoFit Column Width', emits: 'autofit-columns' },
|
|
607
|
+
{ value: 'visibility', label: 'Visibility', heading: true },
|
|
608
|
+
{ value: 'hide-rows', label: 'Hide Rows', keys: 'Ctrl+9', emits: 'hide-rows' },
|
|
609
|
+
{ value: 'hide-columns', label: 'Hide Columns', keys: 'Ctrl+0', emits: 'hide-columns' },
|
|
610
|
+
{ value: 'unhide-rows', label: 'Unhide Rows', keys: 'Ctrl+Shift+9', emits: 'unhide-rows' },
|
|
611
|
+
{ value: 'unhide-columns', label: 'Unhide Columns', keys: 'Ctrl+Shift+0', emits: 'unhide-columns' },
|
|
612
|
+
{ value: 'protection', label: 'Protection', heading: true },
|
|
613
|
+
{ value: 'lock-cell', label: 'Lock Cell', icon: 'lock', emits: 'toggle-lock', toggle: true },
|
|
614
|
+
{ value: 'format-cells', label: 'Format Cells...', keys: 'Ctrl+1', emits: 'format-cells' },
|
|
615
|
+
],
|
|
616
|
+
}),
|
|
617
|
+
],
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
// Excel's Styles group, the part with something behind it: one large
|
|
621
|
+
// Conditional Formatting dropdown. Its entries are raised for the
|
|
622
|
+
// shell, which owns the small dialogs and the rules per sheet; the
|
|
623
|
+
// headings are Excel's submenus, flattened.
|
|
624
|
+
id: 'styles',
|
|
625
|
+
icon: 'cf',
|
|
626
|
+
label: 'Styles',
|
|
627
|
+
items: [
|
|
628
|
+
{
|
|
629
|
+
id: 'conditional-formatting', label: 'Conditional Formatting', title: 'Conditional Formatting',
|
|
630
|
+
icon: 'cf', kind: 'dropdown', size: 'large',
|
|
631
|
+
options: [
|
|
632
|
+
{ value: 'h', label: 'Highlight Cells Rules', heading: true },
|
|
633
|
+
{ value: 'cf-greater', label: 'Greater Than...', icon: 'cf-greater', emits: 'cf-greater' },
|
|
634
|
+
{ value: 'cf-less', label: 'Less Than...', icon: 'cf-less', emits: 'cf-less' },
|
|
635
|
+
{ value: 'cf-between', label: 'Between...', icon: 'cf-between', emits: 'cf-between' },
|
|
636
|
+
{ value: 'cf-equal', label: 'Equal To...', icon: 'cf-equal', emits: 'cf-equal' },
|
|
637
|
+
{ value: 'cf-text', label: 'Text that Contains...', icon: 'cf-text', emits: 'cf-text' },
|
|
638
|
+
{ value: 'cf-duplicates', label: 'Duplicate Values...', icon: 'cf-duplicates', emits: 'cf-duplicates' },
|
|
639
|
+
{ value: 't', label: 'Top/Bottom Rules', heading: true },
|
|
640
|
+
{ value: 'cf-top10', label: 'Top 10 Items...', icon: 'cf-top', emits: 'cf-top10' },
|
|
641
|
+
{ value: 'cf-bottom10', label: 'Bottom 10 Items...', icon: 'cf-bottom', emits: 'cf-bottom10' },
|
|
642
|
+
{ value: 'cf-above-average', label: 'Above Average...', icon: 'cf-above', emits: 'cf-above-average' },
|
|
643
|
+
{ value: 'cf-below-average', label: 'Below Average...', icon: 'cf-below', emits: 'cf-below-average' },
|
|
644
|
+
{ value: 'b', label: 'Data Bars, Color Scales, Icon Sets', heading: true },
|
|
645
|
+
{ value: 'cf-data-bar', label: 'Data Bar', icon: 'cf-bar', emits: 'cf-data-bar' },
|
|
646
|
+
{ value: 'cf-color-scale-3', label: 'Green - Yellow - Red Color Scale', icon: 'cf-scale', emits: 'cf-color-scale-3' },
|
|
647
|
+
{ value: 'cf-color-scale-2', label: 'Green - White Color Scale', icon: 'cf-scale', emits: 'cf-color-scale-2' },
|
|
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' },
|
|
651
|
+
{ value: 'c', label: 'Clear Rules', heading: true },
|
|
652
|
+
{ value: 'cf-clear-selection', label: 'Clear Rules from Selected Cells', emits: 'cf-clear-selection' },
|
|
653
|
+
{ value: 'cf-clear-sheet', label: 'Clear Rules from Entire Sheet', emits: 'cf-clear-sheet' },
|
|
654
|
+
{ value: 'm', label: 'Manage', heading: true },
|
|
655
|
+
{ value: 'cf-manage', label: 'Manage Rules...', emits: 'cf-manage' },
|
|
656
|
+
],
|
|
657
|
+
},
|
|
658
|
+
],
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
id: 'editing',
|
|
662
|
+
icon: 'find',
|
|
663
|
+
label: 'Editing',
|
|
664
|
+
items: [
|
|
665
|
+
// Undo and Redo open the group as a column of two small icons, the
|
|
666
|
+
// way Cut and Copy stand beside Paste; the owner wanted them here
|
|
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.
|
|
670
|
+
small(1, {
|
|
671
|
+
id: 'undo', label: 'Undo', title: 'Undo', keys: 'Ctrl+Z', icon: 'undo', kind: 'button',
|
|
672
|
+
isEnabled: (cmd) => cmd.api.canUndo(),
|
|
673
|
+
emits: 'undo',
|
|
674
|
+
}),
|
|
675
|
+
small(2, {
|
|
676
|
+
id: 'redo', label: 'Redo', title: 'Redo', keys: 'Ctrl+Y', icon: 'redo', kind: 'button',
|
|
677
|
+
isEnabled: (cmd) => cmd.api.canRedo(),
|
|
678
|
+
emits: 'redo',
|
|
679
|
+
}),
|
|
680
|
+
small(1, {
|
|
681
|
+
id: 'autosum', label: 'AutoSum', title: 'AutoSum', keys: 'Alt+=',
|
|
682
|
+
icon: 'autosum', kind: 'button', wide: true, run: fromCommand(autoSum),
|
|
683
|
+
}),
|
|
684
|
+
small(2, {
|
|
685
|
+
id: 'fill-down', label: 'Fill Down', title: 'Fill Down', keys: 'Ctrl+D',
|
|
686
|
+
icon: 'fill-down', kind: 'button', wide: true, run: (cmd) => fillDown(cmd),
|
|
687
|
+
}),
|
|
688
|
+
small(3, {
|
|
689
|
+
id: 'fill-right', label: 'Fill Right', title: 'Fill Right', keys: 'Ctrl+R',
|
|
690
|
+
icon: 'fill-right', kind: 'button', wide: true, run: (cmd) => fillRight(cmd),
|
|
691
|
+
}),
|
|
692
|
+
small(1, {
|
|
693
|
+
id: 'clear-formats', label: 'Clear', title: 'Clear Formats (keeps values)',
|
|
694
|
+
icon: 'clear', kind: 'button', wide: true, isEnabled: canFormat,
|
|
695
|
+
run: clearFormats,
|
|
696
|
+
}),
|
|
697
|
+
small(2, {
|
|
698
|
+
id: 'filter', label: 'Filter', title: 'Filter', keys: 'Ctrl+Shift+L',
|
|
699
|
+
icon: 'filter', kind: 'toggle', wide: true, emits: 'toggle-filter',
|
|
700
|
+
}),
|
|
701
|
+
small(3, {
|
|
702
|
+
id: 'find', label: 'Find & Select', title: 'Find and Replace', keys: 'Ctrl+H',
|
|
703
|
+
icon: 'find', kind: 'button', wide: true, emits: 'find-replace',
|
|
704
|
+
}),
|
|
705
|
+
],
|
|
706
|
+
},
|
|
707
|
+
],
|
|
708
|
+
};
|
|
709
|
+
const INSERT = {
|
|
710
|
+
id: 'insert',
|
|
711
|
+
label: 'Insert',
|
|
712
|
+
groups: [
|
|
713
|
+
{
|
|
714
|
+
id: 'tables',
|
|
715
|
+
icon: 'table',
|
|
716
|
+
label: 'Tables',
|
|
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' },
|
|
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' }),
|
|
726
|
+
],
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
id: 'charts',
|
|
730
|
+
icon: 'chart',
|
|
731
|
+
label: 'Charts',
|
|
732
|
+
items: [
|
|
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' }),
|
|
782
|
+
],
|
|
783
|
+
},
|
|
784
|
+
{
|
|
785
|
+
id: 'insert-cells',
|
|
786
|
+
icon: 'insert-cells',
|
|
787
|
+
label: 'Cells',
|
|
788
|
+
items: [
|
|
789
|
+
small(1, {
|
|
790
|
+
id: 'insert-rows', label: 'Insert', title: 'Insert rows or columns', icon: 'insert-cells', kind: 'button', wide: true,
|
|
791
|
+
run: (cmd) => structural(cmd, 'insert') || insertRows(cmd),
|
|
792
|
+
isEnabled: canRestructure,
|
|
793
|
+
}),
|
|
794
|
+
small(2, {
|
|
795
|
+
id: 'delete-rows', label: 'Delete', title: 'Delete rows or columns', icon: 'delete-cells', kind: 'button', wide: true,
|
|
796
|
+
run: (cmd) => structural(cmd, 'delete') || deleteRows(cmd),
|
|
797
|
+
isEnabled: canRestructure,
|
|
798
|
+
}),
|
|
799
|
+
],
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
id: 'insert-function',
|
|
803
|
+
icon: 'function',
|
|
804
|
+
label: 'Functions',
|
|
805
|
+
items: [
|
|
806
|
+
{ id: 'function', label: 'Insert Function', title: 'Insert Function', keys: 'Shift+F3', icon: 'function', kind: 'button', size: 'large', emits: 'insert-function' },
|
|
807
|
+
],
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
id: 'insert-sheet',
|
|
811
|
+
icon: 'new-sheet',
|
|
812
|
+
label: 'Sheets',
|
|
813
|
+
items: [
|
|
814
|
+
{
|
|
815
|
+
id: 'new-sheet', label: 'New Sheet', title: 'New sheet', keys: 'Shift+F11',
|
|
816
|
+
icon: 'new-sheet', kind: 'button', size: 'large',
|
|
817
|
+
isEnabled: () => getWorkbook() !== null,
|
|
818
|
+
run: () => {
|
|
819
|
+
const wb = getWorkbook();
|
|
820
|
+
if (!wb)
|
|
821
|
+
return false;
|
|
822
|
+
wb.addSheet();
|
|
823
|
+
return true;
|
|
824
|
+
},
|
|
825
|
+
},
|
|
826
|
+
],
|
|
827
|
+
},
|
|
828
|
+
],
|
|
829
|
+
};
|
|
830
|
+
const FORMULAS = {
|
|
831
|
+
id: 'formulas',
|
|
832
|
+
label: 'Formulas',
|
|
833
|
+
groups: [
|
|
834
|
+
{
|
|
835
|
+
id: 'function-library',
|
|
836
|
+
icon: 'function',
|
|
837
|
+
label: 'Function Library',
|
|
838
|
+
items: [
|
|
839
|
+
{ id: 'f-insert', label: 'Insert Function', title: 'Insert Function', keys: 'Shift+F3', icon: 'function', kind: 'button', size: 'large', emits: 'insert-function' },
|
|
840
|
+
{ id: 'f-autosum', label: 'AutoSum', title: 'AutoSum', keys: 'Alt+=', icon: 'autosum', kind: 'button', size: 'large', run: fromCommand(autoSum) },
|
|
841
|
+
],
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
id: 'defined-names',
|
|
845
|
+
icon: 'name-manager',
|
|
846
|
+
label: 'Defined Names',
|
|
847
|
+
items: [
|
|
848
|
+
{ id: 'name-manager', label: 'Name Manager', title: 'Name Manager', keys: 'Ctrl+F3', icon: 'name-manager', kind: 'button', size: 'large', emits: 'name-manager' },
|
|
849
|
+
],
|
|
850
|
+
},
|
|
851
|
+
{
|
|
852
|
+
id: 'auditing',
|
|
853
|
+
icon: 'show-formulas',
|
|
854
|
+
label: 'Formula Auditing',
|
|
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' }),
|
|
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' }),
|
|
862
|
+
],
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
id: 'calculation',
|
|
866
|
+
icon: 'calculate',
|
|
867
|
+
label: 'Calculation',
|
|
868
|
+
items: [
|
|
869
|
+
{ id: 'recalc', label: 'Calculate Now', title: 'Recalculate the workbook', keys: 'F9', icon: 'calculate', kind: 'button', size: 'large', emits: 'recalculate' },
|
|
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' }),
|
|
872
|
+
],
|
|
873
|
+
},
|
|
874
|
+
],
|
|
875
|
+
};
|
|
876
|
+
const DATA = {
|
|
877
|
+
id: 'data',
|
|
878
|
+
label: 'Data',
|
|
879
|
+
groups: [
|
|
880
|
+
{
|
|
881
|
+
id: 'sort-filter',
|
|
882
|
+
icon: 'filter',
|
|
883
|
+
label: 'Sort & Filter',
|
|
884
|
+
items: [
|
|
885
|
+
small(1, { id: 'sort-asc', label: 'Sort A to Z', title: 'Sort A to Z', icon: 'sort-asc', kind: 'button', emits: 'sort-asc' }),
|
|
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' },
|
|
888
|
+
{ id: 'filter-data', label: 'Filter', title: 'Filter', keys: 'Ctrl+Shift+L', icon: 'filter', kind: 'toggle', size: 'large', emits: 'toggle-filter' },
|
|
889
|
+
],
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
id: 'data-tools',
|
|
893
|
+
icon: 'text-to-columns',
|
|
894
|
+
label: 'Data Tools',
|
|
895
|
+
items: [
|
|
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' },
|
|
897
|
+
{ id: 'remove-duplicates', label: 'Remove Duplicates', title: 'Remove duplicate rows', icon: 'remove-duplicates', kind: 'button', size: 'large', emits: 'remove-duplicates' },
|
|
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
|
+
},
|
|
909
|
+
],
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
id: 'forecast',
|
|
913
|
+
icon: 'goal-seek',
|
|
914
|
+
label: 'Forecast',
|
|
915
|
+
items: [
|
|
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' },
|
|
917
|
+
],
|
|
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
|
+
},
|
|
949
|
+
],
|
|
950
|
+
};
|
|
951
|
+
function toggleWrap(cmd) {
|
|
952
|
+
const target = getFormatTarget();
|
|
953
|
+
if (!target)
|
|
954
|
+
return false;
|
|
955
|
+
const rects = rectsOf(cmd);
|
|
956
|
+
if (!rects.length)
|
|
957
|
+
return false;
|
|
958
|
+
if (!formatAllowed(target, rects))
|
|
959
|
+
return false;
|
|
960
|
+
withFormatUndo(cmd, target, rects, () => target.store.toggle(rects, 'wrap', target.lookup));
|
|
961
|
+
target.onChange?.();
|
|
962
|
+
return true;
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Excel's Review tab, the parts with something behind them. Comments are
|
|
966
|
+
* the sheet's notes: New Comment opens the editor on the active cell (and
|
|
967
|
+
* edits the one there), Delete, Previous and Next walk them, Show All
|
|
968
|
+
* Comments lists them. Protect Sheet and Unprotect Sheet are one slot, the
|
|
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.
|
|
973
|
+
*/
|
|
974
|
+
const REVIEW = {
|
|
975
|
+
id: 'review',
|
|
976
|
+
label: 'Review',
|
|
977
|
+
groups: [
|
|
978
|
+
{
|
|
979
|
+
id: 'comments',
|
|
980
|
+
icon: 'comment',
|
|
981
|
+
label: 'Comments',
|
|
982
|
+
items: [
|
|
983
|
+
{ id: 'new-comment', label: 'New Comment', title: 'New Comment', keys: 'Shift+F2', icon: 'comment', kind: 'button', size: 'large', emits: 'new-comment' },
|
|
984
|
+
small(1, { id: 'delete-comment', label: 'Delete', title: 'Delete Comment', icon: 'comment-delete', kind: 'button', wide: true, emits: 'delete-comment' }),
|
|
985
|
+
small(2, { id: 'prev-comment', label: 'Previous', title: 'Previous Comment', icon: 'comment-prev', kind: 'button', wide: true, emits: 'prev-comment' }),
|
|
986
|
+
small(3, { id: 'next-comment', label: 'Next', title: 'Next Comment', icon: 'comment-next', kind: 'button', wide: true, emits: 'next-comment' }),
|
|
987
|
+
{ id: 'toggle-comments', label: 'Show All Comments', title: 'Show All Comments', icon: 'comments-all', kind: 'toggle', size: 'large', emits: 'toggle-comments' },
|
|
988
|
+
],
|
|
989
|
+
},
|
|
990
|
+
{
|
|
991
|
+
id: 'protect',
|
|
992
|
+
icon: 'protect',
|
|
993
|
+
label: 'Protect',
|
|
994
|
+
items: [
|
|
995
|
+
{
|
|
996
|
+
id: 'protect-sheet', label: 'Protect Sheet', title: 'Protect Sheet: locked cells can no longer be changed',
|
|
997
|
+
icon: 'protect', kind: 'button', size: 'large', emits: 'protect-sheet',
|
|
998
|
+
},
|
|
999
|
+
{
|
|
1000
|
+
id: 'unprotect-sheet', label: 'Unprotect Sheet', title: 'Unprotect Sheet',
|
|
1001
|
+
icon: 'unprotect', kind: 'button', size: 'large', emits: 'unprotect-sheet',
|
|
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
|
+
},
|
|
1007
|
+
],
|
|
1008
|
+
},
|
|
1009
|
+
],
|
|
1010
|
+
};
|
|
1011
|
+
/**
|
|
1012
|
+
* Excel's View tab, the part with something behind it: Window > Freeze
|
|
1013
|
+
* Panes, Excel's dropdown of Freeze Panes / Freeze Top Row / Freeze First
|
|
1014
|
+
* Column / Unfreeze Panes. Raised rather than run here: the sheet shell
|
|
1015
|
+
* keeps the freeze per sheet and puts it back when the sheet comes up
|
|
1016
|
+
* again.
|
|
1017
|
+
*/
|
|
1018
|
+
const VIEW = {
|
|
1019
|
+
id: 'view',
|
|
1020
|
+
label: 'View',
|
|
1021
|
+
groups: [
|
|
1022
|
+
{
|
|
1023
|
+
id: 'show',
|
|
1024
|
+
icon: 'gridlines',
|
|
1025
|
+
label: 'Show',
|
|
1026
|
+
items: [
|
|
1027
|
+
small(1, { id: 'gridlines', label: 'Gridlines', title: 'Show or hide the gridlines', icon: 'gridlines', kind: 'toggle', wide: true, emits: 'toggle-gridlines' }),
|
|
1028
|
+
small(2, { id: 'formula-bar', label: 'Formula Bar', title: 'Show or hide the formula bar', icon: 'formula-bar', kind: 'toggle', wide: true, emits: 'toggle-formula-bar' }),
|
|
1029
|
+
small(3, { id: 'headings', label: 'Headings', title: 'Show or hide the row numbers and column letters', icon: 'headings', kind: 'toggle', wide: true, emits: 'toggle-headings' }),
|
|
1030
|
+
],
|
|
1031
|
+
},
|
|
1032
|
+
{
|
|
1033
|
+
id: 'window',
|
|
1034
|
+
icon: 'freeze',
|
|
1035
|
+
label: 'Window',
|
|
1036
|
+
items: [
|
|
1037
|
+
{
|
|
1038
|
+
id: 'freeze', label: 'Freeze Panes', title: 'Freeze Panes', icon: 'freeze', kind: 'dropdown', size: 'large',
|
|
1039
|
+
options: [
|
|
1040
|
+
{ value: 'freeze-panes', label: 'Freeze Panes', icon: 'freeze', emits: 'freeze-panes' },
|
|
1041
|
+
{ value: 'freeze-top-row', label: 'Freeze Top Row', emits: 'freeze-top-row' },
|
|
1042
|
+
{ value: 'freeze-first-column', label: 'Freeze First Column', emits: 'freeze-first-column' },
|
|
1043
|
+
{ value: 'unfreeze-panes', label: 'Unfreeze Panes', icon: 'unfreeze', emits: 'unfreeze-panes' },
|
|
1044
|
+
],
|
|
1045
|
+
},
|
|
1046
|
+
],
|
|
1047
|
+
},
|
|
1048
|
+
],
|
|
1049
|
+
};
|
|
1050
|
+
export const RIBBON_TABS = [FILE, HOME, INSERT, PAGE_LAYOUT, FORMULAS, DATA, REVIEW, VIEW];
|
|
1051
|
+
/** Every item across every tab, for tests and for a command palette. */
|
|
1052
|
+
export function ribbonItems() {
|
|
1053
|
+
return RIBBON_TABS.flatMap((tab) => tab.groups.flatMap((group) => group.items));
|
|
1054
|
+
}
|