@svgrid/enterprise 3.0.0 → 3.0.2
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/README.md +95 -95
- package/dist/ExpressionEditorHarness.svelte.d.ts +2 -2
- package/dist/SvAdvancedFilter.svelte.d.ts +2 -2
- package/dist/SvAlertRuleEditor.svelte.d.ts +2 -2
- package/dist/SvAlertsManager.svelte.d.ts +3 -3
- package/dist/SvAlertsPanel.svelte.d.ts +1 -1
- package/dist/SvAuthGate.svelte +115 -115
- package/dist/SvAuthGate.svelte.d.ts +1 -1
- package/dist/SvBoard.svelte.d.ts +1 -1
- package/dist/SvExportMenu.svelte +553 -553
- package/dist/SvExportMenu.svelte.d.ts +2 -2
- package/dist/SvExpressionEditor.svelte.d.ts +2 -2
- package/dist/SvFileInput.svelte +113 -113
- package/dist/SvFormulaBar.svelte +606 -0
- package/dist/SvFormulaBar.svelte.d.ts +62 -0
- package/dist/SvGridAlerts.svelte.d.ts +2 -2
- package/dist/SvGridBoard.svelte +2358 -2358
- package/dist/SvGridBulkEditDrawer.svelte.d.ts +1 -1
- package/dist/SvGridEditPanel.svelte +1157 -1157
- package/dist/SvGridEditPanel.svelte.d.ts +3 -3
- package/dist/SvGridMasterDetail.svelte +116 -116
- package/dist/SvGridMasterDetail.svelte.d.ts +1 -1
- package/dist/SvGridScheduler.svelte +5358 -5358
- package/dist/SvImportDialog.svelte +1020 -1020
- package/dist/SvImportDialog.svelte.d.ts +2 -2
- package/dist/SvLookupInput.svelte +180 -180
- package/dist/SvLookupInput.svelte.d.ts +1 -1
- package/dist/SvPivotDesigner.svelte +2041 -1990
- package/dist/SvPivotDesigner.svelte.d.ts +2 -2
- package/dist/SvRecordDetail.svelte.d.ts +1 -1
- package/dist/SvRibbonIcon.svelte +46 -0
- package/dist/SvRibbonIcon.svelte.d.ts +17 -0
- package/dist/SvSchedule.svelte.d.ts +1 -1
- package/dist/SvSchemaChart.svelte +236 -234
- package/dist/SvSchemaChart.svelte.d.ts +2 -2
- package/dist/SvSchemaDashboard.svelte +130 -130
- package/dist/SvSchemaDashboard.svelte.d.ts +3 -3
- package/dist/SvSheet.svelte +4114 -0
- package/dist/SvSheet.svelte.d.ts +142 -0
- package/dist/SvSheetComment.svelte +98 -0
- package/dist/SvSheetComment.svelte.d.ts +22 -0
- package/dist/SvSheetConditionalFormat.svelte +162 -0
- package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
- package/dist/SvSheetDataValidation.svelte +249 -0
- package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
- package/dist/SvSheetFilterMenu.svelte +217 -0
- package/dist/SvSheetFilterMenu.svelte.d.ts +17 -0
- package/dist/SvSheetFindReplace.svelte +132 -0
- package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
- package/dist/SvSheetFormatCells.svelte +421 -0
- package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
- package/dist/SvSheetGoalSeek.svelte +144 -0
- package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
- package/dist/SvSheetInsertFunction.svelte +147 -0
- package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
- package/dist/SvSheetListPicker.svelte +89 -0
- package/dist/SvSheetListPicker.svelte.d.ts +16 -0
- package/dist/SvSheetManageRules.svelte +185 -0
- package/dist/SvSheetManageRules.svelte.d.ts +16 -0
- package/dist/SvSheetNameManager.svelte +225 -0
- package/dist/SvSheetNameManager.svelte.d.ts +11 -0
- package/dist/SvSheetPasteSpecial.svelte +105 -0
- package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
- package/dist/SvSheetRemoveDuplicates.svelte +149 -0
- package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
- package/dist/SvSheetRibbon.svelte +1201 -0
- package/dist/SvSheetRibbon.svelte.d.ts +34 -0
- package/dist/SvSheetSizeDialog.svelte +58 -0
- package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
- package/dist/SvSheetTabs.svelte +441 -0
- package/dist/SvSheetTabs.svelte.d.ts +36 -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 +83 -0
- package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
- package/dist/advanced-filter/expr-columns-from-grid.d.ts +1 -1
- package/dist/advanced-filter-enable.js +3 -3
- package/dist/alerts/alert-engine-attach.d.ts +2 -2
- package/dist/alerts/alert-engine-attach.js +3 -3
- package/dist/alerts/alert-engine.d.ts +1 -1
- package/dist/alerts/alert-engine.js +2 -2
- package/dist/alerts/alert-formats.d.ts +1 -1
- package/dist/alerts/alert-formats.js +1 -1
- package/dist/alerts/alert-observer.d.ts +3 -3
- package/dist/alerts/alert-observer.js +1 -1
- package/dist/alerts/alert-storage.d.ts +1 -1
- package/dist/alerts/alert-store.svelte.d.ts +1 -1
- package/dist/alerts/alert-types.d.ts +2 -2
- package/dist/alerts.js +2 -2
- package/dist/board.js +2 -2
- package/dist/cdn/svgrid-enterprise.svelte-external.js +19046 -5428
- package/dist/designer/assets/GridMenus-BlsvL_aU.js +8 -0
- package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
- package/dist/designer/assets/SvChartMenu-D9hEeHar.js +1 -0
- package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
- package/dist/designer/assets/SvDateRangeInput-C0iCCZ8o.css +1 -0
- package/dist/designer/assets/SvDateTimePicker-DARvKUL2.js +1 -0
- package/dist/designer/assets/SvDateTimePicker-DPv09DIT.css +1 -0
- package/dist/designer/assets/{preload-helper-CG0n22O7.js → SvGrid.helpers-BgT-gnCo.js} +1 -1
- package/dist/designer/assets/SvGridCellEditor-C7uQXYds.js +4 -0
- package/dist/designer/assets/SvGridChart-B8j1SSy3.js +3 -0
- package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
- package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
- package/dist/designer/assets/SvGridChartBuilder-kvyIU_Rl.js +1 -0
- package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
- package/dist/designer/assets/SvGridChartPanel-pT6ITc2P.js +4 -0
- package/dist/designer/assets/SvGridChartView-7msfnWZT.css +1 -0
- package/dist/designer/assets/SvGridChartView-bg281UA1.js +1 -0
- package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +1 -0
- package/dist/designer/assets/SvGridDropdown-CcidB3rm.css +1 -0
- package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
- package/dist/designer/assets/SvListBox-BXfyqy4a.css +1 -0
- package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
- package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
- package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
- package/dist/designer/assets/SvTabs-UFCMTHXS.js +1 -0
- package/dist/designer/assets/cell-formatting-wr5wm7US.js +1 -0
- package/dist/designer/assets/chart-cIPUsbM5.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-DtTxpBUU.js +1 -0
- package/dist/designer/assets/chart-summary-Czu_5epb.js +1 -0
- package/dist/designer/assets/chart-trend-D5I5VEe8.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/editor-contract-Bpoa7A5g.js +1 -0
- package/dist/designer/assets/export-format-D-eP4b2l.js +6 -0
- package/dist/designer/assets/focus-trap-CAreAhlU.js +1 -0
- package/dist/designer/assets/index-CMFgAoVV.css +1 -0
- package/dist/designer/assets/{index-zUBix-JQ.js → index-DwU7CAMm.js} +2985 -141
- package/dist/designer/assets/list-option-BP_dWS66.js +1 -0
- package/dist/designer/assets/preload-helper-HclGiUj8.js +1 -0
- package/dist/designer/assets/row-resize-DLktcqUK.js +1 -0
- package/dist/designer/assets/src-CITpcm6b.js +1 -0
- package/dist/designer/assets/src-EdI3Xqds.js +58 -0
- package/dist/designer/index.html +32 -23
- package/dist/export-conditional.d.ts +1 -1
- package/dist/export-pdf.d.ts +89 -0
- package/dist/export-pdf.js +130 -0
- package/dist/export-print.js +19 -19
- package/dist/export-xls.d.ts +2 -2
- package/dist/export.d.ts +2 -2
- package/dist/export.js +23 -16
- package/dist/expressions/builder-tree.d.ts +2 -2
- package/dist/expressions/builder-tree.js +1 -1
- package/dist/expressions/compile.d.ts +1 -1
- package/dist/import.js +1 -1
- package/dist/index.d.ts +116 -53
- package/dist/index.js +117 -50
- package/dist/install.d.ts +4 -4
- package/dist/install.js +16 -11
- package/dist/license.d.ts +3 -2
- package/dist/license.js +9 -4
- package/dist/node/studio.js +187 -116
- package/dist/pivot-chart.d.ts +26 -2
- package/dist/pivot-chart.js +25 -69
- package/dist/pivot-designer.d.ts +1 -1
- package/dist/pivot-enable.js +3 -3
- package/dist/print.d.ts +1 -1
- package/dist/print.js +4 -4
- package/dist/scheduler-config.d.ts +5 -5
- package/dist/scheduler-freebusy.d.ts +1 -1
- package/dist/scheduler-freebusy.js +1 -1
- package/dist/scheduler.js +2 -2
- package/dist/schema-designer.d.ts +1 -1
- package/dist/schema-designer.js +2 -2
- package/dist/selection-bar.js +2 -2
- package/dist/sheet/address.d.ts +43 -0
- package/dist/sheet/address.js +81 -0
- package/dist/sheet/ast.d.ts +94 -0
- package/dist/sheet/ast.js +56 -0
- package/dist/sheet/auto-filter.d.ts +66 -0
- package/dist/sheet/auto-filter.js +147 -0
- package/dist/sheet/autocomplete.d.ts +42 -0
- package/dist/sheet/autocomplete.js +162 -0
- package/dist/sheet/coerce.d.ts +31 -0
- package/dist/sheet/coerce.js +122 -0
- package/dist/sheet/commands.d.ts +89 -0
- package/dist/sheet/commands.js +230 -0
- package/dist/sheet/comments.d.ts +29 -0
- package/dist/sheet/comments.js +73 -0
- package/dist/sheet/conditional-formats.d.ts +144 -0
- package/dist/sheet/conditional-formats.js +316 -0
- package/dist/sheet/deps.d.ts +60 -0
- package/dist/sheet/deps.js +199 -0
- package/dist/sheet/document.d.ts +150 -0
- package/dist/sheet/document.js +264 -0
- package/dist/sheet/edit-keys.d.ts +14 -0
- package/dist/sheet/edit-keys.js +40 -0
- package/dist/sheet/entry.d.ts +31 -0
- package/dist/sheet/entry.js +76 -0
- package/dist/sheet/evaluate.d.ts +61 -0
- package/dist/sheet/evaluate.js +337 -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 +99 -0
- package/dist/sheet/format-store.js +233 -0
- package/dist/sheet/freeze.d.ts +54 -0
- package/dist/sheet/freeze.js +58 -0
- package/dist/sheet/function-catalog.d.ts +10 -0
- package/dist/sheet/function-catalog.js +94 -0
- package/dist/sheet/functions.d.ts +28 -0
- package/dist/sheet/functions.js +362 -0
- package/dist/sheet/goal-seek.d.ts +73 -0
- package/dist/sheet/goal-seek.js +153 -0
- package/dist/sheet/index.d.ts +53 -0
- package/dist/sheet/index.js +53 -0
- package/dist/sheet/merges.d.ts +71 -0
- package/dist/sheet/merges.js +137 -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 +63 -0
- package/dist/sheet/number-format.js +508 -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 +108 -0
- package/dist/sheet/paste-special.d.ts +164 -0
- package/dist/sheet/paste-special.js +592 -0
- package/dist/sheet/protection.d.ts +21 -0
- package/dist/sheet/protection.js +48 -0
- package/dist/sheet/rects.d.ts +45 -0
- package/dist/sheet/rects.js +112 -0
- package/dist/sheet/refs.d.ts +82 -0
- package/dist/sheet/refs.js +266 -0
- package/dist/sheet/ribbon-icons.d.ts +31 -0
- package/dist/sheet/ribbon-icons.js +350 -0
- package/dist/sheet/ribbon.d.ts +173 -0
- package/dist/sheet/ribbon.js +753 -0
- package/dist/sheet/shortcuts.d.ts +164 -0
- package/dist/sheet/shortcuts.js +623 -0
- package/dist/sheet/structure.d.ts +87 -0
- package/dist/sheet/structure.js +166 -0
- package/dist/sheet/tables.d.ts +70 -0
- package/dist/sheet/tables.js +147 -0
- package/dist/sheet/tokenize.d.ts +54 -0
- package/dist/sheet/tokenize.js +304 -0
- package/dist/sheet/transforms.d.ts +76 -0
- package/dist/sheet/transforms.js +154 -0
- package/dist/sheet/validation.d.ts +92 -0
- package/dist/sheet/validation.js +241 -0
- package/dist/sheet/workbook.d.ts +72 -0
- package/dist/sheet/workbook.js +409 -0
- package/dist/sheet-enable.d.ts +6 -0
- package/dist/sheet-enable.js +46 -0
- package/dist/sources/aggregate.d.ts +1 -1
- package/dist/sources/auth-supabase.js +1 -1
- package/dist/sources/dashboard.d.ts +2 -2
- package/dist/sources/dashboard.js +1 -1
- package/dist/sources/index.d.ts +13 -13
- package/dist/sources/index.js +13 -13
- package/dist/sources/realtime-supabase.js +1 -1
- package/dist/sources/relation-lookup.d.ts +1 -1
- package/dist/sources/relation-lookup.js +1 -1
- package/dist/sources/rest-adapters.d.ts +1 -1
- package/dist/sources/rest-adapters.js +1 -1
- package/dist/sources/rest.d.ts +2 -2
- package/dist/sources/rest.js +3 -3
- package/dist/sources/supabase.d.ts +2 -2
- package/dist/sources/supabase.js +3 -3
- package/dist/sources/with-entity-rules.d.ts +1 -1
- package/dist/sources/with-entity-rules.js +1 -1
- package/dist/sources/with-relation-labels.d.ts +1 -1
- package/dist/studio/emit-project.js +2161 -2127
- package/dist/studio/emit-schema.js +369 -369
- package/dist/studio/index.d.ts +1 -1
- package/dist/studio/index.js +1 -1
- package/dist/studio/introspect-db.js +45 -45
- package/dist/studio/project.d.ts +10 -0
- package/dist/studio/samples/crm.js +6 -6
- package/dist/studio/samples/fleet.js +7 -7
- package/dist/studio/samples/insurance.js +9 -9
- package/dist/studio/samples/inventory.js +12 -12
- package/dist/studio/samples/projects.js +5 -5
- package/dist/studio/samples/support.js +8 -8
- package/dist/studio/scaffold-app.js +104 -104
- package/dist/studio/scaffold.js +151 -151
- package/dist/studio/ui-components.d.ts +7 -0
- package/dist/studio/ui-components.generated.js +63 -1
- package/dist/studio/ui-components.js +35 -0
- package/dist/sveltekit/in-memory.d.ts +3 -3
- package/dist/sveltekit/in-memory.js +4 -4
- package/dist/sveltekit/index.d.ts +6 -6
- package/dist/sveltekit/index.js +5 -5
- package/dist/sveltekit/query-plan.d.ts +1 -1
- package/dist/sveltekit/sql-source.d.ts +4 -4
- package/dist/sveltekit/sql-source.js +4 -4
- package/dist/sveltekit/sql.d.ts +1 -1
- package/dist/sveltekit/transport.d.ts +2 -2
- package/dist/sveltekit/transport.js +1 -1
- package/dist/upgrade-prompt.js +25 -25
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +12 -4
- package/dist/designer/assets/GridMenus-Cgilexpk.js +0 -8
- package/dist/designer/assets/SvDateRangeInput-BV5OXYQ2.css +0 -1
- package/dist/designer/assets/SvDateRangeInput-CVn-yqrQ.js +0 -1
- package/dist/designer/assets/SvDateTimePicker-BdioTrJQ.js +0 -1
- package/dist/designer/assets/SvDateTimePicker-CY8TK4BT.css +0 -1
- package/dist/designer/assets/SvField-BF-9TJSd.css +0 -1
- package/dist/designer/assets/SvField-BsqiA5me.js +0 -1
- package/dist/designer/assets/SvGridCellEditor-dLY7_kk9.js +0 -2
- package/dist/designer/assets/SvGridChart-BEDNTdc5.js +0 -2
- package/dist/designer/assets/SvGridChart-Vu4Nvjiv.css +0 -1
- package/dist/designer/assets/SvGridChartPanel-x3lzSxuf.js +0 -10
- package/dist/designer/assets/SvGridChartView-CAKhPELi.js +0 -1
- package/dist/designer/assets/SvGridChartView-DX9HfkBR.css +0 -1
- package/dist/designer/assets/SvGridDropdown-CAYG7Y-O.js +0 -1
- package/dist/designer/assets/SvGridDropdown-Crwb2P3Q.css +0 -1
- package/dist/designer/assets/SvListBox-CVYQcLX9.js +0 -1
- package/dist/designer/assets/SvListBox-DgN8kvjt.css +0 -1
- package/dist/designer/assets/chart-DHEgt4lN.js +0 -1
- package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
- package/dist/designer/assets/date-format-4DJvNtG2.js +0 -1
- package/dist/designer/assets/date-format-Dzy4mTGh.css +0 -1
- package/dist/designer/assets/easing-zaypKrr0.js +0 -3
- package/dist/designer/assets/export-format-DwjuTfrQ.js +0 -6
- package/dist/designer/assets/index-Cp7fDJ3b.css +0 -1
- package/dist/designer/assets/js-scroller.svelte-Bhxqb3-c.js +0 -110
- package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
- package/dist/designer/assets/src-B7DNcoQK.css +0 -1
- package/dist/designer/assets/src-BoYyigAC.js +0 -2896
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -178
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js +0 -3875
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js +0 -21
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js +0 -1938
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js +0 -205
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js +0 -18
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js +0 -264
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js +0 -697
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -3
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -134
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -55
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -2
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -46843
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -237
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -2
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -4
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -7
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -4
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -5
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -5
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -5
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -6
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -83
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -559
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -24
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -122
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -2
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -89
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -241
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js +0 -4938
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js +0 -495
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js +0 -190
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js +0 -8
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js.map +0 -1
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js +0 -138
- package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js.map +0 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { GridCommandContext } from '@svgrid/grid/shortcuts';
|
|
2
|
+
import { type RibbonTab, type RibbonActionId } from './sheet/ribbon.js';
|
|
3
|
+
type Props = {
|
|
4
|
+
/**
|
|
5
|
+
* How to reach the grid. A getter rather than the context itself because
|
|
6
|
+
* the context is rebuilt per call and the ribbon needs a live one at the
|
|
7
|
+
* moment a button is pressed, not the one that existed at mount.
|
|
8
|
+
*/
|
|
9
|
+
cmd: () => GridCommandContext | null;
|
|
10
|
+
/** Called after any action that changed something, so the host re-renders. */
|
|
11
|
+
onChange?: () => void;
|
|
12
|
+
/** Actions the ribbon does not run itself, because they need chrome. */
|
|
13
|
+
onAction?: (action: RibbonActionId, cmd: GridCommandContext) => void;
|
|
14
|
+
/** Which of `onAction`'s toggles are currently on. The host owns that
|
|
15
|
+
* state (there is no store here to read it from), so it reports it. */
|
|
16
|
+
activeActions?: ReadonlyArray<RibbonActionId>;
|
|
17
|
+
tabs?: ReadonlyArray<RibbonTab>;
|
|
18
|
+
/** Start on a tab other than the first. */
|
|
19
|
+
tab?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Actions to leave off the ribbon: a button nobody answers is worse
|
|
22
|
+
* than no button. A group with nothing left in it goes too.
|
|
23
|
+
*/
|
|
24
|
+
without?: ReadonlyArray<RibbonActionId>;
|
|
25
|
+
/**
|
|
26
|
+
* Excel's collapsed ribbon: the tabs alone. A click on a tab shows the
|
|
27
|
+
* band over the sheet until a command runs or the pointer leaves;
|
|
28
|
+
* double-clicking a tab, the chevron and Ctrl+F1 toggle it.
|
|
29
|
+
*/
|
|
30
|
+
collapsed?: boolean;
|
|
31
|
+
};
|
|
32
|
+
declare const SvSheetRibbon: import("svelte").Component<Props, {}, "tab" | "collapsed">;
|
|
33
|
+
type SvSheetRibbon = ReturnType<typeof SvSheetRibbon>;
|
|
34
|
+
export default SvSheetRibbon;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Column Width and Row Height boxes: one number, OK, Cancel. The
|
|
4
|
+
* shell opens it from the column letter's and the row number's menus and
|
|
5
|
+
* applies the size to every column or row the selection spans.
|
|
6
|
+
*/
|
|
7
|
+
import { SvModal } from '@svgrid/grid'
|
|
8
|
+
|
|
9
|
+
type Props = {
|
|
10
|
+
open?: boolean
|
|
11
|
+
title: string
|
|
12
|
+
label: string
|
|
13
|
+
value: number
|
|
14
|
+
onApply: (px: number) => void
|
|
15
|
+
onClose?: () => void
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let { open = $bindable(false), title, label, value, onApply, onClose }: Props = $props()
|
|
19
|
+
|
|
20
|
+
let draft = $state('')
|
|
21
|
+
let input = $state<HTMLInputElement | null>(null)
|
|
22
|
+
|
|
23
|
+
$effect(() => {
|
|
24
|
+
if (!open) return
|
|
25
|
+
draft = String(Math.round(value))
|
|
26
|
+
queueMicrotask(() => { input?.focus(); input?.select() })
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const px = $derived(Number(draft))
|
|
30
|
+
const valid = $derived(Number.isFinite(px) && px >= 4 && px <= 2000)
|
|
31
|
+
|
|
32
|
+
function ok() {
|
|
33
|
+
if (!valid) return
|
|
34
|
+
onApply(Math.round(px))
|
|
35
|
+
open = false
|
|
36
|
+
onClose?.()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function close() {
|
|
40
|
+
open = false
|
|
41
|
+
onClose?.()
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<SvModal bind:open onClose={onClose} {title} size="sm">
|
|
46
|
+
<form class="sv-sheet-dialog" onsubmit={(e) => { e.preventDefault(); ok() }}>
|
|
47
|
+
<label class="field auto">
|
|
48
|
+
<span>{label}</span>
|
|
49
|
+
<input bind:this={input} type="number" min="4" max="2000" bind:value={draft} />
|
|
50
|
+
</label>
|
|
51
|
+
</form>
|
|
52
|
+
{#snippet footer()}
|
|
53
|
+
<div class="sv-sheet-dialog-buttons">
|
|
54
|
+
<button type="button" class="btn primary" onclick={ok} disabled={!valid}>OK</button>
|
|
55
|
+
<button type="button" class="btn" onclick={close}>Cancel</button>
|
|
56
|
+
</div>
|
|
57
|
+
{/snippet}
|
|
58
|
+
</SvModal>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
open?: boolean;
|
|
3
|
+
title: string;
|
|
4
|
+
label: string;
|
|
5
|
+
value: number;
|
|
6
|
+
onApply: (px: number) => void;
|
|
7
|
+
onClose?: () => void;
|
|
8
|
+
};
|
|
9
|
+
declare const SvSheetSizeDialog: import("svelte").Component<Props, {}, "open">;
|
|
10
|
+
type SvSheetSizeDialog = ReturnType<typeof SvSheetSizeDialog>;
|
|
11
|
+
export default SvSheetSizeDialog;
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* The sheet tab strip along the bottom of a workbook.
|
|
4
|
+
*
|
|
5
|
+
* Owns no workbook state of its own: it renders what the workbook reports
|
|
6
|
+
* and calls back, so the keyboard shortcuts and the tabs cannot disagree
|
|
7
|
+
* about which sheet is active.
|
|
8
|
+
*/
|
|
9
|
+
import type { Workbook } from './sheet/workbook'
|
|
10
|
+
import { isValidSheetName } from './sheet/workbook'
|
|
11
|
+
|
|
12
|
+
type Props = {
|
|
13
|
+
workbook: Workbook
|
|
14
|
+
/** Called after any change, so the consumer can re-render. */
|
|
15
|
+
onChange?: () => void
|
|
16
|
+
/**
|
|
17
|
+
* Called after a sheet is renamed or removed, before `onChange`. Anything
|
|
18
|
+
* the consumer keeps per sheet and keys by name - the shell keeps a
|
|
19
|
+
* format store per sheet - has to follow the rename or drop the entry,
|
|
20
|
+
* and the workbook itself has no event for either.
|
|
21
|
+
*/
|
|
22
|
+
onRename?: (from: string, to: string) => void
|
|
23
|
+
onRemove?: (name: string) => void
|
|
24
|
+
/** Off hides the add button and the context actions. */
|
|
25
|
+
editable?: boolean
|
|
26
|
+
/**
|
|
27
|
+
* Bump this whenever the workbook is mutated from OUTSIDE the strip - the
|
|
28
|
+
* Ctrl+PageUp/PageDown shortcuts, or app code calling `addSheet`.
|
|
29
|
+
*
|
|
30
|
+
* A `Workbook` is a plain object, not `$state`, so reading `workbook.sheets`
|
|
31
|
+
* creates no reactive dependency and the strip would otherwise render once
|
|
32
|
+
* and then show whatever the sheet list was at mount. Pass the same counter
|
|
33
|
+
* `onChange` increments.
|
|
34
|
+
*/
|
|
35
|
+
version?: number
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let { workbook, onChange, onRename, onRemove, editable = true, version = 0 }: Props = $props()
|
|
39
|
+
|
|
40
|
+
let renaming = $state<string | null>(null)
|
|
41
|
+
let draft = $state('')
|
|
42
|
+
let error = $state<string | null>(null)
|
|
43
|
+
let dragging = $state<string | null>(null)
|
|
44
|
+
|
|
45
|
+
// The strip's own mutations do not go through the consumer's counter, so it
|
|
46
|
+
// keeps one of its own and reads both.
|
|
47
|
+
let localVersion = $state(0)
|
|
48
|
+
|
|
49
|
+
const sheets = $derived.by(() => {
|
|
50
|
+
void version
|
|
51
|
+
void localVersion
|
|
52
|
+
return workbook.sheets
|
|
53
|
+
})
|
|
54
|
+
const activeSheet = $derived.by(() => {
|
|
55
|
+
void version
|
|
56
|
+
void localVersion
|
|
57
|
+
return workbook.active
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
function changed() {
|
|
61
|
+
localVersion += 1
|
|
62
|
+
onChange?.()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function select(name: string) {
|
|
66
|
+
workbook.setActive(name)
|
|
67
|
+
changed()
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function startRename(name: string) {
|
|
71
|
+
if (!editable) return
|
|
72
|
+
renaming = name
|
|
73
|
+
draft = name
|
|
74
|
+
error = null
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function commitRename() {
|
|
78
|
+
const from = renaming
|
|
79
|
+
if (from === null) return
|
|
80
|
+
const to = draft.trim()
|
|
81
|
+
renaming = null
|
|
82
|
+
if (to === '' || to === from) return
|
|
83
|
+
if (!isValidSheetName(to)) {
|
|
84
|
+
error = `"${to}" is not a valid sheet name`
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
if (!workbook.renameSheet(from, to)) {
|
|
88
|
+
error = `a sheet named "${to}" already exists`
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
error = null
|
|
92
|
+
onRename?.(from, to)
|
|
93
|
+
changed()
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function add() {
|
|
97
|
+
workbook.addSheet()
|
|
98
|
+
changed()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function remove(name: string) {
|
|
102
|
+
// The workbook refuses to remove the last sheet; reflect that rather than
|
|
103
|
+
// showing a button that does nothing.
|
|
104
|
+
if (!workbook.removeSheet(name)) return
|
|
105
|
+
onRemove?.(name)
|
|
106
|
+
changed()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ---- Excel's right-click menu on a tab ------------------------------------
|
|
110
|
+
let menu = $state<{ name: string; x: number; y: number } | null>(null)
|
|
111
|
+
|
|
112
|
+
function openMenu(event: MouseEvent, name: string) {
|
|
113
|
+
if (!editable) return
|
|
114
|
+
event.preventDefault()
|
|
115
|
+
select(name)
|
|
116
|
+
menu = { name, x: event.clientX, y: event.clientY }
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The tabs sit at the foot of the sheet, so a menu dropped from the click
|
|
120
|
+
* runs off the bottom of the window; it opens upward from the click, as
|
|
121
|
+
* Excel's does, and is pulled back inside at the right edge.
|
|
122
|
+
*/
|
|
123
|
+
function keepMenuInView(node: HTMLElement, _at: { x: number; y: number } | null) {
|
|
124
|
+
const fit = () => {
|
|
125
|
+
const box = node.getBoundingClientRect()
|
|
126
|
+
if (!menu) return
|
|
127
|
+
const x = Math.max(8, Math.min(menu.x, window.innerWidth - box.width - 8))
|
|
128
|
+
const y = menu.y + box.height > window.innerHeight - 8 ? Math.max(8, menu.y - box.height) : menu.y
|
|
129
|
+
if (x !== menu.x || y !== menu.y) menu = { ...menu, x, y }
|
|
130
|
+
}
|
|
131
|
+
fit()
|
|
132
|
+
return { update: fit }
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function moveBy(name: string, delta: -1 | 1) {
|
|
136
|
+
const at = workbook.sheets.indexOf(name)
|
|
137
|
+
const to = at + delta
|
|
138
|
+
if (at < 0 || to < 0 || to >= workbook.sheets.length) return
|
|
139
|
+
workbook.moveSheet(name, to)
|
|
140
|
+
changed()
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function insertBefore(name: string) {
|
|
144
|
+
const at = workbook.sheets.indexOf(name)
|
|
145
|
+
const added = workbook.addSheet(undefined, Math.max(at, 0))
|
|
146
|
+
workbook.setActive(added)
|
|
147
|
+
changed()
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// ---- the scroll arrows, for more tabs than fit --------------------------
|
|
151
|
+
// Excel greys each arrow until it can move something: with every tab in
|
|
152
|
+
// view both are grey, and at either end of a long strip the arrow that
|
|
153
|
+
// points off it is. Read from the strip's scroll box after every scroll,
|
|
154
|
+
// resize and tab change.
|
|
155
|
+
let strip = $state<HTMLDivElement | null>(null)
|
|
156
|
+
let canLeft = $state(false)
|
|
157
|
+
let canRight = $state(false)
|
|
158
|
+
function measureStrip() {
|
|
159
|
+
const el = strip
|
|
160
|
+
if (!el) { canLeft = false; canRight = false; return }
|
|
161
|
+
canLeft = el.scrollLeft > 1
|
|
162
|
+
canRight = el.scrollLeft + el.clientWidth < el.scrollWidth - 1
|
|
163
|
+
}
|
|
164
|
+
$effect(() => {
|
|
165
|
+
const el = strip
|
|
166
|
+
if (!el) return
|
|
167
|
+
void version
|
|
168
|
+
void sheets
|
|
169
|
+
measureStrip()
|
|
170
|
+
const ro = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(measureStrip)
|
|
171
|
+
ro?.observe(el)
|
|
172
|
+
el.addEventListener('scroll', measureStrip)
|
|
173
|
+
return () => { ro?.disconnect(); el.removeEventListener('scroll', measureStrip) }
|
|
174
|
+
})
|
|
175
|
+
function scrollTabs(delta: number) {
|
|
176
|
+
strip?.scrollBy({ left: delta, behavior: 'smooth' })
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function onDrop(target: string) {
|
|
180
|
+
const moved = dragging
|
|
181
|
+
dragging = null
|
|
182
|
+
if (!moved || moved === target) return
|
|
183
|
+
const to = workbook.sheets.indexOf(target)
|
|
184
|
+
if (to < 0) return
|
|
185
|
+
workbook.moveSheet(moved, to)
|
|
186
|
+
changed()
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Left and right arrows move between tabs, which is what a tablist owes a
|
|
190
|
+
* keyboard user; the shortcut layer's Ctrl+PageUp/Down does the same from
|
|
191
|
+
* anywhere in the grid. */
|
|
192
|
+
function onTabKey(event: KeyboardEvent, name: string) {
|
|
193
|
+
const at = sheets.indexOf(name)
|
|
194
|
+
if (event.key === 'ArrowRight' && at < sheets.length - 1) {
|
|
195
|
+
event.preventDefault()
|
|
196
|
+
select(sheets[at + 1]!)
|
|
197
|
+
} else if (event.key === 'ArrowLeft' && at > 0) {
|
|
198
|
+
event.preventDefault()
|
|
199
|
+
select(sheets[at - 1]!)
|
|
200
|
+
} else if (event.key === 'F2') {
|
|
201
|
+
event.preventDefault()
|
|
202
|
+
startRename(name)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
</script>
|
|
206
|
+
|
|
207
|
+
<svelte:window
|
|
208
|
+
onpointerdown={(e) => { if (menu && !(e.target as HTMLElement).closest('.sheet-menu')) menu = null }}
|
|
209
|
+
onkeydown={(e) => { if (e.key === 'Escape') menu = null }}
|
|
210
|
+
/>
|
|
211
|
+
|
|
212
|
+
<div class="sv-sheet-tabs">
|
|
213
|
+
<!-- Excel's tab-scrolling arrows: always drawn, greyed until they can move something. -->
|
|
214
|
+
<div class="nav">
|
|
215
|
+
<button type="button" class="nav-btn" tabindex="-1" aria-label="Scroll tabs left" disabled={!canLeft} onclick={() => scrollTabs(-120)}>
|
|
216
|
+
<svg viewBox="0 0 8 8" width="8" height="8"><path d="M5.5 1L2.5 4l3 3" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
217
|
+
</button>
|
|
218
|
+
<button type="button" class="nav-btn" tabindex="-1" aria-label="Scroll tabs right" disabled={!canRight} onclick={() => scrollTabs(120)}>
|
|
219
|
+
<svg viewBox="0 0 8 8" width="8" height="8"><path d="M2.5 1l3 3-3 3" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
220
|
+
</button>
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
<div role="tablist" aria-label="Sheets" class="tabs" bind:this={strip}>
|
|
224
|
+
{#each sheets as name (name)}
|
|
225
|
+
{@const isActive = name === activeSheet}
|
|
226
|
+
<!-- role="presentation" so the tablist still OWNS the role="tab"
|
|
227
|
+
button: an unmarked wrapper div between them breaks the ARIA
|
|
228
|
+
tablist / tab relationship. -->
|
|
229
|
+
<div
|
|
230
|
+
role="presentation"
|
|
231
|
+
class="tab"
|
|
232
|
+
class:active={isActive}
|
|
233
|
+
class:dragging={dragging === name}
|
|
234
|
+
draggable={editable}
|
|
235
|
+
ondragstart={() => (dragging = name)}
|
|
236
|
+
ondragover={(e) => e.preventDefault()}
|
|
237
|
+
ondrop={() => onDrop(name)}
|
|
238
|
+
ondragend={() => (dragging = null)}
|
|
239
|
+
oncontextmenu={(e) => openMenu(e, name)}
|
|
240
|
+
>
|
|
241
|
+
{#if renaming === name}
|
|
242
|
+
<!-- svelte-ignore a11y_autofocus -->
|
|
243
|
+
<input
|
|
244
|
+
class="rename"
|
|
245
|
+
aria-label="Sheet name"
|
|
246
|
+
autofocus
|
|
247
|
+
value={draft}
|
|
248
|
+
oninput={(e) => (draft = e.currentTarget.value)}
|
|
249
|
+
onblur={commitRename}
|
|
250
|
+
onkeydown={(e) => {
|
|
251
|
+
if (e.key === 'Enter') { e.preventDefault(); commitRename() }
|
|
252
|
+
if (e.key === 'Escape') { e.preventDefault(); renaming = null }
|
|
253
|
+
}}
|
|
254
|
+
/>
|
|
255
|
+
{:else}
|
|
256
|
+
<button
|
|
257
|
+
type="button"
|
|
258
|
+
role="tab"
|
|
259
|
+
aria-selected={isActive}
|
|
260
|
+
tabindex={isActive ? 0 : -1}
|
|
261
|
+
onclick={() => select(name)}
|
|
262
|
+
ondblclick={() => startRename(name)}
|
|
263
|
+
onkeydown={(e) => onTabKey(e, name)}
|
|
264
|
+
>{name}</button>
|
|
265
|
+
{/if}
|
|
266
|
+
</div>
|
|
267
|
+
{/each}
|
|
268
|
+
</div>
|
|
269
|
+
|
|
270
|
+
{#if editable}
|
|
271
|
+
<button type="button" class="add" aria-label="New sheet" title="New sheet (Shift+F11)" onclick={add}>
|
|
272
|
+
<svg viewBox="0 0 10 10" width="10" height="10" aria-hidden="true"><path d="M5 1.5v7M1.5 5h7" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" /></svg>
|
|
273
|
+
</button>
|
|
274
|
+
{/if}
|
|
275
|
+
|
|
276
|
+
{#if error}
|
|
277
|
+
<span class="error" role="alert">{error}</span>
|
|
278
|
+
{/if}
|
|
279
|
+
</div>
|
|
280
|
+
|
|
281
|
+
{#if menu}
|
|
282
|
+
<!--
|
|
283
|
+
The sheet menu Excel opens on right-click. Delete lives here and nowhere
|
|
284
|
+
on the tab face, so a stray click cannot remove a sheet.
|
|
285
|
+
-->
|
|
286
|
+
<div class="sheet-menu" role="menu" aria-label={`${menu.name} sheet`} style:left={`${menu.x}px`} style:top={`${menu.y}px`} use:keepMenuInView={menu}>
|
|
287
|
+
<button type="button" role="menuitem" onclick={() => { insertBefore(menu!.name); menu = null }}>Insert...</button>
|
|
288
|
+
<button type="button" role="menuitem" disabled={sheets.length < 2} onclick={() => { remove(menu!.name); menu = null }}>Delete</button>
|
|
289
|
+
<button type="button" role="menuitem" onclick={() => { startRename(menu!.name); menu = null }}>Rename</button>
|
|
290
|
+
<div class="sep" role="separator"></div>
|
|
291
|
+
<button type="button" role="menuitem" disabled={sheets.indexOf(menu.name) === 0} onclick={() => { moveBy(menu!.name, -1); menu = null }}>Move Left</button>
|
|
292
|
+
<button type="button" role="menuitem" disabled={sheets.indexOf(menu.name) === sheets.length - 1} onclick={() => { moveBy(menu!.name, 1); menu = null }}>Move Right</button>
|
|
293
|
+
</div>
|
|
294
|
+
{/if}
|
|
295
|
+
|
|
296
|
+
<style>
|
|
297
|
+
.sv-sheet-tabs {
|
|
298
|
+
display: flex;
|
|
299
|
+
align-items: stretch;
|
|
300
|
+
height: 26px;
|
|
301
|
+
font-family: var(--sg-font, "Segoe UI", system-ui, sans-serif);
|
|
302
|
+
font-size: 12px;
|
|
303
|
+
background: var(--sg-header-bg, #f3f3f3);
|
|
304
|
+
border-top: 1px solid var(--sg-border, #d1d1d1);
|
|
305
|
+
color: var(--sg-fg, #242424);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.nav {
|
|
309
|
+
display: flex;
|
|
310
|
+
align-items: center;
|
|
311
|
+
padding: 0 4px 0 6px;
|
|
312
|
+
gap: 2px;
|
|
313
|
+
color: var(--sg-muted, #616161);
|
|
314
|
+
}
|
|
315
|
+
.nav-btn {
|
|
316
|
+
display: inline-flex;
|
|
317
|
+
align-items: center;
|
|
318
|
+
justify-content: center;
|
|
319
|
+
width: 14px;
|
|
320
|
+
height: 18px;
|
|
321
|
+
padding: 0;
|
|
322
|
+
border: 0;
|
|
323
|
+
border-radius: 2px;
|
|
324
|
+
background: transparent;
|
|
325
|
+
color: inherit;
|
|
326
|
+
cursor: pointer;
|
|
327
|
+
}
|
|
328
|
+
.nav-btn:hover:not(:disabled) { background: var(--sg-row-hover-bg, #e6e6e6); color: var(--sg-fg, #242424); }
|
|
329
|
+
.nav-btn:disabled { opacity: 0.35; cursor: default; }
|
|
330
|
+
|
|
331
|
+
.tabs {
|
|
332
|
+
display: flex;
|
|
333
|
+
align-items: stretch;
|
|
334
|
+
overflow-x: auto;
|
|
335
|
+
scrollbar-width: none;
|
|
336
|
+
}
|
|
337
|
+
.tabs::-webkit-scrollbar { display: none; }
|
|
338
|
+
|
|
339
|
+
/* Excel's tabs: grey strip, the active one lifted to white with the accent
|
|
340
|
+
drawn as a line along its bottom edge and its name in the accent. */
|
|
341
|
+
.tab {
|
|
342
|
+
position: relative;
|
|
343
|
+
display: flex;
|
|
344
|
+
align-items: stretch;
|
|
345
|
+
min-width: 64px;
|
|
346
|
+
border-right: 1px solid var(--sg-border, #d1d1d1);
|
|
347
|
+
}
|
|
348
|
+
.tab:first-child { border-left: 1px solid var(--sg-border, #d1d1d1); }
|
|
349
|
+
.tab.active {
|
|
350
|
+
background: var(--sg-bg, #fff);
|
|
351
|
+
box-shadow: inset 0 -2px 0 0 var(--sg-accent, #107c41);
|
|
352
|
+
}
|
|
353
|
+
.tab.active button {
|
|
354
|
+
color: var(--sg-accent, #107c41);
|
|
355
|
+
font-weight: 600;
|
|
356
|
+
}
|
|
357
|
+
.tab:not(.active):hover { background: var(--sg-row-hover-bg, #e9e9e9); }
|
|
358
|
+
.tab.dragging { opacity: 0.5; }
|
|
359
|
+
button[role='tab'] {
|
|
360
|
+
flex: 1 1 auto;
|
|
361
|
+
font: inherit;
|
|
362
|
+
border: 0;
|
|
363
|
+
background: transparent;
|
|
364
|
+
color: var(--sg-muted, #444);
|
|
365
|
+
padding: 0 12px;
|
|
366
|
+
cursor: pointer;
|
|
367
|
+
white-space: nowrap;
|
|
368
|
+
text-align: center;
|
|
369
|
+
}
|
|
370
|
+
button[role='tab']:focus-visible {
|
|
371
|
+
outline: 2px solid var(--sg-focus-ring, var(--sg-accent, #107c41));
|
|
372
|
+
outline-offset: -2px;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.add {
|
|
376
|
+
align-self: center;
|
|
377
|
+
display: inline-flex;
|
|
378
|
+
align-items: center;
|
|
379
|
+
justify-content: center;
|
|
380
|
+
width: 18px;
|
|
381
|
+
height: 18px;
|
|
382
|
+
margin-left: 6px;
|
|
383
|
+
padding: 0;
|
|
384
|
+
border: 1px solid var(--sg-border, #c8c6c4);
|
|
385
|
+
border-radius: 50%;
|
|
386
|
+
background: var(--sg-bg, #fff);
|
|
387
|
+
color: var(--sg-muted, #616161);
|
|
388
|
+
cursor: pointer;
|
|
389
|
+
}
|
|
390
|
+
.add:hover { color: var(--sg-fg, #242424); border-color: var(--sg-muted, #8a8886); }
|
|
391
|
+
.add:focus-visible {
|
|
392
|
+
outline: 2px solid var(--sg-focus-ring, var(--sg-accent, #107c41));
|
|
393
|
+
outline-offset: 1px;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.rename {
|
|
397
|
+
font: inherit;
|
|
398
|
+
width: 92px;
|
|
399
|
+
margin: 2px 4px;
|
|
400
|
+
border: 1px solid var(--sg-accent, #107c41);
|
|
401
|
+
border-radius: 2px;
|
|
402
|
+
padding: 1px 4px;
|
|
403
|
+
background: var(--sg-input-bg, var(--sg-bg, #fff));
|
|
404
|
+
color: var(--sg-fg, #242424);
|
|
405
|
+
}
|
|
406
|
+
.error {
|
|
407
|
+
align-self: center;
|
|
408
|
+
margin-left: 8px;
|
|
409
|
+
color: var(--sg-danger, #dc2626);
|
|
410
|
+
font-size: 12px;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.sheet-menu {
|
|
414
|
+
position: fixed;
|
|
415
|
+
z-index: 1000;
|
|
416
|
+
min-width: 150px;
|
|
417
|
+
padding: 4px;
|
|
418
|
+
font-family: var(--sg-font, "Segoe UI", system-ui, sans-serif);
|
|
419
|
+
font-size: 12px;
|
|
420
|
+
background: var(--sg-bg, #fff);
|
|
421
|
+
color: var(--sg-fg, #242424);
|
|
422
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
423
|
+
border-radius: 4px;
|
|
424
|
+
box-shadow: 0 8px 24px rgb(0 0 0 / 0.14);
|
|
425
|
+
}
|
|
426
|
+
.sheet-menu button {
|
|
427
|
+
display: block;
|
|
428
|
+
width: 100%;
|
|
429
|
+
padding: 5px 10px;
|
|
430
|
+
font: inherit;
|
|
431
|
+
text-align: left;
|
|
432
|
+
border: 0;
|
|
433
|
+
border-radius: 3px;
|
|
434
|
+
background: transparent;
|
|
435
|
+
color: inherit;
|
|
436
|
+
cursor: pointer;
|
|
437
|
+
}
|
|
438
|
+
.sheet-menu button:hover:not(:disabled) { background: var(--sg-row-hover-bg, #f0f0f0); }
|
|
439
|
+
.sheet-menu button:disabled { opacity: 0.4; cursor: default; }
|
|
440
|
+
.sheet-menu .sep { height: 1px; margin: 4px 6px; background: var(--sg-border, #e0e0e0); }
|
|
441
|
+
</style>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sheet tab strip along the bottom of a workbook.
|
|
3
|
+
*
|
|
4
|
+
* Owns no workbook state of its own: it renders what the workbook reports
|
|
5
|
+
* and calls back, so the keyboard shortcuts and the tabs cannot disagree
|
|
6
|
+
* about which sheet is active.
|
|
7
|
+
*/
|
|
8
|
+
import type { Workbook } from './sheet/workbook.js';
|
|
9
|
+
type Props = {
|
|
10
|
+
workbook: Workbook;
|
|
11
|
+
/** Called after any change, so the consumer can re-render. */
|
|
12
|
+
onChange?: () => void;
|
|
13
|
+
/**
|
|
14
|
+
* Called after a sheet is renamed or removed, before `onChange`. Anything
|
|
15
|
+
* the consumer keeps per sheet and keys by name - the shell keeps a
|
|
16
|
+
* format store per sheet - has to follow the rename or drop the entry,
|
|
17
|
+
* and the workbook itself has no event for either.
|
|
18
|
+
*/
|
|
19
|
+
onRename?: (from: string, to: string) => void;
|
|
20
|
+
onRemove?: (name: string) => void;
|
|
21
|
+
/** Off hides the add button and the context actions. */
|
|
22
|
+
editable?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Bump this whenever the workbook is mutated from OUTSIDE the strip - the
|
|
25
|
+
* Ctrl+PageUp/PageDown shortcuts, or app code calling `addSheet`.
|
|
26
|
+
*
|
|
27
|
+
* A `Workbook` is a plain object, not `$state`, so reading `workbook.sheets`
|
|
28
|
+
* creates no reactive dependency and the strip would otherwise render once
|
|
29
|
+
* and then show whatever the sheet list was at mount. Pass the same counter
|
|
30
|
+
* `onChange` increments.
|
|
31
|
+
*/
|
|
32
|
+
version?: number;
|
|
33
|
+
};
|
|
34
|
+
declare const SvSheetTabs: import("svelte").Component<Props, {}, "">;
|
|
35
|
+
type SvSheetTabs = ReturnType<typeof SvSheetTabs>;
|
|
36
|
+
export default SvSheetTabs;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-only harness for SvSheetTabs.
|
|
3
|
+
*
|
|
4
|
+
* `mount()` takes a plain props object, and a plain object's fields are not
|
|
5
|
+
* reactive, so a test cannot change a prop after mounting and see the
|
|
6
|
+
* component respond. This box holds the props in `$state` so it can - which is
|
|
7
|
+
* what proves the strip follows an OUTSIDE workbook mutation (Ctrl+PageUp and
|
|
8
|
+
* friends) rather than only its own button clicks.
|
|
9
|
+
*
|
|
10
|
+
* Runes only compile in `.svelte.ts`, hence the separate file. The `.test.`
|
|
11
|
+
* segment keeps it out of the published tarball (tools/strip-dist-tests.mjs)
|
|
12
|
+
* and out of vitest's `*.dom.test.ts` include.
|
|
13
|
+
*/
|
|
14
|
+
export declare function reactiveProps<T extends Record<string, unknown>>(initial: T): {
|
|
15
|
+
props: T;
|
|
16
|
+
set(patch: Partial<T>): void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-only harness for SvSheetTabs.
|
|
3
|
+
*
|
|
4
|
+
* `mount()` takes a plain props object, and a plain object's fields are not
|
|
5
|
+
* reactive, so a test cannot change a prop after mounting and see the
|
|
6
|
+
* component respond. This box holds the props in `$state` so it can - which is
|
|
7
|
+
* what proves the strip follows an OUTSIDE workbook mutation (Ctrl+PageUp and
|
|
8
|
+
* friends) rather than only its own button clicks.
|
|
9
|
+
*
|
|
10
|
+
* Runes only compile in `.svelte.ts`, hence the separate file. The `.test.`
|
|
11
|
+
* segment keeps it out of the published tarball (tools/strip-dist-tests.mjs)
|
|
12
|
+
* and out of vitest's `*.dom.test.ts` include.
|
|
13
|
+
*/
|
|
14
|
+
export function reactiveProps(initial) {
|
|
15
|
+
const box = $state({ ...initial });
|
|
16
|
+
return {
|
|
17
|
+
props: box,
|
|
18
|
+
set(patch) {
|
|
19
|
+
Object.assign(box, patch);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|