@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,15 @@
|
|
|
1
|
+
import { type EditRange } from './sheet/protection.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
/** The sheet's ranges as they stand. */
|
|
5
|
+
ranges: ReadonlyArray<EditRange>;
|
|
6
|
+
/** The selection as A1 text, what a new range's cells open on. */
|
|
7
|
+
selection: string;
|
|
8
|
+
onApply: (ranges: EditRange[]) => void;
|
|
9
|
+
/** The Protect Sheet... button: the shell opens that dialog. */
|
|
10
|
+
onProtect: () => void;
|
|
11
|
+
onClose?: () => void;
|
|
12
|
+
};
|
|
13
|
+
declare const SvSheetEditRanges: import("svelte").Component<Props, {}, "open">;
|
|
14
|
+
type SvSheetEditRanges = ReturnType<typeof SvSheetEditRanges>;
|
|
15
|
+
export default SvSheetEditRanges;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Error Checking: the cells on this sheet worth a second look,
|
|
4
|
+
* walked one at a time. Each one says what the error means rather than
|
|
5
|
+
* leaving the code to be looked up, and Show Calculation Steps hands the
|
|
6
|
+
* cell to Evaluate Formula, which is where the answer usually is.
|
|
7
|
+
*
|
|
8
|
+
* The selection follows the walk, so the cell being talked about is the
|
|
9
|
+
* cell on screen.
|
|
10
|
+
*/
|
|
11
|
+
import { untrack } from 'svelte'
|
|
12
|
+
import { SvModal } from '@svgrid/grid'
|
|
13
|
+
import { useSheetText } from './sheet-text'
|
|
14
|
+
import { colToLetters } from './sheet/address'
|
|
15
|
+
import { checkSheet, describeFinding, type ErrorFinding } from './sheet/error-check'
|
|
16
|
+
import type { Workbook } from './sheet/workbook'
|
|
17
|
+
|
|
18
|
+
type Props = {
|
|
19
|
+
open?: boolean
|
|
20
|
+
workbook: Workbook
|
|
21
|
+
sheet: string
|
|
22
|
+
/** Put the selection on a cell being looked at. */
|
|
23
|
+
onGoTo: (cell: { row: number; col: number }) => void
|
|
24
|
+
/** Open Evaluate Formula on the cell being looked at. */
|
|
25
|
+
onSteps: (cell: { row: number; col: number }) => void
|
|
26
|
+
onClose?: () => void
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let { open = $bindable(false), workbook, sheet, onGoTo, onSteps, onClose }: Props = $props()
|
|
30
|
+
const t = useSheetText()
|
|
31
|
+
|
|
32
|
+
let findings = $state<ErrorFinding[]>([])
|
|
33
|
+
let at = $state(0)
|
|
34
|
+
let nextButton = $state<HTMLButtonElement | null>(null)
|
|
35
|
+
|
|
36
|
+
const current = $derived(findings[at] ?? null)
|
|
37
|
+
const address = $derived(current ? `${colToLetters(current.col)}${current.row + 1}` : '')
|
|
38
|
+
|
|
39
|
+
// Opening is the only thing this effect follows. Reading the workbook
|
|
40
|
+
// through it would tie it to every repaint, and moving the selection
|
|
41
|
+
// repaints, so the walk would restart itself forever.
|
|
42
|
+
$effect(() => {
|
|
43
|
+
if (!open) return
|
|
44
|
+
untrack(load)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
function load() {
|
|
48
|
+
const found = checkSheet(sheet, {
|
|
49
|
+
rowCount: () => workbook.rowCount(sheet),
|
|
50
|
+
colCount: () => workbook.colCount(sheet),
|
|
51
|
+
getRaw: (row, col) => workbook.getRaw(sheet, row, col),
|
|
52
|
+
getValue: (row, col) => workbook.getValue(sheet, row, col),
|
|
53
|
+
})
|
|
54
|
+
findings = found
|
|
55
|
+
at = 0
|
|
56
|
+
show(found[0])
|
|
57
|
+
queueMicrotask(() => nextButton?.focus())
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function show(finding: ErrorFinding | undefined) {
|
|
61
|
+
if (finding) onGoTo({ row: finding.row, col: finding.col })
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function move(by: number) {
|
|
65
|
+
const list = findings
|
|
66
|
+
if (list.length === 0) return
|
|
67
|
+
at = (at + by + list.length) % list.length
|
|
68
|
+
show(list[at])
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function close() {
|
|
72
|
+
open = false
|
|
73
|
+
onClose?.()
|
|
74
|
+
}
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<SvModal bind:open onClose={onClose} title={t('errors.title')} size="sm">
|
|
78
|
+
<div class="sv-sheet-dialog">
|
|
79
|
+
{#if current}
|
|
80
|
+
<p class="position">{t('errors.position', { index: at + 1, count: findings.length })}</p>
|
|
81
|
+
<p class="headline">
|
|
82
|
+
<code>{address}</code>
|
|
83
|
+
<strong>{current.kind === 'error' ? current.error : t('errors.inconsistent')}</strong>
|
|
84
|
+
</p>
|
|
85
|
+
<pre class="formula">{current.text}</pre>
|
|
86
|
+
<p class="meaning">{describeFinding(current)}</p>
|
|
87
|
+
{:else}
|
|
88
|
+
<p class="none">{t('errors.none')}</p>
|
|
89
|
+
{/if}
|
|
90
|
+
<p class="hint">{t('errors.hint')}</p>
|
|
91
|
+
</div>
|
|
92
|
+
{#snippet footer()}
|
|
93
|
+
<div class="sv-sheet-dialog-buttons">
|
|
94
|
+
<button type="button" class="btn" onclick={() => move(-1)} disabled={findings.length < 2}>{t('errors.previous')}</button>
|
|
95
|
+
<button type="button" class="btn" bind:this={nextButton} onclick={() => move(1)} disabled={findings.length < 2}>{t('errors.next')}</button>
|
|
96
|
+
<span class="spacer"></span>
|
|
97
|
+
<button
|
|
98
|
+
type="button"
|
|
99
|
+
class="btn primary"
|
|
100
|
+
disabled={!current}
|
|
101
|
+
onclick={() => { if (current) { open = false; onSteps({ row: current.row, col: current.col }) } }}
|
|
102
|
+
>{t('errors.steps')}</button>
|
|
103
|
+
<button type="button" class="btn" onclick={close}>{t('close')}</button>
|
|
104
|
+
</div>
|
|
105
|
+
{/snippet}
|
|
106
|
+
</SvModal>
|
|
107
|
+
|
|
108
|
+
<style>
|
|
109
|
+
.spacer { flex: 1; }
|
|
110
|
+
.position { margin: 0 0 6px; color: var(--sg-muted, #64748b); font-size: 12px; }
|
|
111
|
+
.headline { margin: 0 0 8px; display: flex; align-items: baseline; gap: 8px; }
|
|
112
|
+
.formula {
|
|
113
|
+
margin: 0 0 8px;
|
|
114
|
+
padding: 8px 10px;
|
|
115
|
+
border: 1px solid var(--sg-border, #d4d4d8);
|
|
116
|
+
border-radius: 4px;
|
|
117
|
+
background: var(--sg-surface-2, #f8fafc);
|
|
118
|
+
font-family: var(--sg-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
|
|
119
|
+
font-size: 13px;
|
|
120
|
+
white-space: pre-wrap;
|
|
121
|
+
overflow-wrap: anywhere;
|
|
122
|
+
}
|
|
123
|
+
.meaning { margin: 0; }
|
|
124
|
+
.none { margin: 0 0 8px; }
|
|
125
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Workbook } from './sheet/workbook.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
workbook: Workbook;
|
|
5
|
+
sheet: string;
|
|
6
|
+
/** Put the selection on a cell being looked at. */
|
|
7
|
+
onGoTo: (cell: {
|
|
8
|
+
row: number;
|
|
9
|
+
col: number;
|
|
10
|
+
}) => void;
|
|
11
|
+
/** Open Evaluate Formula on the cell being looked at. */
|
|
12
|
+
onSteps: (cell: {
|
|
13
|
+
row: number;
|
|
14
|
+
col: number;
|
|
15
|
+
}) => void;
|
|
16
|
+
onClose?: () => void;
|
|
17
|
+
};
|
|
18
|
+
declare const SvSheetErrors: import("svelte").Component<Props, {}, "open">;
|
|
19
|
+
type SvSheetErrors = ReturnType<typeof SvSheetErrors>;
|
|
20
|
+
export default SvSheetErrors;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Excel's Evaluate Formula: the active cell's formula with one part
|
|
4
|
+
* underlined, and a button that replaces that part with what it is worth.
|
|
5
|
+
* Keep clicking and the formula collapses into the cell's answer, which is
|
|
6
|
+
* the quickest way to see which half of a long formula is the wrong half.
|
|
7
|
+
*
|
|
8
|
+
* The walk itself is `evaluationSteps`; this shows it and lets the reader
|
|
9
|
+
* move back and forth through it.
|
|
10
|
+
*/
|
|
11
|
+
import { untrack } from 'svelte'
|
|
12
|
+
import { SvModal } from '@svgrid/grid'
|
|
13
|
+
import { useSheetText } from './sheet-text'
|
|
14
|
+
import { colToLetters } from './sheet/address'
|
|
15
|
+
import { parseFormula } from './sheet/parse'
|
|
16
|
+
import { evaluationSteps, printValue, type EvaluationStep } from './sheet/evaluate-steps'
|
|
17
|
+
import type { Workbook } from './sheet/workbook'
|
|
18
|
+
|
|
19
|
+
type Props = {
|
|
20
|
+
open?: boolean
|
|
21
|
+
workbook: Workbook
|
|
22
|
+
sheet: string
|
|
23
|
+
/** The cell to walk, which is the active one when the dialog opens. */
|
|
24
|
+
cell: { row: number; col: number }
|
|
25
|
+
onClose?: () => void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let { open = $bindable(false), workbook, sheet, cell, onClose }: Props = $props()
|
|
29
|
+
const t = useSheetText()
|
|
30
|
+
|
|
31
|
+
let steps = $state<EvaluationStep[]>([])
|
|
32
|
+
let at = $state(0)
|
|
33
|
+
let problem = $state('')
|
|
34
|
+
let evaluateButton = $state<HTMLButtonElement | null>(null)
|
|
35
|
+
|
|
36
|
+
const address = $derived(`${sheet}!${colToLetters(cell.col)}${cell.row + 1}`)
|
|
37
|
+
/** The line on screen: the formula as it stands before the next step, or
|
|
38
|
+
* the final value once every part has been worked out. */
|
|
39
|
+
const current = $derived(steps[at] ?? null)
|
|
40
|
+
const finished = $derived(steps.length > 0 && at >= steps.length)
|
|
41
|
+
const answer = $derived(steps.length > 0 ? steps[steps.length - 1]!.value : null)
|
|
42
|
+
|
|
43
|
+
// The cell is followed, because Error Checking hands this dialog a new
|
|
44
|
+
// one while it is open; the workbook is not, or every repaint would
|
|
45
|
+
// restart the walk.
|
|
46
|
+
$effect(() => {
|
|
47
|
+
if (!open) return
|
|
48
|
+
const target = cell
|
|
49
|
+
untrack(() => walk(target))
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
function walk(target: { row: number; col: number }) {
|
|
53
|
+
at = 0
|
|
54
|
+
problem = ''
|
|
55
|
+
steps = []
|
|
56
|
+
const text = workbook.getRaw(sheet, target.row, target.col).trim()
|
|
57
|
+
if (!text.startsWith('=')) {
|
|
58
|
+
problem = t('evaluate.noFormula')
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
steps = evaluationSteps(
|
|
63
|
+
parseFormula(text),
|
|
64
|
+
(formula) => workbook.evaluateText(sheet, formula, undefined, { row: target.row, col: target.col }),
|
|
65
|
+
)
|
|
66
|
+
} catch {
|
|
67
|
+
problem = t('evaluate.noFormula')
|
|
68
|
+
}
|
|
69
|
+
queueMicrotask(() => evaluateButton?.focus())
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function close() {
|
|
73
|
+
open = false
|
|
74
|
+
onClose?.()
|
|
75
|
+
}
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<SvModal bind:open onClose={onClose} title={t('evaluate.title')} size="md">
|
|
79
|
+
<div class="sv-sheet-dialog">
|
|
80
|
+
<p class="reference"><span class="label">{t('evaluate.reference')}</span> <code>{address}</code></p>
|
|
81
|
+
{#if problem}
|
|
82
|
+
<p class="error">{problem}</p>
|
|
83
|
+
{:else}
|
|
84
|
+
<p class="label">{t('evaluate.evaluation')}</p>
|
|
85
|
+
<pre class="evaluation" data-testid="sv-sheet-evaluation">{#if current}{current.formula.slice(0, current.from)}<mark>{current.formula.slice(current.from, current.to)}</mark>{current.formula.slice(current.to)}{:else}{printValue(answer ?? '')}{/if}</pre>
|
|
86
|
+
{#if finished}
|
|
87
|
+
<p class="done">{t('evaluate.done')} <strong>{printValue(answer ?? '')}</strong></p>
|
|
88
|
+
{/if}
|
|
89
|
+
<p class="hint">{t('evaluate.hint')}</p>
|
|
90
|
+
{/if}
|
|
91
|
+
</div>
|
|
92
|
+
{#snippet footer()}
|
|
93
|
+
<div class="sv-sheet-dialog-buttons">
|
|
94
|
+
<button type="button" class="btn" onclick={() => { at = Math.max(0, at - 1) }} disabled={at === 0 || !!problem}>{t('evaluate.stepBack')}</button>
|
|
95
|
+
<button type="button" class="btn" onclick={() => { at = 0 }} disabled={at === 0 || !!problem}>{t('evaluate.restart')}</button>
|
|
96
|
+
<span class="spacer"></span>
|
|
97
|
+
<button
|
|
98
|
+
type="button"
|
|
99
|
+
class="btn primary"
|
|
100
|
+
bind:this={evaluateButton}
|
|
101
|
+
onclick={() => { at = Math.min(steps.length, at + 1) }}
|
|
102
|
+
disabled={finished || !!problem}
|
|
103
|
+
>{t('evaluate.evaluate')}</button>
|
|
104
|
+
<button type="button" class="btn" onclick={close}>{t('close')}</button>
|
|
105
|
+
</div>
|
|
106
|
+
{/snippet}
|
|
107
|
+
</SvModal>
|
|
108
|
+
|
|
109
|
+
<style>
|
|
110
|
+
.spacer { flex: 1; }
|
|
111
|
+
.reference { margin: 0 0 8px; }
|
|
112
|
+
.label { color: var(--sg-muted, #64748b); font-size: 12px; }
|
|
113
|
+
.evaluation {
|
|
114
|
+
margin: 0;
|
|
115
|
+
padding: 10px 12px;
|
|
116
|
+
border: 1px solid var(--sg-border, #d4d4d8);
|
|
117
|
+
border-radius: 4px;
|
|
118
|
+
background: var(--sg-surface-2, #f8fafc);
|
|
119
|
+
font-family: var(--sg-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
|
|
120
|
+
font-size: 13px;
|
|
121
|
+
line-height: 1.6;
|
|
122
|
+
white-space: pre-wrap;
|
|
123
|
+
overflow-wrap: anywhere;
|
|
124
|
+
}
|
|
125
|
+
.evaluation mark {
|
|
126
|
+
background: var(--sg-accent-soft, #dbeafe);
|
|
127
|
+
color: inherit;
|
|
128
|
+
text-decoration: underline;
|
|
129
|
+
text-underline-offset: 3px;
|
|
130
|
+
}
|
|
131
|
+
.done { margin: 8px 0 0; }
|
|
132
|
+
.error { margin: 4px 0 0; color: var(--sg-danger, #c42b1c); font-size: 12px; }
|
|
133
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Workbook } from './sheet/workbook.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
workbook: Workbook;
|
|
5
|
+
sheet: string;
|
|
6
|
+
/** The cell to walk, which is the active one when the dialog opens. */
|
|
7
|
+
cell: {
|
|
8
|
+
row: number;
|
|
9
|
+
col: number;
|
|
10
|
+
};
|
|
11
|
+
onClose?: () => void;
|
|
12
|
+
};
|
|
13
|
+
declare const SvSheetEvaluate: import("svelte").Component<Props, {}, "open">;
|
|
14
|
+
type SvSheetEvaluate = ReturnType<typeof SvSheetEvaluate>;
|
|
15
|
+
export default SvSheetEvaluate;
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* The menu an AutoFilter arrow drops: Excel's, in its order. Sort A to Z
|
|
4
|
+
* and Z to A, Clear Filter From the column, a condition (Text Filters or
|
|
5
|
+
* Number Filters: equals, greater than, contains, between and the rest,
|
|
6
|
+
* two of them joined with And / Or), a search box, (Select All) and the
|
|
7
|
+
* column's values to tick, OK and Cancel. The shell mounts it inside the
|
|
8
|
+
* popover anchored to the header cell.
|
|
9
|
+
*/
|
|
10
|
+
import { useSheetText } from './sheet-text'
|
|
11
|
+
import type { ExcelFilterOperator } from '@svgrid/grid/filtering'
|
|
12
|
+
import { valuesFilter, type ColumnFilter, type FilterValue, type FilterCondition, type DatePeriod } from './sheet/auto-filter'
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
/** The header text, for Clear Filter From "X". */
|
|
16
|
+
header: string
|
|
17
|
+
/** The column's values with their counts. */
|
|
18
|
+
values: ReadonlyArray<FilterValue>
|
|
19
|
+
/** The filter on the column now, if any. */
|
|
20
|
+
filter: ColumnFilter | null
|
|
21
|
+
/** Whether the column holds numbers, for Number Filters over Text Filters. */
|
|
22
|
+
numeric: boolean
|
|
23
|
+
/** Whether the column holds dates, for Date Filters. */
|
|
24
|
+
dates?: boolean
|
|
25
|
+
/** The fills the column's cells carry (null for none), for Filter by
|
|
26
|
+
* Color; the entry is left off with fewer than two. */
|
|
27
|
+
fills?: ReadonlyArray<string | null>
|
|
28
|
+
onSort: (direction: 'asc' | 'desc') => void
|
|
29
|
+
onApply: (filter: ColumnFilter | null) => void
|
|
30
|
+
onCancel: () => void
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let { header, values, filter, numeric, dates = false, fills = [], onSort, onApply, onCancel }: Props = $props()
|
|
34
|
+
const t = useSheetText()
|
|
35
|
+
|
|
36
|
+
const PERIODS: ReadonlyArray<DatePeriod> = [
|
|
37
|
+
'equals', 'before', 'after', 'between', 'tomorrow', 'today', 'yesterday',
|
|
38
|
+
'nextWeek', 'thisWeek', 'lastWeek', 'nextMonth', 'thisMonth', 'lastMonth',
|
|
39
|
+
'nextQuarter', 'thisQuarter', 'lastQuarter', 'nextYear', 'thisYear', 'lastYear', 'yearToDate',
|
|
40
|
+
]
|
|
41
|
+
const typedPeriod = (p: DatePeriod) => p === 'equals' || p === 'before' || p === 'after' || p === 'between'
|
|
42
|
+
|
|
43
|
+
const TEXT_OPS: ReadonlyArray<ExcelFilterOperator> = [
|
|
44
|
+
'equals', 'notEquals', 'startsWith', 'endsWith', 'contains', 'notContains', 'isBlank', 'isNotBlank',
|
|
45
|
+
]
|
|
46
|
+
const NUMBER_OPS: ReadonlyArray<ExcelFilterOperator> = [
|
|
47
|
+
'equals', 'notEquals', 'greaterThan', 'lessThan', 'between', 'isBlank', 'isNotBlank',
|
|
48
|
+
]
|
|
49
|
+
const ops = $derived(numeric ? NUMBER_OPS : TEXT_OPS)
|
|
50
|
+
|
|
51
|
+
let search = $state('')
|
|
52
|
+
let ticked = $state<Set<string>>(new Set())
|
|
53
|
+
let mode = $state<'values' | 'condition' | 'date' | 'top'>('values')
|
|
54
|
+
let period = $state<DatePeriod>('today')
|
|
55
|
+
let d1 = $state('')
|
|
56
|
+
let d2 = $state('')
|
|
57
|
+
let topSide = $state<'top' | 'bottom'>('top')
|
|
58
|
+
let topCount = $state(10)
|
|
59
|
+
let topUnit = $state<'items' | 'percent'>('items')
|
|
60
|
+
let op1 = $state<ExcelFilterOperator>('equals')
|
|
61
|
+
let v1 = $state('')
|
|
62
|
+
let v1to = $state('')
|
|
63
|
+
let join = $state<'and' | 'or'>('and')
|
|
64
|
+
let op2 = $state<ExcelFilterOperator | ''>('')
|
|
65
|
+
let v2 = $state('')
|
|
66
|
+
let v2to = $state('')
|
|
67
|
+
let searchBox = $state<HTMLInputElement | null>(null)
|
|
68
|
+
|
|
69
|
+
$effect(() => {
|
|
70
|
+
// Open on the column's state: the ticks it has, or the condition it has.
|
|
71
|
+
const f = filter
|
|
72
|
+
const all = values.map((v) => v.text)
|
|
73
|
+
if (f?.kind === 'values') ticked = new Set(f.included ? all.filter((t) => f.included!.includes(t)) : all.filter((t) => !f.excluded.includes(t)))
|
|
74
|
+
else ticked = new Set(all)
|
|
75
|
+
mode = f?.kind === 'condition' ? 'condition' : f?.kind === 'date' ? 'date' : f?.kind === 'top' ? 'top' : 'values'
|
|
76
|
+
period = f?.kind === 'date' ? f.period : 'today'
|
|
77
|
+
d1 = f?.kind === 'date' ? f.value ?? '' : ''
|
|
78
|
+
d2 = f?.kind === 'date' ? f.valueTo ?? '' : ''
|
|
79
|
+
topSide = f?.kind === 'top' && !f.top ? 'bottom' : 'top'
|
|
80
|
+
topCount = f?.kind === 'top' ? f.count : 10
|
|
81
|
+
topUnit = f?.kind === 'top' && f.percent ? 'percent' : 'items'
|
|
82
|
+
if (f?.kind === 'condition') {
|
|
83
|
+
op1 = f.first.op; v1 = f.first.value ?? ''; v1to = f.first.valueTo ?? ''
|
|
84
|
+
join = f.join ?? 'and'
|
|
85
|
+
op2 = f.second?.op ?? ''; v2 = f.second?.value ?? ''; v2to = f.second?.valueTo ?? ''
|
|
86
|
+
} else {
|
|
87
|
+
op1 = 'equals'; v1 = ''; v1to = ''; join = 'and'; op2 = ''; v2 = ''; v2to = ''
|
|
88
|
+
}
|
|
89
|
+
search = ''
|
|
90
|
+
queueMicrotask(() => searchBox?.focus())
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const shown = $derived.by(() => {
|
|
94
|
+
const needle = search.trim().toLowerCase()
|
|
95
|
+
return needle ? values.filter((v) => v.text.toLowerCase().includes(needle)) : values
|
|
96
|
+
})
|
|
97
|
+
const allShownTicked = $derived(shown.length > 0 && shown.every((v) => ticked.has(v.text)))
|
|
98
|
+
const noneShownTicked = $derived(shown.every((v) => !ticked.has(v.text)))
|
|
99
|
+
|
|
100
|
+
function toggle(text: string) {
|
|
101
|
+
const next = new Set(ticked)
|
|
102
|
+
if (next.has(text)) next.delete(text)
|
|
103
|
+
else next.add(text)
|
|
104
|
+
ticked = next
|
|
105
|
+
mode = 'values'
|
|
106
|
+
}
|
|
107
|
+
function toggleAll() {
|
|
108
|
+
const next = new Set(ticked)
|
|
109
|
+
if (allShownTicked) for (const v of shown) next.delete(v.text)
|
|
110
|
+
else for (const v of shown) next.add(v.text)
|
|
111
|
+
ticked = next
|
|
112
|
+
mode = 'values'
|
|
113
|
+
}
|
|
114
|
+
const needsValue = (op: ExcelFilterOperator | '') => op !== '' && op !== 'isBlank' && op !== 'isNotBlank'
|
|
115
|
+
const conditionValid = $derived(
|
|
116
|
+
(!needsValue(op1) || v1.trim() !== '') && (op1 !== 'between' || v1to.trim() !== '')
|
|
117
|
+
&& (op2 === '' || !needsValue(op2) || v2.trim() !== '') && (op2 !== 'between' || v2to.trim() !== ''),
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
const dateValid = $derived(
|
|
121
|
+
!typedPeriod(period) || (d1.trim() !== '' && (period !== 'between' || d2.trim() !== '')),
|
|
122
|
+
)
|
|
123
|
+
const topValid = $derived(Number.isFinite(topCount) && topCount > 0)
|
|
124
|
+
|
|
125
|
+
function ok() {
|
|
126
|
+
if (mode === 'date') {
|
|
127
|
+
if (!dateValid) return
|
|
128
|
+
onApply({ kind: 'date', period, ...(typedPeriod(period) ? { value: d1.trim() } : {}), ...(period === 'between' ? { valueTo: d2.trim() } : {}) })
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
if (mode === 'top') {
|
|
132
|
+
if (!topValid) return
|
|
133
|
+
onApply({ kind: 'top', top: topSide === 'top', count: Math.trunc(topCount), ...(topUnit === 'percent' ? { percent: true } : {}) })
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
if (mode === 'condition') {
|
|
137
|
+
if (!conditionValid) return
|
|
138
|
+
const first: FilterCondition = { op: op1, ...(needsValue(op1) ? { value: v1.trim() } : {}), ...(op1 === 'between' ? { valueTo: v1to.trim() } : {}) }
|
|
139
|
+
const second: FilterCondition | undefined = op2 === ''
|
|
140
|
+
? undefined
|
|
141
|
+
: { op: op2, ...(needsValue(op2) ? { value: v2.trim() } : {}), ...(op2 === 'between' ? { valueTo: v2to.trim() } : {}) }
|
|
142
|
+
onApply({ kind: 'condition', first, ...(second ? { join, second } : {}) })
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
// A search applies its results, as Excel's does: the values it hides
|
|
146
|
+
// are out, whatever their ticks, and the ticked matches stay.
|
|
147
|
+
const keep = search.trim() ? new Set(shown.filter((v) => ticked.has(v.text)).map((v) => v.text)) : ticked
|
|
148
|
+
onApply(valuesFilter(values.map((v) => v.text), keep))
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function onKeyDown(event: KeyboardEvent) {
|
|
152
|
+
if (event.key === 'Enter' && !(event.target instanceof HTMLButtonElement)) { event.preventDefault(); ok() }
|
|
153
|
+
}
|
|
154
|
+
</script>
|
|
155
|
+
|
|
156
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
157
|
+
<div class="sv-sheet-filter-menu" role="dialog" tabindex="-1" aria-label={t('filter.label', { header })} onkeydown={onKeyDown}>
|
|
158
|
+
<button type="button" class="row" onclick={() => onSort('asc')}>{t(numeric ? 'filter.sortSmallest' : 'filter.sortAsc')}</button>
|
|
159
|
+
<button type="button" class="row" onclick={() => onSort('desc')}>{t(numeric ? 'filter.sortLargest' : 'filter.sortDesc')}</button>
|
|
160
|
+
<hr />
|
|
161
|
+
<button type="button" class="row" disabled={!filter} onclick={() => onApply(null)}>{t('filter.clear', { header })}</button>
|
|
162
|
+
{#if fills.length > 1}
|
|
163
|
+
<!-- Excel's Filter by Color: the fills the column carries, as swatches. -->
|
|
164
|
+
<details class="conditions colours" open={filter?.kind === 'color'}>
|
|
165
|
+
<summary>{t('filter.byColor')}</summary>
|
|
166
|
+
<div class="swatches" role="group" aria-label={t('filter.byColorGroup')}>
|
|
167
|
+
{#each fills as fill (fill ?? '')}
|
|
168
|
+
<button
|
|
169
|
+
type="button"
|
|
170
|
+
class="swatch"
|
|
171
|
+
class:none={fill === null}
|
|
172
|
+
class:on={filter?.kind === 'color' && (filter.fill ?? '') === (fill ?? '')}
|
|
173
|
+
style:background={fill ?? undefined}
|
|
174
|
+
title={fill ?? t('filter.noFill')}
|
|
175
|
+
aria-label={fill ? t('filter.byFill', { fill }) : t('filter.byNoFill')}
|
|
176
|
+
onclick={() => onApply({ kind: 'color', fill })}
|
|
177
|
+
>{#if fill === null}{t('filter.noFill')}{/if}</button>
|
|
178
|
+
{/each}
|
|
179
|
+
</div>
|
|
180
|
+
</details>
|
|
181
|
+
{/if}
|
|
182
|
+
{#if dates}
|
|
183
|
+
<details class="conditions" open={mode === 'date'} ontoggle={(e) => { if ((e.currentTarget as HTMLDetailsElement).open) mode = 'date' }}>
|
|
184
|
+
<summary>{t('filter.dateFilters')}</summary>
|
|
185
|
+
<div class="condition">
|
|
186
|
+
<select bind:value={period} aria-label={t('filter.datePeriod')} onchange={() => (mode = 'date')}>
|
|
187
|
+
{#each PERIODS as id (id)}<option value={id}>{t(`filter.period.${id}`)}</option>{/each}
|
|
188
|
+
</select>
|
|
189
|
+
{#if typedPeriod(period)}<input type="date" bind:value={d1} aria-label={t('filter.date')} oninput={() => (mode = 'date')} />{/if}
|
|
190
|
+
{#if period === 'between'}<span>{t('filter.and')}</span><input type="date" bind:value={d2} aria-label={t('filter.secondDate')} />{/if}
|
|
191
|
+
</div>
|
|
192
|
+
</details>
|
|
193
|
+
{/if}
|
|
194
|
+
<details class="conditions" open={mode === 'condition'} ontoggle={(e) => { if ((e.currentTarget as HTMLDetailsElement).open) mode = 'condition' }}>
|
|
195
|
+
<summary>{t(numeric ? 'filter.numberFilters' : 'filter.textFilters')}</summary>
|
|
196
|
+
<div class="condition">
|
|
197
|
+
<select bind:value={op1} aria-label={t('filter.firstCondition')} onchange={() => (mode = 'condition')}>
|
|
198
|
+
{#each ops as op (op)}<option value={op}>{t(`filter.op.${op}`)}</option>{/each}
|
|
199
|
+
</select>
|
|
200
|
+
{#if needsValue(op1)}<input type="text" bind:value={v1} aria-label={t('filter.firstValue')} oninput={() => (mode = 'condition')} />{/if}
|
|
201
|
+
{#if op1 === 'between'}<span>{t('filter.and')}</span><input type="text" bind:value={v1to} aria-label={t('filter.firstUpperValue')} />{/if}
|
|
202
|
+
</div>
|
|
203
|
+
<div class="join">
|
|
204
|
+
<label class="check"><input type="radio" name="sv-sheet-filter-join" value="and" bind:group={join} /> {t('filter.joinAnd')}</label>
|
|
205
|
+
<label class="check"><input type="radio" name="sv-sheet-filter-join" value="or" bind:group={join} /> {t('filter.joinOr')}</label>
|
|
206
|
+
</div>
|
|
207
|
+
<div class="condition">
|
|
208
|
+
<select bind:value={op2} aria-label={t('filter.secondCondition')}>
|
|
209
|
+
<option value="">{t('filter.none')}</option>
|
|
210
|
+
{#each ops as op (op)}<option value={op}>{t(`filter.op.${op}`)}</option>{/each}
|
|
211
|
+
</select>
|
|
212
|
+
{#if needsValue(op2)}<input type="text" bind:value={v2} aria-label={t('filter.secondValue')} />{/if}
|
|
213
|
+
{#if op2 === 'between'}<span>{t('filter.and')}</span><input type="text" bind:value={v2to} aria-label={t('filter.secondUpperValue')} />{/if}
|
|
214
|
+
</div>
|
|
215
|
+
</details>
|
|
216
|
+
{#if numeric}
|
|
217
|
+
<details class="conditions" open={mode === 'top'} ontoggle={(e) => { if ((e.currentTarget as HTMLDetailsElement).open) mode = 'top' }}>
|
|
218
|
+
<summary>{t('filter.top10')}</summary>
|
|
219
|
+
<div class="condition top">
|
|
220
|
+
<select bind:value={topSide} aria-label={t('filter.topOrBottom')} onchange={() => (mode = 'top')}>
|
|
221
|
+
<option value="top">{t('filter.top')}</option>
|
|
222
|
+
<option value="bottom">{t('filter.bottom')}</option>
|
|
223
|
+
</select>
|
|
224
|
+
<input type="number" min="1" bind:value={topCount} aria-label={t('filter.howMany')} oninput={() => (mode = 'top')} />
|
|
225
|
+
<select bind:value={topUnit} aria-label={t('filter.itemsOrPercent')}>
|
|
226
|
+
<option value="items">{t('filter.items')}</option>
|
|
227
|
+
<option value="percent">{t('filter.percent')}</option>
|
|
228
|
+
</select>
|
|
229
|
+
</div>
|
|
230
|
+
</details>
|
|
231
|
+
{/if}
|
|
232
|
+
<hr />
|
|
233
|
+
<input bind:this={searchBox} type="search" class="search" placeholder={t('filter.search')} aria-label={t('filter.searchValues')} bind:value={search} />
|
|
234
|
+
<div class="values" role="group" aria-label={t('filter.values')}>
|
|
235
|
+
<label class="check all">
|
|
236
|
+
<input type="checkbox" checked={allShownTicked} indeterminate={!allShownTicked && !noneShownTicked} onchange={toggleAll} />
|
|
237
|
+
{t(search.trim() ? 'filter.selectAllResults' : 'filter.selectAll')}
|
|
238
|
+
</label>
|
|
239
|
+
{#each shown as v (v.text)}
|
|
240
|
+
<label class="check">
|
|
241
|
+
<input type="checkbox" checked={ticked.has(v.text)} onchange={() => toggle(v.text)} />
|
|
242
|
+
<span class="text">{v.text === '' ? t('filter.blanks') : v.text}</span>
|
|
243
|
+
<span class="count">{v.count}</span>
|
|
244
|
+
</label>
|
|
245
|
+
{/each}
|
|
246
|
+
{#if shown.length === 0}<div class="none">{t('filter.noMatches')}</div>{/if}
|
|
247
|
+
</div>
|
|
248
|
+
<div class="sv-sheet-dialog-buttons">
|
|
249
|
+
<button type="button" class="btn primary" onclick={ok} disabled={mode === 'condition' ? !conditionValid : mode === 'date' ? !dateValid : mode === 'top' ? !topValid : noneShownTicked && !search.trim()}>{t('ok')}</button>
|
|
250
|
+
<button type="button" class="btn" onclick={onCancel}>{t('cancel')}</button>
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
|
|
254
|
+
<style>
|
|
255
|
+
.sv-sheet-filter-menu {
|
|
256
|
+
display: flex;
|
|
257
|
+
flex-direction: column;
|
|
258
|
+
gap: 4px;
|
|
259
|
+
width: 260px;
|
|
260
|
+
padding: 6px;
|
|
261
|
+
font-size: 12px;
|
|
262
|
+
color: var(--sg-fg, #242424);
|
|
263
|
+
}
|
|
264
|
+
hr { width: 100%; margin: 2px 0; border: 0; border-top: 1px solid var(--sg-border, #d1d1d1); }
|
|
265
|
+
.row {
|
|
266
|
+
padding: 5px 8px;
|
|
267
|
+
font: inherit;
|
|
268
|
+
text-align: left;
|
|
269
|
+
color: inherit;
|
|
270
|
+
background: transparent;
|
|
271
|
+
border: 0;
|
|
272
|
+
border-radius: 3px;
|
|
273
|
+
cursor: pointer;
|
|
274
|
+
}
|
|
275
|
+
.row:hover:not(:disabled) { background: var(--sg-row-hover-bg, #f0f0f0); }
|
|
276
|
+
.row:disabled { opacity: 0.5; cursor: default; }
|
|
277
|
+
.conditions summary { padding: 5px 8px; cursor: pointer; border-radius: 3px; }
|
|
278
|
+
.conditions summary:hover { background: var(--sg-row-hover-bg, #f0f0f0); }
|
|
279
|
+
.condition, .join { display: flex; align-items: center; gap: 6px; padding: 3px 8px; }
|
|
280
|
+
.condition select { flex: 0 0 120px; }
|
|
281
|
+
.condition input { flex: 1 1 60px; min-width: 40px; }
|
|
282
|
+
.condition.top select { flex: 0 0 80px; }
|
|
283
|
+
.condition.top input { flex: 0 0 56px; }
|
|
284
|
+
.swatches { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 8px; }
|
|
285
|
+
.swatch {
|
|
286
|
+
width: 22px;
|
|
287
|
+
height: 22px;
|
|
288
|
+
padding: 0;
|
|
289
|
+
font: inherit;
|
|
290
|
+
font-size: 10px;
|
|
291
|
+
color: inherit;
|
|
292
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
293
|
+
border-radius: 3px;
|
|
294
|
+
cursor: pointer;
|
|
295
|
+
}
|
|
296
|
+
.swatch.none { width: auto; padding: 0 6px; background: var(--sg-bg, #fff); }
|
|
297
|
+
.swatch.on { outline: 2px solid var(--sg-accent, #217346); outline-offset: 1px; }
|
|
298
|
+
select, input[type="text"], .search {
|
|
299
|
+
height: 24px;
|
|
300
|
+
padding: 0 6px;
|
|
301
|
+
font: inherit;
|
|
302
|
+
color: inherit;
|
|
303
|
+
background: var(--sg-bg, #fff);
|
|
304
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
305
|
+
border-radius: 3px;
|
|
306
|
+
}
|
|
307
|
+
.search { width: 100%; box-sizing: border-box; }
|
|
308
|
+
.values {
|
|
309
|
+
max-height: 180px;
|
|
310
|
+
overflow-y: auto;
|
|
311
|
+
padding: 2px 4px;
|
|
312
|
+
border: 1px solid var(--sg-border, #d1d1d1);
|
|
313
|
+
border-radius: 3px;
|
|
314
|
+
}
|
|
315
|
+
.check { display: flex; align-items: center; gap: 6px; padding: 2px 4px; cursor: default; }
|
|
316
|
+
.check.all { font-weight: 600; }
|
|
317
|
+
.check .text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
318
|
+
.check .count { color: var(--sg-muted, #616161); }
|
|
319
|
+
.none { padding: 4px; color: var(--sg-muted, #616161); }
|
|
320
|
+
</style>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ColumnFilter, type FilterValue } from './sheet/auto-filter.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
/** The header text, for Clear Filter From "X". */
|
|
4
|
+
header: string;
|
|
5
|
+
/** The column's values with their counts. */
|
|
6
|
+
values: ReadonlyArray<FilterValue>;
|
|
7
|
+
/** The filter on the column now, if any. */
|
|
8
|
+
filter: ColumnFilter | null;
|
|
9
|
+
/** Whether the column holds numbers, for Number Filters over Text Filters. */
|
|
10
|
+
numeric: boolean;
|
|
11
|
+
/** Whether the column holds dates, for Date Filters. */
|
|
12
|
+
dates?: boolean;
|
|
13
|
+
/** The fills the column's cells carry (null for none), for Filter by
|
|
14
|
+
* Color; the entry is left off with fewer than two. */
|
|
15
|
+
fills?: ReadonlyArray<string | null>;
|
|
16
|
+
onSort: (direction: 'asc' | 'desc') => void;
|
|
17
|
+
onApply: (filter: ColumnFilter | null) => void;
|
|
18
|
+
onCancel: () => void;
|
|
19
|
+
};
|
|
20
|
+
declare const SvSheetFilterMenu: import("svelte").Component<Props, {}, "">;
|
|
21
|
+
type SvSheetFilterMenu = ReturnType<typeof SvSheetFilterMenu>;
|
|
22
|
+
export default SvSheetFilterMenu;
|