@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,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The spreadsheet shell: everything between the ribbon and the sheet tabs.
|
|
3
|
+
*
|
|
4
|
+
* SvSheetRibbon Home / Insert / Formulas / Data
|
|
5
|
+
* SvFormulaBar Name Box + fx, showing the RAW text of the active cell
|
|
6
|
+
* SvGrid A..Z column headers over the built-in 1..N gutter
|
|
7
|
+
* SvSheetTabs sheet tabs
|
|
8
|
+
* status bar Sum / Average / Count of the selection, as Excel has
|
|
9
|
+
*
|
|
10
|
+
* Composition, not a second grid. Every part here already existed and was
|
|
11
|
+
* being re-assembled by hand in four separate demos; the value of the
|
|
12
|
+
* component is that the wiring BETWEEN them is done once and correctly -
|
|
13
|
+
* the formula bar shows the raw text rather than the computed value, the
|
|
14
|
+
* format store is keyed by row id so sorting cannot strand formatting, the
|
|
15
|
+
* ribbon and the keyboard run the same actions, and the tab strip is told
|
|
16
|
+
* when a shortcut moved the active sheet.
|
|
17
|
+
*
|
|
18
|
+
* <SvSheet workbook={wb} />
|
|
19
|
+
*
|
|
20
|
+
* That is the whole required API. Everything else is opt-out.
|
|
21
|
+
*/
|
|
22
|
+
import { type SvGridApi, type TableFeatures } from '@svgrid/grid';
|
|
23
|
+
import type { GridCommandContext } from '@svgrid/grid/shortcuts';
|
|
24
|
+
import type { Workbook, SheetData } from './sheet/workbook.js';
|
|
25
|
+
import { type SheetDocument, type SheetState, type SheetChangeReason } from './sheet/document.js';
|
|
26
|
+
import { type CellFormatEntry } from './sheet/format-store.js';
|
|
27
|
+
import { type SheetPresence } from './sheet/presence.js';
|
|
28
|
+
import { type SheetLocalization } from './sheet/messages.js';
|
|
29
|
+
import { type GridSheetSpec } from './sheet/sheet-kinds.js';
|
|
30
|
+
import { type Rect } from './sheet/rects.js';
|
|
31
|
+
import type { RibbonActionId } from './sheet/ribbon.js';
|
|
32
|
+
/**
|
|
33
|
+
* A grid row carries the RAW text of every cell on it, keyed by column
|
|
34
|
+
* letter, as well as its position.
|
|
35
|
+
*
|
|
36
|
+
* It would be tempting to keep the values only in the workbook and let the
|
|
37
|
+
* cell snippet read them, since the snippet is what paints. That does not
|
|
38
|
+
* work, and not only for rendering: the grid's own machinery reads
|
|
39
|
+
* `row[field]`, so an empty row object means `cmd.getCellValue` returns
|
|
40
|
+
* undefined for every cell, and then Ctrl+Arrow thinks the sheet is blank,
|
|
41
|
+
* AutoSum finds no run to total, and the inline editor has nothing to open
|
|
42
|
+
* on. The workbook stays authoritative; this is its projection.
|
|
43
|
+
*/
|
|
44
|
+
type SheetRow = {
|
|
45
|
+
id: string;
|
|
46
|
+
index: number;
|
|
47
|
+
} & Record<string, string | number>;
|
|
48
|
+
type SheetApi = SvGridApi<TableFeatures, SheetRow>;
|
|
49
|
+
type Props = {
|
|
50
|
+
/**
|
|
51
|
+
* The document to edit: the workbook plus everything a sheet keeps beside
|
|
52
|
+
* its cells (formats, sizes, hidden lines, frozen panes, comments). Build
|
|
53
|
+
* one with `createSheetDocument` to save it, restore it or listen to it
|
|
54
|
+
* outside the component; without it the shell makes its own from
|
|
55
|
+
* `workbook` or `data` and hands it back through `onReady`.
|
|
56
|
+
*/
|
|
57
|
+
document?: SheetDocument;
|
|
58
|
+
/** The workbook to edit. One is created from `data` when absent. */
|
|
59
|
+
workbook?: Workbook;
|
|
60
|
+
/** Seed sheets, when not supplying a workbook. */
|
|
61
|
+
data?: ReadonlyArray<SheetData>;
|
|
62
|
+
/**
|
|
63
|
+
* Tabs that are a bound table rather than a cell grid, by name.
|
|
64
|
+
*
|
|
65
|
+
* Each one keeps records instead of cells and renders as a grid, and
|
|
66
|
+
* its records are projected into the workbook's cells, so
|
|
67
|
+
* `=SUM(Orders!D2:D99)` on a cell tab reads it like any other sheet.
|
|
68
|
+
* A name here that `data` does not list is added as a new tab.
|
|
69
|
+
*/
|
|
70
|
+
gridSheets?: Record<string, GridSheetSpec>;
|
|
71
|
+
/** Minimum grid size, so a sparse sheet still looks like a sheet. */
|
|
72
|
+
rows?: number;
|
|
73
|
+
columns?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Grid viewport height in pixels, or `'100%'` to fill the parent.
|
|
76
|
+
*
|
|
77
|
+
* The chrome around the grid - ribbon, formula bar, tabs, status bar -
|
|
78
|
+
* is about 290px tall, so a fixed grid height is a fixed component
|
|
79
|
+
* height with that added on. In a flex column that is too tall for the
|
|
80
|
+
* space, the tab strip is what gets pushed under whatever comes next.
|
|
81
|
+
* With `'100%'` the component is a flex item that fills its column and
|
|
82
|
+
* the grid takes whatever the chrome leaves.
|
|
83
|
+
*/
|
|
84
|
+
height?: number | '100%';
|
|
85
|
+
/** Default column width. */
|
|
86
|
+
columnWidth?: number;
|
|
87
|
+
/** Row height in pixels. Excel's is 20 at 100%; 22 fits the grid's 13px font. */
|
|
88
|
+
rowHeight?: number;
|
|
89
|
+
/**
|
|
90
|
+
* `theme` (the default) paints the shell with the host's `--sg-*`
|
|
91
|
+
* tokens, so it follows whatever theme the app around it runs, as the
|
|
92
|
+
* grid does. `excel` pins Excel's own palette and geometry, light or
|
|
93
|
+
* dark with the page, for an app that wants it to read as Excel
|
|
94
|
+
* whatever the theme.
|
|
95
|
+
*/
|
|
96
|
+
look?: 'excel' | 'theme';
|
|
97
|
+
/**
|
|
98
|
+
* Per-column overrides, keyed by column letter: `{ A: 150 }`.
|
|
99
|
+
*
|
|
100
|
+
* A sheet's first column usually holds labels and the rest hold numbers,
|
|
101
|
+
* so one width for all of them truncates the only column that needs the
|
|
102
|
+
* room. Columns stay drag-resizable either way.
|
|
103
|
+
*/
|
|
104
|
+
columnWidths?: Readonly<Record<string, number>>;
|
|
105
|
+
/**
|
|
106
|
+
* Cell formats to start with, keyed by A1 address: `{ B2: { bold: true },
|
|
107
|
+
* 'E13': { numFmt: '0.0%' } }`.
|
|
108
|
+
*
|
|
109
|
+
* A bare address formats the sheet that is active when the shell mounts.
|
|
110
|
+
* Qualify it to reach another sheet, the way a formula would:
|
|
111
|
+
* `{ 'Orders!F2': { numFmt: '$#,##0.00' }, "'Price list'!C2": ... }`.
|
|
112
|
+
* Formats are per sheet, as they are in Excel; a fill on Summary!C5 says
|
|
113
|
+
* nothing about Orders!C5.
|
|
114
|
+
*
|
|
115
|
+
* Without this the sheet can only be formatted by hand after it loads,
|
|
116
|
+
* which makes it impossible to ship a document that opens looking the way
|
|
117
|
+
* it was saved. Applied once at mount; after that the stores own it.
|
|
118
|
+
*/
|
|
119
|
+
formats?: Readonly<Record<string, CellFormatEntry>>;
|
|
120
|
+
/**
|
|
121
|
+
* Kept for the applications that passed it: the shell answers Insert >
|
|
122
|
+
* Table and Insert > Chart itself now, so nothing has to be listed
|
|
123
|
+
* here. An application that wants its own can still take either over
|
|
124
|
+
* through `onAction`.
|
|
125
|
+
*
|
|
126
|
+
* @deprecated Both buttons are always on.
|
|
127
|
+
*/
|
|
128
|
+
extras?: ReadonlyArray<'insert-table' | 'insert-chart'>;
|
|
129
|
+
/**
|
|
130
|
+
* The shell's language: `text` overrides any of its strings (the
|
|
131
|
+
* ribbon's, the dialogs', the status bar's; see `SheetMessages`) and
|
|
132
|
+
* `locale` formats the status bar's numbers and the grid's own
|
|
133
|
+
* matching. Unset keys stay English, so a partial map is fine.
|
|
134
|
+
*/
|
|
135
|
+
localization?: SheetLocalization;
|
|
136
|
+
/**
|
|
137
|
+
* Who signs a comment: the name a new comment and a reply carry, the
|
|
138
|
+
* way Excel signs a threaded comment with the signed-in user. Unset,
|
|
139
|
+
* a new comment is a plain note and a reply carries its time alone.
|
|
140
|
+
*/
|
|
141
|
+
commentAuthor?: string;
|
|
142
|
+
/** Hide any part of the chrome. */
|
|
143
|
+
showRibbon?: boolean;
|
|
144
|
+
showFormulaBar?: boolean;
|
|
145
|
+
showTabs?: boolean;
|
|
146
|
+
showStatusBar?: boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Every action the ribbon, the cell menu, the formula bar and the
|
|
149
|
+
* shortcuts raise. The shell has a dialog of its own for Find and
|
|
150
|
+
* Replace, Paste Special, Format Cells and Insert Function; a handler
|
|
151
|
+
* that returns `true` has taken the action over and the shell's dialog
|
|
152
|
+
* stays closed, so an application can put its own in their place.
|
|
153
|
+
*/
|
|
154
|
+
onAction?: (action: RibbonActionId, cmd: GridCommandContext) => void | boolean;
|
|
155
|
+
/**
|
|
156
|
+
* A button drawn in a cell was pressed. `action` is the region's own
|
|
157
|
+
* `action`, or its id when it has none, so a sheet can tell one column
|
|
158
|
+
* of buttons from another.
|
|
159
|
+
*/
|
|
160
|
+
onCellAction?: (event: {
|
|
161
|
+
row: number;
|
|
162
|
+
col: number;
|
|
163
|
+
action: string;
|
|
164
|
+
sheet: string;
|
|
165
|
+
}) => void;
|
|
166
|
+
onReady?: (api: SheetApi, document: SheetDocument) => void;
|
|
167
|
+
/**
|
|
168
|
+
* Something the user did landed in the document: a cell, a format, a
|
|
169
|
+
* size, a hidden line, a frozen pane, a sheet, a comment, or a structural
|
|
170
|
+
* edit. Called once per tick with every reason since the last call, so a
|
|
171
|
+
* paste of forty cells is one call; the natural place for an autosave
|
|
172
|
+
* (`getState()`, debounced). Undo and redo report too.
|
|
173
|
+
*/
|
|
174
|
+
onChange?: (reasons: ReadonlyArray<SheetChangeReason>) => void;
|
|
175
|
+
/**
|
|
176
|
+
* Other people on this workbook: each one's sheet, selection, name and
|
|
177
|
+
* colour, drawn over the cells as a coloured box with a tag.
|
|
178
|
+
*
|
|
179
|
+
* Presence is not part of the document and is never saved: a cursor
|
|
180
|
+
* belongs to a session. It comes in as a prop so the transport stays
|
|
181
|
+
* the application's, and `createDeltaStream` carries it for an
|
|
182
|
+
* application that wants one wire for both.
|
|
183
|
+
*/
|
|
184
|
+
presence?: ReadonlyArray<SheetPresence>;
|
|
185
|
+
/**
|
|
186
|
+
* Where THIS user is, every time it moves: the sheet, the selection and
|
|
187
|
+
* the active cell. What an application broadcasts as its own presence.
|
|
188
|
+
*/
|
|
189
|
+
onPresence?: (me: {
|
|
190
|
+
sheet: string;
|
|
191
|
+
rect: Rect;
|
|
192
|
+
active: {
|
|
193
|
+
row: number;
|
|
194
|
+
col: number;
|
|
195
|
+
};
|
|
196
|
+
}) => void;
|
|
197
|
+
};
|
|
198
|
+
declare const SvSheet: import("svelte").Component<Props, {
|
|
199
|
+
getState: () => SheetState;
|
|
200
|
+
setState: (state: SheetState) => void;
|
|
201
|
+
open: (file: Blob & {
|
|
202
|
+
name?: string;
|
|
203
|
+
}) => Promise<void>;
|
|
204
|
+
toXlsx: () => Promise<Blob>;
|
|
205
|
+
toOds: () => Promise<Blob>;
|
|
206
|
+
toXls: () => Blob;
|
|
207
|
+
toCsv: () => string;
|
|
208
|
+
printHtml: () => string;
|
|
209
|
+
print: () => void;
|
|
210
|
+
newWorkbook: () => void;
|
|
211
|
+
refresh: () => void;
|
|
212
|
+
act: (action: RibbonActionId) => void;
|
|
213
|
+
}, "">;
|
|
214
|
+
type SvSheet = ReturnType<typeof SvSheet>;
|
|
215
|
+
export default SvSheet;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Chart Design tab, as the one dialog the sheet needs: the chart
|
|
4
|
+
* type, its title, whether the range's first row and column are labels,
|
|
5
|
+
* whether a series is a column of the range or a row, and stacking.
|
|
6
|
+
* Opened by a double-click on a chart or by Chart Setup on the ribbon
|
|
7
|
+
* while one is selected. Delete removes the chart.
|
|
8
|
+
*/
|
|
9
|
+
import { useSheetText } from './sheet-text'
|
|
10
|
+
import { SvModal } from '@svgrid/grid'
|
|
11
|
+
import {
|
|
12
|
+
SHEET_CHART_TYPES, SHEET_CHART_TRENDS, copyObject,
|
|
13
|
+
type SheetChartObject, type SheetChartType, type SheetChartTrend,
|
|
14
|
+
} from './sheet/objects'
|
|
15
|
+
import { colToLetters } from './sheet/address'
|
|
16
|
+
|
|
17
|
+
type Props = {
|
|
18
|
+
open?: boolean
|
|
19
|
+
/** The chart as it stands. */
|
|
20
|
+
chart: SheetChartObject
|
|
21
|
+
/**
|
|
22
|
+
* The series it is drawing, by the labels the range gives them: what
|
|
23
|
+
* the secondary-axis list offers. The dialog has the chart, not the
|
|
24
|
+
* cells, so the shell reads them off the drawing.
|
|
25
|
+
*/
|
|
26
|
+
seriesLabels?: ReadonlyArray<string>
|
|
27
|
+
onApply: (chart: SheetChartObject) => void
|
|
28
|
+
onDelete: () => void
|
|
29
|
+
onClose?: () => void
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let { open = $bindable(false), chart, seriesLabels = [], onApply, onDelete, onClose }: Props = $props()
|
|
33
|
+
const t = useSheetText()
|
|
34
|
+
|
|
35
|
+
let type = $state<SheetChartType>('bar')
|
|
36
|
+
let title = $state('')
|
|
37
|
+
let headers = $state(true)
|
|
38
|
+
let series = $state<'columns' | 'rows'>('columns')
|
|
39
|
+
let stacked = $state(false)
|
|
40
|
+
let trend = $state<SheetChartTrend | ''>('')
|
|
41
|
+
let secondary = $state('')
|
|
42
|
+
let first = $state<HTMLSelectElement | null>(null)
|
|
43
|
+
|
|
44
|
+
$effect(() => {
|
|
45
|
+
if (!open) return
|
|
46
|
+
type = chart.type
|
|
47
|
+
title = chart.title ?? ''
|
|
48
|
+
headers = chart.headers
|
|
49
|
+
series = chart.series
|
|
50
|
+
stacked = Boolean(chart.stacked)
|
|
51
|
+
trend = chart.trend ?? ''
|
|
52
|
+
secondary = chart.secondary ?? ''
|
|
53
|
+
queueMicrotask(() => first?.focus())
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const rangeText = $derived.by(() => {
|
|
57
|
+
const [r1, c1, r2, c2] = chart.range
|
|
58
|
+
return `${colToLetters(c1)}${r1 + 1}:${colToLetters(c2)}${r2 + 1}`
|
|
59
|
+
})
|
|
60
|
+
/** Stacking means nothing on a pie or a scatter. */
|
|
61
|
+
const stackable = $derived(type === 'bar' || type === 'area' || type === 'line')
|
|
62
|
+
/** A pie has one axis and no trend to draw over it. */
|
|
63
|
+
const twoAxes = $derived(type !== 'pie')
|
|
64
|
+
|
|
65
|
+
function ok() {
|
|
66
|
+
const next = copyObject(chart) as SheetChartObject
|
|
67
|
+
next.type = type
|
|
68
|
+
next.headers = headers
|
|
69
|
+
next.series = series
|
|
70
|
+
if (title.trim()) next.title = title.trim()
|
|
71
|
+
else delete next.title
|
|
72
|
+
if (stacked && stackable) next.stacked = true
|
|
73
|
+
else delete next.stacked
|
|
74
|
+
// A pie has one axis and no line to trend, so neither setting survives
|
|
75
|
+
// a change to one: keeping a hidden setting is how a dialog lies.
|
|
76
|
+
if (trend && twoAxes) next.trend = trend
|
|
77
|
+
else delete next.trend
|
|
78
|
+
// A second axis means nothing on a pie, and nothing for a series that
|
|
79
|
+
// is no longer there.
|
|
80
|
+
if (secondary && twoAxes && seriesLabels.includes(secondary)) next.secondary = secondary
|
|
81
|
+
else delete next.secondary
|
|
82
|
+
open = false
|
|
83
|
+
onApply(next)
|
|
84
|
+
onClose?.()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function close() {
|
|
88
|
+
open = false
|
|
89
|
+
onClose?.()
|
|
90
|
+
}
|
|
91
|
+
</script>
|
|
92
|
+
|
|
93
|
+
<SvModal bind:open onClose={onClose} title={t('chartSetup.title')} size="sm">
|
|
94
|
+
<form class="sv-sheet-dialog" onsubmit={(e) => { e.preventDefault(); ok() }}>
|
|
95
|
+
<div class="where">{t('chartSetup.range', { range: rangeText })}</div>
|
|
96
|
+
<label class="field">
|
|
97
|
+
<span>{t('chartSetup.type')}</span>
|
|
98
|
+
<select bind:this={first} bind:value={type}>
|
|
99
|
+
{#each SHEET_CHART_TYPES as kind (kind)}<option value={kind}>{t(`chartSetup.type.${kind}`)}</option>{/each}
|
|
100
|
+
</select>
|
|
101
|
+
</label>
|
|
102
|
+
<label class="field">
|
|
103
|
+
<span>{t('chartSetup.chartTitle')}</span>
|
|
104
|
+
<input type="text" bind:value={title} spellcheck="false" placeholder={t('chartSetup.titlePlaceholder')} />
|
|
105
|
+
</label>
|
|
106
|
+
<label class="field">
|
|
107
|
+
<span>{t('chartSetup.series')}</span>
|
|
108
|
+
<select bind:value={series}>
|
|
109
|
+
<option value="columns">{t('chartSetup.series.columns')}</option>
|
|
110
|
+
<option value="rows">{t('chartSetup.series.rows')}</option>
|
|
111
|
+
</select>
|
|
112
|
+
</label>
|
|
113
|
+
{#if twoAxes}
|
|
114
|
+
<label class="field">
|
|
115
|
+
<span>{t('chartSetup.trend')}</span>
|
|
116
|
+
<select bind:value={trend}>
|
|
117
|
+
<option value="">{t('chartSetup.trend.none')}</option>
|
|
118
|
+
{#each SHEET_CHART_TRENDS as kind (kind)}<option value={kind}>{t(`chartSetup.trend.${kind}`)}</option>{/each}
|
|
119
|
+
</select>
|
|
120
|
+
</label>
|
|
121
|
+
{#if seriesLabels.length > 1}
|
|
122
|
+
<label class="field">
|
|
123
|
+
<span>{t('chartSetup.secondary')}</span>
|
|
124
|
+
<select bind:value={secondary}>
|
|
125
|
+
<option value="">{t('chartSetup.secondary.none')}</option>
|
|
126
|
+
{#each seriesLabels as label (label)}<option value={label}>{label}</option>{/each}
|
|
127
|
+
</select>
|
|
128
|
+
</label>
|
|
129
|
+
{/if}
|
|
130
|
+
{/if}
|
|
131
|
+
<div class="checks">
|
|
132
|
+
<label class="check"><input type="checkbox" bind:checked={headers} /> {t('chartSetup.headers')}</label>
|
|
133
|
+
{#if stackable}
|
|
134
|
+
<label class="check"><input type="checkbox" bind:checked={stacked} /> {t('chartSetup.stacked')}</label>
|
|
135
|
+
{/if}
|
|
136
|
+
</div>
|
|
137
|
+
<p class="hint">{t('chartSetup.hint')}</p>
|
|
138
|
+
</form>
|
|
139
|
+
{#snippet footer()}
|
|
140
|
+
<div class="sv-sheet-dialog-buttons">
|
|
141
|
+
<button type="button" class="btn" onclick={() => { open = false; onDelete() }}>{t('delete')}</button>
|
|
142
|
+
<span class="spacer"></span>
|
|
143
|
+
<button type="button" class="btn primary" onclick={ok}>{t('ok')}</button>
|
|
144
|
+
<button type="button" class="btn" onclick={close}>{t('cancel')}</button>
|
|
145
|
+
</div>
|
|
146
|
+
{/snippet}
|
|
147
|
+
</SvModal>
|
|
148
|
+
|
|
149
|
+
<style>
|
|
150
|
+
.spacer { flex: 1; }
|
|
151
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type SheetChartObject } from './sheet/objects.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
/** The chart as it stands. */
|
|
5
|
+
chart: SheetChartObject;
|
|
6
|
+
/**
|
|
7
|
+
* The series it is drawing, by the labels the range gives them: what
|
|
8
|
+
* the secondary-axis list offers. The dialog has the chart, not the
|
|
9
|
+
* cells, so the shell reads them off the drawing.
|
|
10
|
+
*/
|
|
11
|
+
seriesLabels?: ReadonlyArray<string>;
|
|
12
|
+
onApply: (chart: SheetChartObject) => void;
|
|
13
|
+
onDelete: () => void;
|
|
14
|
+
onClose?: () => void;
|
|
15
|
+
};
|
|
16
|
+
declare const SvSheetChartSetup: import("svelte").Component<Props, {}, "open">;
|
|
17
|
+
type SvSheetChartSetup = ReturnType<typeof SvSheetChartSetup>;
|
|
18
|
+
export default SvSheetChartSetup;
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* The comment box: Excel's note editor for a new comment, and its
|
|
4
|
+
* threaded comment card once one is there. New: a textarea over the
|
|
5
|
+
* text, Save, and the text kept whatever closes the box (Escape and a
|
|
6
|
+
* click elsewhere included), which is why every keystroke is reported
|
|
7
|
+
* through `onDraft` and the shell saves the draft on dismissal;
|
|
8
|
+
* Ctrl+Enter saves too. Existing: the first entry with its author and
|
|
9
|
+
* time, the replies under it, Edit and Delete on each, a reply box,
|
|
10
|
+
* and Resolve / Reopen in the head. Replies, edits and the resolved
|
|
11
|
+
* state go out whole through `onUpdate`; the first text through
|
|
12
|
+
* `onSave`, as before; Delete removes the thread. The shell mounts it
|
|
13
|
+
* inside the popover anchored to the cell.
|
|
14
|
+
*/
|
|
15
|
+
import { useSheetText } from './sheet-text'
|
|
16
|
+
import type { CommentThread, CommentEntry } from './sheet/comments'
|
|
17
|
+
|
|
18
|
+
type Props = {
|
|
19
|
+
/** The comment as it is, null for a new one. */
|
|
20
|
+
thread: CommentThread | null
|
|
21
|
+
/** The first text as it stands, the draft the box opens on. */
|
|
22
|
+
text: string
|
|
23
|
+
/** A1 of the cell, for the heading. */
|
|
24
|
+
address: string
|
|
25
|
+
/** Who signs a reply, when the application says. */
|
|
26
|
+
author?: string
|
|
27
|
+
/** For the times. */
|
|
28
|
+
locale?: string
|
|
29
|
+
/** Every change of the first text, so the shell can keep it on dismissal. */
|
|
30
|
+
onDraft: (text: string) => void
|
|
31
|
+
onSave: (text: string) => void
|
|
32
|
+
onDelete: () => void
|
|
33
|
+
/** A reply, an edited or deleted reply, or Resolve / Reopen: the whole thread as it should be. */
|
|
34
|
+
onUpdate: (thread: CommentThread) => void
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let { thread, text, address, author, locale, onDraft, onSave, onDelete, onUpdate }: Props = $props()
|
|
38
|
+
const t = useSheetText()
|
|
39
|
+
|
|
40
|
+
let draft = $state('')
|
|
41
|
+
let editingRoot = $state(false)
|
|
42
|
+
let reply = $state('')
|
|
43
|
+
let editingReply = $state<number | null>(null)
|
|
44
|
+
let replyDraft = $state('')
|
|
45
|
+
let box = $state<HTMLTextAreaElement | null>(null)
|
|
46
|
+
let replyBox = $state<HTMLTextAreaElement | null>(null)
|
|
47
|
+
|
|
48
|
+
$effect(() => {
|
|
49
|
+
draft = text
|
|
50
|
+
editingRoot = false
|
|
51
|
+
editingReply = null
|
|
52
|
+
reply = ''
|
|
53
|
+
queueMicrotask(() => {
|
|
54
|
+
const target = thread ? replyBox : box
|
|
55
|
+
if (!target) return
|
|
56
|
+
target.focus()
|
|
57
|
+
target.setSelectionRange(target.value.length, target.value.length)
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
const composing = $derived(!thread || editingRoot)
|
|
62
|
+
|
|
63
|
+
function when(at: string | undefined): string {
|
|
64
|
+
if (!at) return ''
|
|
65
|
+
const ms = Date.parse(at)
|
|
66
|
+
if (!Number.isFinite(ms)) return ''
|
|
67
|
+
try {
|
|
68
|
+
return new Date(ms).toLocaleString(locale, { dateStyle: 'medium', timeStyle: 'short' })
|
|
69
|
+
} catch {
|
|
70
|
+
return new Date(ms).toLocaleString(undefined, { dateStyle: 'medium', timeStyle: 'short' })
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const stamp = (): Pick<CommentEntry, 'author' | 'at'> => ({ ...(author ? { author } : {}), at: new Date().toISOString() })
|
|
75
|
+
|
|
76
|
+
function saveRoot() {
|
|
77
|
+
editingRoot = false
|
|
78
|
+
onSave(draft)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function postReply() {
|
|
82
|
+
const body = reply.trim()
|
|
83
|
+
if (!thread || !body) return
|
|
84
|
+
onUpdate({ ...thread, replies: [...(thread.replies ?? []), { text: body, ...stamp() }] })
|
|
85
|
+
reply = ''
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function saveReply(index: number) {
|
|
89
|
+
if (!thread) return
|
|
90
|
+
const body = replyDraft.trim()
|
|
91
|
+
const replies = (thread.replies ?? []).map((r, i) => (i === index ? { ...r, text: body } : r)).filter((r) => r.text)
|
|
92
|
+
editingReply = null
|
|
93
|
+
onUpdate({ ...thread, replies })
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function deleteReply(index: number) {
|
|
97
|
+
if (!thread) return
|
|
98
|
+
onUpdate({ ...thread, replies: (thread.replies ?? []).filter((_, i) => i !== index) })
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function setResolved(resolved: boolean) {
|
|
102
|
+
if (!thread) return
|
|
103
|
+
const next = { ...thread }
|
|
104
|
+
if (resolved) next.resolved = true
|
|
105
|
+
else delete next.resolved
|
|
106
|
+
onUpdate(next)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
110
|
+
if (event.key !== 'Enter' || !(event.ctrlKey || event.metaKey)) return
|
|
111
|
+
event.preventDefault()
|
|
112
|
+
const target = event.target
|
|
113
|
+
if (target === replyBox) postReply()
|
|
114
|
+
else if (editingReply !== null) saveReply(editingReply)
|
|
115
|
+
else if (composing) saveRoot()
|
|
116
|
+
}
|
|
117
|
+
</script>
|
|
118
|
+
|
|
119
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
120
|
+
<div class="sv-sheet-comment" class:threaded={!!thread} role="dialog" tabindex="-1" aria-label={t('commentOn', { address })} onkeydown={onKeyDown}>
|
|
121
|
+
<div class="head">
|
|
122
|
+
<span>{address}</span>
|
|
123
|
+
{#if thread}
|
|
124
|
+
{#if thread.resolved}
|
|
125
|
+
<span class="badge">{t('commentResolved')}</span>
|
|
126
|
+
<button type="button" class="link" onclick={() => setResolved(false)}>{t('commentReopen')}</button>
|
|
127
|
+
{:else}
|
|
128
|
+
<button type="button" class="link" onclick={() => setResolved(true)}>{t('commentResolve')}</button>
|
|
129
|
+
{/if}
|
|
130
|
+
{/if}
|
|
131
|
+
</div>
|
|
132
|
+
{#if composing}
|
|
133
|
+
<textarea
|
|
134
|
+
bind:this={box}
|
|
135
|
+
bind:value={draft}
|
|
136
|
+
oninput={() => onDraft(draft)}
|
|
137
|
+
rows="4"
|
|
138
|
+
aria-label={t('comment')}
|
|
139
|
+
placeholder={t('commentPlaceholder')}
|
|
140
|
+
spellcheck="false"
|
|
141
|
+
></textarea>
|
|
142
|
+
<div class="sv-sheet-dialog-buttons">
|
|
143
|
+
<span class="keys">{t('commentSaves')}</span>
|
|
144
|
+
<button type="button" class="btn primary" onclick={saveRoot}>{t('save')}</button>
|
|
145
|
+
{#if thread}
|
|
146
|
+
<button type="button" class="btn" onclick={() => { draft = text; onDraft(text); editingRoot = false }}>{t('cancel')}</button>
|
|
147
|
+
{:else if text}
|
|
148
|
+
<button type="button" class="btn" onclick={onDelete}>{t('delete')}</button>
|
|
149
|
+
{/if}
|
|
150
|
+
</div>
|
|
151
|
+
{:else if thread}
|
|
152
|
+
<div class="entry root">
|
|
153
|
+
<div class="who">
|
|
154
|
+
{#if thread.author}<span class="author">{thread.author}</span>{/if}
|
|
155
|
+
{#if thread.at}<span class="when">{when(thread.at)}</span>{/if}
|
|
156
|
+
</div>
|
|
157
|
+
<div class="text">{thread.text}</div>
|
|
158
|
+
<div class="actions">
|
|
159
|
+
<button type="button" class="link" onclick={() => { editingRoot = true; queueMicrotask(() => box?.focus()) }}>{t('commentEdit')}</button>
|
|
160
|
+
<button type="button" class="link" onclick={onDelete}>{t('delete')}</button>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
{#each thread.replies ?? [] as entry, i (i)}
|
|
164
|
+
<div class="entry reply">
|
|
165
|
+
<div class="who">
|
|
166
|
+
{#if entry.author}<span class="author">{entry.author}</span>{/if}
|
|
167
|
+
{#if entry.at}<span class="when">{when(entry.at)}</span>{/if}
|
|
168
|
+
</div>
|
|
169
|
+
{#if editingReply === i}
|
|
170
|
+
<textarea bind:value={replyDraft} rows="3" aria-label={t('commentReply')} spellcheck="false"></textarea>
|
|
171
|
+
<div class="actions">
|
|
172
|
+
<button type="button" class="link" onclick={() => saveReply(i)}>{t('save')}</button>
|
|
173
|
+
<button type="button" class="link" onclick={() => (editingReply = null)}>{t('cancel')}</button>
|
|
174
|
+
</div>
|
|
175
|
+
{:else}
|
|
176
|
+
<div class="text">{entry.text}</div>
|
|
177
|
+
<div class="actions">
|
|
178
|
+
<button type="button" class="link" onclick={() => { editingReply = i; replyDraft = entry.text }}>{t('commentEdit')}</button>
|
|
179
|
+
<button type="button" class="link" onclick={() => deleteReply(i)}>{t('delete')}</button>
|
|
180
|
+
</div>
|
|
181
|
+
{/if}
|
|
182
|
+
</div>
|
|
183
|
+
{/each}
|
|
184
|
+
{#if !thread.resolved}
|
|
185
|
+
<textarea
|
|
186
|
+
bind:this={replyBox}
|
|
187
|
+
bind:value={reply}
|
|
188
|
+
rows="2"
|
|
189
|
+
aria-label={t('commentReply')}
|
|
190
|
+
placeholder={t('commentReplyPlaceholder')}
|
|
191
|
+
spellcheck="false"
|
|
192
|
+
></textarea>
|
|
193
|
+
<div class="sv-sheet-dialog-buttons">
|
|
194
|
+
<span class="keys">{t('commentPosts')}</span>
|
|
195
|
+
<button type="button" class="btn primary" onclick={postReply} disabled={!reply.trim()}>{t('commentReply')}</button>
|
|
196
|
+
</div>
|
|
197
|
+
{/if}
|
|
198
|
+
{/if}
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
<style>
|
|
202
|
+
.sv-sheet-comment {
|
|
203
|
+
display: flex;
|
|
204
|
+
flex-direction: column;
|
|
205
|
+
gap: 6px;
|
|
206
|
+
width: 260px;
|
|
207
|
+
padding: 8px;
|
|
208
|
+
font-size: 12px;
|
|
209
|
+
color: var(--sg-fg, #242424);
|
|
210
|
+
}
|
|
211
|
+
.sv-sheet-comment.threaded {
|
|
212
|
+
width: 300px;
|
|
213
|
+
max-height: 360px;
|
|
214
|
+
overflow-y: auto;
|
|
215
|
+
}
|
|
216
|
+
.head {
|
|
217
|
+
display: flex;
|
|
218
|
+
align-items: center;
|
|
219
|
+
gap: 8px;
|
|
220
|
+
font-weight: 600;
|
|
221
|
+
color: var(--sg-muted, #616161);
|
|
222
|
+
}
|
|
223
|
+
.head .link { margin-left: auto; }
|
|
224
|
+
.badge {
|
|
225
|
+
padding: 1px 6px;
|
|
226
|
+
font-size: 11px;
|
|
227
|
+
font-weight: 600;
|
|
228
|
+
color: var(--sg-on-accent, #fff);
|
|
229
|
+
background: var(--sg-accent, #107c41);
|
|
230
|
+
border-radius: 9px;
|
|
231
|
+
}
|
|
232
|
+
.keys {
|
|
233
|
+
margin-right: auto;
|
|
234
|
+
font-size: 11px;
|
|
235
|
+
color: var(--sg-muted, #616161);
|
|
236
|
+
}
|
|
237
|
+
.entry {
|
|
238
|
+
display: flex;
|
|
239
|
+
flex-direction: column;
|
|
240
|
+
gap: 3px;
|
|
241
|
+
padding: 6px 0;
|
|
242
|
+
border-top: 1px solid var(--sg-border, #e5e5e5);
|
|
243
|
+
}
|
|
244
|
+
.entry.root { border-top: 0; padding-top: 0; }
|
|
245
|
+
.entry.reply { padding-left: 12px; }
|
|
246
|
+
.who {
|
|
247
|
+
display: flex;
|
|
248
|
+
gap: 8px;
|
|
249
|
+
align-items: baseline;
|
|
250
|
+
font-size: 11px;
|
|
251
|
+
color: var(--sg-muted, #616161);
|
|
252
|
+
}
|
|
253
|
+
.author { font-weight: 600; color: var(--sg-fg, #242424); }
|
|
254
|
+
.text { white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
255
|
+
.actions { display: flex; gap: 10px; }
|
|
256
|
+
.link {
|
|
257
|
+
padding: 0;
|
|
258
|
+
font: inherit;
|
|
259
|
+
font-size: 11px;
|
|
260
|
+
color: var(--sg-accent, #107c41);
|
|
261
|
+
background: none;
|
|
262
|
+
border: 0;
|
|
263
|
+
cursor: pointer;
|
|
264
|
+
}
|
|
265
|
+
.link:hover { text-decoration: underline; }
|
|
266
|
+
textarea {
|
|
267
|
+
width: 100%;
|
|
268
|
+
box-sizing: border-box;
|
|
269
|
+
resize: vertical;
|
|
270
|
+
min-height: 40px;
|
|
271
|
+
padding: 6px 8px;
|
|
272
|
+
font: inherit;
|
|
273
|
+
line-height: 1.4;
|
|
274
|
+
color: inherit;
|
|
275
|
+
background: var(--sg-bg, #fff);
|
|
276
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
277
|
+
border-radius: 3px;
|
|
278
|
+
}
|
|
279
|
+
textarea:focus-visible {
|
|
280
|
+
outline: 2px solid var(--sg-focus-ring, var(--sg-accent, #107c41));
|
|
281
|
+
outline-offset: -1px;
|
|
282
|
+
}
|
|
283
|
+
</style>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CommentThread } from './sheet/comments.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
/** The comment as it is, null for a new one. */
|
|
4
|
+
thread: CommentThread | null;
|
|
5
|
+
/** The first text as it stands, the draft the box opens on. */
|
|
6
|
+
text: string;
|
|
7
|
+
/** A1 of the cell, for the heading. */
|
|
8
|
+
address: string;
|
|
9
|
+
/** Who signs a reply, when the application says. */
|
|
10
|
+
author?: string;
|
|
11
|
+
/** For the times. */
|
|
12
|
+
locale?: string;
|
|
13
|
+
/** Every change of the first text, so the shell can keep it on dismissal. */
|
|
14
|
+
onDraft: (text: string) => void;
|
|
15
|
+
onSave: (text: string) => void;
|
|
16
|
+
onDelete: () => void;
|
|
17
|
+
/** A reply, an edited or deleted reply, or Resolve / Reopen: the whole thread as it should be. */
|
|
18
|
+
onUpdate: (thread: CommentThread) => void;
|
|
19
|
+
};
|
|
20
|
+
declare const SvSheetComment: import("svelte").Component<Props, {}, "">;
|
|
21
|
+
type SvSheetComment = ReturnType<typeof SvSheetComment>;
|
|
22
|
+
export default SvSheetComment;
|