@svgrid/enterprise 3.0.1 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +94 -24
- package/README.md +36 -4
- package/dist/SvAdvancedFilter.svelte +1 -1
- package/dist/SvAlertsManager.svelte +2 -1
- package/dist/SvBoard.svelte +2 -1
- package/dist/SvExportMenu.svelte +4 -1
- package/dist/SvExportMenu.svelte.d.ts +0 -13
- package/dist/SvExpressionEditor.svelte +3 -3
- package/dist/SvFormulaBar.svelte +680 -0
- package/dist/SvFormulaBar.svelte.d.ts +69 -0
- package/dist/SvGridAlerts.svelte +49 -9
- package/dist/SvGridBoard.svelte +13 -8
- package/dist/SvGridBulkEditDrawer.svelte +26 -2
- package/dist/SvGridEditPanel.svelte +3 -0
- package/dist/SvGridScheduler.svelte +69 -40
- package/dist/SvGridSelectionBar.svelte +10 -3
- package/dist/SvPivotDesigner.svelte +263 -54
- package/dist/SvPivotDesigner.svelte.d.ts +27 -20
- package/dist/SvRibbonIcon.svelte +46 -0
- package/dist/SvRibbonIcon.svelte.d.ts +17 -0
- package/dist/SvSchemaChart.svelte +4 -2
- package/dist/SvSheet.svelte +7914 -0
- package/dist/SvSheet.svelte.d.ts +215 -0
- package/dist/SvSheetChartSetup.svelte +151 -0
- package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
- package/dist/SvSheetComment.svelte +283 -0
- package/dist/SvSheetComment.svelte.d.ts +22 -0
- package/dist/SvSheetConditionalFormat.svelte +159 -0
- package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
- package/dist/SvSheetDataValidation.svelte +273 -0
- package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
- package/dist/SvSheetEditRanges.svelte +217 -0
- package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
- package/dist/SvSheetErrors.svelte +125 -0
- package/dist/SvSheetErrors.svelte.d.ts +20 -0
- package/dist/SvSheetEvaluate.svelte +133 -0
- package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
- package/dist/SvSheetFilterMenu.svelte +320 -0
- package/dist/SvSheetFilterMenu.svelte.d.ts +22 -0
- package/dist/SvSheetFindReplace.svelte +132 -0
- package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
- package/dist/SvSheetFormatCells.svelte +465 -0
- package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
- package/dist/SvSheetGoalSeek.svelte +145 -0
- package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
- package/dist/SvSheetInsertFunction.svelte +149 -0
- package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
- package/dist/SvSheetIteration.svelte +81 -0
- package/dist/SvSheetIteration.svelte.d.ts +10 -0
- package/dist/SvSheetLink.svelte +99 -0
- package/dist/SvSheetLink.svelte.d.ts +17 -0
- package/dist/SvSheetListPicker.svelte +91 -0
- package/dist/SvSheetListPicker.svelte.d.ts +10 -0
- package/dist/SvSheetManageRules.svelte +187 -0
- package/dist/SvSheetManageRules.svelte.d.ts +16 -0
- package/dist/SvSheetNameManager.svelte +227 -0
- package/dist/SvSheetNameManager.svelte.d.ts +11 -0
- package/dist/SvSheetPageSetup.svelte +159 -0
- package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
- package/dist/SvSheetPasteSpecial.svelte +107 -0
- package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
- package/dist/SvSheetPivot.svelte +220 -0
- package/dist/SvSheetPivot.svelte.d.ts +21 -0
- package/dist/SvSheetProtectSheet.svelte +81 -0
- package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
- package/dist/SvSheetRemoveDuplicates.svelte +152 -0
- package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
- package/dist/SvSheetRibbon.svelte +1254 -0
- package/dist/SvSheetRibbon.svelte.d.ts +34 -0
- package/dist/SvSheetSizeDialog.svelte +60 -0
- package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
- package/dist/SvSheetSort.svelte +218 -0
- package/dist/SvSheetSort.svelte.d.ts +28 -0
- package/dist/SvSheetSparklines.svelte +135 -0
- package/dist/SvSheetSparklines.svelte.d.ts +14 -0
- package/dist/SvSheetTable.svelte +160 -0
- package/dist/SvSheetTable.svelte.d.ts +24 -0
- package/dist/SvSheetTabs.svelte +571 -0
- package/dist/SvSheetTabs.svelte.d.ts +50 -0
- package/dist/SvSheetTabs.test-harness.svelte.d.ts +17 -0
- package/dist/SvSheetTabs.test-harness.svelte.js +22 -0
- package/dist/SvSheetTextToColumns.svelte +172 -0
- package/dist/SvSheetTextToColumns.svelte.d.ts +13 -0
- package/dist/SvSheetValidationAlert.svelte +85 -0
- package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
- package/dist/advanced-filter-enable.js +1 -1
- package/dist/alerts/alert-engine.d.ts +6 -0
- package/dist/alerts/alert-engine.js +21 -4
- package/dist/alerts/alert-formats.js +2 -0
- package/dist/alerts/alert-types.d.ts +1 -1
- package/dist/alerts.d.ts +1 -1
- package/dist/alerts.js +2 -2
- package/dist/board.js +2 -2
- package/dist/bulk-edit.d.ts +3 -1
- package/dist/bulk-edit.js +1 -1
- package/dist/cdn/svgrid-enterprise.svelte-external.js +43538 -6539
- package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
- package/dist/designer/assets/SvChartMenu-BDoeqGz6.js +1 -0
- package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
- package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
- package/dist/designer/assets/SvDateTimePicker-DCPg7WGN.js +1 -0
- package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
- package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
- package/dist/designer/assets/SvGridChart-Cy1ATrWh.js +3 -0
- package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
- package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
- package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
- package/dist/designer/assets/SvGridChartPanel-CATdVc9X.js +4 -0
- package/dist/designer/assets/{SvGridChartView-DUc-1RUf.css → SvGridChartView-7msfnWZT.css} +1 -1
- package/dist/designer/assets/SvGridChartView-CmsZtCED.js +1 -0
- package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
- package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
- package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
- package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
- package/dist/designer/assets/SvTabs-2mHC6oaz.js +1 -0
- package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
- package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
- package/dist/designer/assets/chart-Cn7MnNqA.js +1 -0
- package/dist/designer/assets/chart-export-B6bkQ3X8.js +11 -0
- package/dist/designer/assets/chart-export-pdf-BbA28-gt.js +11 -0
- package/dist/designer/assets/chart-panel-messages-Dz7PTIqT.js +1 -0
- package/dist/designer/assets/chart-summary-BD1qYB2R.js +1 -0
- package/dist/designer/assets/chart-trend-B8xr5LuD.js +1 -0
- package/dist/designer/assets/chart-validate-BMqM-qkF.js +1 -0
- package/dist/designer/assets/column-resize-BYDzR1Ve.js +1 -0
- package/dist/designer/assets/date-format-B8JbEtIG.js +1 -0
- package/dist/designer/assets/date-format-DKS-z0xS.css +1 -0
- package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
- package/dist/designer/assets/editor-contract-Bpoa7A5g.js +1 -0
- package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
- package/dist/designer/assets/focus-trap-V2-6Fy9I.js +1 -0
- package/dist/designer/assets/{index-C_a9Cj8Y.js → index-D5bVbuzI.js} +318 -315
- package/dist/designer/assets/index-_JVFxt02.css +1 -0
- package/dist/designer/assets/list-option-BP_dWS66.js +1 -0
- package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
- package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
- package/dist/designer/assets/src-CITpcm6b.js +1 -0
- package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
- package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
- package/dist/designer/index.html +29 -19
- package/dist/export-pdf.d.ts +164 -0
- package/dist/export-pdf.js +346 -15
- package/dist/export.js +25 -10
- package/dist/gantt/SvGridGantt.svelte +2890 -0
- package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
- package/dist/gantt/gantt-config.d.ts +73 -0
- package/dist/gantt/gantt-config.js +1 -0
- package/dist/gantt/gantt-critical-path.d.ts +67 -0
- package/dist/gantt/gantt-critical-path.js +207 -0
- package/dist/gantt/gantt-model.d.ts +257 -0
- package/dist/gantt/gantt-model.js +651 -0
- package/dist/gantt/gantt-resources.d.ts +59 -0
- package/dist/gantt/gantt-resources.js +71 -0
- package/dist/gantt/gantt.d.ts +7 -0
- package/dist/gantt/gantt.js +36 -0
- package/dist/gantt/index.d.ts +15 -0
- package/dist/gantt/index.js +22 -0
- package/dist/gantt/timeline-arrows.d.ts +102 -0
- package/dist/gantt/timeline-arrows.js +181 -0
- package/dist/import.d.ts +2 -2
- package/dist/import.js +1 -1
- package/dist/index.d.ts +93 -3
- package/dist/index.js +107 -3
- package/dist/install.js +13 -1
- package/dist/license-core.d.ts +17 -1
- package/dist/license-core.js +16 -5
- package/dist/license.d.ts +18 -2
- package/dist/license.js +71 -6
- package/dist/node/studio.js +203 -9
- package/dist/pivot-chart.d.ts +25 -1
- package/dist/pivot-chart.js +25 -69
- package/dist/pivot-enable.js +2 -2
- package/dist/scheduler-dependencies.d.ts +35 -0
- package/dist/scheduler-dependencies.js +36 -1
- package/dist/scheduler.js +2 -2
- package/dist/selection-bar.js +2 -2
- package/dist/server/SvGroupCell.svelte +213 -0
- package/dist/server/SvGroupCell.svelte.d.ts +62 -0
- package/dist/server/SvRowGroupPanel.svelte +322 -0
- package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
- package/dist/server/enable.d.ts +17 -0
- package/dist/server/enable.js +49 -0
- package/dist/server/index.d.ts +22 -0
- package/dist/server/index.js +24 -0
- package/dist/server/messages.d.ts +45 -0
- package/dist/server/messages.js +35 -0
- package/dist/server/server-group-model.d.ts +104 -0
- package/dist/server/server-group-model.js +272 -0
- package/dist/server/server-pivot.d.ts +46 -0
- package/dist/server/server-pivot.js +57 -0
- package/dist/server/server-row-model.d.ts +547 -0
- package/dist/server/server-row-model.js +1551 -0
- package/dist/server/server-selection.d.ts +99 -0
- package/dist/server/server-selection.js +215 -0
- package/dist/server/svgrid-adapter.d.ts +155 -0
- package/dist/server/svgrid-adapter.js +202 -0
- package/dist/sheet/address.d.ts +43 -0
- package/dist/sheet/address.js +81 -0
- package/dist/sheet/ast.d.ts +138 -0
- package/dist/sheet/ast.js +70 -0
- package/dist/sheet/auto-filter.d.ts +120 -0
- package/dist/sheet/auto-filter.js +295 -0
- package/dist/sheet/autocomplete.d.ts +51 -0
- package/dist/sheet/autocomplete.js +248 -0
- package/dist/sheet/cell-images.d.ts +39 -0
- package/dist/sheet/cell-images.js +90 -0
- package/dist/sheet/cell-types.d.ts +58 -0
- package/dist/sheet/cell-types.js +96 -0
- package/dist/sheet/coerce.d.ts +71 -0
- package/dist/sheet/coerce.js +289 -0
- package/dist/sheet/commands.d.ts +89 -0
- package/dist/sheet/commands.js +230 -0
- package/dist/sheet/comments.d.ts +63 -0
- package/dist/sheet/comments.js +131 -0
- package/dist/sheet/conditional-formats.d.ts +167 -0
- package/dist/sheet/conditional-formats.js +341 -0
- package/dist/sheet/csv.d.ts +32 -0
- package/dist/sheet/csv.js +158 -0
- package/dist/sheet/culture.d.ts +87 -0
- package/dist/sheet/culture.js +247 -0
- package/dist/sheet/delta.d.ts +102 -0
- package/dist/sheet/delta.js +203 -0
- package/dist/sheet/deps.d.ts +104 -0
- package/dist/sheet/deps.js +274 -0
- package/dist/sheet/document.d.ts +252 -0
- package/dist/sheet/document.js +465 -0
- package/dist/sheet/edit-keys.d.ts +14 -0
- package/dist/sheet/edit-keys.js +40 -0
- package/dist/sheet/engine.d.ts +67 -0
- package/dist/sheet/engine.js +19 -0
- package/dist/sheet/entry.d.ts +35 -0
- package/dist/sheet/entry.js +226 -0
- package/dist/sheet/error-check.d.ts +49 -0
- package/dist/sheet/error-check.js +83 -0
- package/dist/sheet/evaluate-steps.d.ts +48 -0
- package/dist/sheet/evaluate-steps.js +196 -0
- package/dist/sheet/evaluate.d.ts +128 -0
- package/dist/sheet/evaluate.js +1049 -0
- package/dist/sheet/filter-files.d.ts +37 -0
- package/dist/sheet/filter-files.js +465 -0
- package/dist/sheet/find-replace.d.ts +62 -0
- package/dist/sheet/find-replace.js +152 -0
- package/dist/sheet/format-store.d.ts +114 -0
- package/dist/sheet/format-store.js +243 -0
- package/dist/sheet/freeze.d.ts +54 -0
- package/dist/sheet/freeze.js +58 -0
- package/dist/sheet/from-rows.d.ts +14 -0
- package/dist/sheet/from-rows.js +50 -0
- package/dist/sheet/function-catalog.d.ts +10 -0
- package/dist/sheet/function-catalog.js +385 -0
- package/dist/sheet/functions.d.ts +28 -0
- package/dist/sheet/functions.js +634 -0
- package/dist/sheet/goal-seek.d.ts +73 -0
- package/dist/sheet/goal-seek.js +153 -0
- package/dist/sheet/index.d.ts +80 -0
- package/dist/sheet/index.js +80 -0
- package/dist/sheet/links.d.ts +57 -0
- package/dist/sheet/links.js +174 -0
- package/dist/sheet/merges.d.ts +71 -0
- package/dist/sheet/merges.js +137 -0
- package/dist/sheet/messages.d.ts +778 -0
- package/dist/sheet/messages.js +806 -0
- package/dist/sheet/names.d.ts +31 -0
- package/dist/sheet/names.js +87 -0
- package/dist/sheet/navigate.d.ts +52 -0
- package/dist/sheet/navigate.js +135 -0
- package/dist/sheet/number-format.d.ts +110 -0
- package/dist/sheet/number-format.js +905 -0
- package/dist/sheet/objects.d.ts +106 -0
- package/dist/sheet/objects.js +149 -0
- package/dist/sheet/ods-document.d.ts +44 -0
- package/dist/sheet/ods-document.js +1275 -0
- package/dist/sheet/open-file.d.ts +26 -0
- package/dist/sheet/open-file.js +56 -0
- package/dist/sheet/outline.d.ts +82 -0
- package/dist/sheet/outline.js +228 -0
- package/dist/sheet/packs/array.d.ts +16 -0
- package/dist/sheet/packs/array.js +172 -0
- package/dist/sheet/packs/database.d.ts +42 -0
- package/dist/sheet/packs/database.js +142 -0
- package/dist/sheet/packs/engineering.d.ts +2 -0
- package/dist/sheet/packs/engineering.js +296 -0
- package/dist/sheet/packs/financial.d.ts +5 -0
- package/dist/sheet/packs/financial.js +220 -0
- package/dist/sheet/packs/math-stats.d.ts +2 -0
- package/dist/sheet/packs/math-stats.js +372 -0
- package/dist/sheet/packs/special.d.ts +44 -0
- package/dist/sheet/packs/special.js +187 -0
- package/dist/sheet/packs/stats-dist.d.ts +2 -0
- package/dist/sheet/packs/stats-dist.js +785 -0
- package/dist/sheet/packs/text-date.d.ts +2 -0
- package/dist/sheet/packs/text-date.js +332 -0
- package/dist/sheet/packs/trig.d.ts +2 -0
- package/dist/sheet/packs/trig.js +73 -0
- package/dist/sheet/page-setup.d.ts +73 -0
- package/dist/sheet/page-setup.js +73 -0
- package/dist/sheet/palette.d.ts +19 -0
- package/dist/sheet/palette.js +84 -0
- package/dist/sheet/parse.d.ts +13 -0
- package/dist/sheet/parse.js +140 -0
- package/dist/sheet/paste-special.d.ts +186 -0
- package/dist/sheet/paste-special.js +601 -0
- package/dist/sheet/pivot-range.d.ts +160 -0
- package/dist/sheet/pivot-range.js +333 -0
- package/dist/sheet/presence.d.ts +73 -0
- package/dist/sheet/presence.js +79 -0
- package/dist/sheet/print.d.ts +104 -0
- package/dist/sheet/print.js +169 -0
- package/dist/sheet/protection.d.ts +75 -0
- package/dist/sheet/protection.js +101 -0
- package/dist/sheet/rects.d.ts +45 -0
- package/dist/sheet/rects.js +112 -0
- package/dist/sheet/refs.d.ts +130 -0
- package/dist/sheet/refs.js +413 -0
- package/dist/sheet/ribbon-icons.d.ts +31 -0
- package/dist/sheet/ribbon-icons.js +536 -0
- package/dist/sheet/ribbon.d.ts +173 -0
- package/dist/sheet/ribbon.js +1054 -0
- package/dist/sheet/sheet-kinds.d.ts +74 -0
- package/dist/sheet/sheet-kinds.js +91 -0
- package/dist/sheet/shortcuts.d.ts +174 -0
- package/dist/sheet/shortcuts.js +674 -0
- package/dist/sheet/sort.d.ts +51 -0
- package/dist/sheet/sort.js +107 -0
- package/dist/sheet/sparklines.d.ts +111 -0
- package/dist/sheet/sparklines.js +204 -0
- package/dist/sheet/structure.d.ts +87 -0
- package/dist/sheet/structure.js +166 -0
- package/dist/sheet/table-styles.d.ts +74 -0
- package/dist/sheet/table-styles.js +152 -0
- package/dist/sheet/tables.d.ts +89 -0
- package/dist/sheet/tables.js +178 -0
- package/dist/sheet/tokenize.d.ts +71 -0
- package/dist/sheet/tokenize.js +355 -0
- package/dist/sheet/transforms.d.ts +76 -0
- package/dist/sheet/transforms.js +154 -0
- package/dist/sheet/validation.d.ts +108 -0
- package/dist/sheet/validation.js +278 -0
- package/dist/sheet/workbook.d.ts +217 -0
- package/dist/sheet/workbook.js +1120 -0
- package/dist/sheet/xls-cfb.d.ts +32 -0
- package/dist/sheet/xls-cfb.js +290 -0
- package/dist/sheet/xls-document.d.ts +10 -0
- package/dist/sheet/xls-document.js +1243 -0
- package/dist/sheet/xls-formula.d.ts +40 -0
- package/dist/sheet/xls-formula.js +569 -0
- package/dist/sheet/xlsx-document.d.ts +108 -0
- package/dist/sheet/xlsx-document.js +1849 -0
- package/dist/sheet/xlsx-drawing.d.ts +99 -0
- package/dist/sheet/xlsx-drawing.js +420 -0
- package/dist/sheet-enable.d.ts +6 -0
- package/dist/sheet-enable.js +45 -0
- package/dist/sheet-text.d.ts +7 -0
- package/dist/sheet-text.js +29 -0
- package/dist/sources/auth-supabase.js +2 -2
- package/dist/sources/realtime-supabase.js +2 -2
- package/dist/sources/rest.d.ts +6 -2
- package/dist/sources/rest.js +42 -7
- package/dist/sources/supabase.d.ts +10 -1
- package/dist/sources/supabase.js +73 -40
- package/dist/studio/emit-project.js +14 -1
- package/dist/studio/index.js +1 -1
- package/dist/studio/project.d.ts +11 -2
- package/dist/studio/project.js +5 -2
- package/dist/studio/ui-components.generated.js +170 -3
- package/dist/sveltekit/in-memory.d.ts +2 -2
- package/dist/sveltekit/in-memory.js +125 -4
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/dist/sveltekit/query-plan.d.ts +50 -4
- package/dist/sveltekit/query-plan.js +25 -3
- package/dist/sveltekit/sql-source.d.ts +6 -0
- package/dist/sveltekit/sql-source.js +34 -6
- package/dist/sveltekit/sql.d.ts +31 -0
- package/dist/sveltekit/sql.js +135 -25
- package/dist/sveltekit/transport.d.ts +10 -2
- package/dist/sveltekit/transport.js +30 -6
- package/dist/upgrade-prompt.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/watermark.js +35 -2
- package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
- package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
- package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
- package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
- package/dist/wc/SvField-B_kurx_P.js +149 -0
- package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
- package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
- package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
- package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
- package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
- package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
- package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
- package/dist/wc/SvModal-DrfOYYyX.js +189 -0
- package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
- package/dist/wc/chart-6OXlybVT.js +4341 -0
- package/dist/wc/chart-export-CeSADGfi.js +135 -0
- package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
- package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
- package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
- package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
- package/dist/wc/client-DQIzjDBG.js +3064 -0
- package/dist/wc/column-resize-DUPgynvc.js +101 -0
- package/dist/wc/date-format-DS-z_h9v.js +1130 -0
- package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
- package/dist/wc/editor-contract-peBDxir_.js +22 -0
- package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
- package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
- package/dist/wc/list-option-DrRyivWp.js +82 -0
- package/dist/wc/popover-WsGlvtQv.js +69 -0
- package/dist/wc/positioning-BiKLfu1E.js +112 -0
- package/dist/wc/react.d.ts +41 -0
- package/dist/wc/react.js +90 -0
- package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
- package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
- package/dist/wc/row-resize-limG_N1z.js +111 -0
- package/dist/wc/sv-sheet-element.d.ts +97 -0
- package/dist/wc/sv-sheet-element.js +44213 -0
- package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
- package/dist/wc/validate-BqDthkNr.js +88 -0
- package/dist/wc/vue.d.ts +31 -0
- package/dist/wc/vue.js +75 -0
- package/package.json +36 -6
- package/dist/designer/assets/GridMenus-B1JtIN21.js +0 -8
- package/dist/designer/assets/SvDateRangeInput-CjO7nn_x.js +0 -1
- package/dist/designer/assets/SvDateTimePicker-ByBD_ov6.js +0 -1
- package/dist/designer/assets/SvField-YDLipR6O.css +0 -1
- package/dist/designer/assets/SvField-cj1PFNgZ.js +0 -1
- package/dist/designer/assets/SvGridCellEditor-0W1L2hJ1.js +0 -2
- package/dist/designer/assets/SvGridChart-DBOR4xcz.js +0 -2
- package/dist/designer/assets/SvGridChart-fkMWeh1J.css +0 -1
- package/dist/designer/assets/SvGridChartPanel-symrhNnR.js +0 -11
- package/dist/designer/assets/SvGridChartView-BmRxq6mU.js +0 -1
- package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
- package/dist/designer/assets/SvListBox-1oUF6Iav.js +0 -110
- package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
- package/dist/designer/assets/chart-DXFganU8.js +0 -1
- package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
- package/dist/designer/assets/date-format-DGagAqRc.css +0 -1
- package/dist/designer/assets/date-format-onlYDsrY.js +0 -1
- package/dist/designer/assets/easing-zaypKrr0.js +0 -3
- package/dist/designer/assets/index-k2stW6L8.css +0 -1
- package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
- package/dist/designer/assets/src-D9p27OGC.js +0 -58
- package/dist/designer/assets/validate-h-aslRV9.js +0 -1
|
@@ -0,0 +1,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,60 @@
|
|
|
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 { useSheetText } from './sheet-text'
|
|
8
|
+
import { SvModal } from '@svgrid/grid'
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
open?: boolean
|
|
12
|
+
title: string
|
|
13
|
+
label: string
|
|
14
|
+
value: number
|
|
15
|
+
onApply: (px: number) => void
|
|
16
|
+
onClose?: () => void
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let { open = $bindable(false), title, label, value, onApply, onClose }: Props = $props()
|
|
20
|
+
const t = useSheetText()
|
|
21
|
+
|
|
22
|
+
let draft = $state('')
|
|
23
|
+
let input = $state<HTMLInputElement | null>(null)
|
|
24
|
+
|
|
25
|
+
$effect(() => {
|
|
26
|
+
if (!open) return
|
|
27
|
+
draft = String(Math.round(value))
|
|
28
|
+
queueMicrotask(() => { input?.focus(); input?.select() })
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
const px = $derived(Number(draft))
|
|
32
|
+
const valid = $derived(Number.isFinite(px) && px >= 4 && px <= 2000)
|
|
33
|
+
|
|
34
|
+
function ok() {
|
|
35
|
+
if (!valid) return
|
|
36
|
+
onApply(Math.round(px))
|
|
37
|
+
open = false
|
|
38
|
+
onClose?.()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function close() {
|
|
42
|
+
open = false
|
|
43
|
+
onClose?.()
|
|
44
|
+
}
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<SvModal bind:open onClose={onClose} {title} size="sm">
|
|
48
|
+
<form class="sv-sheet-dialog" onsubmit={(e) => { e.preventDefault(); ok() }}>
|
|
49
|
+
<label class="field auto">
|
|
50
|
+
<span>{label}</span>
|
|
51
|
+
<input bind:this={input} type="number" min="4" max="2000" bind:value={draft} />
|
|
52
|
+
</label>
|
|
53
|
+
</form>
|
|
54
|
+
{#snippet footer()}
|
|
55
|
+
<div class="sv-sheet-dialog-buttons">
|
|
56
|
+
<button type="button" class="btn primary" onclick={ok} disabled={!valid}>{t('ok')}</button>
|
|
57
|
+
<button type="button" class="btn" onclick={close}>{t('cancel')}</button>
|
|
58
|
+
</div>
|
|
59
|
+
{/snippet}
|
|
60
|
+
</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,218 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Sort dialog: a level per key, each a column and an order, over
|
|
4
|
+
* the block the shell worked out, with "My data has headers" deciding
|
|
5
|
+
* whether the first row is named in the column lists or sorted with the
|
|
6
|
+
* rest. Add Level, Delete Level, OK; the shell does the sorting, in one
|
|
7
|
+
* undo, from the keys handed back.
|
|
8
|
+
*/
|
|
9
|
+
import { useSheetText } from './sheet-text'
|
|
10
|
+
import { untrack } from 'svelte'
|
|
11
|
+
import { SvModal } from '@svgrid/grid'
|
|
12
|
+
import type { Workbook } from './sheet/workbook'
|
|
13
|
+
import type { SortKey } from './sheet/sort'
|
|
14
|
+
import { colToLetters } from './sheet/address'
|
|
15
|
+
|
|
16
|
+
type Block = { top: number; left: number; bottom: number; right: number }
|
|
17
|
+
|
|
18
|
+
type Props = {
|
|
19
|
+
open?: boolean
|
|
20
|
+
workbook: Workbook
|
|
21
|
+
/** The block to sort, and whether its first row looks like headers. */
|
|
22
|
+
block: Block
|
|
23
|
+
headerGuess: boolean
|
|
24
|
+
/** The column the dialog opens on: the active cell's. */
|
|
25
|
+
activeCol: number
|
|
26
|
+
/**
|
|
27
|
+
* A cell's fill or font colour, for a level that sorts on one. Without
|
|
28
|
+
* it the Sort On list offers values only, since there would be no
|
|
29
|
+
* colours to offer.
|
|
30
|
+
*/
|
|
31
|
+
colourAt?: (row: number, col: number, on: 'fill' | 'color') => string | null
|
|
32
|
+
onApply: (keys: SortKey[], hasHeaders: boolean) => void
|
|
33
|
+
onClose?: () => void
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let { open = $bindable(false), workbook, block, headerGuess, activeCol, colourAt, onApply, onClose }: Props = $props()
|
|
37
|
+
const t = useSheetText()
|
|
38
|
+
|
|
39
|
+
let levels = $state<SortKey[]>([])
|
|
40
|
+
let hasHeaders = $state(true)
|
|
41
|
+
|
|
42
|
+
const raw = (r: number, c: number) => workbook.getRaw(workbook.active, r, c)
|
|
43
|
+
|
|
44
|
+
/** The column list: the header text when the block has headers, else the letter. */
|
|
45
|
+
const columns = $derived.by(() =>
|
|
46
|
+
Array.from({ length: block.right - block.left + 1 }, (_, i) => {
|
|
47
|
+
const col = block.left + i
|
|
48
|
+
const letter = t('sort.columnLetter', { letter: colToLetters(col) })
|
|
49
|
+
return { col, label: hasHeaders ? raw(block.top, col) || letter : letter }
|
|
50
|
+
}),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
$effect(() => {
|
|
54
|
+
if (!open) return
|
|
55
|
+
untrack(() => {
|
|
56
|
+
hasHeaders = headerGuess
|
|
57
|
+
levels = [{ col: Math.min(Math.max(activeCol, block.left), block.right), direction: 'asc', on: 'value' }]
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The colours a level's column carries, each once. Excel offers exactly
|
|
63
|
+
* these, because a colour that is nowhere in the column would sort
|
|
64
|
+
* nothing.
|
|
65
|
+
*/
|
|
66
|
+
function coloursIn(col: number, on: 'fill' | 'color'): string[] {
|
|
67
|
+
if (!colourAt) return []
|
|
68
|
+
const seen: string[] = []
|
|
69
|
+
for (let r = block.top + (hasHeaders ? 1 : 0); r <= block.bottom; r += 1) {
|
|
70
|
+
const colour = colourAt(r, col, on)?.trim().toLowerCase()
|
|
71
|
+
if (colour && !seen.includes(colour)) seen.push(colour)
|
|
72
|
+
}
|
|
73
|
+
return seen
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Keep a level's colour one the column actually carries. */
|
|
77
|
+
function onSortOnChange(level: SortKey) {
|
|
78
|
+
if (level.on === 'value') { level.colour = undefined; return }
|
|
79
|
+
const colours = coloursIn(level.col, level.on === 'color' ? 'color' : 'fill')
|
|
80
|
+
if (!level.colour || !colours.includes(level.colour)) level.colour = colours[0]
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function addLevel() {
|
|
84
|
+
// The next column not yet used, or the first one when all are.
|
|
85
|
+
const used = new Set(levels.map((l) => l.col))
|
|
86
|
+
const free = columns.find((c) => !used.has(c.col)) ?? columns[0]
|
|
87
|
+
if (!free) return
|
|
88
|
+
levels = [...levels, { col: free.col, direction: 'asc', on: 'value' }]
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function deleteLevel(index: number) {
|
|
92
|
+
if (levels.length <= 1) return
|
|
93
|
+
levels = levels.filter((_, i) => i !== index)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function ok() {
|
|
97
|
+
if (!levels.length) return
|
|
98
|
+
onApply(levels.map((l) => ({ ...l })), hasHeaders)
|
|
99
|
+
open = false
|
|
100
|
+
onClose?.()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function close() {
|
|
104
|
+
open = false
|
|
105
|
+
onClose?.()
|
|
106
|
+
}
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<SvModal bind:open onClose={onClose} title={t('sort.title')} size="sm" width={460}>
|
|
110
|
+
<form class="sv-sheet-dialog sort" onsubmit={(e) => { e.preventDefault(); ok() }}>
|
|
111
|
+
<div class="toolbar">
|
|
112
|
+
<button type="button" class="btn" onclick={addLevel} disabled={levels.length >= columns.length}>{t('sort.addLevel')}</button>
|
|
113
|
+
<button type="button" class="btn" onclick={() => deleteLevel(levels.length - 1)} disabled={levels.length <= 1}>{t('sort.deleteLevel')}</button>
|
|
114
|
+
<span class="spacer"></span>
|
|
115
|
+
<label class="check"><input type="checkbox" bind:checked={hasHeaders} /> {t('sort.hasHeaders')}</label>
|
|
116
|
+
</div>
|
|
117
|
+
<div class="levels" role="list" aria-label={t('sort.levels')}>
|
|
118
|
+
{#each levels as level, index (index)}
|
|
119
|
+
{@const by = t(index === 0 ? 'sort.sortBy' : 'sort.thenBy')}
|
|
120
|
+
<div class="level" role="listitem">
|
|
121
|
+
<span class="by">{by}</span>
|
|
122
|
+
<select aria-label={t('sort.column', { by })} bind:value={level.col}>
|
|
123
|
+
{#each columns as c (c.col)}<option value={c.col}>{c.label}</option>{/each}
|
|
124
|
+
</select>
|
|
125
|
+
<select
|
|
126
|
+
aria-label={t('sort.on', { by })}
|
|
127
|
+
bind:value={level.on}
|
|
128
|
+
onchange={() => onSortOnChange(level)}
|
|
129
|
+
disabled={!colourAt}
|
|
130
|
+
>
|
|
131
|
+
<option value="value">{t('sort.onValue')}</option>
|
|
132
|
+
<option value="fill">{t('sort.onFill')}</option>
|
|
133
|
+
<option value="color">{t('sort.onFont')}</option>
|
|
134
|
+
</select>
|
|
135
|
+
<select aria-label={t('sort.order', { by })} bind:value={level.direction}>
|
|
136
|
+
<option value="asc">{level.on === 'value' ? t('sort.asc') : t('sort.onTop')}</option>
|
|
137
|
+
<option value="desc">{level.on === 'value' ? t('sort.desc') : t('sort.onBottom')}</option>
|
|
138
|
+
</select>
|
|
139
|
+
{#if level.on !== 'value'}
|
|
140
|
+
{@const colours = coloursIn(level.col, level.on === 'color' ? 'color' : 'fill')}
|
|
141
|
+
<span class="colour-row">
|
|
142
|
+
<span class="by">{t('sort.colour')}</span>
|
|
143
|
+
{#if colours.length}
|
|
144
|
+
<select aria-label={t('sort.colour')} bind:value={level.colour}>
|
|
145
|
+
{#each colours as colour (colour)}<option value={colour}>{colour}</option>{/each}
|
|
146
|
+
</select>
|
|
147
|
+
<span class="swatch" style:background={level.colour} aria-hidden="true"></span>
|
|
148
|
+
{:else}
|
|
149
|
+
<span class="none">{t('sort.noColours')}</span>
|
|
150
|
+
{/if}
|
|
151
|
+
</span>
|
|
152
|
+
{/if}
|
|
153
|
+
</div>
|
|
154
|
+
{/each}
|
|
155
|
+
</div>
|
|
156
|
+
<p class="hint">
|
|
157
|
+
{t('sort.hint', { range: `${colToLetters(block.left)}${block.top + 1}:${colToLetters(block.right)}${block.bottom + 1}` })}
|
|
158
|
+
</p>
|
|
159
|
+
</form>
|
|
160
|
+
{#snippet footer()}
|
|
161
|
+
<div class="sv-sheet-dialog-buttons">
|
|
162
|
+
<button type="button" class="btn primary" onclick={ok} disabled={!levels.length}>{t('ok')}</button>
|
|
163
|
+
<button type="button" class="btn" onclick={close}>{t('cancel')}</button>
|
|
164
|
+
</div>
|
|
165
|
+
{/snippet}
|
|
166
|
+
</SvModal>
|
|
167
|
+
|
|
168
|
+
<style>
|
|
169
|
+
.toolbar {
|
|
170
|
+
display: flex;
|
|
171
|
+
align-items: center;
|
|
172
|
+
gap: 6px;
|
|
173
|
+
margin-bottom: 8px;
|
|
174
|
+
}
|
|
175
|
+
.toolbar .spacer { flex: 1; }
|
|
176
|
+
.levels {
|
|
177
|
+
display: flex;
|
|
178
|
+
flex-direction: column;
|
|
179
|
+
gap: 6px;
|
|
180
|
+
padding: 6px;
|
|
181
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
182
|
+
border-radius: 3px;
|
|
183
|
+
background: var(--sg-bg, #fff);
|
|
184
|
+
}
|
|
185
|
+
.level {
|
|
186
|
+
display: grid;
|
|
187
|
+
grid-template-columns: 64px 1fr 104px 112px;
|
|
188
|
+
align-items: center;
|
|
189
|
+
gap: 8px;
|
|
190
|
+
}
|
|
191
|
+
/* The colour a colour level sorts on, under the level it belongs to. */
|
|
192
|
+
.colour-row {
|
|
193
|
+
grid-column: 1 / -1;
|
|
194
|
+
display: grid;
|
|
195
|
+
grid-template-columns: 64px 1fr auto;
|
|
196
|
+
align-items: center;
|
|
197
|
+
gap: 8px;
|
|
198
|
+
}
|
|
199
|
+
.colour-row .swatch {
|
|
200
|
+
width: 18px;
|
|
201
|
+
height: 18px;
|
|
202
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
203
|
+
border-radius: 3px;
|
|
204
|
+
}
|
|
205
|
+
.colour-row .none { color: var(--sg-muted, #616161); font-size: 12px; }
|
|
206
|
+
.level .by { color: var(--sg-muted, #616161); }
|
|
207
|
+
.level select {
|
|
208
|
+
min-width: 0;
|
|
209
|
+
font: inherit;
|
|
210
|
+
color: inherit;
|
|
211
|
+
background: var(--sg-bg, #fff);
|
|
212
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
213
|
+
border-radius: 2px;
|
|
214
|
+
padding: 2px 4px;
|
|
215
|
+
}
|
|
216
|
+
.check { display: inline-flex; align-items: center; gap: 6px; }
|
|
217
|
+
.hint { margin: 8px 0 0; color: var(--sg-muted, #616161); font-size: 12px; }
|
|
218
|
+
</style>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Workbook } from './sheet/workbook.js';
|
|
2
|
+
import type { SortKey } from './sheet/sort.js';
|
|
3
|
+
type Block = {
|
|
4
|
+
top: number;
|
|
5
|
+
left: number;
|
|
6
|
+
bottom: number;
|
|
7
|
+
right: number;
|
|
8
|
+
};
|
|
9
|
+
type Props = {
|
|
10
|
+
open?: boolean;
|
|
11
|
+
workbook: Workbook;
|
|
12
|
+
/** The block to sort, and whether its first row looks like headers. */
|
|
13
|
+
block: Block;
|
|
14
|
+
headerGuess: boolean;
|
|
15
|
+
/** The column the dialog opens on: the active cell's. */
|
|
16
|
+
activeCol: number;
|
|
17
|
+
/**
|
|
18
|
+
* A cell's fill or font colour, for a level that sorts on one. Without
|
|
19
|
+
* it the Sort On list offers values only, since there would be no
|
|
20
|
+
* colours to offer.
|
|
21
|
+
*/
|
|
22
|
+
colourAt?: (row: number, col: number, on: 'fill' | 'color') => string | null;
|
|
23
|
+
onApply: (keys: SortKey[], hasHeaders: boolean) => void;
|
|
24
|
+
onClose?: () => void;
|
|
25
|
+
};
|
|
26
|
+
declare const SvSheetSort: import("svelte").Component<Props, {}, "open">;
|
|
27
|
+
type SvSheetSort = ReturnType<typeof SvSheetSort>;
|
|
28
|
+
export default SvSheetSort;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Create Sparklines dialog, and its Sparkline Design tab folded
|
|
4
|
+
* into the same box: the kind, the two ranges, the colours, one scale for
|
|
5
|
+
* the group or one each. Opened by Insert > Sparklines, and again by a
|
|
6
|
+
* double-click on a cell that holds one, which is how a group is edited.
|
|
7
|
+
*/
|
|
8
|
+
import { SvModal } from '@svgrid/grid'
|
|
9
|
+
import { useSheetText } from './sheet-text'
|
|
10
|
+
import { parseRangeText, rangeText } from './sheet/protection'
|
|
11
|
+
import { SPARKLINE_TYPES, type SheetSparklineType, type SparklineGroup } from './sheet/sparklines'
|
|
12
|
+
import type { Rect } from './sheet/format-store'
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
open?: boolean
|
|
16
|
+
/** The group as it stands, new or being edited. */
|
|
17
|
+
group: SparklineGroup
|
|
18
|
+
/** True when the group is already on the sheet, which offers Delete. */
|
|
19
|
+
existing?: boolean
|
|
20
|
+
onApply: (group: SparklineGroup) => void
|
|
21
|
+
onDelete?: () => void
|
|
22
|
+
onClose?: () => void
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let { open = $bindable(false), group, existing = false, onApply, onDelete, onClose }: Props = $props()
|
|
26
|
+
const t = useSheetText()
|
|
27
|
+
|
|
28
|
+
let type = $state<SheetSparklineType>('line')
|
|
29
|
+
let data = $state('')
|
|
30
|
+
let location = $state('')
|
|
31
|
+
let colour = $state('')
|
|
32
|
+
let negative = $state('')
|
|
33
|
+
let sameScale = $state(false)
|
|
34
|
+
let markers = $state(false)
|
|
35
|
+
let error = $state('')
|
|
36
|
+
let first = $state<HTMLSelectElement | null>(null)
|
|
37
|
+
|
|
38
|
+
$effect(() => {
|
|
39
|
+
if (!open) return
|
|
40
|
+
type = group.type
|
|
41
|
+
data = rangeText([group.data])
|
|
42
|
+
location = rangeText([group.location])
|
|
43
|
+
colour = group.color ?? ''
|
|
44
|
+
negative = group.negativeColor ?? ''
|
|
45
|
+
sameScale = Boolean(group.sameScale)
|
|
46
|
+
markers = Boolean(group.markers)
|
|
47
|
+
error = ''
|
|
48
|
+
queueMicrotask(() => first?.focus())
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
/** One rectangle, or null: these two fields take a range, not a list. */
|
|
52
|
+
function oneRect(text: string): Rect | null {
|
|
53
|
+
const rects = parseRangeText(text)
|
|
54
|
+
return rects && rects.length === 1 ? rects[0]! : null
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The location has to hold one cell per line of the data. */
|
|
58
|
+
function shapesAgree(d: Rect, l: Rect): boolean {
|
|
59
|
+
const lines = l[2] - l[0] >= l[3] - l[1] ? d[2] - d[0] : d[3] - d[1]
|
|
60
|
+
const cells = Math.max(l[2] - l[0], l[3] - l[1])
|
|
61
|
+
return lines === cells
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function ok() {
|
|
65
|
+
const d = oneRect(data)
|
|
66
|
+
const l = oneRect(location)
|
|
67
|
+
if (!d || !l) { error = t('sparklines.badRange'); return }
|
|
68
|
+
if (!shapesAgree(d, l)) { error = t('sparklines.mismatch'); return }
|
|
69
|
+
const next: SparklineGroup = { ...group, type, data: d, location: l, sameScale, markers }
|
|
70
|
+
if (colour.trim()) next.color = colour.trim()
|
|
71
|
+
else delete next.color
|
|
72
|
+
if (negative.trim()) next.negativeColor = negative.trim()
|
|
73
|
+
else delete next.negativeColor
|
|
74
|
+
open = false
|
|
75
|
+
onApply(next)
|
|
76
|
+
onClose?.()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function close() {
|
|
80
|
+
open = false
|
|
81
|
+
onClose?.()
|
|
82
|
+
}
|
|
83
|
+
</script>
|
|
84
|
+
|
|
85
|
+
<SvModal bind:open onClose={onClose} title={t('sparklines.title')} size="sm">
|
|
86
|
+
<form class="sv-sheet-dialog" onsubmit={(e) => { e.preventDefault(); ok() }}>
|
|
87
|
+
<label class="field">
|
|
88
|
+
<span>{t('sparklines.type')}</span>
|
|
89
|
+
<select bind:this={first} bind:value={type}>
|
|
90
|
+
{#each SPARKLINE_TYPES as kind (kind)}<option value={kind}>{t(`sparklines.type.${kind}`)}</option>{/each}
|
|
91
|
+
</select>
|
|
92
|
+
</label>
|
|
93
|
+
<label class="field">
|
|
94
|
+
<span>{t('sparklines.data')}</span>
|
|
95
|
+
<input type="text" bind:value={data} spellcheck="false" placeholder={t('sparklines.dataPlaceholder')} />
|
|
96
|
+
</label>
|
|
97
|
+
<label class="field">
|
|
98
|
+
<span>{t('sparklines.location')}</span>
|
|
99
|
+
<input type="text" bind:value={location} spellcheck="false" placeholder={t('sparklines.locationPlaceholder')} />
|
|
100
|
+
</label>
|
|
101
|
+
<label class="field">
|
|
102
|
+
<span>{t('sparklines.colour')}</span>
|
|
103
|
+
<input type="color" value={colour || '#107c41'} oninput={(e) => (colour = e.currentTarget.value)} />
|
|
104
|
+
</label>
|
|
105
|
+
{#if type !== 'line'}
|
|
106
|
+
<label class="field">
|
|
107
|
+
<span>{t('sparklines.negativeColour')}</span>
|
|
108
|
+
<input type="color" value={negative || '#c42b1c'} oninput={(e) => (negative = e.currentTarget.value)} />
|
|
109
|
+
</label>
|
|
110
|
+
{/if}
|
|
111
|
+
<div class="checks">
|
|
112
|
+
<label class="check"><input type="checkbox" bind:checked={sameScale} /> {t('sparklines.sameScale')}</label>
|
|
113
|
+
{#if type === 'line'}
|
|
114
|
+
<label class="check"><input type="checkbox" bind:checked={markers} /> {t('sparklines.markers')}</label>
|
|
115
|
+
{/if}
|
|
116
|
+
</div>
|
|
117
|
+
{#if error}<p class="error">{error}</p>{/if}
|
|
118
|
+
<p class="hint">{t('sparklines.hint')}</p>
|
|
119
|
+
</form>
|
|
120
|
+
{#snippet footer()}
|
|
121
|
+
<div class="sv-sheet-dialog-buttons">
|
|
122
|
+
{#if existing && onDelete}
|
|
123
|
+
<button type="button" class="btn" onclick={() => { open = false; onDelete?.() }}>{t('delete')}</button>
|
|
124
|
+
{/if}
|
|
125
|
+
<span class="spacer"></span>
|
|
126
|
+
<button type="button" class="btn primary" onclick={ok}>{t('ok')}</button>
|
|
127
|
+
<button type="button" class="btn" onclick={close}>{t('cancel')}</button>
|
|
128
|
+
</div>
|
|
129
|
+
{/snippet}
|
|
130
|
+
</SvModal>
|
|
131
|
+
|
|
132
|
+
<style>
|
|
133
|
+
.spacer { flex: 1; }
|
|
134
|
+
.error { margin: 4px 0 0; color: var(--sg-danger, #c42b1c); font-size: 12px; }
|
|
135
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type SparklineGroup } from './sheet/sparklines.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
/** The group as it stands, new or being edited. */
|
|
5
|
+
group: SparklineGroup;
|
|
6
|
+
/** True when the group is already on the sheet, which offers Delete. */
|
|
7
|
+
existing?: boolean;
|
|
8
|
+
onApply: (group: SparklineGroup) => void;
|
|
9
|
+
onDelete?: () => void;
|
|
10
|
+
onClose?: () => void;
|
|
11
|
+
};
|
|
12
|
+
declare const SvSheetSparklines: import("svelte").Component<Props, {}, "open">;
|
|
13
|
+
type SvSheetSparklines = ReturnType<typeof SvSheetSparklines>;
|
|
14
|
+
export default SvSheetSparklines;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Create Table dialog: the cells, whether the first row is the
|
|
4
|
+
* header, the name the columns will be read by, and a totals row.
|
|
5
|
+
* Opened by Insert > Table or Ctrl+T, and again on a cell inside one,
|
|
6
|
+
* which is how a table is renamed or resized.
|
|
7
|
+
*/
|
|
8
|
+
import { SvModal } from '@svgrid/grid'
|
|
9
|
+
import { useSheetText } from './sheet-text'
|
|
10
|
+
import { parseRangeText, rangeText } from './sheet/protection'
|
|
11
|
+
import { isValidTableName } from './sheet/tables'
|
|
12
|
+
import {
|
|
13
|
+
TABLE_STYLES, DEFAULT_TABLE_STYLE, NO_TABLE_STYLE,
|
|
14
|
+
tableStyleColours, tableStyleLabel,
|
|
15
|
+
} from './sheet/table-styles'
|
|
16
|
+
import type { Rect } from './sheet/format-store'
|
|
17
|
+
|
|
18
|
+
type Props = {
|
|
19
|
+
open?: boolean
|
|
20
|
+
/** The block the table covers, header row included. */
|
|
21
|
+
range: Rect
|
|
22
|
+
name: string
|
|
23
|
+
headers?: boolean
|
|
24
|
+
totals?: boolean
|
|
25
|
+
existing?: boolean
|
|
26
|
+
/** The look, by Excel's name for it, or `'None'`. */
|
|
27
|
+
style?: string
|
|
28
|
+
onApply: (table: { range: Rect; name: string; headers: boolean; totals: boolean; style: string }) => void
|
|
29
|
+
onRemove?: () => void
|
|
30
|
+
onClose?: () => void
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let {
|
|
34
|
+
open = $bindable(false), range, name, headers = true, totals = false, existing = false,
|
|
35
|
+
style = DEFAULT_TABLE_STYLE, onApply, onRemove, onClose,
|
|
36
|
+
}: Props = $props()
|
|
37
|
+
const t = useSheetText()
|
|
38
|
+
|
|
39
|
+
let where = $state('')
|
|
40
|
+
let label = $state('')
|
|
41
|
+
let hasHeaders = $state(true)
|
|
42
|
+
let hasTotals = $state(false)
|
|
43
|
+
let look = $state(DEFAULT_TABLE_STYLE)
|
|
44
|
+
let error = $state('')
|
|
45
|
+
let first = $state<HTMLInputElement | null>(null)
|
|
46
|
+
|
|
47
|
+
$effect(() => {
|
|
48
|
+
if (!open) return
|
|
49
|
+
where = rangeText([range])
|
|
50
|
+
label = name
|
|
51
|
+
hasHeaders = headers
|
|
52
|
+
hasTotals = totals
|
|
53
|
+
look = style
|
|
54
|
+
error = ''
|
|
55
|
+
queueMicrotask(() => first?.focus())
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
function ok() {
|
|
59
|
+
const rects = parseRangeText(where)
|
|
60
|
+
const block = rects && rects.length === 1 ? rects[0]! : null
|
|
61
|
+
if (!block) { error = t('table.badRange'); return }
|
|
62
|
+
if (!isValidTableName(label.trim())) { error = t('table.badName'); return }
|
|
63
|
+
open = false
|
|
64
|
+
onApply({ range: block as Rect, name: label.trim(), headers: hasHeaders, totals: hasTotals, style: look })
|
|
65
|
+
onClose?.()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function close() {
|
|
69
|
+
open = false
|
|
70
|
+
onClose?.()
|
|
71
|
+
}
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<!-- Opened from inside a table it edits that table, so it does not say
|
|
75
|
+
Create: the name, the range and the style are the ones it has. -->
|
|
76
|
+
<SvModal bind:open onClose={onClose} title={t(existing ? 'table.editTitle' : 'table.title')} size="sm">
|
|
77
|
+
<form class="sv-sheet-dialog" onsubmit={(e) => { e.preventDefault(); ok() }}>
|
|
78
|
+
<label class="field">
|
|
79
|
+
<span>{t('table.range')}</span>
|
|
80
|
+
<input type="text" bind:this={first} bind:value={where} spellcheck="false" placeholder={t('table.rangePlaceholder')} />
|
|
81
|
+
</label>
|
|
82
|
+
<label class="field">
|
|
83
|
+
<span>{t('table.name')}</span>
|
|
84
|
+
<input type="text" bind:value={label} spellcheck="false" placeholder={t('table.namePlaceholder')} />
|
|
85
|
+
</label>
|
|
86
|
+
<div class="checks">
|
|
87
|
+
<label class="check"><input type="checkbox" bind:checked={hasHeaders} /> {t('table.headers')}</label>
|
|
88
|
+
<label class="check"><input type="checkbox" bind:checked={hasTotals} /> {t('table.totals')}</label>
|
|
89
|
+
</div>
|
|
90
|
+
<fieldset class="styles">
|
|
91
|
+
<legend>{t('table.style')}</legend>
|
|
92
|
+
<div class="gallery" role="radiogroup" aria-label={t('table.style')}>
|
|
93
|
+
<button
|
|
94
|
+
type="button"
|
|
95
|
+
class="swatch none"
|
|
96
|
+
class:chosen={look === NO_TABLE_STYLE}
|
|
97
|
+
role="radio"
|
|
98
|
+
aria-checked={look === NO_TABLE_STYLE}
|
|
99
|
+
title={t('table.styleNone')}
|
|
100
|
+
aria-label={t('table.styleNone')}
|
|
101
|
+
onclick={() => { look = NO_TABLE_STYLE }}
|
|
102
|
+
><span class="row head"></span><span class="row"></span><span class="row"></span></button>
|
|
103
|
+
{#each TABLE_STYLES as preset (preset.id)}
|
|
104
|
+
{@const colours = tableStyleColours(preset)}
|
|
105
|
+
<button
|
|
106
|
+
type="button"
|
|
107
|
+
class="swatch"
|
|
108
|
+
class:chosen={look === preset.id}
|
|
109
|
+
role="radio"
|
|
110
|
+
aria-checked={look === preset.id}
|
|
111
|
+
title={tableStyleLabel(preset)}
|
|
112
|
+
aria-label={tableStyleLabel(preset)}
|
|
113
|
+
onclick={() => { look = preset.id }}
|
|
114
|
+
>
|
|
115
|
+
<span class="row head" style={`background:${colours?.header}`}></span>
|
|
116
|
+
<span class="row" style={`background:${colours?.band}`}></span>
|
|
117
|
+
<span class="row"></span>
|
|
118
|
+
</button>
|
|
119
|
+
{/each}
|
|
120
|
+
</div>
|
|
121
|
+
</fieldset>
|
|
122
|
+
{#if error}<p class="error">{error}</p>{/if}
|
|
123
|
+
<p class="hint">{t('table.hint')}</p>
|
|
124
|
+
</form>
|
|
125
|
+
{#snippet footer()}
|
|
126
|
+
<div class="sv-sheet-dialog-buttons">
|
|
127
|
+
{#if existing && onRemove}
|
|
128
|
+
<button type="button" class="btn" onclick={() => { open = false; onRemove?.() }}>{t('delete')}</button>
|
|
129
|
+
{/if}
|
|
130
|
+
<span class="spacer"></span>
|
|
131
|
+
<button type="button" class="btn primary" onclick={ok}>{t('ok')}</button>
|
|
132
|
+
<button type="button" class="btn" onclick={close}>{t('cancel')}</button>
|
|
133
|
+
</div>
|
|
134
|
+
{/snippet}
|
|
135
|
+
</SvModal>
|
|
136
|
+
|
|
137
|
+
<style>
|
|
138
|
+
.spacer { flex: 1; }
|
|
139
|
+
/* The gallery: each swatch is a header band over two body rows, which is
|
|
140
|
+
the smallest drawing that still says what the style will look like. */
|
|
141
|
+
.styles { margin: 8px 0 0; padding: 0; border: 0; }
|
|
142
|
+
.styles legend { padding: 0 0 4px; color: var(--sg-muted, #64748b); font-size: 12px; }
|
|
143
|
+
.gallery { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
|
|
144
|
+
.swatch {
|
|
145
|
+
display: flex;
|
|
146
|
+
flex-direction: column;
|
|
147
|
+
gap: 1px;
|
|
148
|
+
padding: 2px;
|
|
149
|
+
border: 1px solid var(--sg-border, #d4d4d8);
|
|
150
|
+
border-radius: 3px;
|
|
151
|
+
background: var(--sg-surface, #fff);
|
|
152
|
+
cursor: pointer;
|
|
153
|
+
}
|
|
154
|
+
.swatch .row { display: block; height: 5px; background: var(--sg-surface-2, #f1f5f9); }
|
|
155
|
+
.swatch .row.head { height: 7px; }
|
|
156
|
+
.swatch.none .row.head { background: var(--sg-border, #d4d4d8); }
|
|
157
|
+
.swatch.chosen { outline: 2px solid var(--sg-accent, #107c41); outline-offset: 1px; }
|
|
158
|
+
.swatch:focus-visible { outline: 2px solid var(--sg-accent, #107c41); outline-offset: 1px; }
|
|
159
|
+
.error { margin: 4px 0 0; color: var(--sg-danger, #c42b1c); font-size: 12px; }
|
|
160
|
+
</style>
|