@rowsncolumns/spreadsheet-state 28.0.72 → 28.0.74
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/dist/cjs/api/advanced-filter.d.ts +72 -0
- package/dist/cjs/api/advanced-filter.d.ts.map +1 -0
- package/dist/cjs/api/advanced-filter.js +0 -0
- package/dist/cjs/api/goal-seek.d.ts +29 -0
- package/dist/cjs/api/goal-seek.d.ts.map +1 -0
- package/dist/cjs/api/goal-seek.js +131 -0
- package/dist/cjs/api/immer-utils.d.ts.map +1 -1
- package/dist/cjs/api/immer-utils.js +2 -0
- package/dist/cjs/api/paint-format.d.ts +41 -0
- package/dist/cjs/api/paint-format.d.ts.map +1 -0
- package/dist/cjs/api/paint-format.js +115 -0
- package/dist/cjs/api/paste-special.d.ts +48 -0
- package/dist/cjs/api/paste-special.d.ts.map +1 -0
- package/dist/cjs/api/paste-special.js +229 -0
- package/dist/cjs/api/split-text.d.ts +12 -0
- package/dist/cjs/api/split-text.d.ts.map +1 -1
- package/dist/cjs/api/split-text.js +41 -0
- package/dist/cjs/api/subtotal.d.ts +85 -0
- package/dist/cjs/api/subtotal.d.ts.map +1 -0
- package/dist/cjs/api/subtotal.js +250 -0
- package/dist/cjs/commands.d.ts +13 -0
- package/dist/cjs/commands.d.ts.map +1 -1
- package/dist/cjs/components/editors/data-validation-rule-editor.d.ts.map +1 -1
- package/dist/cjs/components/editors/data-validation-rule-editor.js +83 -16
- package/dist/cjs/components/editors/table-editor.js +7 -2
- package/dist/cjs/hooks/use-calculation-worker.d.ts.map +1 -1
- package/dist/cjs/hooks/use-calculation-worker.js +39 -8
- package/dist/cjs/hooks/use-calculation.d.ts +12 -2
- package/dist/cjs/hooks/use-calculation.d.ts.map +1 -1
- package/dist/cjs/hooks/use-calculation.js +71 -35
- package/dist/cjs/hooks/use-on-advanced-filter.d.ts +21 -0
- package/dist/cjs/hooks/use-on-advanced-filter.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-advanced-filter.js +42 -0
- package/dist/cjs/hooks/use-on-goal-seek.d.ts +30 -0
- package/dist/cjs/hooks/use-on-goal-seek.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-goal-seek.js +140 -0
- package/dist/cjs/hooks/use-on-import-excel.d.ts +10 -1
- package/dist/cjs/hooks/use-on-import-excel.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-import-excel.js +8 -4
- package/dist/cjs/hooks/use-on-merge-unmerge-cells.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-merge-unmerge-cells.js +53 -34
- package/dist/cjs/hooks/use-on-paste.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-paste.js +82 -52
- package/dist/cjs/hooks/use-on-remove-duplicates.d.ts +2 -1
- package/dist/cjs/hooks/use-on-remove-duplicates.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-remove-duplicates.js +5 -3
- package/dist/cjs/hooks/use-on-show-column.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-show-column.js +2 -0
- package/dist/cjs/hooks/use-on-show-row.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-show-row.js +2 -0
- package/dist/cjs/hooks/use-on-subtotal.d.ts +26 -0
- package/dist/cjs/hooks/use-on-subtotal.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-subtotal.js +53 -0
- package/dist/cjs/hooks/use-paint-format.d.ts +19 -3
- package/dist/cjs/hooks/use-paint-format.d.ts.map +1 -1
- package/dist/cjs/hooks/use-paint-format.js +85 -31
- package/dist/cjs/hooks/use-sheet-properties.d.ts +3 -0
- package/dist/cjs/hooks/use-sheet-properties.d.ts.map +1 -1
- package/dist/cjs/hooks/use-sheet-properties.js +8 -0
- package/dist/cjs/hooks/use-split-text-to-columns.d.ts +2 -1
- package/dist/cjs/hooks/use-split-text-to-columns.d.ts.map +1 -1
- package/dist/cjs/hooks/use-split-text-to-columns.js +3 -2
- package/dist/cjs/hooks/use-spreadsheet-state.d.ts +50 -36
- package/dist/cjs/hooks/use-spreadsheet-state.d.ts.map +1 -1
- package/dist/cjs/hooks/use-spreadsheet-state.js +98 -18
- package/dist/cjs/index.d.ts +9 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +9 -0
- package/dist/cjs/interface/calculation-interface.d.ts.map +1 -1
- package/dist/cjs/interface/calculation-interface.js +5 -0
- package/dist/cjs/interface/change-batch-stream.d.ts.map +1 -1
- package/dist/cjs/interface/change-batch-stream.js +12 -6
- package/dist/cjs/interface/change-batch.d.ts.map +1 -1
- package/dist/cjs/interface/change-batch.js +17 -9
- package/dist/cjs/interface/change-formatting.d.ts.map +1 -1
- package/dist/cjs/interface/change-formatting.js +30 -11
- package/dist/cjs/interface/hide-column.d.ts.map +1 -1
- package/dist/cjs/interface/hide-column.js +4 -0
- package/dist/cjs/interface/hide-row.d.ts.map +1 -1
- package/dist/cjs/interface/hide-row.js +4 -0
- package/dist/cjs/interface/remove-duplicates.d.ts +3 -2
- package/dist/cjs/interface/remove-duplicates.d.ts.map +1 -1
- package/dist/cjs/interface/remove-duplicates.js +41 -7
- package/dist/cjs/interface/split-text.d.ts +2 -1
- package/dist/cjs/interface/split-text.d.ts.map +1 -1
- package/dist/cjs/interface/split-text.js +7 -3
- package/dist/cjs/interface/spreadsheet-interface.d.ts +2 -1
- package/dist/cjs/interface/spreadsheet-interface.d.ts.map +1 -1
- package/dist/cjs/interface/spreadsheet-interface.js +5 -5
- package/dist/cjs/sheet-cell.d.ts.map +1 -1
- package/dist/cjs/sheet-cell.js +7 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/api/advanced-filter.d.ts +72 -0
- package/dist/esm/api/advanced-filter.d.ts.map +1 -0
- package/dist/esm/api/advanced-filter.js +0 -0
- package/dist/esm/api/goal-seek.d.ts +29 -0
- package/dist/esm/api/goal-seek.d.ts.map +1 -0
- package/dist/esm/api/goal-seek.js +108 -0
- package/dist/esm/api/immer-utils.d.ts.map +1 -1
- package/dist/esm/api/immer-utils.js +2 -0
- package/dist/esm/api/paint-format.d.ts +41 -0
- package/dist/esm/api/paint-format.d.ts.map +1 -0
- package/dist/esm/api/paint-format.js +77 -0
- package/dist/esm/api/paste-special.d.ts +48 -0
- package/dist/esm/api/paste-special.d.ts.map +1 -0
- package/dist/esm/api/paste-special.js +220 -0
- package/dist/esm/api/split-text.d.ts +12 -0
- package/dist/esm/api/split-text.d.ts.map +1 -1
- package/dist/esm/api/split-text.js +28 -0
- package/dist/esm/api/subtotal.d.ts +85 -0
- package/dist/esm/api/subtotal.d.ts.map +1 -0
- package/dist/esm/api/subtotal.js +181 -0
- package/dist/esm/commands.d.ts +13 -0
- package/dist/esm/commands.d.ts.map +1 -1
- package/dist/esm/components/editors/data-validation-rule-editor.d.ts.map +1 -1
- package/dist/esm/components/editors/data-validation-rule-editor.js +52 -4
- package/dist/esm/components/editors/table-editor.js +7 -4
- package/dist/esm/hooks/use-calculation-worker.d.ts.map +1 -1
- package/dist/esm/hooks/use-calculation-worker.js +20 -2
- package/dist/esm/hooks/use-calculation.d.ts +12 -2
- package/dist/esm/hooks/use-calculation.d.ts.map +1 -1
- package/dist/esm/hooks/use-calculation.js +38 -7
- package/dist/esm/hooks/use-on-advanced-filter.d.ts +21 -0
- package/dist/esm/hooks/use-on-advanced-filter.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-advanced-filter.js +41 -0
- package/dist/esm/hooks/use-on-goal-seek.d.ts +30 -0
- package/dist/esm/hooks/use-on-goal-seek.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-goal-seek.js +82 -0
- package/dist/esm/hooks/use-on-import-excel.d.ts +10 -1
- package/dist/esm/hooks/use-on-import-excel.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-import-excel.js +8 -4
- package/dist/esm/hooks/use-on-merge-unmerge-cells.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-merge-unmerge-cells.js +13 -13
- package/dist/esm/hooks/use-on-paste.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-paste.js +49 -14
- package/dist/esm/hooks/use-on-remove-duplicates.d.ts +2 -1
- package/dist/esm/hooks/use-on-remove-duplicates.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-remove-duplicates.js +5 -3
- package/dist/esm/hooks/use-on-show-column.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-show-column.js +2 -0
- package/dist/esm/hooks/use-on-show-row.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-show-row.js +2 -0
- package/dist/esm/hooks/use-on-subtotal.d.ts +26 -0
- package/dist/esm/hooks/use-on-subtotal.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-subtotal.js +48 -0
- package/dist/esm/hooks/use-paint-format.d.ts +19 -3
- package/dist/esm/hooks/use-paint-format.d.ts.map +1 -1
- package/dist/esm/hooks/use-paint-format.js +71 -29
- package/dist/esm/hooks/use-sheet-properties.d.ts +3 -0
- package/dist/esm/hooks/use-sheet-properties.d.ts.map +1 -1
- package/dist/esm/hooks/use-sheet-properties.js +8 -0
- package/dist/esm/hooks/use-split-text-to-columns.d.ts +2 -1
- package/dist/esm/hooks/use-split-text-to-columns.d.ts.map +1 -1
- package/dist/esm/hooks/use-split-text-to-columns.js +3 -2
- package/dist/esm/hooks/use-spreadsheet-state.d.ts +50 -36
- package/dist/esm/hooks/use-spreadsheet-state.d.ts.map +1 -1
- package/dist/esm/hooks/use-spreadsheet-state.js +89 -16
- package/dist/esm/index.d.ts +9 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +9 -0
- package/dist/esm/interface/calculation-interface.d.ts.map +1 -1
- package/dist/esm/interface/calculation-interface.js +3 -0
- package/dist/esm/interface/change-batch-stream.d.ts.map +1 -1
- package/dist/esm/interface/change-batch-stream.js +12 -6
- package/dist/esm/interface/change-batch.d.ts.map +1 -1
- package/dist/esm/interface/change-batch.js +15 -9
- package/dist/esm/interface/change-formatting.d.ts.map +1 -1
- package/dist/esm/interface/change-formatting.js +28 -11
- package/dist/esm/interface/hide-column.d.ts.map +1 -1
- package/dist/esm/interface/hide-column.js +4 -0
- package/dist/esm/interface/hide-row.d.ts.map +1 -1
- package/dist/esm/interface/hide-row.js +4 -0
- package/dist/esm/interface/remove-duplicates.d.ts +3 -2
- package/dist/esm/interface/remove-duplicates.d.ts.map +1 -1
- package/dist/esm/interface/remove-duplicates.js +37 -6
- package/dist/esm/interface/split-text.d.ts +2 -1
- package/dist/esm/interface/split-text.d.ts.map +1 -1
- package/dist/esm/interface/split-text.js +6 -3
- package/dist/esm/interface/spreadsheet-interface.d.ts +2 -1
- package/dist/esm/interface/spreadsheet-interface.d.ts.map +1 -1
- package/dist/esm/interface/spreadsheet-interface.js +5 -5
- package/dist/esm/sheet-cell.d.ts.map +1 -1
- package/dist/esm/sheet-cell.js +7 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +18 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"immer-utils.d.ts","sourceRoot":"","sources":["../../../api/immer-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,IAAI,2BAA2B,EAC/C,SAAS,IAAI,oBAAoB,EAClC,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAI7E,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACZ,MAAM,2BAA2B,CAAC;AASnC,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAQxE,KAAK,SAAS,CAAC,CAAC,SAAS,QAAQ,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAC7D,KAAK,gBAAgB,CAAC,CAAC,SAAS,QAAQ,GAAG,IAAI,GAAG,SAAS,IACzD,2BAA2B,CAAC,CAAC,CAAC,CAAC;AAEjC,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,QAAQ,EACjD,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAC1B,SAAS,MAAM,EACf,WAAW,MAAM,KAgBD,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,EAC9D,CAAC;AAGF,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,QAAQ,EACvD,SAAS,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,KACjE,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAa9C,CAAC;AAGF,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAAS,QAAQ,EACxD,UAAU,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,oBAItC,CAAC;
|
|
1
|
+
{"version":3,"file":"immer-utils.d.ts","sourceRoot":"","sources":["../../../api/immer-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,6 +67,8 @@ const formatDerivationRules = {
|
|
|
67
67
|
UNIQUE: { type: "fixed_index", index: 0 },
|
|
68
68
|
TAKE: { type: "fixed_index", index: 0 },
|
|
69
69
|
DROP: { type: "fixed_index", index: 0 },
|
|
70
|
+
TRIMRANGE: { type: "fixed_index", index: 0 },
|
|
71
|
+
EXPAND: { type: "fixed_index", index: 0 },
|
|
70
72
|
TOCOL: { type: "fixed_index", index: 0 },
|
|
71
73
|
TOROW: { type: "fixed_index", index: 0 },
|
|
72
74
|
WRAPROWS: { type: "fixed_index", index: 0 },
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { CellFormat, GridRange } from "@rowsncolumns/common-types";
|
|
2
|
+
/**
|
|
3
|
+
* Format-painter pattern shared by both engines: the captured 2-D format grid plus the
|
|
4
|
+
* source block's merge configuration, re-based to the block's top-left so it can be tiled
|
|
5
|
+
* onto any target (Google Sheets copies merges with the format; Excel's painter does too).
|
|
6
|
+
*/
|
|
7
|
+
export type PaintPattern = {
|
|
8
|
+
formats: (CellFormat | null | undefined)[][];
|
|
9
|
+
/** Merges fully inside the source block, as 0-based offsets from its top-left. */
|
|
10
|
+
merges: GridRange[];
|
|
11
|
+
/** Source block size — the tiling period. */
|
|
12
|
+
rows: number;
|
|
13
|
+
cols: number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The merges the painter carries from a source block: every merge that lies FULLY inside
|
|
17
|
+
* `source`, re-based to 0-based offsets from the block's top-left. A merge reaching outside the
|
|
18
|
+
* block is not part of its pattern (Sheets/Excel behave the same — the painter copies the look of
|
|
19
|
+
* the selected cells, not of the cells around them).
|
|
20
|
+
*/
|
|
21
|
+
export declare const collectPaintMerges: (merges: GridRange[] | null | undefined, source: GridRange) => GridRange[];
|
|
22
|
+
/**
|
|
23
|
+
* Tile a pattern's relative merges across `target` with the pattern's period (`rows` × `cols`),
|
|
24
|
+
* the same way the format grid itself is tiled by the formatting applier. A merge that a partial
|
|
25
|
+
* trailing tile would push past the target's edge is dropped — the painter never creates a merge
|
|
26
|
+
* that the user did not drag over.
|
|
27
|
+
*/
|
|
28
|
+
export declare const tilePaintMerges: (relativeMerges: GridRange[], rows: number, cols: number, target: GridRange) => GridRange[];
|
|
29
|
+
/**
|
|
30
|
+
* The banded (table stripe / alternating-colour) format the grid paints under a cell, looked up
|
|
31
|
+
* in the map `getBandedCells` builds for a sheet.
|
|
32
|
+
*/
|
|
33
|
+
export declare const getBandedCellFormat: (bandedCells: Map<string, CellFormat> | undefined | null, rowIndex: number, columnIndex: number) => CellFormat | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Layer a cell's explicit format over the banded format the grid would paint beneath it, so the
|
|
36
|
+
* captured pattern carries the VISIBLE look (Sheets copies the alternating colours as static cell
|
|
37
|
+
* fills — it does not create a table or banding at the target). Explicit keys win; an explicit
|
|
38
|
+
* `undefined` never clobbers a banded value.
|
|
39
|
+
*/
|
|
40
|
+
export declare const layerBandedFormat: (explicit: CellFormat | null | undefined, banded: CellFormat | undefined) => CellFormat | null | undefined;
|
|
41
|
+
//# sourceMappingURL=paint-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paint-format.d.ts","sourceRoot":"","sources":["../../../api/paint-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAGxE;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,CAAC,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAAE,CAAC;IAC7C,kFAAkF;IAClF,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAQF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,SAAS,EAAE,GAAG,IAAI,GAAG,SAAS,EACtC,QAAQ,SAAS,KAChB,SAAS,EAaX,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,gBAAgB,SAAS,EAAE,EAC3B,MAAM,MAAM,EACZ,MAAM,MAAM,EACZ,QAAQ,SAAS,KAChB,SAAS,EAqBX,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAC9B,aAAa,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,SAAS,GAAG,IAAI,EACvD,UAAU,MAAM,EAChB,aAAa,MAAM,KAClB,UAAU,GAAG,SACyC,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAU,UAAU,GAAG,IAAI,GAAG,SAAS,EACvC,QAAQ,UAAU,GAAG,SAAS,KAC7B,UAAU,GAAG,IAAI,GAAG,SAWtB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { cellIdentifier } from "@rowsncolumns/grid";
|
|
2
|
+
const rangeContains = (outer, inner) => inner.startRowIndex >= outer.startRowIndex &&
|
|
3
|
+
inner.endRowIndex <= outer.endRowIndex &&
|
|
4
|
+
inner.startColumnIndex >= outer.startColumnIndex &&
|
|
5
|
+
inner.endColumnIndex <= outer.endColumnIndex;
|
|
6
|
+
/**
|
|
7
|
+
* The merges the painter carries from a source block: every merge that lies FULLY inside
|
|
8
|
+
* `source`, re-based to 0-based offsets from the block's top-left. A merge reaching outside the
|
|
9
|
+
* block is not part of its pattern (Sheets/Excel behave the same — the painter copies the look of
|
|
10
|
+
* the selected cells, not of the cells around them).
|
|
11
|
+
*/
|
|
12
|
+
export const collectPaintMerges = (merges, source) => {
|
|
13
|
+
if (!merges?.length)
|
|
14
|
+
return [];
|
|
15
|
+
const out = [];
|
|
16
|
+
for (const merge of merges) {
|
|
17
|
+
if (!rangeContains(source, merge))
|
|
18
|
+
continue;
|
|
19
|
+
out.push({
|
|
20
|
+
startRowIndex: merge.startRowIndex - source.startRowIndex,
|
|
21
|
+
endRowIndex: merge.endRowIndex - source.startRowIndex,
|
|
22
|
+
startColumnIndex: merge.startColumnIndex - source.startColumnIndex,
|
|
23
|
+
endColumnIndex: merge.endColumnIndex - source.startColumnIndex,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Tile a pattern's relative merges across `target` with the pattern's period (`rows` × `cols`),
|
|
30
|
+
* the same way the format grid itself is tiled by the formatting applier. A merge that a partial
|
|
31
|
+
* trailing tile would push past the target's edge is dropped — the painter never creates a merge
|
|
32
|
+
* that the user did not drag over.
|
|
33
|
+
*/
|
|
34
|
+
export const tilePaintMerges = (relativeMerges, rows, cols, target) => {
|
|
35
|
+
if (!relativeMerges.length || rows <= 0 || cols <= 0)
|
|
36
|
+
return [];
|
|
37
|
+
const out = [];
|
|
38
|
+
for (let top = target.startRowIndex; top <= target.endRowIndex; top += rows) {
|
|
39
|
+
for (let left = target.startColumnIndex; left <= target.endColumnIndex; left += cols) {
|
|
40
|
+
for (const merge of relativeMerges) {
|
|
41
|
+
const placed = {
|
|
42
|
+
startRowIndex: top + merge.startRowIndex,
|
|
43
|
+
endRowIndex: top + merge.endRowIndex,
|
|
44
|
+
startColumnIndex: left + merge.startColumnIndex,
|
|
45
|
+
endColumnIndex: left + merge.endColumnIndex,
|
|
46
|
+
};
|
|
47
|
+
if (rangeContains(target, placed))
|
|
48
|
+
out.push(placed);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* The banded (table stripe / alternating-colour) format the grid paints under a cell, looked up
|
|
56
|
+
* in the map `getBandedCells` builds for a sheet.
|
|
57
|
+
*/
|
|
58
|
+
export const getBandedCellFormat = (bandedCells, rowIndex, columnIndex) => bandedCells?.get(cellIdentifier(rowIndex, columnIndex));
|
|
59
|
+
/**
|
|
60
|
+
* Layer a cell's explicit format over the banded format the grid would paint beneath it, so the
|
|
61
|
+
* captured pattern carries the VISIBLE look (Sheets copies the alternating colours as static cell
|
|
62
|
+
* fills — it does not create a table or banding at the target). Explicit keys win; an explicit
|
|
63
|
+
* `undefined` never clobbers a banded value.
|
|
64
|
+
*/
|
|
65
|
+
export const layerBandedFormat = (explicit, banded) => {
|
|
66
|
+
if (!banded)
|
|
67
|
+
return explicit;
|
|
68
|
+
const merged = { ...banded };
|
|
69
|
+
if (explicit) {
|
|
70
|
+
for (const [key, value] of Object.entries(explicit)) {
|
|
71
|
+
if (value !== undefined) {
|
|
72
|
+
merged[key] = value;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return merged;
|
|
77
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { CellData, PasteSpecialOperation, PasteSpecialOptions, PasteSpecialType } from "@rowsncolumns/spreadsheet";
|
|
2
|
+
/** Synthetic clipboard key carrying the legacy single-mode `PasteSpecialType`. */
|
|
3
|
+
export declare const PASTE_SPECIAL_TYPE_KEY = "pasteSpecialType";
|
|
4
|
+
/** Synthetic clipboard key carrying a JSON-encoded `PasteSpecialOptions`. */
|
|
5
|
+
export declare const PASTE_SPECIAL_OPTIONS_KEY = "pasteSpecialOptions";
|
|
6
|
+
export type ResolvedPasteSpecialOptions = {
|
|
7
|
+
paste: NonNullable<PasteSpecialOptions["paste"]>;
|
|
8
|
+
operation?: PasteSpecialOperation;
|
|
9
|
+
skipBlanks: boolean;
|
|
10
|
+
transpose: boolean;
|
|
11
|
+
/** True when any Paste Special mode is active (the destination is not a plain overwrite). */
|
|
12
|
+
isSpecial: boolean;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Normalize a `PasteSpecialOptions` (or the legacy single-mode string) into
|
|
16
|
+
* the flags the paste pipelines branch on.
|
|
17
|
+
*/
|
|
18
|
+
export declare const normalizePasteSpecialOptions: (input: PasteSpecialOptions | PasteSpecialType | null | undefined) => ResolvedPasteSpecialOptions;
|
|
19
|
+
/**
|
|
20
|
+
* Read the Paste Special request the grid stashed on the clipboard event
|
|
21
|
+
* (`pasteSpecialOptions` JSON wins over the legacy `pasteSpecialType`).
|
|
22
|
+
*/
|
|
23
|
+
export declare const resolvePasteSpecialOptions: (clipboardData: Pick<DataTransfer, "getData"> | null | undefined) => ResolvedPasteSpecialOptions;
|
|
24
|
+
/**
|
|
25
|
+
* A clipboard cell that carries no value: Paste Special "Skip blanks" leaves
|
|
26
|
+
* the destination untouched for these. A shared-string reference counts as a
|
|
27
|
+
* value.
|
|
28
|
+
*/
|
|
29
|
+
export declare const isBlankClipboardCell: (cell: CellData | null | undefined) => boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Excel Paste Special → Operation. Combines one clipboard cell with the
|
|
32
|
+
* destination cell it lands on and returns the cell data to write there:
|
|
33
|
+
*
|
|
34
|
+
* - number ⊕ number → the arithmetic result (blank destination counts as 0,
|
|
35
|
+
* numeric text is coerced; a non-finite result such as `x/0` is written as
|
|
36
|
+
* the formula `=x/0` so the cell shows `#DIV/0!`).
|
|
37
|
+
* - a formula on either side → a combined formula (`=(dest)+(source)`), the
|
|
38
|
+
* source formula already relocated to the destination by the paste.
|
|
39
|
+
* - blank source → the destination is left as it is (Excel: `d + 0`; the
|
|
40
|
+
* classic "paste-add a blank cell" trick still coerces numeric text).
|
|
41
|
+
* - non-numeric text destination → left as it is.
|
|
42
|
+
* - non-numeric text source → `=dest+"text"` (Excel's `#VALUE!`).
|
|
43
|
+
*
|
|
44
|
+
* `paste: "values"` callers pre-resolve the source to values with
|
|
45
|
+
* `pickValue`, so the source side is never a formula there.
|
|
46
|
+
*/
|
|
47
|
+
export declare const applyPasteOperation: <T extends CellData>(source: T | CellData | null | undefined, destination: CellData | null | undefined, operation: PasteSpecialOperation, sheetId: number, locale?: string) => CellData;
|
|
48
|
+
//# sourceMappingURL=paste-special.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paste-special.d.ts","sourceRoot":"","sources":["../../../api/paste-special.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AAanC,kFAAkF;AAClF,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,6EAA6E;AAC7E,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,EAAE,WAAW,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,6FAA6F;IAC7F,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AA+BF;;;GAGG;AACH,eAAO,MAAM,4BAA4B,GACvC,OAAO,mBAAmB,GAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,KAC/D,2BAsBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GACrC,eAAe,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,KAC9D,2BAkBF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,SAAS,KAChC,OAWF,CAAC;AA8FF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,QAAQ,EACpD,QAAQ,CAAC,GAAG,QAAQ,GAAG,IAAI,GAAG,SAAS,EACvC,aAAa,QAAQ,GAAG,IAAI,GAAG,SAAS,EACxC,WAAW,qBAAqB,EAChC,SAAS,MAAM,EACf,SAAS,MAAM,KACd,QAmCF,CAAC"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { getCellUserEnteredValue, getExtendedValueBool, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, isNil, } from "@rowsncolumns/utils";
|
|
2
|
+
import { SheetCell } from "../sheet-cell";
|
|
3
|
+
import { convertToNumber, isNumber } from "./datatype";
|
|
4
|
+
/** Synthetic clipboard key carrying the legacy single-mode `PasteSpecialType`. */
|
|
5
|
+
export const PASTE_SPECIAL_TYPE_KEY = "pasteSpecialType";
|
|
6
|
+
/** Synthetic clipboard key carrying a JSON-encoded `PasteSpecialOptions`. */
|
|
7
|
+
export const PASTE_SPECIAL_OPTIONS_KEY = "pasteSpecialOptions";
|
|
8
|
+
const PLAIN_PASTE = {
|
|
9
|
+
paste: "all",
|
|
10
|
+
skipBlanks: false,
|
|
11
|
+
transpose: false,
|
|
12
|
+
isSpecial: false,
|
|
13
|
+
};
|
|
14
|
+
const LEGACY_TYPE_TO_OPTIONS = {
|
|
15
|
+
Transposed: { transpose: true },
|
|
16
|
+
Formatting: { paste: "formats" },
|
|
17
|
+
Formula: { paste: "formulas" },
|
|
18
|
+
Value: { paste: "values" },
|
|
19
|
+
Link: {},
|
|
20
|
+
};
|
|
21
|
+
const isOperation = (value) => value === "add" ||
|
|
22
|
+
value === "subtract" ||
|
|
23
|
+
value === "multiply" ||
|
|
24
|
+
value === "divide";
|
|
25
|
+
const isPasteMode = (value) => value === "all" ||
|
|
26
|
+
value === "values" ||
|
|
27
|
+
value === "formulas" ||
|
|
28
|
+
value === "formats";
|
|
29
|
+
/**
|
|
30
|
+
* Normalize a `PasteSpecialOptions` (or the legacy single-mode string) into
|
|
31
|
+
* the flags the paste pipelines branch on.
|
|
32
|
+
*/
|
|
33
|
+
export const normalizePasteSpecialOptions = (input) => {
|
|
34
|
+
if (!input)
|
|
35
|
+
return PLAIN_PASTE;
|
|
36
|
+
const options = typeof input === "string" ? LEGACY_TYPE_TO_OPTIONS[input] ?? {} : input;
|
|
37
|
+
const paste = isPasteMode(options.paste) ? options.paste : "all";
|
|
38
|
+
// Excel greys Operation out under Paste → Formats: a formats paste never
|
|
39
|
+
// touches destination values, so an operation is dropped here for both
|
|
40
|
+
// pipelines rather than each guarding separately.
|
|
41
|
+
const operation = paste !== "formats" && isOperation(options.operation)
|
|
42
|
+
? options.operation
|
|
43
|
+
: undefined;
|
|
44
|
+
const skipBlanks = Boolean(options.skipBlanks);
|
|
45
|
+
const transpose = Boolean(options.transpose);
|
|
46
|
+
return {
|
|
47
|
+
paste,
|
|
48
|
+
operation,
|
|
49
|
+
skipBlanks,
|
|
50
|
+
transpose,
|
|
51
|
+
isSpecial: paste !== "all" || operation !== undefined || skipBlanks || transpose,
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Read the Paste Special request the grid stashed on the clipboard event
|
|
56
|
+
* (`pasteSpecialOptions` JSON wins over the legacy `pasteSpecialType`).
|
|
57
|
+
*/
|
|
58
|
+
export const resolvePasteSpecialOptions = (clipboardData) => {
|
|
59
|
+
if (!clipboardData)
|
|
60
|
+
return PLAIN_PASTE;
|
|
61
|
+
const encoded = clipboardData.getData(PASTE_SPECIAL_OPTIONS_KEY);
|
|
62
|
+
if (encoded) {
|
|
63
|
+
try {
|
|
64
|
+
const parsed = JSON.parse(encoded);
|
|
65
|
+
if (parsed && typeof parsed === "object") {
|
|
66
|
+
return normalizePasteSpecialOptions(parsed);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Fall through to the legacy key
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const legacy = clipboardData.getData(PASTE_SPECIAL_TYPE_KEY);
|
|
74
|
+
return normalizePasteSpecialOptions(legacy || undefined);
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* A clipboard cell that carries no value: Paste Special "Skip blanks" leaves
|
|
78
|
+
* the destination untouched for these. A shared-string reference counts as a
|
|
79
|
+
* value.
|
|
80
|
+
*/
|
|
81
|
+
export const isBlankClipboardCell = (cell) => {
|
|
82
|
+
if (isNil(cell))
|
|
83
|
+
return true;
|
|
84
|
+
if (!isNil(cell.ss))
|
|
85
|
+
return false;
|
|
86
|
+
const ue = getCellUserEnteredValue(cell);
|
|
87
|
+
if (isNil(ue))
|
|
88
|
+
return true;
|
|
89
|
+
return (isNil(getExtendedValueFormula(ue)) &&
|
|
90
|
+
isNil(getExtendedValueNumber(ue)) &&
|
|
91
|
+
isNil(getExtendedValueString(ue)) &&
|
|
92
|
+
isNil(getExtendedValueBool(ue)));
|
|
93
|
+
};
|
|
94
|
+
const classifyOperand = (cell, locale) => {
|
|
95
|
+
if (isNil(cell))
|
|
96
|
+
return { kind: "blank" };
|
|
97
|
+
const ue = getCellUserEnteredValue(cell);
|
|
98
|
+
const formula = getExtendedValueFormula(ue);
|
|
99
|
+
if (!isNil(formula)) {
|
|
100
|
+
const body = formula.trim().replace(/^=/, "");
|
|
101
|
+
return body ? { kind: "formula", body } : { kind: "blank" };
|
|
102
|
+
}
|
|
103
|
+
const nv = getExtendedValueNumber(ue);
|
|
104
|
+
if (!isNil(nv))
|
|
105
|
+
return { kind: "number", value: nv };
|
|
106
|
+
const bv = getExtendedValueBool(ue);
|
|
107
|
+
if (!isNil(bv))
|
|
108
|
+
return { kind: "number", value: bv ? 1 : 0 };
|
|
109
|
+
const sv = getExtendedValueString(ue);
|
|
110
|
+
if (isNil(sv) || sv === "")
|
|
111
|
+
return { kind: "blank" };
|
|
112
|
+
if (isNumber(sv, locale)) {
|
|
113
|
+
return { kind: "number", value: convertToNumber(sv, locale) };
|
|
114
|
+
}
|
|
115
|
+
return { kind: "text", value: sv };
|
|
116
|
+
};
|
|
117
|
+
const OPERATOR = {
|
|
118
|
+
add: "+",
|
|
119
|
+
subtract: "-",
|
|
120
|
+
multiply: "*",
|
|
121
|
+
divide: "/",
|
|
122
|
+
};
|
|
123
|
+
const compute = (operation, left, right) => {
|
|
124
|
+
switch (operation) {
|
|
125
|
+
case "add":
|
|
126
|
+
return left + right;
|
|
127
|
+
case "subtract":
|
|
128
|
+
return left - right;
|
|
129
|
+
case "multiply":
|
|
130
|
+
return left * right;
|
|
131
|
+
case "divide":
|
|
132
|
+
return left / right;
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
const numberLiteral = (value) => value < 0 ? `(${String(value)})` : String(value);
|
|
136
|
+
/** Render an operand as a formula fragment (a formula body is parenthesized). */
|
|
137
|
+
const toFormulaFragment = (operand) => {
|
|
138
|
+
switch (operand.kind) {
|
|
139
|
+
case "blank":
|
|
140
|
+
return "0";
|
|
141
|
+
case "number":
|
|
142
|
+
return numberLiteral(operand.value);
|
|
143
|
+
case "formula":
|
|
144
|
+
return `(${operand.body})`;
|
|
145
|
+
case "text":
|
|
146
|
+
return `"${operand.value.replace(/"/g, '""')}"`;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Strip every value facet from a clipboard cell, keeping its formatting so a
|
|
151
|
+
* "Paste all + operation" still carries the source formats.
|
|
152
|
+
*/
|
|
153
|
+
const withoutValue = (cell) => {
|
|
154
|
+
if (isNil(cell))
|
|
155
|
+
return {};
|
|
156
|
+
const { ue: _ue, ev: _ev, fv: _fv, ss: _ss, userEnteredValue: _userEnteredValue, effectiveValue: _effectiveValue, formattedValue: _formattedValue, ...rest } = cell;
|
|
157
|
+
return rest;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Excel Paste Special → Operation. Combines one clipboard cell with the
|
|
161
|
+
* destination cell it lands on and returns the cell data to write there:
|
|
162
|
+
*
|
|
163
|
+
* - number ⊕ number → the arithmetic result (blank destination counts as 0,
|
|
164
|
+
* numeric text is coerced; a non-finite result such as `x/0` is written as
|
|
165
|
+
* the formula `=x/0` so the cell shows `#DIV/0!`).
|
|
166
|
+
* - a formula on either side → a combined formula (`=(dest)+(source)`), the
|
|
167
|
+
* source formula already relocated to the destination by the paste.
|
|
168
|
+
* - blank source → the destination is left as it is (Excel: `d + 0`; the
|
|
169
|
+
* classic "paste-add a blank cell" trick still coerces numeric text).
|
|
170
|
+
* - non-numeric text destination → left as it is.
|
|
171
|
+
* - non-numeric text source → `=dest+"text"` (Excel's `#VALUE!`).
|
|
172
|
+
*
|
|
173
|
+
* `paste: "values"` callers pre-resolve the source to values with
|
|
174
|
+
* `pickValue`, so the source side is never a formula there.
|
|
175
|
+
*/
|
|
176
|
+
export const applyPasteOperation = (source, destination, operation, sheetId, locale) => {
|
|
177
|
+
const src = classifyOperand(source, locale);
|
|
178
|
+
const dst = classifyOperand(destination, locale);
|
|
179
|
+
const base = withoutValue(source);
|
|
180
|
+
const keepDestination = () => {
|
|
181
|
+
const destinationValue = getCellUserEnteredValue(destination);
|
|
182
|
+
return isNil(destinationValue) ? base : { ...base, ue: destinationValue };
|
|
183
|
+
};
|
|
184
|
+
if (dst.kind === "text") {
|
|
185
|
+
return keepDestination();
|
|
186
|
+
}
|
|
187
|
+
if (src.kind === "blank") {
|
|
188
|
+
if (dst.kind === "number" &&
|
|
189
|
+
(operation === "add" || operation === "subtract")) {
|
|
190
|
+
// `d + 0` — the destination's numeric text becomes a number.
|
|
191
|
+
return writeValue(base, dst.value, sheetId, locale);
|
|
192
|
+
}
|
|
193
|
+
return keepDestination();
|
|
194
|
+
}
|
|
195
|
+
const leftIsNumeric = dst.kind === "blank" || dst.kind === "number";
|
|
196
|
+
if (leftIsNumeric && src.kind === "number") {
|
|
197
|
+
const left = dst.kind === "number" ? dst.value : 0;
|
|
198
|
+
const result = compute(operation, left, src.value);
|
|
199
|
+
if (Number.isFinite(result)) {
|
|
200
|
+
return writeValue(base, result, sheetId, locale);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const formula = `=${toFormulaFragment(dst)}${OPERATOR[operation]}${toFormulaFragment(src)}`;
|
|
204
|
+
return writeValue(base, formula, sheetId, locale);
|
|
205
|
+
};
|
|
206
|
+
const writeValue = (base, value, sheetId, locale) => {
|
|
207
|
+
const sheetCell = new SheetCell();
|
|
208
|
+
sheetCell.setLocale(locale);
|
|
209
|
+
sheetCell.assign(sheetId, undefined, base);
|
|
210
|
+
sheetCell.setUserEnteredValue(value);
|
|
211
|
+
const result = sheetCell.getCellData() ?? { ...base };
|
|
212
|
+
// Typing a number stamps an inferred `uf.numberFormat`; an unformatted
|
|
213
|
+
// source (values-only paste) must stay unformatted so the destination's
|
|
214
|
+
// own format survives the merge.
|
|
215
|
+
if (!base.uf && result.uf) {
|
|
216
|
+
const { uf: _uf, ...rest } = result;
|
|
217
|
+
return rest;
|
|
218
|
+
}
|
|
219
|
+
return result;
|
|
220
|
+
};
|
|
@@ -1,2 +1,14 @@
|
|
|
1
|
+
import type { SplitTextOptions } from "@rowsncolumns/spreadsheet";
|
|
1
2
|
export declare const splitTextToColumns: (values: (string | null | undefined)[], delimiter?: string) => string[][];
|
|
3
|
+
export type { SplitTextOptions };
|
|
4
|
+
/** Normalized, ascending, de-duplicated positive break positions. */
|
|
5
|
+
export declare const normalizeColumnBreaks: (columnBreaks: number[]) => number[];
|
|
6
|
+
/**
|
|
7
|
+
* Excel's Text to Columns → Fixed width: cut each cell at the given
|
|
8
|
+
* character positions. Fields are trimmed like the delimited path (Excel's
|
|
9
|
+
* General column data format drops the padding spaces fixed-width data is
|
|
10
|
+
* aligned with). Cells without breaks inside their text still split — the
|
|
11
|
+
* trailing fields are empty — so the resulting block is rectangular.
|
|
12
|
+
*/
|
|
13
|
+
export declare const splitTextFixedWidth: (values: (string | null | undefined)[], columnBreaks: number[]) => string[][];
|
|
2
14
|
//# sourceMappingURL=split-text.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"split-text.d.ts","sourceRoot":"","sources":["../../../api/split-text.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"split-text.d.ts","sourceRoot":"","sources":["../../../api/split-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,YAAW,MAAY,KACtB,MAAM,EAAE,EAwBV,CAAC;AAEF,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,GAAI,cAAc,MAAM,EAAE,KAAG,MAAM,EAG3C,CAAC;AAE3B;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,cAAc,MAAM,EAAE,KACrB,MAAM,EAAE,EAgBV,CAAC"}
|
|
@@ -22,3 +22,31 @@ export const splitTextToColumns = (values, delimiter = ",") => {
|
|
|
22
22
|
return trimmedParts;
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
|
+
/** Normalized, ascending, de-duplicated positive break positions. */
|
|
26
|
+
export const normalizeColumnBreaks = (columnBreaks) => [...new Set(columnBreaks)]
|
|
27
|
+
.filter((position) => Number.isInteger(position) && position > 0)
|
|
28
|
+
.sort((a, b) => a - b);
|
|
29
|
+
/**
|
|
30
|
+
* Excel's Text to Columns → Fixed width: cut each cell at the given
|
|
31
|
+
* character positions. Fields are trimmed like the delimited path (Excel's
|
|
32
|
+
* General column data format drops the padding spaces fixed-width data is
|
|
33
|
+
* aligned with). Cells without breaks inside their text still split — the
|
|
34
|
+
* trailing fields are empty — so the resulting block is rectangular.
|
|
35
|
+
*/
|
|
36
|
+
export const splitTextFixedWidth = (values, columnBreaks) => {
|
|
37
|
+
const breaks = normalizeColumnBreaks(columnBreaks);
|
|
38
|
+
return values.map((cell) => {
|
|
39
|
+
if (isNil(cell)) {
|
|
40
|
+
return [""];
|
|
41
|
+
}
|
|
42
|
+
const text = String(cell);
|
|
43
|
+
const parts = [];
|
|
44
|
+
let start = 0;
|
|
45
|
+
for (const position of breaks) {
|
|
46
|
+
parts.push(text.slice(start, position).trim());
|
|
47
|
+
start = position;
|
|
48
|
+
}
|
|
49
|
+
parts.push(text.slice(start).trim());
|
|
50
|
+
return parts;
|
|
51
|
+
});
|
|
52
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { GridRange } from "@rowsncolumns/common-types";
|
|
2
|
+
import { SUBTOTAL_FUNCTIONS, type SubtotalFunction, type SubtotalOptions } from "@rowsncolumns/spreadsheet";
|
|
3
|
+
export { SUBTOTAL_FUNCTIONS };
|
|
4
|
+
export type { SubtotalFunction, SubtotalOptions };
|
|
5
|
+
/**
|
|
6
|
+
* The `SUBTOTAL(function_num, …)` code each "Use function" entry writes.
|
|
7
|
+
* Codes 1–11 (not 101–111): the subtotal rows Excel inserts count manually
|
|
8
|
+
* hidden rows.
|
|
9
|
+
*/
|
|
10
|
+
export declare const SUBTOTAL_FUNCTION_NUMBERS: Record<SubtotalFunction, number>;
|
|
11
|
+
/** Excel's total-row labels: "<group> Total" per group, "Grand Total" at the bottom. */
|
|
12
|
+
export declare const SUBTOTAL_GRAND_TOTAL_LABEL = "Grand Total";
|
|
13
|
+
export declare const subtotalGroupLabel: (groupValue: string) => string;
|
|
14
|
+
/**
|
|
15
|
+
* Reads a cell of the data range. `getValue` should return the DISPLAYED text
|
|
16
|
+
* when the host has one (Excel groups and labels on what the cells show —
|
|
17
|
+
* `1/1/2024 Total`, not `45292 Total`). `getFormula` returns the `=…` text for
|
|
18
|
+
* a formula cell. `getOutlineLevel` returns a row's current outline level so
|
|
19
|
+
* "Replace current subtotals" can rebuild the outline from level 0.
|
|
20
|
+
*/
|
|
21
|
+
export type SubtotalReader = {
|
|
22
|
+
getValue: (rowIndex: number, columnIndex: number) => string | number | boolean | null | undefined;
|
|
23
|
+
getFormula: (rowIndex: number, columnIndex: number) => string | undefined;
|
|
24
|
+
getOutlineLevel?: (rowIndex: number) => number | undefined;
|
|
25
|
+
};
|
|
26
|
+
/** One `change-batch` write: a single row segment at final coordinates. */
|
|
27
|
+
export type SubtotalWrite = {
|
|
28
|
+
rowIndex: number;
|
|
29
|
+
startColumnIndex: number;
|
|
30
|
+
values: (string | null)[];
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The plan applies in this order, every index already in FINAL coordinates
|
|
34
|
+
* (the sheet after all removals and insertions):
|
|
35
|
+
* 1. `deleteRows` (descending original indexes — existing subtotal rows),
|
|
36
|
+
* 2. `insertRows` ascending: inserting at final row `r` shifts the not-yet
|
|
37
|
+
* final rows below it, so ascending order lands each new row exactly
|
|
38
|
+
* where the plan expects it,
|
|
39
|
+
* 3. `writes` (labels + SUBTOTAL formulas),
|
|
40
|
+
* 4. `ungroupRows`: one `ungroup-rows` call per entry — the outline reset of
|
|
41
|
+
* "Replace current subtotals". Group / ungroup are ±1 steps in both
|
|
42
|
+
* engines, so pass `k` lists the surviving data rows that were deeper
|
|
43
|
+
* than level `k`; after the passes every row of the range is back at
|
|
44
|
+
* level 0 (empty when nothing was outlined or when not replacing), then
|
|
45
|
+
* 5. `outlineGroups`: one `group-rows` call per entry (Excel's levels — the
|
|
46
|
+
* first spans every row above the grand total, the second the detail
|
|
47
|
+
* rows of each group, so detail rows end at level 2 and subtotal rows
|
|
48
|
+
* at level 1 — the same three-level outline on every re-apply).
|
|
49
|
+
*/
|
|
50
|
+
export type SubtotalPlan = {
|
|
51
|
+
deleteRows: number[];
|
|
52
|
+
insertRows: number[];
|
|
53
|
+
writes: SubtotalWrite[];
|
|
54
|
+
ungroupRows: number[][];
|
|
55
|
+
outlineGroups: number[][];
|
|
56
|
+
/** Number of groups found. */
|
|
57
|
+
groupCount: number;
|
|
58
|
+
/** The range after the plan is applied (header row included when present). */
|
|
59
|
+
resultRange: GridRange;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Plans Excel's Subtotal command over `options.range`. Consecutive rows with
|
|
63
|
+
* the same group-column value form a group (Excel does not sort — it expects
|
|
64
|
+
* the data sorted and totals each run of equal values). Each group gets a
|
|
65
|
+
* total row right below it holding "<value> Total" in the group column and
|
|
66
|
+
* `=SUBTOTAL(n, first:last)` over the group's data rows in every aggregate
|
|
67
|
+
* column; a grand-total row closes the range with `SUBTOTAL` over the whole
|
|
68
|
+
* data block (SUBTOTAL ignores the nested subtotal rows, like Excel). With
|
|
69
|
+
* `replaceCurrent` the range's existing outline is cleared too, so a re-apply
|
|
70
|
+
* yields Excel's fresh detail 2 / subtotal 1 / grand total 0 levels instead
|
|
71
|
+
* of nesting deeper; without it the new levels stack on the old ones (Excel's
|
|
72
|
+
* nested subtotals). Returns `undefined` when the range has no data rows.
|
|
73
|
+
*/
|
|
74
|
+
export declare const planSubtotals: (options: SubtotalOptions, reader: SubtotalReader) => SubtotalPlan | undefined;
|
|
75
|
+
/** The state callbacks a plan is applied through — the same in both engines. */
|
|
76
|
+
export type SubtotalPlanExecutor = {
|
|
77
|
+
onDeleteRow: (sheetId: number, rowIndexes: number[]) => void;
|
|
78
|
+
onInsertRow: (sheetId: number, referenceRowIndex: number, numRows?: number) => void;
|
|
79
|
+
onChangeBatch: (sheetId: number, range: GridRange, values: (string | null)[][]) => void;
|
|
80
|
+
onGroupRows: (sheetId: number, rowIndexes: number[]) => void;
|
|
81
|
+
onUngroupRows: (sheetId: number, rowIndexes: number[]) => void;
|
|
82
|
+
};
|
|
83
|
+
/** Applies a {@link SubtotalPlan} in its documented order. */
|
|
84
|
+
export declare const applySubtotalPlan: (sheetId: number, plan: SubtotalPlan, executor: SubtotalPlanExecutor) => void;
|
|
85
|
+
//# sourceMappingURL=subtotal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subtotal.d.ts","sourceRoot":"","sources":["../../../api/subtotal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EACL,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAC9B,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAYtE,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,0BAA0B,gBAAgB,CAAC;AACxD,eAAO,MAAM,kBAAkB,GAAI,YAAY,MAAM,WACP,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;IAClG,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC1E,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC5D,CAAC;AAEF,2EAA2E;AAC3E,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC;IAC1B,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,WAAW,EAAE,SAAS,CAAC;CACxB,CAAC;AAcF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,GACxB,SAAS,eAAe,EACxB,QAAQ,cAAc,KACrB,YAAY,GAAG,SAyHjB,CAAC;AAEF,gFAAgF;AAChF,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7D,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpF,aAAa,EAAE,CACb,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,KACxB,IAAI,CAAC;IACV,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7D,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAChE,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,EACf,MAAM,YAAY,EAClB,UAAU,oBAAoB,SAwB/B,CAAC"}
|