@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,147 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Insert Function: search or pick a category, choose a function,
|
|
4
|
+
* read its argument list and what it does, and OK starts the active cell
|
|
5
|
+
* on `=NAME(` with the caret inside the parentheses, where the formula
|
|
6
|
+
* bar's autocomplete and signature hint take over. Excel follows with a
|
|
7
|
+
* Function Arguments dialog; typing the arguments in place with the
|
|
8
|
+
* signature shown is the same information with less chrome.
|
|
9
|
+
*/
|
|
10
|
+
import { SvModal } from '@svgrid/grid'
|
|
11
|
+
import { functionCatalog, FUNCTION_GROUPS, type FunctionGroup, type FunctionInfo } from './sheet/function-catalog'
|
|
12
|
+
|
|
13
|
+
type Props = {
|
|
14
|
+
open?: boolean
|
|
15
|
+
onPick: (name: string) => void
|
|
16
|
+
onClose?: () => void
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let { open = $bindable(false), onPick, onClose }: Props = $props()
|
|
20
|
+
|
|
21
|
+
const all = functionCatalog()
|
|
22
|
+
let search = $state('')
|
|
23
|
+
let group = $state<FunctionGroup | 'All'>('All')
|
|
24
|
+
let selected = $state<string>(all[0]?.name ?? '')
|
|
25
|
+
let searchInput = $state<HTMLInputElement | null>(null)
|
|
26
|
+
|
|
27
|
+
const shown = $derived.by<FunctionInfo[]>(() => {
|
|
28
|
+
const needle = search.trim().toUpperCase()
|
|
29
|
+
return all.filter((f) =>
|
|
30
|
+
(group === 'All' || f.group === group) &&
|
|
31
|
+
(needle === '' || f.name.includes(needle) || f.description.toUpperCase().includes(needle)),
|
|
32
|
+
)
|
|
33
|
+
})
|
|
34
|
+
const current = $derived(all.find((f) => f.name === selected) ?? null)
|
|
35
|
+
|
|
36
|
+
// The highlighted function follows the filter, so Enter always inserts
|
|
37
|
+
// something visible.
|
|
38
|
+
$effect(() => {
|
|
39
|
+
if (shown.length && !shown.some((f) => f.name === selected)) selected = shown[0]!.name
|
|
40
|
+
})
|
|
41
|
+
$effect(() => {
|
|
42
|
+
if (open) queueMicrotask(() => searchInput?.focus())
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
function ok() {
|
|
46
|
+
if (!current) return
|
|
47
|
+
onPick(current.name)
|
|
48
|
+
open = false
|
|
49
|
+
onClose?.()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function close() {
|
|
53
|
+
open = false
|
|
54
|
+
onClose?.()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function onListKey(event: KeyboardEvent) {
|
|
58
|
+
const index = shown.findIndex((f) => f.name === selected)
|
|
59
|
+
if (event.key === 'ArrowDown') {
|
|
60
|
+
event.preventDefault()
|
|
61
|
+
selected = shown[Math.min(index + 1, shown.length - 1)]?.name ?? selected
|
|
62
|
+
} else if (event.key === 'ArrowUp') {
|
|
63
|
+
event.preventDefault()
|
|
64
|
+
selected = shown[Math.max(index - 1, 0)]?.name ?? selected
|
|
65
|
+
} else if (event.key === 'Enter') {
|
|
66
|
+
event.preventDefault()
|
|
67
|
+
ok()
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<SvModal bind:open onClose={onClose} title="Insert Function" size="md">
|
|
73
|
+
<div class="sv-sheet-dialog insert" role="group" aria-label="Insert Function">
|
|
74
|
+
<label class="field">
|
|
75
|
+
<span>Search for a function:</span>
|
|
76
|
+
<input bind:this={searchInput} type="text" bind:value={search} onkeydown={onListKey} spellcheck="false" autocomplete="off" placeholder="Type a name or what you want to do" />
|
|
77
|
+
</label>
|
|
78
|
+
<label class="field">
|
|
79
|
+
<span>Or select a category:</span>
|
|
80
|
+
<select bind:value={group}>
|
|
81
|
+
<option value="All">All</option>
|
|
82
|
+
{#each FUNCTION_GROUPS as g (g)}
|
|
83
|
+
<option value={g}>{g}</option>
|
|
84
|
+
{/each}
|
|
85
|
+
</select>
|
|
86
|
+
</label>
|
|
87
|
+
<div class="label">Select a function:</div>
|
|
88
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
89
|
+
<ul class="list" role="listbox" aria-label="Functions" tabindex="0" onkeydown={onListKey}>
|
|
90
|
+
{#each shown as fn (fn.name)}
|
|
91
|
+
<!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_noninteractive_element_interactions -->
|
|
92
|
+
<li
|
|
93
|
+
role="option"
|
|
94
|
+
aria-selected={fn.name === selected}
|
|
95
|
+
class:selected={fn.name === selected}
|
|
96
|
+
onclick={() => (selected = fn.name)}
|
|
97
|
+
ondblclick={ok}
|
|
98
|
+
>{fn.name}</li>
|
|
99
|
+
{:else}
|
|
100
|
+
<li class="empty">No function matches.</li>
|
|
101
|
+
{/each}
|
|
102
|
+
</ul>
|
|
103
|
+
{#if current}
|
|
104
|
+
<div class="about">
|
|
105
|
+
<div class="signature">{current.signature}</div>
|
|
106
|
+
<div class="description">{current.description || 'No description.'}</div>
|
|
107
|
+
</div>
|
|
108
|
+
{/if}
|
|
109
|
+
</div>
|
|
110
|
+
{#snippet footer()}
|
|
111
|
+
<div class="sv-sheet-dialog-buttons">
|
|
112
|
+
<button type="button" class="btn primary" onclick={ok} disabled={!current}>OK</button>
|
|
113
|
+
<button type="button" class="btn" onclick={close}>Cancel</button>
|
|
114
|
+
</div>
|
|
115
|
+
{/snippet}
|
|
116
|
+
</SvModal>
|
|
117
|
+
|
|
118
|
+
<style>
|
|
119
|
+
.label { font-weight: 600; }
|
|
120
|
+
.insert :global(.field) { grid-template-columns: 160px 1fr; }
|
|
121
|
+
.list {
|
|
122
|
+
height: 160px;
|
|
123
|
+
margin: 0;
|
|
124
|
+
padding: 2px 0;
|
|
125
|
+
overflow-y: auto;
|
|
126
|
+
list-style: none;
|
|
127
|
+
background: var(--sg-bg, #fff);
|
|
128
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
129
|
+
border-radius: var(--sg-radius, 3px);
|
|
130
|
+
font-family: ui-monospace, Consolas, monospace;
|
|
131
|
+
font-size: 12px;
|
|
132
|
+
}
|
|
133
|
+
.list:focus { outline: none; border-color: var(--sg-accent, #217346); }
|
|
134
|
+
.list li {
|
|
135
|
+
padding: 2px 8px;
|
|
136
|
+
cursor: default;
|
|
137
|
+
}
|
|
138
|
+
.list li:hover { background: var(--sg-row-hover-bg, #f5f5f5); }
|
|
139
|
+
.list li.selected {
|
|
140
|
+
color: var(--sg-on-accent, #fff);
|
|
141
|
+
background: var(--sg-accent, #217346);
|
|
142
|
+
}
|
|
143
|
+
.list li.empty { color: var(--sg-muted, #616161); font-family: inherit; }
|
|
144
|
+
.about { display: flex; flex-direction: column; gap: 4px; min-height: 52px; }
|
|
145
|
+
.signature { font-weight: 600; font-family: ui-monospace, Consolas, monospace; font-size: 12px; }
|
|
146
|
+
.description { color: var(--sg-muted, #616161); }
|
|
147
|
+
</style>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
open?: boolean;
|
|
3
|
+
onPick: (name: string) => void;
|
|
4
|
+
onClose?: () => void;
|
|
5
|
+
};
|
|
6
|
+
declare const SvSheetInsertFunction: import("svelte").Component<Props, {}, "open">;
|
|
7
|
+
type SvSheetInsertFunction = ReturnType<typeof SvSheetInsertFunction>;
|
|
8
|
+
export default SvSheetInsertFunction;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* The list a validated cell drops down: Excel's in-cell dropdown. The
|
|
4
|
+
* choices as the rule lists them, the current value marked, arrow keys
|
|
5
|
+
* and Enter to pick, Escape to leave the cell as it is. The shell mounts
|
|
6
|
+
* it inside the popover anchored to the cell.
|
|
7
|
+
*/
|
|
8
|
+
type Props = {
|
|
9
|
+
choices: ReadonlyArray<string>
|
|
10
|
+
/** The cell's current text, marked in the list. */
|
|
11
|
+
value: string
|
|
12
|
+
onPick: (choice: string) => void
|
|
13
|
+
onCancel: () => void
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let { choices, value, onPick, onCancel }: Props = $props()
|
|
17
|
+
|
|
18
|
+
let list = $state<HTMLDivElement | null>(null)
|
|
19
|
+
let index = $state(0)
|
|
20
|
+
|
|
21
|
+
$effect(() => {
|
|
22
|
+
const at = choices.findIndex((c) => c.toLowerCase() === value.trim().toLowerCase())
|
|
23
|
+
index = at >= 0 ? at : 0
|
|
24
|
+
queueMicrotask(() => list?.focus())
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
28
|
+
if (event.key === 'ArrowDown') { event.preventDefault(); index = Math.min(index + 1, choices.length - 1); scrollTo() }
|
|
29
|
+
else if (event.key === 'ArrowUp') { event.preventDefault(); index = Math.max(index - 1, 0); scrollTo() }
|
|
30
|
+
else if (event.key === 'Home') { event.preventDefault(); index = 0; scrollTo() }
|
|
31
|
+
else if (event.key === 'End') { event.preventDefault(); index = choices.length - 1; scrollTo() }
|
|
32
|
+
else if (event.key === 'Enter' || event.key === 'Tab') { event.preventDefault(); const c = choices[index]; if (c !== undefined) onPick(c) }
|
|
33
|
+
else if (event.key === 'Escape') { event.preventDefault(); onCancel() }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function scrollTo() {
|
|
37
|
+
list?.querySelector<HTMLElement>(`[data-index="${index}"]`)?.scrollIntoView({ block: 'nearest' })
|
|
38
|
+
}
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<div
|
|
42
|
+
bind:this={list}
|
|
43
|
+
class="sv-sheet-list-picker"
|
|
44
|
+
role="listbox"
|
|
45
|
+
aria-label="Choices"
|
|
46
|
+
tabindex="0"
|
|
47
|
+
aria-activedescendant={choices.length ? `sv-sheet-choice-${index}` : undefined}
|
|
48
|
+
onkeydown={onKeyDown}
|
|
49
|
+
>
|
|
50
|
+
{#if choices.length === 0}
|
|
51
|
+
<div class="empty">The list is empty.</div>
|
|
52
|
+
{:else}
|
|
53
|
+
{#each choices as choice, i (i)}
|
|
54
|
+
<!-- svelte-ignore a11y_click_events_have_key_events, a11y_interactive_supports_focus -->
|
|
55
|
+
<div
|
|
56
|
+
id={`sv-sheet-choice-${i}`}
|
|
57
|
+
class="choice"
|
|
58
|
+
class:on={i === index}
|
|
59
|
+
role="option"
|
|
60
|
+
aria-selected={i === index}
|
|
61
|
+
data-index={i}
|
|
62
|
+
onpointermove={() => (index = i)}
|
|
63
|
+
onclick={() => onPick(choice)}
|
|
64
|
+
>{choice}</div>
|
|
65
|
+
{/each}
|
|
66
|
+
{/if}
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<style>
|
|
70
|
+
.sv-sheet-list-picker {
|
|
71
|
+
min-width: 120px;
|
|
72
|
+
max-width: 320px;
|
|
73
|
+
max-height: 200px;
|
|
74
|
+
overflow-y: auto;
|
|
75
|
+
padding: 4px 0;
|
|
76
|
+
font-size: 12px;
|
|
77
|
+
color: var(--sg-fg, #242424);
|
|
78
|
+
outline: none;
|
|
79
|
+
}
|
|
80
|
+
.choice {
|
|
81
|
+
padding: 4px 10px;
|
|
82
|
+
white-space: nowrap;
|
|
83
|
+
overflow: hidden;
|
|
84
|
+
text-overflow: ellipsis;
|
|
85
|
+
cursor: default;
|
|
86
|
+
}
|
|
87
|
+
.choice.on { background: var(--sg-selection-bg, rgba(16, 124, 65, 0.12)); }
|
|
88
|
+
.empty { padding: 4px 10px; color: var(--sg-muted, #616161); }
|
|
89
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The list a validated cell drops down: Excel's in-cell dropdown. The
|
|
3
|
+
* choices as the rule lists them, the current value marked, arrow keys
|
|
4
|
+
* and Enter to pick, Escape to leave the cell as it is. The shell mounts
|
|
5
|
+
* it inside the popover anchored to the cell.
|
|
6
|
+
*/
|
|
7
|
+
type Props = {
|
|
8
|
+
choices: ReadonlyArray<string>;
|
|
9
|
+
/** The cell's current text, marked in the list. */
|
|
10
|
+
value: string;
|
|
11
|
+
onPick: (choice: string) => void;
|
|
12
|
+
onCancel: () => void;
|
|
13
|
+
};
|
|
14
|
+
declare const SvSheetListPicker: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type SvSheetListPicker = ReturnType<typeof SvSheetListPicker>;
|
|
16
|
+
export default SvSheetListPicker;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Conditional Formatting Rules Manager: the rules of the sheet
|
|
4
|
+
* (or of the current selection), in priority order, each with what it
|
|
5
|
+
* does, a sample and where it applies; Edit Rule (for the rules the small
|
|
6
|
+
* dialog can edit), Delete Rule, Move Up, Move Down and Stop If True. The
|
|
7
|
+
* list is a working copy: OK hands it back as one change, Cancel drops
|
|
8
|
+
* it.
|
|
9
|
+
*/
|
|
10
|
+
import { SvModal } from '@svgrid/grid'
|
|
11
|
+
import { describeCf, hasStyle, cfIn, type CfRule, type CfStyledRule } from './sheet/conditional-formats'
|
|
12
|
+
import { colToLetters } from './sheet/address'
|
|
13
|
+
import type { Rect } from './sheet/rects'
|
|
14
|
+
|
|
15
|
+
type Props = {
|
|
16
|
+
open?: boolean
|
|
17
|
+
rules: ReadonlyArray<CfRule>
|
|
18
|
+
/** The selection, for the Current Selection filter. */
|
|
19
|
+
selection: ReadonlyArray<Rect>
|
|
20
|
+
onApply: (rules: CfRule[]) => void
|
|
21
|
+
/** Edit Rule: the shell opens the small dialog on the rule and calls
|
|
22
|
+
* `replace` with the result. */
|
|
23
|
+
onEdit: (rule: CfStyledRule, replace: (next: CfStyledRule) => void) => void
|
|
24
|
+
onClose?: () => void
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let { open = $bindable(false), rules, selection, onApply, onEdit, onClose }: Props = $props()
|
|
28
|
+
|
|
29
|
+
let working = $state<CfRule[]>([])
|
|
30
|
+
let scope = $state<'sheet' | 'selection'>('sheet')
|
|
31
|
+
let selected = $state<string | null>(null)
|
|
32
|
+
|
|
33
|
+
$effect(() => {
|
|
34
|
+
if (!open) return
|
|
35
|
+
// Read the props, write the state: reading `working` back here would
|
|
36
|
+
// make the effect depend on what it just wrote and run without end.
|
|
37
|
+
const copy = rules.map((r) => ({ ...r, rects: r.rects.map((x) => [...x] as unknown as Rect) }))
|
|
38
|
+
working = copy
|
|
39
|
+
scope = 'sheet'
|
|
40
|
+
selected = copy[0]?.id ?? null
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const shown = $derived(scope === 'sheet' ? working : cfIn(working, selection))
|
|
44
|
+
const current = $derived(working.find((r) => r.id === selected) ?? null)
|
|
45
|
+
const index = $derived(current ? working.indexOf(current) : -1)
|
|
46
|
+
|
|
47
|
+
const address = (rects: ReadonlyArray<Rect>) =>
|
|
48
|
+
rects.map(([r1, c1, r2, c2]) => {
|
|
49
|
+
const a = `${colToLetters(c1)}${r1 + 1}`
|
|
50
|
+
const b = `${colToLetters(c2)}${r2 + 1}`
|
|
51
|
+
return a === b ? a : `${a}:${b}`
|
|
52
|
+
}).join(', ')
|
|
53
|
+
|
|
54
|
+
const sample = (rule: CfRule): { background?: string; color?: string; text: string } => {
|
|
55
|
+
if (hasStyle(rule)) return { background: rule.style.fill, color: rule.style.color, text: 'AaBbCcYyZz' }
|
|
56
|
+
if (rule.kind === 'dataBar') return { background: `linear-gradient(90deg, ${rule.color} 60%, transparent 60%)`, text: '' }
|
|
57
|
+
if (rule.kind === 'colorScale') return { background: `linear-gradient(90deg, ${rule.colors.join(', ')})`, text: '' }
|
|
58
|
+
return { text: 'Icon Set' }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function remove() {
|
|
62
|
+
if (index < 0) return
|
|
63
|
+
working = working.filter((_, i) => i !== index)
|
|
64
|
+
selected = working[Math.min(index, working.length - 1)]?.id ?? null
|
|
65
|
+
}
|
|
66
|
+
function move(delta: -1 | 1) {
|
|
67
|
+
if (index < 0) return
|
|
68
|
+
const to = index + delta
|
|
69
|
+
if (to < 0 || to >= working.length) return
|
|
70
|
+
const next = working.slice()
|
|
71
|
+
const [rule] = next.splice(index, 1)
|
|
72
|
+
next.splice(to, 0, rule!)
|
|
73
|
+
working = next
|
|
74
|
+
}
|
|
75
|
+
function toggleStop(rule: CfRule) {
|
|
76
|
+
working = working.map((r) => (r.id === rule.id ? { ...r, stopIfTrue: !r.stopIfTrue } : r))
|
|
77
|
+
}
|
|
78
|
+
function edit() {
|
|
79
|
+
const rule = current
|
|
80
|
+
if (!rule || !hasStyle(rule)) return
|
|
81
|
+
onEdit(rule, (next) => {
|
|
82
|
+
working = working.map((r) => (r.id === rule.id ? next : r))
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
function ok() {
|
|
86
|
+
onApply(working)
|
|
87
|
+
open = false
|
|
88
|
+
onClose?.()
|
|
89
|
+
}
|
|
90
|
+
function close() {
|
|
91
|
+
open = false
|
|
92
|
+
onClose?.()
|
|
93
|
+
}
|
|
94
|
+
</script>
|
|
95
|
+
|
|
96
|
+
<SvModal bind:open onClose={onClose} title="Conditional Formatting Rules Manager" size="md" width={640}>
|
|
97
|
+
<div class="sv-sheet-dialog manage">
|
|
98
|
+
<label class="field auto">
|
|
99
|
+
<span>Show formatting rules for:</span>
|
|
100
|
+
<select bind:value={scope}>
|
|
101
|
+
<option value="sheet">This Worksheet</option>
|
|
102
|
+
<option value="selection">Current Selection</option>
|
|
103
|
+
</select>
|
|
104
|
+
</label>
|
|
105
|
+
<div class="toolbar">
|
|
106
|
+
<button type="button" class="btn" onclick={edit} disabled={!current || !hasStyle(current)}>Edit Rule...</button>
|
|
107
|
+
<button type="button" class="btn" onclick={remove} disabled={!current}>Delete Rule</button>
|
|
108
|
+
<button type="button" class="btn" onclick={() => move(-1)} disabled={index <= 0} aria-label="Move Up" title="Move Up">▲</button>
|
|
109
|
+
<button type="button" class="btn" onclick={() => move(1)} disabled={index < 0 || index >= working.length - 1} aria-label="Move Down" title="Move Down">▼</button>
|
|
110
|
+
</div>
|
|
111
|
+
<div class="list" role="grid" aria-label="Rules">
|
|
112
|
+
<div class="head" role="row">
|
|
113
|
+
<span role="columnheader">Rule (applied in order shown)</span>
|
|
114
|
+
<span role="columnheader">Format</span>
|
|
115
|
+
<span role="columnheader">Applies to</span>
|
|
116
|
+
<span role="columnheader">Stop If True</span>
|
|
117
|
+
</div>
|
|
118
|
+
{#if shown.length === 0}
|
|
119
|
+
<div class="empty">No rules {scope === 'sheet' ? 'on this sheet' : 'over the selection'}.</div>
|
|
120
|
+
{/if}
|
|
121
|
+
{#each shown as rule (rule.id)}
|
|
122
|
+
{@const s = sample(rule)}
|
|
123
|
+
<!-- svelte-ignore a11y_click_events_have_key_events, a11y_interactive_supports_focus -->
|
|
124
|
+
<div class="rule" class:on={rule.id === selected} role="row" aria-selected={rule.id === selected} onclick={() => (selected = rule.id)}>
|
|
125
|
+
<span role="gridcell" class="what">{describeCf(rule)}</span>
|
|
126
|
+
<span role="gridcell" class="sample" style:background={s.background ?? 'transparent'} style:color={s.color ?? 'inherit'}>{s.text}</span>
|
|
127
|
+
<span role="gridcell" class="where">{address(rule.rects)}</span>
|
|
128
|
+
<span role="gridcell" class="stop"><input type="checkbox" checked={!!rule.stopIfTrue} aria-label="Stop If True" onchange={() => toggleStop(rule)} onclick={(e) => e.stopPropagation()} /></span>
|
|
129
|
+
</div>
|
|
130
|
+
{/each}
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
{#snippet footer()}
|
|
134
|
+
<div class="sv-sheet-dialog-buttons">
|
|
135
|
+
<button type="button" class="btn primary" onclick={ok}>OK</button>
|
|
136
|
+
<button type="button" class="btn" onclick={close}>Cancel</button>
|
|
137
|
+
</div>
|
|
138
|
+
{/snippet}
|
|
139
|
+
</SvModal>
|
|
140
|
+
|
|
141
|
+
<style>
|
|
142
|
+
.toolbar { display: flex; gap: 6px; }
|
|
143
|
+
.toolbar .btn {
|
|
144
|
+
height: 26px;
|
|
145
|
+
padding: 0 10px;
|
|
146
|
+
font: inherit;
|
|
147
|
+
color: inherit;
|
|
148
|
+
background: var(--sg-bg, #fff);
|
|
149
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
150
|
+
border-radius: var(--sg-radius, 3px);
|
|
151
|
+
cursor: pointer;
|
|
152
|
+
}
|
|
153
|
+
.toolbar .btn:hover:not(:disabled) { background: var(--sg-row-hover-bg, #f5f5f5); }
|
|
154
|
+
.toolbar .btn:disabled { opacity: 0.5; cursor: default; }
|
|
155
|
+
.list {
|
|
156
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
157
|
+
border-radius: var(--sg-radius, 3px);
|
|
158
|
+
max-height: 260px;
|
|
159
|
+
overflow-y: auto;
|
|
160
|
+
}
|
|
161
|
+
.head, .rule {
|
|
162
|
+
display: grid;
|
|
163
|
+
grid-template-columns: 1fr 120px 130px 84px;
|
|
164
|
+
align-items: center;
|
|
165
|
+
gap: 8px;
|
|
166
|
+
padding: 4px 8px;
|
|
167
|
+
}
|
|
168
|
+
.head {
|
|
169
|
+
font-weight: 600;
|
|
170
|
+
color: var(--sg-muted, #616161);
|
|
171
|
+
background: var(--sg-bg-subtle, #f3f3f3);
|
|
172
|
+
border-bottom: 1px solid var(--sg-border, #d1d1d1);
|
|
173
|
+
}
|
|
174
|
+
.rule { cursor: default; }
|
|
175
|
+
.rule.on { background: var(--sg-selection-bg, rgba(16, 124, 65, 0.12)); }
|
|
176
|
+
.rule .sample {
|
|
177
|
+
padding: 2px 6px;
|
|
178
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
179
|
+
text-align: center;
|
|
180
|
+
min-height: 20px;
|
|
181
|
+
}
|
|
182
|
+
.rule .where { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
183
|
+
.rule .stop { text-align: center; }
|
|
184
|
+
.empty { padding: 10px; color: var(--sg-muted, #616161); }
|
|
185
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type CfRule, type CfStyledRule } from './sheet/conditional-formats.js';
|
|
2
|
+
import type { Rect } from './sheet/rects.js';
|
|
3
|
+
type Props = {
|
|
4
|
+
open?: boolean;
|
|
5
|
+
rules: ReadonlyArray<CfRule>;
|
|
6
|
+
/** The selection, for the Current Selection filter. */
|
|
7
|
+
selection: ReadonlyArray<Rect>;
|
|
8
|
+
onApply: (rules: CfRule[]) => void;
|
|
9
|
+
/** Edit Rule: the shell opens the small dialog on the rule and calls
|
|
10
|
+
* `replace` with the result. */
|
|
11
|
+
onEdit: (rule: CfStyledRule, replace: (next: CfStyledRule) => void) => void;
|
|
12
|
+
onClose?: () => void;
|
|
13
|
+
};
|
|
14
|
+
declare const SvSheetManageRules: import("svelte").Component<Props, {}, "open">;
|
|
15
|
+
type SvSheetManageRules = ReturnType<typeof SvSheetManageRules>;
|
|
16
|
+
export default SvSheetManageRules;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Name Manager: every defined name with what it refers to and
|
|
4
|
+
* what that is worth right now; edit one in place, delete one, add one.
|
|
5
|
+
* Writes go to `workbook.names`, and the shell is told afterwards, since
|
|
6
|
+
* no cell was typed into and the sheet would otherwise not repaint.
|
|
7
|
+
*/
|
|
8
|
+
import { SvModal } from '@svgrid/grid'
|
|
9
|
+
import type { Workbook } from './sheet/workbook'
|
|
10
|
+
import type { DefinedName } from './sheet/names'
|
|
11
|
+
import { isValidName } from './sheet/names'
|
|
12
|
+
import { parseA1 } from './sheet/address'
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
open?: boolean
|
|
16
|
+
workbook: Workbook
|
|
17
|
+
/** Called after every change, so the shell recomputes and repaints. */
|
|
18
|
+
onChange: () => void
|
|
19
|
+
onClose?: () => void
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let { open = $bindable(false), workbook, onChange, onClose }: Props = $props()
|
|
23
|
+
|
|
24
|
+
let names = $state<DefinedName[]>([])
|
|
25
|
+
let newName = $state('')
|
|
26
|
+
let newRefersTo = $state('')
|
|
27
|
+
let editing = $state<string | null>(null)
|
|
28
|
+
let editRefersTo = $state('')
|
|
29
|
+
let problem = $state<string | null>(null)
|
|
30
|
+
|
|
31
|
+
function reload() {
|
|
32
|
+
names = workbook.names.list()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
$effect(() => {
|
|
36
|
+
if (!open) return
|
|
37
|
+
reload()
|
|
38
|
+
newName = ''
|
|
39
|
+
newRefersTo = ''
|
|
40
|
+
editing = null
|
|
41
|
+
problem = null
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
/** What a name is worth right now, for the Value column. */
|
|
45
|
+
function valueOf(entry: DefinedName): string {
|
|
46
|
+
const text = entry.refersTo.replace(/^=/, '')
|
|
47
|
+
const bang = text.lastIndexOf('!')
|
|
48
|
+
const sheetName = bang >= 0 ? text.slice(0, bang).replace(/^'(.*)'$/, '$1') : workbook.active
|
|
49
|
+
const address = bang >= 0 ? text.slice(bang + 1) : text
|
|
50
|
+
const [first, last] = address.split(':')
|
|
51
|
+
const from = parseA1(first ?? '')
|
|
52
|
+
if (!from || from.row === null) return ''
|
|
53
|
+
if (last) {
|
|
54
|
+
const to = parseA1(last)
|
|
55
|
+
if (to && to.row !== null) {
|
|
56
|
+
const cells = (to.row - from.row + 1) * (to.col - from.col + 1)
|
|
57
|
+
return `${cells} cells`
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const v = workbook.getValue(sheetName, from.row, from.col)
|
|
61
|
+
if (typeof v === 'object' && v !== null) return v.error
|
|
62
|
+
if (typeof v === 'number') return v.toLocaleString('en-US', { maximumFractionDigits: 4 })
|
|
63
|
+
return String(v)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Accept `Assumptions!B6`, `=Assumptions!$B$6`, `B6` or a range. */
|
|
67
|
+
function normalise(refersTo: string): string | null {
|
|
68
|
+
const text = refersTo.trim().replace(/^=/, '')
|
|
69
|
+
if (text === '') return null
|
|
70
|
+
const bang = text.lastIndexOf('!')
|
|
71
|
+
const address = bang >= 0 ? text.slice(bang + 1) : text
|
|
72
|
+
const [first, last] = address.split(':')
|
|
73
|
+
if (!parseA1(first ?? '')) return null
|
|
74
|
+
if (last !== undefined && !parseA1(last)) return null
|
|
75
|
+
const sheet = bang >= 0 ? text.slice(0, bang + 1) : `${quote(workbook.active)}!`
|
|
76
|
+
return `=${sheet}${address}`
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const quote = (name: string) => (/^[A-Za-z_][A-Za-z0-9_.]*$/.test(name) ? name : `'${name.replace(/'/g, "''")}'`)
|
|
80
|
+
|
|
81
|
+
function changed() {
|
|
82
|
+
onChange()
|
|
83
|
+
reload()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function add() {
|
|
87
|
+
const name = newName.trim()
|
|
88
|
+
if (!isValidName(name)) { problem = `"${name}" is not a valid name: letters, digits and underscores, not a cell address`; return }
|
|
89
|
+
if (workbook.names.has(name)) { problem = `${name} is already defined; edit it below instead`; return }
|
|
90
|
+
const refersTo = normalise(newRefersTo)
|
|
91
|
+
if (!refersTo) { problem = `"${newRefersTo}" is not a cell or range`; return }
|
|
92
|
+
workbook.names.define(name, refersTo)
|
|
93
|
+
newName = ''
|
|
94
|
+
newRefersTo = ''
|
|
95
|
+
problem = null
|
|
96
|
+
changed()
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function startEdit(entry: DefinedName) {
|
|
100
|
+
editing = entry.name
|
|
101
|
+
editRefersTo = entry.refersTo
|
|
102
|
+
problem = null
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function saveEdit() {
|
|
106
|
+
if (!editing) return
|
|
107
|
+
const refersTo = normalise(editRefersTo)
|
|
108
|
+
if (!refersTo) { problem = `"${editRefersTo}" is not a cell or range`; return }
|
|
109
|
+
workbook.names.define(editing, refersTo)
|
|
110
|
+
editing = null
|
|
111
|
+
problem = null
|
|
112
|
+
changed()
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function remove(name: string) {
|
|
116
|
+
workbook.names.remove(name)
|
|
117
|
+
changed()
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function close() {
|
|
121
|
+
open = false
|
|
122
|
+
onClose?.()
|
|
123
|
+
}
|
|
124
|
+
</script>
|
|
125
|
+
|
|
126
|
+
<SvModal bind:open onClose={onClose} title="Name Manager" size="md">
|
|
127
|
+
<div class="sv-sheet-dialog manager" role="group" aria-label="Name Manager">
|
|
128
|
+
<table class="names">
|
|
129
|
+
<thead>
|
|
130
|
+
<tr><th>Name</th><th>Refers to</th><th>Value</th><th></th></tr>
|
|
131
|
+
</thead>
|
|
132
|
+
<tbody>
|
|
133
|
+
{#each names as entry (entry.name)}
|
|
134
|
+
<tr>
|
|
135
|
+
<td class="mono">{entry.name}</td>
|
|
136
|
+
<td class="mono">
|
|
137
|
+
{#if editing === entry.name}
|
|
138
|
+
<input
|
|
139
|
+
type="text"
|
|
140
|
+
bind:value={editRefersTo}
|
|
141
|
+
aria-label="Refers to"
|
|
142
|
+
spellcheck="false"
|
|
143
|
+
onkeydown={(e) => { if (e.key === 'Enter') { e.preventDefault(); saveEdit() } if (e.key === 'Escape') { e.stopPropagation(); editing = null } }}
|
|
144
|
+
/>
|
|
145
|
+
{:else}
|
|
146
|
+
{entry.refersTo}
|
|
147
|
+
{/if}
|
|
148
|
+
</td>
|
|
149
|
+
<td class="num">{valueOf(entry)}</td>
|
|
150
|
+
<td class="actions">
|
|
151
|
+
{#if editing === entry.name}
|
|
152
|
+
<button type="button" class="link" onclick={saveEdit}>Save</button>
|
|
153
|
+
<button type="button" class="link" onclick={() => (editing = null)}>Cancel</button>
|
|
154
|
+
{:else}
|
|
155
|
+
<button type="button" class="link" onclick={() => startEdit(entry)}>Edit</button>
|
|
156
|
+
<button type="button" class="link" onclick={() => remove(entry.name)}>Delete</button>
|
|
157
|
+
{/if}
|
|
158
|
+
</td>
|
|
159
|
+
</tr>
|
|
160
|
+
{:else}
|
|
161
|
+
<tr><td colspan="4" class="empty">No defined names. Add one below.</td></tr>
|
|
162
|
+
{/each}
|
|
163
|
+
</tbody>
|
|
164
|
+
</table>
|
|
165
|
+
|
|
166
|
+
<form class="new" onsubmit={(e) => { e.preventDefault(); add() }}>
|
|
167
|
+
<label>
|
|
168
|
+
<span>Name:</span>
|
|
169
|
+
<input type="text" bind:value={newName} placeholder="TaxRate" spellcheck="false" />
|
|
170
|
+
</label>
|
|
171
|
+
<label>
|
|
172
|
+
<span>Refers to:</span>
|
|
173
|
+
<input type="text" bind:value={newRefersTo} placeholder="Inputs!B3 or B2:B13" spellcheck="false" />
|
|
174
|
+
</label>
|
|
175
|
+
<button type="submit" class="btn">New</button>
|
|
176
|
+
</form>
|
|
177
|
+
{#if problem}<p class="status problem" role="alert">{problem}</p>{/if}
|
|
178
|
+
</div>
|
|
179
|
+
{#snippet footer()}
|
|
180
|
+
<div class="sv-sheet-dialog-buttons">
|
|
181
|
+
<button type="button" class="btn" onclick={close}>Close</button>
|
|
182
|
+
</div>
|
|
183
|
+
{/snippet}
|
|
184
|
+
</SvModal>
|
|
185
|
+
|
|
186
|
+
<style>
|
|
187
|
+
.names { width: 100%; border-collapse: collapse; }
|
|
188
|
+
.names th {
|
|
189
|
+
text-align: left;
|
|
190
|
+
font-weight: 600;
|
|
191
|
+
color: var(--sg-muted, #616161);
|
|
192
|
+
padding: 4px 8px;
|
|
193
|
+
border-bottom: 1px solid var(--sg-border, #d1d1d1);
|
|
194
|
+
}
|
|
195
|
+
.names td { padding: 4px 8px; border-bottom: 1px solid var(--sg-border, #e5e5e5); vertical-align: middle; }
|
|
196
|
+
.mono { font-family: ui-monospace, Consolas, monospace; font-size: 12px; }
|
|
197
|
+
.num { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
|
|
198
|
+
.actions { display: flex; gap: 8px; justify-content: flex-end; white-space: nowrap; }
|
|
199
|
+
.empty { text-align: center; color: var(--sg-muted, #616161); }
|
|
200
|
+
.link {
|
|
201
|
+
padding: 0;
|
|
202
|
+
font: inherit;
|
|
203
|
+
color: var(--sg-accent, #217346);
|
|
204
|
+
background: none;
|
|
205
|
+
border: 0;
|
|
206
|
+
cursor: pointer;
|
|
207
|
+
}
|
|
208
|
+
.link:hover { text-decoration: underline; }
|
|
209
|
+
.new { display: grid; grid-template-columns: 1fr 1.6fr auto; gap: 8px; align-items: end; }
|
|
210
|
+
.new label { display: flex; flex-direction: column; gap: 4px; }
|
|
211
|
+
.new .btn {
|
|
212
|
+
height: 26px;
|
|
213
|
+
padding: 0 14px;
|
|
214
|
+
font: inherit;
|
|
215
|
+
color: var(--sg-fg, #242424);
|
|
216
|
+
background: var(--sg-bg, #fff);
|
|
217
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
218
|
+
border-radius: var(--sg-radius, 3px);
|
|
219
|
+
cursor: pointer;
|
|
220
|
+
}
|
|
221
|
+
.problem { color: var(--sg-danger, #dc2626); }
|
|
222
|
+
@media (max-width: 560px) {
|
|
223
|
+
.new { grid-template-columns: 1fr; }
|
|
224
|
+
}
|
|
225
|
+
</style>
|