@rowsncolumns/spreadsheet-state 28.0.74 → 28.0.76
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/anchored-objects.d.ts +66 -0
- package/dist/cjs/api/anchored-objects.d.ts.map +1 -0
- package/dist/cjs/api/anchored-objects.js +259 -0
- package/dist/cjs/api/datatype.d.ts.map +1 -1
- package/dist/cjs/api/datatype.js +8 -1
- package/dist/cjs/api/dependency.d.ts +13 -2
- package/dist/cjs/api/dependency.d.ts.map +1 -1
- package/dist/cjs/api/dependency.js +11 -5
- package/dist/cjs/api/fill-series-spec.d.ts +35 -0
- package/dist/cjs/api/fill-series-spec.d.ts.map +1 -0
- package/dist/cjs/api/fill-series-spec.js +164 -0
- package/dist/cjs/api/fill.d.ts +95 -3
- package/dist/cjs/api/fill.d.ts.map +1 -1
- package/dist/cjs/api/fill.js +1186 -418
- package/dist/cjs/api/formula.d.ts +61 -4
- package/dist/cjs/api/formula.d.ts.map +1 -1
- package/dist/cjs/api/formula.js +250 -61
- package/dist/cjs/api/immer-utils.d.ts.map +1 -1
- package/dist/cjs/api/immer-utils.js +20 -15
- package/dist/cjs/api/intl.d.ts.map +1 -1
- package/dist/cjs/api/merges.d.ts +8 -0
- package/dist/cjs/api/merges.d.ts.map +1 -1
- package/dist/cjs/api/merges.js +64 -1
- package/dist/cjs/api/named-range-structural.d.ts +62 -0
- package/dist/cjs/api/named-range-structural.d.ts.map +1 -0
- package/dist/cjs/api/named-range-structural.js +197 -0
- package/dist/cjs/api/paint-format.d.ts +15 -1
- package/dist/cjs/api/paint-format.d.ts.map +1 -1
- package/dist/cjs/api/paint-format.js +69 -10
- package/dist/cjs/api/range-rule-helpers.d.ts +45 -1
- package/dist/cjs/api/range-rule-helpers.d.ts.map +1 -1
- package/dist/cjs/api/range-rule-helpers.js +159 -6
- package/dist/cjs/api/structural-formula-update.d.ts.map +1 -1
- package/dist/cjs/api/structural-formula-update.js +24 -6
- package/dist/cjs/api/structural-guards.d.ts +78 -0
- package/dist/cjs/api/structural-guards.d.ts.map +1 -0
- package/dist/cjs/api/structural-guards.js +202 -0
- package/dist/cjs/api/structural-table-refs.d.ts +94 -0
- package/dist/cjs/api/structural-table-refs.d.ts.map +1 -0
- package/dist/cjs/api/structural-table-refs.js +313 -0
- package/dist/cjs/commands.d.ts +11 -1
- package/dist/cjs/commands.d.ts.map +1 -1
- package/dist/cjs/constants.d.ts +25 -0
- package/dist/cjs/constants.d.ts.map +1 -0
- package/dist/cjs/constants.js +26 -0
- package/dist/cjs/hooks/use-calculation-worker.d.ts.map +1 -1
- package/dist/cjs/hooks/use-calculation-worker.js +64 -6
- package/dist/cjs/hooks/use-calculation.d.ts +8 -1
- package/dist/cjs/hooks/use-calculation.d.ts.map +1 -1
- package/dist/cjs/hooks/use-calculation.js +15 -0
- package/dist/cjs/hooks/use-on-calculation-success.d.ts +7 -0
- package/dist/cjs/hooks/use-on-calculation-success.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-calculation-success.js +7 -1
- package/dist/cjs/hooks/use-on-delete-cells-shift-left.d.ts +13 -3
- package/dist/cjs/hooks/use-on-delete-cells-shift-left.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-delete-cells-shift-left.js +27 -2
- package/dist/cjs/hooks/use-on-delete-cells-shift-up.d.ts +13 -3
- package/dist/cjs/hooks/use-on-delete-cells-shift-up.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-delete-cells-shift-up.js +27 -2
- package/dist/cjs/hooks/use-on-delete-column.d.ts +13 -4
- package/dist/cjs/hooks/use-on-delete-column.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-delete-column.js +14 -2
- package/dist/cjs/hooks/use-on-delete-row.d.ts +13 -4
- package/dist/cjs/hooks/use-on-delete-row.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-delete-row.js +14 -2
- package/dist/cjs/hooks/use-on-fill.d.ts +13 -4
- package/dist/cjs/hooks/use-on-fill.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-fill.js +28 -7
- package/dist/cjs/hooks/use-on-insert-cells-shift-down.d.ts +13 -3
- package/dist/cjs/hooks/use-on-insert-cells-shift-down.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-insert-cells-shift-down.js +27 -2
- package/dist/cjs/hooks/use-on-insert-cells-shift-right.d.ts +13 -3
- package/dist/cjs/hooks/use-on-insert-cells-shift-right.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-insert-cells-shift-right.js +27 -2
- package/dist/cjs/hooks/use-on-insert-column.d.ts +10 -3
- package/dist/cjs/hooks/use-on-insert-column.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-insert-column.js +33 -7
- package/dist/cjs/hooks/use-on-insert-row.d.ts +10 -3
- package/dist/cjs/hooks/use-on-insert-row.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-insert-row.js +32 -7
- package/dist/cjs/hooks/use-paint-format.d.ts.map +1 -1
- package/dist/cjs/hooks/use-paint-format.js +10 -7
- package/dist/cjs/hooks/use-spreadsheet-state.d.ts +3 -3
- package/dist/cjs/hooks/use-spreadsheet-state.d.ts.map +1 -1
- package/dist/cjs/hooks/use-spreadsheet-state.js +73 -16
- package/dist/cjs/hooks/use-structured-reference.d.ts.map +1 -1
- package/dist/cjs/hooks/use-structured-reference.js +10 -6
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +3 -0
- package/dist/cjs/interface/apply-fill.d.ts +3 -3
- package/dist/cjs/interface/apply-fill.d.ts.map +1 -1
- package/dist/cjs/interface/apply-fill.js +100 -53
- package/dist/cjs/interface/calculation-interface.d.ts +9 -0
- package/dist/cjs/interface/calculation-interface.d.ts.map +1 -1
- package/dist/cjs/interface/calculation-interface.js +31 -2
- package/dist/cjs/interface/delete-cells-shift-left.d.ts +8 -1
- package/dist/cjs/interface/delete-cells-shift-left.d.ts.map +1 -1
- package/dist/cjs/interface/delete-cells-shift-left.js +158 -80
- package/dist/cjs/interface/delete-cells-shift-up.d.ts +9 -1
- package/dist/cjs/interface/delete-cells-shift-up.d.ts.map +1 -1
- package/dist/cjs/interface/delete-cells-shift-up.js +155 -73
- package/dist/cjs/interface/delete-column.d.ts +1 -1
- package/dist/cjs/interface/delete-column.d.ts.map +1 -1
- package/dist/cjs/interface/delete-column.js +90 -31
- package/dist/cjs/interface/delete-row.d.ts +1 -1
- package/dist/cjs/interface/delete-row.d.ts.map +1 -1
- package/dist/cjs/interface/delete-row.js +85 -26
- package/dist/cjs/interface/insert-cells-shift-down.d.ts +10 -1
- package/dist/cjs/interface/insert-cells-shift-down.d.ts.map +1 -1
- package/dist/cjs/interface/insert-cells-shift-down.js +147 -52
- package/dist/cjs/interface/insert-cells-shift-right.d.ts +10 -1
- package/dist/cjs/interface/insert-cells-shift-right.d.ts.map +1 -1
- package/dist/cjs/interface/insert-cells-shift-right.js +154 -58
- package/dist/cjs/interface/insert-column.d.ts +1 -1
- package/dist/cjs/interface/insert-column.d.ts.map +1 -1
- package/dist/cjs/interface/insert-column.js +46 -8
- package/dist/cjs/interface/insert-row.d.ts +1 -1
- package/dist/cjs/interface/insert-row.d.ts.map +1 -1
- package/dist/cjs/interface/insert-row.js +47 -10
- package/dist/cjs/interface/spreadsheet-interface.d.ts +1 -1
- package/dist/cjs/interface/spreadsheet-interface.d.ts.map +1 -1
- package/dist/cjs/interface/spreadsheet-interface.js +33 -0
- package/dist/cjs/sheet-cell.d.ts.map +1 -1
- package/dist/cjs/sheet-cell.js +30 -6
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/api/anchored-objects.d.ts +66 -0
- package/dist/esm/api/anchored-objects.d.ts.map +1 -0
- package/dist/esm/api/anchored-objects.js +212 -0
- package/dist/esm/api/datatype.d.ts.map +1 -1
- package/dist/esm/api/datatype.js +8 -1
- package/dist/esm/api/dependency.d.ts +13 -2
- package/dist/esm/api/dependency.d.ts.map +1 -1
- package/dist/esm/api/dependency.js +10 -4
- package/dist/esm/api/fill-series-spec.d.ts +35 -0
- package/dist/esm/api/fill-series-spec.d.ts.map +1 -0
- package/dist/esm/api/fill-series-spec.js +160 -0
- package/dist/esm/api/fill.d.ts +95 -3
- package/dist/esm/api/fill.d.ts.map +1 -1
- package/dist/esm/api/fill.js +1158 -418
- package/dist/esm/api/formula.d.ts +61 -4
- package/dist/esm/api/formula.d.ts.map +1 -1
- package/dist/esm/api/formula.js +238 -60
- package/dist/esm/api/immer-utils.d.ts.map +1 -1
- package/dist/esm/api/immer-utils.js +20 -15
- package/dist/esm/api/intl.d.ts.map +1 -1
- package/dist/esm/api/merges.d.ts +8 -0
- package/dist/esm/api/merges.d.ts.map +1 -1
- package/dist/esm/api/merges.js +51 -0
- package/dist/esm/api/named-range-structural.d.ts +62 -0
- package/dist/esm/api/named-range-structural.d.ts.map +1 -0
- package/dist/esm/api/named-range-structural.js +176 -0
- package/dist/esm/api/paint-format.d.ts +15 -1
- package/dist/esm/api/paint-format.d.ts.map +1 -1
- package/dist/esm/api/paint-format.js +46 -1
- package/dist/esm/api/range-rule-helpers.d.ts +45 -1
- package/dist/esm/api/range-rule-helpers.d.ts.map +1 -1
- package/dist/esm/api/range-rule-helpers.js +153 -1
- package/dist/esm/api/structural-formula-update.d.ts.map +1 -1
- package/dist/esm/api/structural-formula-update.js +24 -6
- package/dist/esm/api/structural-guards.d.ts +78 -0
- package/dist/esm/api/structural-guards.d.ts.map +1 -0
- package/dist/esm/api/structural-guards.js +186 -0
- package/dist/esm/api/structural-table-refs.d.ts +94 -0
- package/dist/esm/api/structural-table-refs.d.ts.map +1 -0
- package/dist/esm/api/structural-table-refs.js +219 -0
- package/dist/esm/commands.d.ts +11 -1
- package/dist/esm/commands.d.ts.map +1 -1
- package/dist/esm/constants.d.ts +25 -0
- package/dist/esm/constants.d.ts.map +1 -0
- package/dist/esm/constants.js +26 -0
- package/dist/esm/hooks/use-calculation-worker.d.ts.map +1 -1
- package/dist/esm/hooks/use-calculation-worker.js +45 -0
- package/dist/esm/hooks/use-calculation.d.ts +8 -1
- package/dist/esm/hooks/use-calculation.d.ts.map +1 -1
- package/dist/esm/hooks/use-calculation.js +15 -0
- package/dist/esm/hooks/use-on-calculation-success.d.ts +7 -0
- package/dist/esm/hooks/use-on-calculation-success.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-calculation-success.js +7 -1
- package/dist/esm/hooks/use-on-delete-cells-shift-left.d.ts +13 -3
- package/dist/esm/hooks/use-on-delete-cells-shift-left.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-delete-cells-shift-left.js +26 -2
- package/dist/esm/hooks/use-on-delete-cells-shift-up.d.ts +13 -3
- package/dist/esm/hooks/use-on-delete-cells-shift-up.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-delete-cells-shift-up.js +26 -2
- package/dist/esm/hooks/use-on-delete-column.d.ts +13 -4
- package/dist/esm/hooks/use-on-delete-column.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-delete-column.js +14 -2
- package/dist/esm/hooks/use-on-delete-row.d.ts +13 -4
- package/dist/esm/hooks/use-on-delete-row.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-delete-row.js +14 -2
- package/dist/esm/hooks/use-on-fill.d.ts +13 -4
- package/dist/esm/hooks/use-on-fill.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-fill.js +24 -4
- package/dist/esm/hooks/use-on-insert-cells-shift-down.d.ts +13 -3
- package/dist/esm/hooks/use-on-insert-cells-shift-down.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-insert-cells-shift-down.js +26 -2
- package/dist/esm/hooks/use-on-insert-cells-shift-right.d.ts +13 -3
- package/dist/esm/hooks/use-on-insert-cells-shift-right.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-insert-cells-shift-right.js +26 -2
- package/dist/esm/hooks/use-on-insert-column.d.ts +10 -3
- package/dist/esm/hooks/use-on-insert-column.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-insert-column.js +33 -7
- package/dist/esm/hooks/use-on-insert-row.d.ts +10 -3
- package/dist/esm/hooks/use-on-insert-row.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-insert-row.js +32 -7
- package/dist/esm/hooks/use-paint-format.d.ts.map +1 -1
- package/dist/esm/hooks/use-paint-format.js +10 -7
- package/dist/esm/hooks/use-spreadsheet-state.d.ts +3 -3
- package/dist/esm/hooks/use-spreadsheet-state.d.ts.map +1 -1
- package/dist/esm/hooks/use-spreadsheet-state.js +73 -16
- package/dist/esm/hooks/use-structured-reference.d.ts.map +1 -1
- package/dist/esm/hooks/use-structured-reference.js +10 -6
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -0
- package/dist/esm/interface/apply-fill.d.ts +3 -3
- package/dist/esm/interface/apply-fill.d.ts.map +1 -1
- package/dist/esm/interface/apply-fill.js +93 -48
- package/dist/esm/interface/calculation-interface.d.ts +9 -0
- package/dist/esm/interface/calculation-interface.d.ts.map +1 -1
- package/dist/esm/interface/calculation-interface.js +33 -2
- package/dist/esm/interface/delete-cells-shift-left.d.ts +8 -1
- package/dist/esm/interface/delete-cells-shift-left.d.ts.map +1 -1
- package/dist/esm/interface/delete-cells-shift-left.js +135 -59
- package/dist/esm/interface/delete-cells-shift-up.d.ts +9 -1
- package/dist/esm/interface/delete-cells-shift-up.d.ts.map +1 -1
- package/dist/esm/interface/delete-cells-shift-up.js +133 -53
- package/dist/esm/interface/delete-column.d.ts +1 -1
- package/dist/esm/interface/delete-column.d.ts.map +1 -1
- package/dist/esm/interface/delete-column.js +80 -11
- package/dist/esm/interface/delete-row.d.ts +1 -1
- package/dist/esm/interface/delete-row.d.ts.map +1 -1
- package/dist/esm/interface/delete-row.js +81 -11
- package/dist/esm/interface/insert-cells-shift-down.d.ts +10 -1
- package/dist/esm/interface/insert-cells-shift-down.d.ts.map +1 -1
- package/dist/esm/interface/insert-cells-shift-down.js +116 -47
- package/dist/esm/interface/insert-cells-shift-right.d.ts +10 -1
- package/dist/esm/interface/insert-cells-shift-right.d.ts.map +1 -1
- package/dist/esm/interface/insert-cells-shift-right.js +120 -51
- package/dist/esm/interface/insert-column.d.ts +1 -1
- package/dist/esm/interface/insert-column.d.ts.map +1 -1
- package/dist/esm/interface/insert-column.js +46 -8
- package/dist/esm/interface/insert-row.d.ts +1 -1
- package/dist/esm/interface/insert-row.d.ts.map +1 -1
- package/dist/esm/interface/insert-row.js +47 -10
- package/dist/esm/interface/spreadsheet-interface.d.ts +1 -1
- package/dist/esm/interface/spreadsheet-interface.d.ts.map +1 -1
- package/dist/esm/interface/spreadsheet-interface.js +29 -0
- package/dist/esm/sheet-cell.d.ts.map +1 -1
- package/dist/esm/sheet-cell.js +30 -6
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +17 -17
|
@@ -1,23 +1,176 @@
|
|
|
1
1
|
import { __assign, __values } from "tslib";
|
|
2
|
+
import { contractRangesInFormula, expandRangesInFormula, formulaToRelativeReference, } from "./formula";
|
|
2
3
|
import { updateSheetRangeOnDelete, updateSheetRangeOnInsert } from "./range";
|
|
4
|
+
/** Excel's grid bounds — the shift region for "every reference at/after the edit". */
|
|
5
|
+
var MAX_ROW_INDEX = 1048576;
|
|
6
|
+
var MAX_COLUMN_INDEX = 16384;
|
|
7
|
+
/**
|
|
8
|
+
* Rewrite one CF / DV formula (`=…`) for a sheet-level insert or delete,
|
|
9
|
+
* exactly as Excel rewrites the rule text: the formula is read as if it
|
|
10
|
+
* were entered in the rule's top-left cell, so relative and absolute
|
|
11
|
+
* references alike are grid positions that shift when they sit at/after
|
|
12
|
+
* the edit (`=$A1>$C$10` + insert row 5 → `=$A1>$C$11`), ranges spanning
|
|
13
|
+
* the edit grow / shrink, and a reference inside a deleted band becomes
|
|
14
|
+
* `#REF!`. Returns the input unchanged when it is not a formula or when
|
|
15
|
+
* no reference moved.
|
|
16
|
+
*/
|
|
17
|
+
export var shiftRuleFormulaForStructuralChange = function (formula, _a) {
|
|
18
|
+
var _b, _c, _d, _e;
|
|
19
|
+
var op = _a.op, axis = _a.axis, index = _a.index, count = _a.count, editedSheetName = _a.editedSheetName, ruleSheetName = _a.ruleSheetName, _f = _a.anchorRebase, anchorRebase = _f === void 0 ? 0 : _f;
|
|
20
|
+
if (!formula.startsWith("=") || count <= 0)
|
|
21
|
+
return formula;
|
|
22
|
+
var sameSheet = ruleSheetName.toLowerCase() === editedSheetName.toLowerCase();
|
|
23
|
+
var isRow = axis === "row";
|
|
24
|
+
var gridBounds = { rowCount: MAX_ROW_INDEX, columnCount: MAX_COLUMN_INDEX };
|
|
25
|
+
var next = formula;
|
|
26
|
+
// 1. The rule's previous top-left cell was deleted: the rule text is now
|
|
27
|
+
// the instance formula of the first surviving cell — relative
|
|
28
|
+
// references move with the anchor, absolutes stay.
|
|
29
|
+
if (anchorRebase > 0 && sameSheet) {
|
|
30
|
+
var source = { rowIndex: 1, columnIndex: 1 };
|
|
31
|
+
var destination = {
|
|
32
|
+
rowIndex: 1 + (isRow ? anchorRebase : 0),
|
|
33
|
+
columnIndex: 1 + (isRow ? 0 : anchorRebase),
|
|
34
|
+
};
|
|
35
|
+
next =
|
|
36
|
+
(_b = formulaToRelativeReference(next, source, destination, ruleSheetName, __assign({ preserveAbsolutes: true, ignoreCircular: true, ignoreReferenceError: true }, gridBounds))) !== null && _b !== void 0 ? _b : next;
|
|
37
|
+
}
|
|
38
|
+
// 2. Delete: references wholly inside the deleted band are gone → `#REF!`.
|
|
39
|
+
// Shifting the band far off-grid lets `formulaToRelativeReference`'s
|
|
40
|
+
// reference-error path emit the token.
|
|
41
|
+
if (op === "delete") {
|
|
42
|
+
var band = isRow
|
|
43
|
+
? {
|
|
44
|
+
startRowIndex: index,
|
|
45
|
+
endRowIndex: index + count - 1,
|
|
46
|
+
startColumnIndex: 1,
|
|
47
|
+
endColumnIndex: MAX_COLUMN_INDEX,
|
|
48
|
+
}
|
|
49
|
+
: {
|
|
50
|
+
startRowIndex: 1,
|
|
51
|
+
endRowIndex: MAX_ROW_INDEX,
|
|
52
|
+
startColumnIndex: index,
|
|
53
|
+
endColumnIndex: index + count - 1,
|
|
54
|
+
};
|
|
55
|
+
var offGrid = -(index + count);
|
|
56
|
+
next =
|
|
57
|
+
(_c = formulaToRelativeReference(next, { rowIndex: index, columnIndex: index }, {
|
|
58
|
+
rowIndex: isRow ? offGrid : index,
|
|
59
|
+
columnIndex: isRow ? index : offGrid,
|
|
60
|
+
}, editedSheetName, {
|
|
61
|
+
exclusionRange: band,
|
|
62
|
+
ignoreCircular: true,
|
|
63
|
+
ignoreReferenceError: true,
|
|
64
|
+
referenceSheetName: editedSheetName,
|
|
65
|
+
includeUnqualifiedReferences: sameSheet,
|
|
66
|
+
// Deliberately NOT the grid bounds: a whole-row / whole-column
|
|
67
|
+
// reference inside the band would otherwise be pushed to a
|
|
68
|
+
// negative index instead of `#REF!`; those stay put and are
|
|
69
|
+
// handled by the range contraction below.
|
|
70
|
+
rowCount: MAX_ROW_INDEX + 1,
|
|
71
|
+
columnCount: MAX_COLUMN_INDEX + 1,
|
|
72
|
+
})) !== null && _c !== void 0 ? _c : next;
|
|
73
|
+
}
|
|
74
|
+
// 3. Ranges that span the edit grow (insert) / shrink (delete).
|
|
75
|
+
next =
|
|
76
|
+
(_d = (op === "insert" ? expandRangesInFormula : contractRangesInFormula)(next, index, count, axis, editedSheetName, { includeUnqualifiedReferences: sameSheet })) !== null && _d !== void 0 ? _d : next;
|
|
77
|
+
// 4. Everything at/after the edit shifts by ±count along the axis.
|
|
78
|
+
var delta = op === "insert" ? count : -count;
|
|
79
|
+
var regionStart = op === "insert" ? index : index + count;
|
|
80
|
+
var region = isRow
|
|
81
|
+
? {
|
|
82
|
+
startRowIndex: regionStart,
|
|
83
|
+
endRowIndex: MAX_ROW_INDEX,
|
|
84
|
+
startColumnIndex: 1,
|
|
85
|
+
endColumnIndex: MAX_COLUMN_INDEX,
|
|
86
|
+
}
|
|
87
|
+
: {
|
|
88
|
+
startRowIndex: 1,
|
|
89
|
+
endRowIndex: MAX_ROW_INDEX,
|
|
90
|
+
startColumnIndex: regionStart,
|
|
91
|
+
endColumnIndex: MAX_COLUMN_INDEX,
|
|
92
|
+
};
|
|
93
|
+
next =
|
|
94
|
+
(_e = formulaToRelativeReference(next, { rowIndex: regionStart, columnIndex: regionStart }, {
|
|
95
|
+
rowIndex: regionStart + (isRow ? delta : 0),
|
|
96
|
+
columnIndex: regionStart + (isRow ? 0 : delta),
|
|
97
|
+
}, editedSheetName, __assign({ exclusionRange: region, ignoreCircular: true, ignoreReferenceError: true, referenceSheetName: editedSheetName, includeUnqualifiedReferences: sameSheet }, gridBounds))) !== null && _e !== void 0 ? _e : next;
|
|
98
|
+
return next;
|
|
99
|
+
};
|
|
100
|
+
var rewriteConditionFormulas = function (condition, params) {
|
|
101
|
+
var e_1, _a;
|
|
102
|
+
if (!(condition === null || condition === void 0 ? void 0 : condition.values))
|
|
103
|
+
return;
|
|
104
|
+
try {
|
|
105
|
+
for (var _b = __values(condition.values), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
106
|
+
var value = _c.value;
|
|
107
|
+
var text = value.userEnteredValue;
|
|
108
|
+
if (typeof text !== "string" || !text.startsWith("="))
|
|
109
|
+
continue;
|
|
110
|
+
var next = shiftRuleFormulaForStructuralChange(text, params);
|
|
111
|
+
if (next !== text)
|
|
112
|
+
value.userEnteredValue = next;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
116
|
+
finally {
|
|
117
|
+
try {
|
|
118
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
119
|
+
}
|
|
120
|
+
finally { if (e_1) throw e_1.error; }
|
|
121
|
+
}
|
|
122
|
+
};
|
|
3
123
|
/**
|
|
4
124
|
* Apply an insert or delete range adjustment to a list of rules whose
|
|
5
125
|
* `ranges: SheetRange[]` field references cells. Used for tables, conditional
|
|
6
126
|
* formats, data validations, etc. Mutates the immer draft in place; rules
|
|
7
127
|
* whose ranges all collapse to nothing are spliced out.
|
|
8
128
|
*
|
|
129
|
+
* When `formulaScope` is given, each rule's condition formulas
|
|
130
|
+
* (`booleanRule.condition.values[].userEnteredValue` for CF,
|
|
131
|
+
* `condition.values[].userEnteredValue` for DV — those starting with `=`)
|
|
132
|
+
* are rewritten as if entered in the rule's applies-to top-left cell, see
|
|
133
|
+
* {@link shiftRuleFormulaForStructuralChange}.
|
|
134
|
+
*
|
|
9
135
|
* Walks `draft` from the end so splice indices don't shift mid-iteration.
|
|
10
136
|
*/
|
|
11
|
-
export var updateRangedRulesOnStructuralChange = function (draft, op, axis, index, count, sheetId) {
|
|
12
|
-
var _a, _b;
|
|
137
|
+
export var updateRangedRulesOnStructuralChange = function (draft, op, axis, index, count, sheetId, formulaScope) {
|
|
138
|
+
var _a, _b, _c, _d;
|
|
13
139
|
var updater = op === "insert" ? updateSheetRangeOnInsert : updateSheetRangeOnDelete;
|
|
140
|
+
var isRow = axis === "row";
|
|
14
141
|
for (var i = draft.length - 1; i >= 0; i--) {
|
|
15
142
|
var rule = draft[i];
|
|
16
|
-
var
|
|
143
|
+
var anchorRange = (_a = rule.ranges) === null || _a === void 0 ? void 0 : _a[0];
|
|
144
|
+
var ranges = (_c = (_b = rule.ranges) === null || _b === void 0 ? void 0 : _b.map(function (range) { return updater(range, axis, index, count, sheetId); }).filter(function (range) { return !!range; })) !== null && _c !== void 0 ? _c : [];
|
|
17
145
|
if (ranges.length) {
|
|
18
146
|
// immer's typing for nested-mutation assignment is flaky here; cast
|
|
19
147
|
// through `unknown` since the runtime shape matches the rule type.
|
|
20
148
|
rule.ranges = ranges;
|
|
149
|
+
if (formulaScope && anchorRange) {
|
|
150
|
+
// Excel anchors a rule's formula at its applies-to top-left. When
|
|
151
|
+
// that cell is deleted, the first surviving cell (right after the
|
|
152
|
+
// deleted band) becomes the anchor and its instance formula the
|
|
153
|
+
// rule text.
|
|
154
|
+
var anchorPosition = isRow
|
|
155
|
+
? anchorRange.startRowIndex
|
|
156
|
+
: anchorRange.startColumnIndex;
|
|
157
|
+
var anchorDeleted = op === "delete" &&
|
|
158
|
+
anchorRange.sheetId === sheetId &&
|
|
159
|
+
anchorPosition >= index &&
|
|
160
|
+
anchorPosition <= index + count - 1;
|
|
161
|
+
var params = {
|
|
162
|
+
op: op,
|
|
163
|
+
axis: axis,
|
|
164
|
+
index: index,
|
|
165
|
+
count: count,
|
|
166
|
+
editedSheetName: formulaScope.getSheetName(sheetId),
|
|
167
|
+
ruleSheetName: formulaScope.getSheetName(anchorRange.sheetId),
|
|
168
|
+
anchorRebase: anchorDeleted ? index + count - anchorPosition : 0,
|
|
169
|
+
};
|
|
170
|
+
var carrier = rule;
|
|
171
|
+
rewriteConditionFormulas((_d = carrier.booleanRule) === null || _d === void 0 ? void 0 : _d.condition, params);
|
|
172
|
+
rewriteConditionFormulas(carrier.condition, params);
|
|
173
|
+
}
|
|
21
174
|
}
|
|
22
175
|
else {
|
|
23
176
|
draft.splice(i, 1);
|
|
@@ -92,7 +245,7 @@ export var updateRangedRulesOnReorder = function (draft, axis, firstIndex, lastI
|
|
|
92
245
|
* bounds (no current caller, but kept symmetric).
|
|
93
246
|
*/
|
|
94
247
|
orthogonalBoundary) {
|
|
95
|
-
var
|
|
248
|
+
var e_2, _a;
|
|
96
249
|
var _b;
|
|
97
250
|
if (firstIndex > lastIndex)
|
|
98
251
|
return;
|
|
@@ -132,11 +285,11 @@ orthogonalBoundary) {
|
|
|
132
285
|
rule.ranges = nextRanges;
|
|
133
286
|
}
|
|
134
287
|
}
|
|
135
|
-
catch (
|
|
288
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
136
289
|
finally {
|
|
137
290
|
try {
|
|
138
291
|
if (draft_1_1 && !draft_1_1.done && (_a = draft_1.return)) _a.call(draft_1);
|
|
139
292
|
}
|
|
140
|
-
finally { if (
|
|
293
|
+
finally { if (e_2) throw e_2.error; }
|
|
141
294
|
}
|
|
142
295
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structural-formula-update.d.ts","sourceRoot":"","sources":["../../../api/structural-formula-update.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAK1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAarD,KAAK,cAAc,GAAG,KAAK,GAAG,QAAQ,CAAC;AACvC,KAAK,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExC,MAAM,MAAM,6BAA6B,CAAC,CAAC,SAAS,QAAQ,IAAI;IAC9D,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,EAAE,cAAc,CAAC;IACrB,EAAE,EAAE,YAAY,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IAEpB,aAAa,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,eAAe,CAAC,CAAC;IAClE;;;;OAIG;IACH,aAAa,CAAC,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,eAAe,CAAC,CAAC;IACnE;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,UAAU,CAC/B,OAAO,cAAc,CACtB,CAAC,sBAAsB,CAAC,CAAC;IAC1B,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1C,kBAAkB,CAAC,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAC7E,qBAAqB,CAAC,EAAE,UAAU,CAChC,OAAO,cAAc,CACtB,CAAC,uBAAuB,CAAC,CAAC;IAE3B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAE/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,iCAAiC,GAAI,CAAC,SAAS,QAAQ,EAClE,QAAQ,6BAA6B,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"structural-formula-update.d.ts","sourceRoot":"","sources":["../../../api/structural-formula-update.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAK1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAarD,KAAK,cAAc,GAAG,KAAK,GAAG,QAAQ,CAAC;AACvC,KAAK,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExC,MAAM,MAAM,6BAA6B,CAAC,CAAC,SAAS,QAAQ,IAAI;IAC9D,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,EAAE,cAAc,CAAC;IACrB,EAAE,EAAE,YAAY,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IAEpB,aAAa,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,eAAe,CAAC,CAAC;IAClE;;;;OAIG;IACH,aAAa,CAAC,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,eAAe,CAAC,CAAC;IACnE;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,UAAU,CAC/B,OAAO,cAAc,CACtB,CAAC,sBAAsB,CAAC,CAAC;IAC1B,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1C,kBAAkB,CAAC,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAC7E,qBAAqB,CAAC,EAAE,UAAU,CAChC,OAAO,cAAc,CACtB,CAAC,uBAAuB,CAAC,CAAC;IAE3B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAE/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,iCAAiC,GAAI,CAAC,SAAS,QAAQ,EAClE,QAAQ,6BAA6B,CAAC,CAAC,CAAC,SA2WzC,CAAC"}
|
|
@@ -89,6 +89,11 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
89
89
|
startColumnIndex: isInsert ? referenceIndex : referenceIndex + count,
|
|
90
90
|
endColumnIndex: columnCount,
|
|
91
91
|
};
|
|
92
|
+
// The cells a delete removes: any reference into them (that Pass 1 did not
|
|
93
|
+
// already contract) is broken to `#REF!` instead of sliding onto the cell
|
|
94
|
+
// that moves into its place.
|
|
95
|
+
var deletedRange = isInsert ? undefined : pass1Range;
|
|
96
|
+
var editedSheetName = getSheetName(sheetId);
|
|
92
97
|
// ---- PASS 1 ----
|
|
93
98
|
var pass1Formulas = collectUniqueDependentsForRange({
|
|
94
99
|
draft: draft,
|
|
@@ -109,10 +114,15 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
109
114
|
var formulaValue = sheetCell.formula;
|
|
110
115
|
if (!formulaValue)
|
|
111
116
|
continue;
|
|
112
|
-
|
|
117
|
+
// Scope to the EDITED sheet: a qualified `Sheet1!A1:A3` on another
|
|
118
|
+
// sheet expands like a local range, while that other sheet's own bare
|
|
119
|
+
// `A1:A3` (which resolves to ITS sheet) is left alone.
|
|
120
|
+
var rangeOptions = {
|
|
121
|
+
includeUnqualifiedReferences: pos.sheetId === sheetId,
|
|
122
|
+
};
|
|
113
123
|
var updatedFormula = isInsert
|
|
114
|
-
? expandRangesInFormula(formulaValue, referenceIndex, count, axis,
|
|
115
|
-
: contractRangesInFormula(formulaValue, referenceIndex, count, axis,
|
|
124
|
+
? expandRangesInFormula(formulaValue, referenceIndex, count, axis, editedSheetName, rangeOptions)
|
|
125
|
+
: contractRangesInFormula(formulaValue, referenceIndex, count, axis, editedSheetName, rangeOptions);
|
|
116
126
|
if (!updatedFormula || updatedFormula === formulaValue)
|
|
117
127
|
continue;
|
|
118
128
|
sheetCell.setFormulaValue(updatedFormula, false);
|
|
@@ -180,7 +190,7 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
180
190
|
shiftExternalDependentFormulaReferences({
|
|
181
191
|
draft: draft,
|
|
182
192
|
position: pos,
|
|
183
|
-
editedSheetName:
|
|
193
|
+
editedSheetName: editedSheetName,
|
|
184
194
|
enqueueCalculation: enqueueCalculation,
|
|
185
195
|
enqueueGraphOperation: enqueueGraphOperation,
|
|
186
196
|
recalcCells: recalcCells,
|
|
@@ -188,6 +198,7 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
188
198
|
rowDelta: rowDelta,
|
|
189
199
|
columnDelta: columnDelta,
|
|
190
200
|
sourceRange: pass2SourceRange,
|
|
201
|
+
deletedRange: deletedRange,
|
|
191
202
|
locale: locale,
|
|
192
203
|
rowCount: rowCount,
|
|
193
204
|
columnCount: columnCount,
|
|
@@ -207,6 +218,7 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
207
218
|
rowDelta: rowDelta,
|
|
208
219
|
columnDelta: columnDelta,
|
|
209
220
|
sourceRange: pass2SourceRange,
|
|
221
|
+
deletedRange: deletedRange,
|
|
210
222
|
locale: locale,
|
|
211
223
|
rowCount: rowCount,
|
|
212
224
|
columnCount: columnCount,
|
|
@@ -231,7 +243,7 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
231
243
|
shiftExternalDependentFormulaReferences({
|
|
232
244
|
draft: draft,
|
|
233
245
|
position: position,
|
|
234
|
-
editedSheetName:
|
|
246
|
+
editedSheetName: editedSheetName,
|
|
235
247
|
enqueueCalculation: enqueueCalculation,
|
|
236
248
|
enqueueGraphOperation: enqueueGraphOperation,
|
|
237
249
|
recalcCells: recalcCells,
|
|
@@ -239,6 +251,7 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
239
251
|
rowDelta: rowDelta,
|
|
240
252
|
columnDelta: columnDelta,
|
|
241
253
|
sourceRange: pass2SourceRange,
|
|
254
|
+
deletedRange: deletedRange,
|
|
242
255
|
locale: locale,
|
|
243
256
|
rowCount: rowCount,
|
|
244
257
|
columnCount: columnCount,
|
|
@@ -284,6 +297,7 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
284
297
|
rowIndex: pos.rowIndex,
|
|
285
298
|
columnIndex: pos.columnIndex,
|
|
286
299
|
},
|
|
300
|
+
activeSheetName: editedSheetName,
|
|
287
301
|
enqueueCalculation: enqueueCalculation,
|
|
288
302
|
enqueueGraphOperation: enqueueGraphOperation,
|
|
289
303
|
recalcCells: recalcCells,
|
|
@@ -291,6 +305,7 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
291
305
|
rowDelta: rowDelta,
|
|
292
306
|
columnDelta: columnDelta,
|
|
293
307
|
sourceRange: pass2SourceRange,
|
|
308
|
+
deletedRange: deletedRange,
|
|
294
309
|
locale: locale,
|
|
295
310
|
rowCount: rowCount,
|
|
296
311
|
columnCount: columnCount,
|
|
@@ -328,6 +343,7 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
328
343
|
moveFormulaAtPosition({
|
|
329
344
|
draft: draft,
|
|
330
345
|
position: { sheetId: sheetId, rowIndex: rowIndex, columnIndex: columnIndex },
|
|
346
|
+
activeSheetName: editedSheetName,
|
|
331
347
|
enqueueCalculation: enqueueCalculation,
|
|
332
348
|
enqueueGraphOperation: enqueueGraphOperation,
|
|
333
349
|
recalcCells: recalcCells,
|
|
@@ -335,6 +351,7 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
335
351
|
rowDelta: rowDelta,
|
|
336
352
|
columnDelta: columnDelta,
|
|
337
353
|
sourceRange: pass2SourceRange,
|
|
354
|
+
deletedRange: deletedRange,
|
|
338
355
|
locale: locale,
|
|
339
356
|
rowCount: rowCount,
|
|
340
357
|
columnCount: columnCount,
|
|
@@ -347,7 +364,7 @@ export var updateFormulasForStructuralChange = function (params) {
|
|
|
347
364
|
};
|
|
348
365
|
var shiftExternalDependentFormulaReferences = function (_a) {
|
|
349
366
|
var _b, _c;
|
|
350
|
-
var draft = _a.draft, position = _a.position, editedSheetName = _a.editedSheetName, enqueueCalculation = _a.enqueueCalculation, enqueueGraphOperation = _a.enqueueGraphOperation, recalcCells = _a.recalcCells, movedKeys = _a.movedKeys, rowDelta = _a.rowDelta, columnDelta = _a.columnDelta, sourceRange = _a.sourceRange, locale = _a.locale, rowCount = _a.rowCount, columnCount = _a.columnCount, cellXfsRegistry = _a.cellXfsRegistry, sharedStringRegistry = _a.sharedStringRegistry;
|
|
367
|
+
var draft = _a.draft, position = _a.position, editedSheetName = _a.editedSheetName, enqueueCalculation = _a.enqueueCalculation, enqueueGraphOperation = _a.enqueueGraphOperation, recalcCells = _a.recalcCells, movedKeys = _a.movedKeys, rowDelta = _a.rowDelta, columnDelta = _a.columnDelta, sourceRange = _a.sourceRange, deletedRange = _a.deletedRange, locale = _a.locale, rowCount = _a.rowCount, columnCount = _a.columnCount, cellXfsRegistry = _a.cellXfsRegistry, sharedStringRegistry = _a.sharedStringRegistry;
|
|
351
368
|
var sheetCell = new SheetCell();
|
|
352
369
|
var currentSheet = createSheetDraft(draft, position.sheetId, position.rowIndex);
|
|
353
370
|
var cellData = (_c = (_b = currentSheet[position.rowIndex]) === null || _b === void 0 ? void 0 : _b.values) === null || _c === void 0 ? void 0 : _c[position.columnIndex];
|
|
@@ -362,6 +379,7 @@ var shiftExternalDependentFormulaReferences = function (_a) {
|
|
|
362
379
|
columnIndex: position.columnIndex + columnDelta,
|
|
363
380
|
}, editedSheetName, {
|
|
364
381
|
exclusionRange: sourceRange,
|
|
382
|
+
deletedRange: deletedRange,
|
|
365
383
|
rowCount: rowCount,
|
|
366
384
|
columnCount: columnCount,
|
|
367
385
|
referenceSheetName: editedSheetName,
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { CellData, CellInterface, GridRange, SelectionArea } from "@rowsncolumns/common-types";
|
|
2
|
+
import type { SelectionAttributes, TableView } from "@rowsncolumns/spreadsheet";
|
|
3
|
+
import { type StructuralRefusal } from "../constants";
|
|
4
|
+
import type { SheetData } from "../hooks/use-spreadsheet-state";
|
|
5
|
+
/**
|
|
6
|
+
* Pure predicates behind Excel's structural-edit refusals. The hooks run them BEFORE the interface
|
|
7
|
+
* function touches any state and `showError` the Excel message on refusal, so a refused edit leaves
|
|
8
|
+
* sheetData / merges / tables / selection exactly as they were.
|
|
9
|
+
*
|
|
10
|
+
* A "band" is the rectangle of cells an edit relocates. Shift cells down at `B2:B3` moves
|
|
11
|
+
* `B2:B∞` — an open end is expressed with `Number.POSITIVE_INFINITY`.
|
|
12
|
+
*/
|
|
13
|
+
export type StructuralBand = GridRange;
|
|
14
|
+
export type ShiftDirection = "down" | "right" | "up" | "left";
|
|
15
|
+
/** The selection a cell shift operates on — the LAST selection, or the active cell as a 1×1. The
|
|
16
|
+
* hooks' guards and the interface functions must agree on it, so both resolve it here. */
|
|
17
|
+
export declare const resolveShiftSelection: (activeCell: CellInterface, selections: SelectionArea<SelectionAttributes>[]) => SelectionArea<SelectionAttributes>;
|
|
18
|
+
/** The cells a shift relocates: the selection's rows/columns from its leading edge to the sheet edge. */
|
|
19
|
+
export declare const shiftBand: (direction: ShiftDirection, range: GridRange) => StructuralBand;
|
|
20
|
+
export declare const isNonBlankCell: (cell: CellData | null | undefined) => boolean;
|
|
21
|
+
/**
|
|
22
|
+
* INS-06 / INS-09 / SHF-10 — the first non-blank cell that a shift of `count` rows (axis `row`) or
|
|
23
|
+
* columns (axis `column`) would push past `limit` (the last valid row/column index). Only cells
|
|
24
|
+
* inside `band` move. `undefined` when the edit is safe.
|
|
25
|
+
*/
|
|
26
|
+
export declare const findOffSheetPush: <T extends CellData>({ rows, axis, count, limit, band, }: {
|
|
27
|
+
rows: SheetData<T>[number] | undefined;
|
|
28
|
+
axis: "row" | "column";
|
|
29
|
+
count: number;
|
|
30
|
+
limit: number | undefined;
|
|
31
|
+
band: StructuralBand;
|
|
32
|
+
}) => CellInterface | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* A range the band reaches but does not contain whole is TORN by the shift. For a delete, a range
|
|
35
|
+
* that touches the deleted block must lie wholly inside it (it is removed with the block) — one
|
|
36
|
+
* straddling the block's edge is torn too.
|
|
37
|
+
*/
|
|
38
|
+
export declare const findTornRange: (ranges: readonly GridRange[] | undefined | null, band: StructuralBand, deletedBlock?: GridRange) => GridRange | undefined;
|
|
39
|
+
/** SHF-05 / MRG-07 — a merge the band covers only partially. */
|
|
40
|
+
export declare const findTornMerge: (merges: readonly GridRange[] | undefined | null, band: StructuralBand, deletedBlock?: GridRange) => GridRange | undefined;
|
|
41
|
+
/** TBL-05 — a table the band covers only partially (a table wholly inside the band moves intact). */
|
|
42
|
+
export declare const findTornTable: (tables: readonly TableView[] | undefined | null, sheetId: number, band: StructuralBand, deletedBlock?: GridRange) => TableView | undefined;
|
|
43
|
+
/** ANC-14 — a CSE / dynamic-array range the band covers only partially. */
|
|
44
|
+
export declare const findTornArray: (arrayRanges: readonly GridRange[] | undefined | null, band: StructuralBand, deletedBlock?: GridRange) => GridRange | undefined;
|
|
45
|
+
/** Ranges (merges / tables) that travel with the band: wholly inside it and, for a delete, not
|
|
46
|
+
* inside the deleted block. */
|
|
47
|
+
export declare const isRangeInsideBand: (range: GridRange, band: StructuralBand) => boolean;
|
|
48
|
+
export declare const isRangeInsideBlock: (outer: GridRange, inner: GridRange) => boolean;
|
|
49
|
+
/**
|
|
50
|
+
* The Excel refusal (if any) for an insert/delete-cells shift of `range`. Checks run in Excel's
|
|
51
|
+
* order: array tear, merge tear, table tear, off-sheet push. `undefined` means the edit may proceed.
|
|
52
|
+
*/
|
|
53
|
+
export declare const getShiftCellsRefusal: <T extends CellData>({ direction, range, sheetId, rows, rowCount, columnCount, merges, tables, arrayRanges, }: {
|
|
54
|
+
direction: ShiftDirection;
|
|
55
|
+
range: GridRange;
|
|
56
|
+
sheetId: number;
|
|
57
|
+
rows: SheetData<T>[number] | undefined;
|
|
58
|
+
/** Last valid row index for a vertical shift (the grid does not grow on a cell shift). */
|
|
59
|
+
rowCount?: number;
|
|
60
|
+
/** Last valid column index for a horizontal shift. */
|
|
61
|
+
columnCount?: number;
|
|
62
|
+
merges?: readonly GridRange[] | null;
|
|
63
|
+
tables?: readonly TableView[] | null;
|
|
64
|
+
arrayRanges?: readonly GridRange[] | null;
|
|
65
|
+
}) => StructuralRefusal | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* INS-06 / INS-09 — the refusal for a whole-row (`axis: "row"`) or whole-column insert of `count`
|
|
68
|
+
* lines before `referenceIndex`, given the hard grid cap (`maxRowCount` / `maxColumnCount`). Blank
|
|
69
|
+
* trailing lines may fall off the end; a non-blank one refuses the insert.
|
|
70
|
+
*/
|
|
71
|
+
export declare const getInsertLinesRefusal: <T extends CellData>({ axis, referenceIndex, count, rows, limit, }: {
|
|
72
|
+
axis: "row" | "column";
|
|
73
|
+
referenceIndex: number;
|
|
74
|
+
count: number;
|
|
75
|
+
rows: SheetData<T>[number] | undefined;
|
|
76
|
+
limit: number | undefined;
|
|
77
|
+
}) => StructuralRefusal | undefined;
|
|
78
|
+
//# sourceMappingURL=structural-guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural-guards.d.ts","sourceRoot":"","sources":["../../../api/structural-guards.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EACb,SAAS,EACT,aAAa,EACd,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAGhF,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAEhE;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC;AAEvC,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC;AAE9D;0FAC0F;AAC1F,eAAO,MAAM,qBAAqB,GAChC,YAAY,aAAa,EACzB,YAAY,aAAa,CAAC,mBAAmB,CAAC,EAAE,KAC/C,aAAa,CAAC,mBAAmB,CAKnC,CAAC;AAcF,yGAAyG;AACzG,eAAO,MAAM,SAAS,GACpB,WAAW,cAAc,EACzB,OAAO,SAAS,KACf,cAmBF,CAAC;AAYF,eAAO,MAAM,cAAc,GACzB,MAAM,QAAQ,GAAG,IAAI,GAAG,SAAS,KAChC,OAMF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,QAAQ,EAAE,qCAMlD;IACD,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACvC,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,EAAE,cAAc,CAAC;CACtB,KAAG,aAAa,GAAG,SA+BnB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GACxB,QAAQ,SAAS,SAAS,EAAE,GAAG,SAAS,GAAG,IAAI,EAC/C,MAAM,cAAc,EACpB,eAAe,SAAS,KACvB,SAAS,GAAG,SAed,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,aAAa,GACxB,QAAQ,SAAS,SAAS,EAAE,GAAG,SAAS,GAAG,IAAI,EAC/C,MAAM,cAAc,EACpB,eAAe,SAAS,0BACoB,CAAC;AAE/C,qGAAqG;AACrG,eAAO,MAAM,aAAa,GACxB,QAAQ,SAAS,SAAS,EAAE,GAAG,SAAS,GAAG,IAAI,EAC/C,SAAS,MAAM,EACf,MAAM,cAAc,EACpB,eAAe,SAAS,KACvB,SAAS,GAAG,SAOd,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,aAAa,GACxB,aAAa,SAAS,SAAS,EAAE,GAAG,SAAS,GAAG,IAAI,EACpD,MAAM,cAAc,EACpB,eAAe,SAAS,0BACyB,CAAC;AAEpD;+BAC+B;AAC/B,eAAO,MAAM,iBAAiB,GAAI,OAAO,SAAS,EAAE,MAAM,cAAc,YAC5C,CAAC;AAE7B,eAAO,MAAM,kBAAkB,UAjKD,SAAS,SAAS,SAAS,YAiKV,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,QAAQ,EAAE,0FAUtD;IACD,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACvC,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAAC;IACrC,WAAW,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAAC;CAC3C,KAAG,iBAAiB,GAAG,SA8BvB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,QAAQ,EAAE,+CAMvD;IACD,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACvC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,KAAG,iBAAiB,GAAG,SAkBvB,CAAC"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { __read } from "tslib";
|
|
2
|
+
import { selectionFromActiveCell } from "@rowsncolumns/utils";
|
|
3
|
+
import { structuralRefusal, } from "../constants";
|
|
4
|
+
/** The selection a cell shift operates on — the LAST selection, or the active cell as a 1×1. The
|
|
5
|
+
* hooks' guards and the interface functions must agree on it, so both resolve it here. */
|
|
6
|
+
export var resolveShiftSelection = function (activeCell, selections) {
|
|
7
|
+
var finalSelections = selections.length
|
|
8
|
+
? selections
|
|
9
|
+
: selectionFromActiveCell(activeCell);
|
|
10
|
+
return finalSelections[finalSelections.length - 1];
|
|
11
|
+
};
|
|
12
|
+
var rangesIntersect = function (a, b) {
|
|
13
|
+
return a.startRowIndex <= b.endRowIndex &&
|
|
14
|
+
a.endRowIndex >= b.startRowIndex &&
|
|
15
|
+
a.startColumnIndex <= b.endColumnIndex &&
|
|
16
|
+
a.endColumnIndex >= b.startColumnIndex;
|
|
17
|
+
};
|
|
18
|
+
var rangeContains = function (outer, inner) {
|
|
19
|
+
return inner.startRowIndex >= outer.startRowIndex &&
|
|
20
|
+
inner.endRowIndex <= outer.endRowIndex &&
|
|
21
|
+
inner.startColumnIndex >= outer.startColumnIndex &&
|
|
22
|
+
inner.endColumnIndex <= outer.endColumnIndex;
|
|
23
|
+
};
|
|
24
|
+
/** The cells a shift relocates: the selection's rows/columns from its leading edge to the sheet edge. */
|
|
25
|
+
export var shiftBand = function (direction, range) {
|
|
26
|
+
switch (direction) {
|
|
27
|
+
case "down":
|
|
28
|
+
case "up":
|
|
29
|
+
return {
|
|
30
|
+
startRowIndex: range.startRowIndex,
|
|
31
|
+
endRowIndex: Number.POSITIVE_INFINITY,
|
|
32
|
+
startColumnIndex: range.startColumnIndex,
|
|
33
|
+
endColumnIndex: range.endColumnIndex,
|
|
34
|
+
};
|
|
35
|
+
case "right":
|
|
36
|
+
case "left":
|
|
37
|
+
return {
|
|
38
|
+
startRowIndex: range.startRowIndex,
|
|
39
|
+
endRowIndex: range.endRowIndex,
|
|
40
|
+
startColumnIndex: range.startColumnIndex,
|
|
41
|
+
endColumnIndex: Number.POSITIVE_INFINITY,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* A cell counts as non-blank when it carries a value, a formula, a format, a note, a link or a
|
|
47
|
+
* citation — Excel's "might appear empty but have blank values, some formatting, or a formula".
|
|
48
|
+
* Derived render results (CF / DV results) don't count.
|
|
49
|
+
*/
|
|
50
|
+
var DERIVED_CELL_KEYS = new Set([
|
|
51
|
+
"conditionalFormattingResultById",
|
|
52
|
+
"dataValidationResult",
|
|
53
|
+
]);
|
|
54
|
+
export var isNonBlankCell = function (cell) {
|
|
55
|
+
if (!cell)
|
|
56
|
+
return false;
|
|
57
|
+
return Object.entries(cell).some(function (_a) {
|
|
58
|
+
var _b = __read(_a, 2), key = _b[0], value = _b[1];
|
|
59
|
+
return !DERIVED_CELL_KEYS.has(key) && value !== undefined && value !== null;
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* INS-06 / INS-09 / SHF-10 — the first non-blank cell that a shift of `count` rows (axis `row`) or
|
|
64
|
+
* columns (axis `column`) would push past `limit` (the last valid row/column index). Only cells
|
|
65
|
+
* inside `band` move. `undefined` when the edit is safe.
|
|
66
|
+
*/
|
|
67
|
+
export var findOffSheetPush = function (_a) {
|
|
68
|
+
var _b, _c;
|
|
69
|
+
var rows = _a.rows, axis = _a.axis, count = _a.count, limit = _a.limit, band = _a.band;
|
|
70
|
+
if (!rows || limit === undefined || count <= 0)
|
|
71
|
+
return undefined;
|
|
72
|
+
var firstPushed = limit - count + 1;
|
|
73
|
+
if (axis === "row") {
|
|
74
|
+
var startRow_1 = Math.max(band.startRowIndex, firstPushed, 1);
|
|
75
|
+
for (var rowIndex = startRow_1; rowIndex < rows.length; rowIndex++) {
|
|
76
|
+
var values = (_b = rows[rowIndex]) === null || _b === void 0 ? void 0 : _b.values;
|
|
77
|
+
if (!values)
|
|
78
|
+
continue;
|
|
79
|
+
var startCol = Math.max(band.startColumnIndex, 1);
|
|
80
|
+
var endCol = Math.min(band.endColumnIndex, values.length - 1);
|
|
81
|
+
for (var columnIndex = startCol; columnIndex <= endCol; columnIndex++) {
|
|
82
|
+
if (isNonBlankCell(values[columnIndex])) {
|
|
83
|
+
return { rowIndex: rowIndex, columnIndex: columnIndex };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
var startRow = Math.max(band.startRowIndex, 1);
|
|
90
|
+
var endRow = Math.min(band.endRowIndex, rows.length - 1);
|
|
91
|
+
for (var rowIndex = startRow; rowIndex <= endRow; rowIndex++) {
|
|
92
|
+
var values = (_c = rows[rowIndex]) === null || _c === void 0 ? void 0 : _c.values;
|
|
93
|
+
if (!values)
|
|
94
|
+
continue;
|
|
95
|
+
var startCol = Math.max(band.startColumnIndex, firstPushed, 1);
|
|
96
|
+
for (var columnIndex = startCol; columnIndex < values.length; columnIndex++) {
|
|
97
|
+
if (isNonBlankCell(values[columnIndex])) {
|
|
98
|
+
return { rowIndex: rowIndex, columnIndex: columnIndex };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return undefined;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* A range the band reaches but does not contain whole is TORN by the shift. For a delete, a range
|
|
106
|
+
* that touches the deleted block must lie wholly inside it (it is removed with the block) — one
|
|
107
|
+
* straddling the block's edge is torn too.
|
|
108
|
+
*/
|
|
109
|
+
export var findTornRange = function (ranges, band, deletedBlock) {
|
|
110
|
+
if (!ranges)
|
|
111
|
+
return undefined;
|
|
112
|
+
return ranges.find(function (range) {
|
|
113
|
+
if (rangesIntersect(range, band) && !rangeContains(band, range)) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (deletedBlock &&
|
|
117
|
+
rangesIntersect(range, deletedBlock) &&
|
|
118
|
+
!rangeContains(deletedBlock, range)) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
/** SHF-05 / MRG-07 — a merge the band covers only partially. */
|
|
125
|
+
export var findTornMerge = function (merges, band, deletedBlock) { return findTornRange(merges, band, deletedBlock); };
|
|
126
|
+
/** TBL-05 — a table the band covers only partially (a table wholly inside the band moves intact). */
|
|
127
|
+
export var findTornTable = function (tables, sheetId, band, deletedBlock) {
|
|
128
|
+
if (!tables)
|
|
129
|
+
return undefined;
|
|
130
|
+
return tables.find(function (table) {
|
|
131
|
+
return table.sheetId === sheetId &&
|
|
132
|
+
!!findTornRange([table.range], band, deletedBlock);
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
/** ANC-14 — a CSE / dynamic-array range the band covers only partially. */
|
|
136
|
+
export var findTornArray = function (arrayRanges, band, deletedBlock) { return findTornRange(arrayRanges, band, deletedBlock); };
|
|
137
|
+
/** Ranges (merges / tables) that travel with the band: wholly inside it and, for a delete, not
|
|
138
|
+
* inside the deleted block. */
|
|
139
|
+
export var isRangeInsideBand = function (range, band) {
|
|
140
|
+
return rangeContains(band, range);
|
|
141
|
+
};
|
|
142
|
+
export var isRangeInsideBlock = rangeContains;
|
|
143
|
+
/**
|
|
144
|
+
* The Excel refusal (if any) for an insert/delete-cells shift of `range`. Checks run in Excel's
|
|
145
|
+
* order: array tear, merge tear, table tear, off-sheet push. `undefined` means the edit may proceed.
|
|
146
|
+
*/
|
|
147
|
+
export var getShiftCellsRefusal = function (_a) {
|
|
148
|
+
var direction = _a.direction, range = _a.range, sheetId = _a.sheetId, rows = _a.rows, rowCount = _a.rowCount, columnCount = _a.columnCount, merges = _a.merges, tables = _a.tables, arrayRanges = _a.arrayRanges;
|
|
149
|
+
var band = shiftBand(direction, range);
|
|
150
|
+
var isDelete = direction === "up" || direction === "left";
|
|
151
|
+
var deletedBlock = isDelete ? range : undefined;
|
|
152
|
+
if (findTornArray(arrayRanges, band, deletedBlock)) {
|
|
153
|
+
return structuralRefusal("torn-array");
|
|
154
|
+
}
|
|
155
|
+
if (findTornMerge(merges, band, deletedBlock)) {
|
|
156
|
+
return structuralRefusal("torn-merge");
|
|
157
|
+
}
|
|
158
|
+
if (findTornTable(tables, sheetId, band, deletedBlock)) {
|
|
159
|
+
return structuralRefusal("torn-table");
|
|
160
|
+
}
|
|
161
|
+
if (!isDelete) {
|
|
162
|
+
var vertical = direction === "down";
|
|
163
|
+
var count = vertical
|
|
164
|
+
? range.endRowIndex - range.startRowIndex + 1
|
|
165
|
+
: range.endColumnIndex - range.startColumnIndex + 1;
|
|
166
|
+
var pushed = findOffSheetPush({
|
|
167
|
+
rows: rows,
|
|
168
|
+
axis: vertical ? "row" : "column",
|
|
169
|
+
count: count,
|
|
170
|
+
limit: vertical ? rowCount : columnCount,
|
|
171
|
+
band: band,
|
|
172
|
+
});
|
|
173
|
+
if (pushed) {
|
|
174
|
+
return structuralRefusal("off-sheet-push");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return undefined;
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* INS-06 / INS-09 — the refusal for a whole-row (`axis: "row"`) or whole-column insert of `count`
|
|
181
|
+
* lines before `referenceIndex`, given the hard grid cap (`maxRowCount` / `maxColumnCount`). Blank
|
|
182
|
+
* trailing lines may fall off the end; a non-blank one refuses the insert.
|
|
183
|
+
*/
|
|
184
|
+
export var getInsertLinesRefusal = function (_a) {
|
|
185
|
+
var axis = _a.axis, referenceIndex = _a.referenceIndex, count = _a.count, rows = _a.rows, limit = _a.limit;
|
|
186
|
+
var band = axis === "row"
|
|
187
|
+
? {
|
|
188
|
+
startRowIndex: referenceIndex,
|
|
189
|
+
endRowIndex: Number.POSITIVE_INFINITY,
|
|
190
|
+
startColumnIndex: 1,
|
|
191
|
+
endColumnIndex: Number.POSITIVE_INFINITY,
|
|
192
|
+
}
|
|
193
|
+
: {
|
|
194
|
+
startRowIndex: 1,
|
|
195
|
+
endRowIndex: Number.POSITIVE_INFINITY,
|
|
196
|
+
startColumnIndex: referenceIndex,
|
|
197
|
+
endColumnIndex: Number.POSITIVE_INFINITY,
|
|
198
|
+
};
|
|
199
|
+
return findOffSheetPush({ rows: rows, axis: axis, count: count, limit: limit, band: band })
|
|
200
|
+
? structuralRefusal("off-sheet-push")
|
|
201
|
+
: undefined;
|
|
202
|
+
};
|