@rowsncolumns/spreadsheet-state 29.1.3 → 29.1.6
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/circular-reference.d.ts +31 -0
- package/dist/cjs/api/circular-reference.d.ts.map +1 -0
- package/dist/cjs/api/circular-reference.js +85 -0
- package/dist/cjs/api/copy-paste.d.ts +6 -0
- package/dist/cjs/api/copy-paste.d.ts.map +1 -1
- package/dist/cjs/api/copy-paste.js +24 -15
- package/dist/cjs/api/datatype.d.ts +2 -0
- package/dist/cjs/api/datatype.d.ts.map +1 -1
- package/dist/cjs/api/datatype.js +50 -27
- package/dist/cjs/api/decimals.d.ts +10 -0
- package/dist/cjs/api/decimals.d.ts.map +1 -1
- package/dist/cjs/api/decimals.js +34 -11
- package/dist/cjs/api/dependency.d.ts +19 -1
- package/dist/cjs/api/dependency.d.ts.map +1 -1
- package/dist/cjs/api/dependency.js +30 -14
- package/dist/cjs/api/filter-condition.d.ts +58 -0
- package/dist/cjs/api/filter-condition.d.ts.map +1 -0
- package/dist/cjs/api/filter-condition.js +157 -0
- package/dist/cjs/api/formula.d.ts.map +1 -1
- package/dist/cjs/api/formula.js +9 -7
- package/dist/cjs/api/image-embed.d.ts +41 -0
- package/dist/cjs/api/image-embed.d.ts.map +1 -0
- package/dist/cjs/api/image-embed.js +55 -0
- package/dist/cjs/api/immer-utils.d.ts.map +1 -1
- package/dist/cjs/api/immer-utils.js +43 -15
- package/dist/cjs/api/named-range-structural.d.ts +29 -3
- package/dist/cjs/api/named-range-structural.d.ts.map +1 -1
- package/dist/cjs/api/named-range-structural.js +36 -11
- package/dist/cjs/api/parse-html.d.ts.map +1 -1
- package/dist/cjs/api/parse-html.js +11 -5
- package/dist/cjs/api/structural-formula-update.d.ts +20 -1
- package/dist/cjs/api/structural-formula-update.d.ts.map +1 -1
- package/dist/cjs/api/structural-formula-update.js +264 -90
- package/dist/cjs/api/structural-guards.d.ts +11 -0
- package/dist/cjs/api/structural-guards.d.ts.map +1 -1
- package/dist/cjs/api/structural-guards.js +45 -1
- package/dist/cjs/api/structural-table-refs.d.ts +15 -2
- package/dist/cjs/api/structural-table-refs.d.ts.map +1 -1
- package/dist/cjs/api/structural-table-refs.js +79 -35
- package/dist/cjs/commands.d.ts +17 -3
- package/dist/cjs/commands.d.ts.map +1 -1
- package/dist/cjs/components/editors/conditional-format-rule-editor.d.ts.map +1 -1
- package/dist/cjs/components/editors/conditional-format-rule-editor.js +19 -7
- package/dist/cjs/constants.d.ts +4 -1
- package/dist/cjs/constants.d.ts.map +1 -1
- package/dist/cjs/constants.js +4 -0
- package/dist/cjs/helpers/sheet-title.d.ts +2 -1
- package/dist/cjs/helpers/sheet-title.d.ts.map +1 -1
- package/dist/cjs/helpers/sheet-title.js +3 -1
- package/dist/cjs/hooks/use-can-edit-cellrange.d.ts +1 -1
- package/dist/cjs/hooks/use-can-edit-cellrange.d.ts.map +1 -1
- package/dist/cjs/hooks/use-can-edit-cellrange.js +1 -1
- package/dist/cjs/hooks/use-on-calculation-success.d.ts +5 -1
- package/dist/cjs/hooks/use-on-calculation-success.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-calculation-success.js +20 -3
- package/dist/cjs/hooks/use-on-copy.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-copy.js +23 -25
- package/dist/cjs/hooks/use-on-create-sheet.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-create-sheet.js +11 -1
- package/dist/cjs/hooks/use-on-delete.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-delete.js +15 -3
- package/dist/cjs/hooks/use-on-drag-n-drop.d.ts +5 -0
- package/dist/cjs/hooks/use-on-drag-n-drop.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-drag-n-drop.js +6 -5
- package/dist/cjs/hooks/use-on-filter-table.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-filter-table.js +6 -1
- package/dist/cjs/hooks/use-on-find-replace.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-find-replace.js +111 -23
- package/dist/cjs/hooks/use-on-insert-image.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-insert-image.js +20 -33
- package/dist/cjs/hooks/use-on-paste.d.ts +2 -1
- package/dist/cjs/hooks/use-on-paste.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-paste.js +53 -24
- package/dist/cjs/hooks/use-on-rename-sheet.d.ts +3 -1
- package/dist/cjs/hooks/use-on-rename-sheet.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-rename-sheet.js +19 -9
- package/dist/cjs/hooks/use-on-sort-column.d.ts +7 -1
- package/dist/cjs/hooks/use-on-sort-column.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-sort-column.js +25 -8
- package/dist/cjs/hooks/use-on-sort-range.d.ts +16 -2
- package/dist/cjs/hooks/use-on-sort-range.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-sort-range.js +72 -40
- package/dist/cjs/hooks/use-on-sort-table.d.ts +7 -2
- package/dist/cjs/hooks/use-on-sort-table.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-sort-table.js +25 -4
- package/dist/cjs/hooks/use-spreadsheet-state.d.ts +5 -3
- package/dist/cjs/hooks/use-spreadsheet-state.d.ts.map +1 -1
- package/dist/cjs/hooks/use-spreadsheet-state.js +7 -0
- package/dist/cjs/hooks/utils/sort-rows.d.ts +15 -0
- package/dist/cjs/hooks/utils/sort-rows.d.ts.map +1 -1
- package/dist/cjs/hooks/utils/sort-rows.js +16 -0
- 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/delete-column.d.ts.map +1 -1
- package/dist/cjs/interface/delete-column.js +254 -101
- package/dist/cjs/interface/delete-row.d.ts.map +1 -1
- package/dist/cjs/interface/delete-row.js +233 -81
- package/dist/cjs/interface/duplicate-sheet.d.ts.map +1 -1
- package/dist/cjs/interface/duplicate-sheet.js +4 -9
- package/dist/cjs/interface/insert-column.d.ts.map +1 -1
- package/dist/cjs/interface/insert-column.js +1 -1
- package/dist/cjs/interface/insert-row.d.ts.map +1 -1
- package/dist/cjs/interface/insert-row.js +1 -1
- package/dist/cjs/interface/new-sheet.d.ts.map +1 -1
- package/dist/cjs/interface/new-sheet.js +6 -13
- package/dist/cjs/sheet-cell.d.ts +9 -0
- package/dist/cjs/sheet-cell.d.ts.map +1 -1
- package/dist/cjs/sheet-cell.js +46 -9
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/api/circular-reference.d.ts +31 -0
- package/dist/esm/api/circular-reference.d.ts.map +1 -0
- package/dist/esm/api/circular-reference.js +55 -0
- package/dist/esm/api/copy-paste.d.ts +6 -0
- package/dist/esm/api/copy-paste.d.ts.map +1 -1
- package/dist/esm/api/copy-paste.js +26 -14
- package/dist/esm/api/datatype.d.ts +2 -0
- package/dist/esm/api/datatype.d.ts.map +1 -1
- package/dist/esm/api/datatype.js +50 -27
- package/dist/esm/api/decimals.d.ts +10 -0
- package/dist/esm/api/decimals.d.ts.map +1 -1
- package/dist/esm/api/decimals.js +31 -10
- package/dist/esm/api/dependency.d.ts +19 -1
- package/dist/esm/api/dependency.d.ts.map +1 -1
- package/dist/esm/api/dependency.js +15 -10
- package/dist/esm/api/filter-condition.d.ts +58 -0
- package/dist/esm/api/filter-condition.d.ts.map +1 -0
- package/dist/esm/api/filter-condition.js +146 -0
- package/dist/esm/api/formula.d.ts.map +1 -1
- package/dist/esm/api/formula.js +9 -7
- package/dist/esm/api/image-embed.d.ts +41 -0
- package/dist/esm/api/image-embed.d.ts.map +1 -0
- package/dist/esm/api/image-embed.js +52 -0
- package/dist/esm/api/immer-utils.d.ts.map +1 -1
- package/dist/esm/api/immer-utils.js +43 -14
- package/dist/esm/api/named-range-structural.d.ts +29 -3
- package/dist/esm/api/named-range-structural.d.ts.map +1 -1
- package/dist/esm/api/named-range-structural.js +35 -11
- package/dist/esm/api/parse-html.d.ts.map +1 -1
- package/dist/esm/api/parse-html.js +14 -5
- package/dist/esm/api/structural-formula-update.d.ts +20 -1
- package/dist/esm/api/structural-formula-update.d.ts.map +1 -1
- package/dist/esm/api/structural-formula-update.js +151 -55
- package/dist/esm/api/structural-guards.d.ts +11 -0
- package/dist/esm/api/structural-guards.d.ts.map +1 -1
- package/dist/esm/api/structural-guards.js +31 -0
- package/dist/esm/api/structural-table-refs.d.ts +15 -2
- package/dist/esm/api/structural-table-refs.d.ts.map +1 -1
- package/dist/esm/api/structural-table-refs.js +49 -18
- package/dist/esm/commands.d.ts +17 -3
- package/dist/esm/commands.d.ts.map +1 -1
- package/dist/esm/components/editors/conditional-format-rule-editor.d.ts.map +1 -1
- package/dist/esm/components/editors/conditional-format-rule-editor.js +18 -7
- package/dist/esm/constants.d.ts +4 -1
- package/dist/esm/constants.d.ts.map +1 -1
- package/dist/esm/constants.js +4 -0
- package/dist/esm/helpers/sheet-title.d.ts +2 -1
- package/dist/esm/helpers/sheet-title.d.ts.map +1 -1
- package/dist/esm/helpers/sheet-title.js +3 -1
- package/dist/esm/hooks/use-can-edit-cellrange.d.ts +1 -1
- package/dist/esm/hooks/use-can-edit-cellrange.d.ts.map +1 -1
- package/dist/esm/hooks/use-can-edit-cellrange.js +1 -1
- package/dist/esm/hooks/use-on-calculation-success.d.ts +5 -1
- package/dist/esm/hooks/use-on-calculation-success.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-calculation-success.js +19 -3
- package/dist/esm/hooks/use-on-copy.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-copy.js +17 -17
- package/dist/esm/hooks/use-on-create-sheet.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-create-sheet.js +11 -1
- package/dist/esm/hooks/use-on-delete.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-delete.js +15 -3
- package/dist/esm/hooks/use-on-drag-n-drop.d.ts +5 -0
- package/dist/esm/hooks/use-on-drag-n-drop.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-drag-n-drop.js +7 -4
- package/dist/esm/hooks/use-on-filter-table.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-filter-table.js +13 -2
- package/dist/esm/hooks/use-on-find-replace.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-find-replace.js +111 -23
- package/dist/esm/hooks/use-on-insert-image.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-insert-image.js +15 -25
- package/dist/esm/hooks/use-on-paste.d.ts +2 -1
- package/dist/esm/hooks/use-on-paste.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-paste.js +46 -15
- package/dist/esm/hooks/use-on-rename-sheet.d.ts +3 -1
- package/dist/esm/hooks/use-on-rename-sheet.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-rename-sheet.js +19 -9
- package/dist/esm/hooks/use-on-sort-column.d.ts +7 -1
- package/dist/esm/hooks/use-on-sort-column.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-sort-column.js +18 -1
- package/dist/esm/hooks/use-on-sort-range.d.ts +16 -2
- package/dist/esm/hooks/use-on-sort-range.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-sort-range.js +30 -3
- package/dist/esm/hooks/use-on-sort-table.d.ts +7 -2
- package/dist/esm/hooks/use-on-sort-table.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-sort-table.js +25 -4
- package/dist/esm/hooks/use-spreadsheet-state.d.ts +5 -3
- package/dist/esm/hooks/use-spreadsheet-state.d.ts.map +1 -1
- package/dist/esm/hooks/use-spreadsheet-state.js +7 -0
- package/dist/esm/hooks/utils/sort-rows.d.ts +15 -0
- package/dist/esm/hooks/utils/sort-rows.d.ts.map +1 -1
- package/dist/esm/hooks/utils/sort-rows.js +15 -0
- 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/delete-column.d.ts.map +1 -1
- package/dist/esm/interface/delete-column.js +111 -80
- package/dist/esm/interface/delete-row.d.ts.map +1 -1
- package/dist/esm/interface/delete-row.js +91 -59
- package/dist/esm/interface/duplicate-sheet.d.ts.map +1 -1
- package/dist/esm/interface/duplicate-sheet.js +4 -9
- package/dist/esm/interface/insert-column.d.ts.map +1 -1
- package/dist/esm/interface/insert-column.js +1 -1
- package/dist/esm/interface/insert-row.d.ts.map +1 -1
- package/dist/esm/interface/insert-row.js +1 -1
- package/dist/esm/interface/new-sheet.d.ts.map +1 -1
- package/dist/esm/interface/new-sheet.js +6 -13
- package/dist/esm/sheet-cell.d.ts +9 -0
- package/dist/esm/sheet-cell.d.ts.map +1 -1
- package/dist/esm/sheet-cell.js +46 -7
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +15 -15
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
import { isNil, iterateCellsInRange } from "@rowsncolumns/utils";
|
|
1
|
+
import { getCellEffectiveValue, getCellUserEnteredValue, getExtendedValueBool, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, isNil, iterateCellsInRange, } from "@rowsncolumns/utils";
|
|
2
2
|
import { produceWithPatches } from "immer";
|
|
3
|
+
import isEqual from "lodash/isEqual";
|
|
3
4
|
import { useCallback } from "react";
|
|
4
5
|
import { createSheetCellIdentifier } from "../api/formula";
|
|
5
6
|
import { createSheetDraft } from "../api/immer-utils";
|
|
6
|
-
import { SheetCell } from "../sheet-cell";
|
|
7
|
+
import { SheetCell, hasExcelTextPrefix, stripExcelTextPrefix, } from "../sheet-cell";
|
|
7
8
|
import { buildSearchRegex } from "./use-search";
|
|
9
|
+
/**
|
|
10
|
+
* The text `text` becomes after replacing every match of `regex` with
|
|
11
|
+
* `replaceWith`, or `undefined` when nothing matches / nothing changes (the
|
|
12
|
+
* cell is then left untouched). `regex` is the `g`-flagged matcher from
|
|
13
|
+
* `buildSearchRegex`, so `lastIndex` is reset before each use.
|
|
14
|
+
*/
|
|
15
|
+
const replaceIn = (regex, text, replaceWith) => {
|
|
16
|
+
regex.lastIndex = 0;
|
|
17
|
+
if (!regex.test(text))
|
|
18
|
+
return undefined;
|
|
19
|
+
regex.lastIndex = 0;
|
|
20
|
+
const next = text.replace(regex, replaceWith ?? "");
|
|
21
|
+
return next === text ? undefined : next;
|
|
22
|
+
};
|
|
8
23
|
export const useOnFindReplace = ({ locale, createHistory, onChangeSheetData, enqueueCalculation, enqueueStructureChange, sharedStringRegistry, onCommand, }) => {
|
|
9
24
|
return useCallback((lookupRanges, searchStr, replaceWith, options) => {
|
|
10
25
|
// Build the matcher once with the same helper `useSearch` uses, so
|
|
@@ -55,28 +70,101 @@ export const useOnFindReplace = ({ locale, createHistory, onChangeSheetData, enq
|
|
|
55
70
|
const currentSheet = createSheetDraft(draft, range.sheetId, rowIndex);
|
|
56
71
|
const cellData = draft[range.sheetId]?.[rowIndex]?.values?.[columnIndex];
|
|
57
72
|
sheetCell.assign(range.sheetId, { rowIndex, columnIndex }, cellData, { locale });
|
|
58
|
-
//
|
|
59
|
-
// the
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
// Excel's Replace edits the cell's STORED content (it runs in
|
|
74
|
+
// "Look in: Formulas" only), so the match text and the write
|
|
75
|
+
// depend on what the cell holds — never on the display alone:
|
|
76
|
+
// - a formula cell is matched on and rewritten in its SOURCE
|
|
77
|
+
// text (`=SUM(A1:A2)` → `=SUM(B1:A2)`); its computed result
|
|
78
|
+
// is not a hit, so the formula is never flattened to a
|
|
79
|
+
// literal;
|
|
80
|
+
// - a text cell is matched on its display (what `useSearch`
|
|
81
|
+
// highlighted) but the replacement runs over the stored
|
|
82
|
+
// string and is written back AS TEXT — `'0123` keeps its
|
|
83
|
+
// quote prefix (`'0124`), a Text-formatted `0123` stays
|
|
84
|
+
// `0124`, and a text whose new content looks numeric is not
|
|
85
|
+
// re-inferred;
|
|
86
|
+
// - a number / boolean / date is matched on its display
|
|
87
|
+
// ("$1,234.50"), the replacement runs over that display and
|
|
88
|
+
// the result is re-entered under the cell's own number
|
|
89
|
+
// format — `$1,235.50` stays the number 1235.5 in currency,
|
|
90
|
+
// `1/15/2025` stays a date serial — and the format itself
|
|
91
|
+
// is left exactly as it was.
|
|
92
|
+
const ue = getCellUserEnteredValue(cellData);
|
|
93
|
+
const ev = getCellEffectiveValue(cellData);
|
|
94
|
+
const formula = getExtendedValueFormula(ue);
|
|
95
|
+
// The legacy model keeps a number's ENTERED string in `ue.sv`
|
|
96
|
+
// ("$1,234.50") and its value in `ev.nv`, so `ue.sv` alone does
|
|
97
|
+
// not make a cell text: a literal is text when it evaluates to
|
|
98
|
+
// a string, carries Excel's `'` prefix, or sits in a Text
|
|
99
|
+
// format. Anything else with a stored string is a typed
|
|
100
|
+
// number / boolean / date.
|
|
101
|
+
const storedText = isNil(formula)
|
|
102
|
+
? getExtendedValueString(ue)
|
|
103
|
+
: undefined;
|
|
104
|
+
const isNumericLiteral = !isNil(getExtendedValueNumber(ev)) ||
|
|
105
|
+
!isNil(getExtendedValueBool(ev));
|
|
106
|
+
const isTextLiteral = !isNil(storedText) &&
|
|
107
|
+
!isNumericLiteral &&
|
|
108
|
+
(!isNil(getExtendedValueString(ev)) ||
|
|
109
|
+
hasExcelTextPrefix(storedText) ||
|
|
110
|
+
sheetCell.isText(sheetCell.getNumberFormat()));
|
|
111
|
+
let next;
|
|
112
|
+
let writeAsText = false;
|
|
113
|
+
let textPrefix = "";
|
|
114
|
+
if (!isNil(formula)) {
|
|
115
|
+
next = replaceIn(regex, formula, replaceWith);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
const formattedValue = sheetCell.formattedValue;
|
|
119
|
+
if (isNil(formattedValue))
|
|
120
|
+
continue;
|
|
121
|
+
// `g` flag is set by `buildSearchRegex`; reset lastIndex
|
|
122
|
+
// before .test so a stateful regex doesn't skip the
|
|
123
|
+
// first character on a re-run.
|
|
124
|
+
regex.lastIndex = 0;
|
|
125
|
+
if (!regex.test(formattedValue))
|
|
126
|
+
continue;
|
|
127
|
+
if (isTextLiteral) {
|
|
128
|
+
if (hasExcelTextPrefix(storedText)) {
|
|
129
|
+
textPrefix = "'";
|
|
130
|
+
}
|
|
131
|
+
const base = textPrefix
|
|
132
|
+
? stripExcelTextPrefix(storedText)
|
|
133
|
+
: storedText;
|
|
134
|
+
// A needle that appears only in an `@`-pattern's
|
|
135
|
+
// decoration (`"Note: "@`) is not cell content.
|
|
136
|
+
next = replaceIn(regex, base, replaceWith);
|
|
137
|
+
writeAsText = true;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
next = replaceIn(regex, formattedValue, replaceWith);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (isNil(next))
|
|
76
144
|
continue;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
145
|
+
if (next === "") {
|
|
146
|
+
sheetCell.setUserEnteredValue("");
|
|
147
|
+
}
|
|
148
|
+
else if (writeAsText) {
|
|
149
|
+
if (textPrefix) {
|
|
150
|
+
// The normal entry path keeps a `'`-prefixed entry as text
|
|
151
|
+
// and preserves the prefix in `ue.sv` for the formula bar.
|
|
152
|
+
sheetCell.setUserEnteredValue(`${textPrefix}${next}`);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
sheetCell.setUserEnteredValue(next, undefined, {
|
|
156
|
+
disableTypeInference: true,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
const numberFormat = sheetCell.getNumberFormat();
|
|
162
|
+
sheetCell.setUserEnteredValue(next);
|
|
163
|
+
if (!isNil(numberFormat) &&
|
|
164
|
+
!isEqual(sheetCell.getNumberFormat(), numberFormat)) {
|
|
165
|
+
sheetCell.setUserEnteredFormat("numberFormat", numberFormat);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
80
168
|
sharedStringRegistry?.registerCell(sheetCell);
|
|
81
169
|
currentSheet[rowIndex].values[columnIndex] =
|
|
82
170
|
sheetCell.getCellData();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-on-insert-image.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-insert-image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EACV,QAAQ,EAER,KAAK,EACN,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"use-on-insert-image.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-insert-image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EACV,QAAQ,EAER,KAAK,EACN,MAAM,2BAA2B,CAAC;AAanC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,KAAK,qBAAqB,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,IAAI;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,kBAAkB,CAAC,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;IAC/D,kBAAkB,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC1D,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACzD,iBAAiB,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAClE,cAAc,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,kHAQnE,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,iBAIb,IAAI,GAAG,MAAM,WACf,MAAM,cACH,aAAa,YACf,iBAAiB,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,kBA0IhE,CAAC"}
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
import { useGetSheetDimensions } from "@rowsncolumns/spreadsheet";
|
|
2
2
|
import { getImageDimensionsFromUrl, readImageFileAsDataUri, } from "@rowsncolumns/toolkit";
|
|
3
|
-
import { log
|
|
3
|
+
import { log } from "@rowsncolumns/utils";
|
|
4
4
|
import { produceWithPatches } from "immer";
|
|
5
5
|
import { useCallback } from "react";
|
|
6
6
|
import { createSheetCellIdentifier } from "../api/formula";
|
|
7
|
+
import { createImageEmbed, fitImageToViewport } from "../api/image-embed";
|
|
7
8
|
import { createSheetDraft } from "../api/immer-utils";
|
|
8
9
|
import { SheetCell } from "../sheet-cell";
|
|
9
10
|
export const useOnInsertImage = ({ locale, idCreationStrategy, enqueueCalculation, createHistory, onChangeEmbeds, onChangeSheetData, onCommand, }) => {
|
|
10
11
|
const getSheetDimensions = useGetSheetDimensions();
|
|
11
12
|
return useCallback(async (fileOrUrl, sheetId, activeCell, options) => {
|
|
12
13
|
const { insertOverCells, embedId } = options ?? {};
|
|
13
|
-
const maxDimension = 800;
|
|
14
14
|
const [imageUrl, width, height] = fileOrUrl instanceof File
|
|
15
15
|
? await readImageFileAsDataUri(fileOrUrl)
|
|
16
16
|
: [
|
|
17
17
|
fileOrUrl,
|
|
18
18
|
...(await getImageDimensionsFromUrl(fileOrUrl)),
|
|
19
19
|
];
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
const finalWidth =
|
|
23
|
-
const finalHeight = finalWidth / ratio;
|
|
20
|
+
// Excel's default picture size: natural pixels, scaled down to fit the visible grid.
|
|
21
|
+
const viewport = getSheetDimensions?.();
|
|
22
|
+
const { widthPixels: finalWidth, heightPixels: finalHeight } = fitImageToViewport(width, height, viewport);
|
|
24
23
|
// Recalc cells
|
|
25
24
|
const recalcCells = new Map();
|
|
26
25
|
const saveHistory = createHistory();
|
|
@@ -33,25 +32,16 @@ export const useOnInsertImage = ({ locale, idCreationStrategy, enqueueCalculatio
|
|
|
33
32
|
if (!draft) {
|
|
34
33
|
draft = [];
|
|
35
34
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
borderColor: "transparent",
|
|
49
|
-
lockAspectRatio: true,
|
|
50
|
-
spec: {
|
|
51
|
-
type: "image",
|
|
52
|
-
imageUrl,
|
|
53
|
-
},
|
|
54
|
-
};
|
|
35
|
+
// The same floating picture the clipboard paste / file drop create.
|
|
36
|
+
const embed = createImageEmbed({
|
|
37
|
+
sheetId,
|
|
38
|
+
anchorCell: activeCell,
|
|
39
|
+
imageUrl,
|
|
40
|
+
width,
|
|
41
|
+
height,
|
|
42
|
+
viewport,
|
|
43
|
+
idCreationStrategy,
|
|
44
|
+
});
|
|
55
45
|
if (embedId) {
|
|
56
46
|
const idx = draft.findIndex((cur) => cur.embedId === embedId);
|
|
57
47
|
if (idx !== -1) {
|
|
@@ -95,7 +95,8 @@ type UseOnPasteProps<T extends CellData, S extends Sheet> = {
|
|
|
95
95
|
*/
|
|
96
96
|
onChangeCitations?: UseSpreadsheetProps<T, S>["onChangeCitations"];
|
|
97
97
|
/**
|
|
98
|
-
* Optional HTML sanitizer for clipboard paste operations
|
|
98
|
+
* Optional additional HTML sanitizer for clipboard paste operations. The
|
|
99
|
+
* built-in sanitizer always runs afterwards; this can only tighten it.
|
|
99
100
|
*/
|
|
100
101
|
sanitizeHtml?: (html: string) => string;
|
|
101
102
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-on-paste.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-paste.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EACV,QAAQ,EACR,wBAAwB,EAExB,mBAAmB,EACnB,KAAK,EACL,SAAS,EACV,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"use-on-paste.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-paste.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isStaticNode } from "@rowsncolumns/dag";
|
|
2
2
|
import { areaInsideArea, areaIntersects, isAreasEqual } from "@rowsncolumns/grid";
|
|
3
3
|
import { selectionFromActiveCell } from "@rowsncolumns/grid";
|
|
4
|
-
import { DEFAULT_COLUMN_COUNT, DEFAULT_ROW_COUNT, findActiveTableWithinCell, loadWebFont, MAX_COLUMN_COUNT, MAX_ROW_COUNT, useFocusEmbedOrChart, useGetFinalRowHeight, useRedrawGrid, } from "@rowsncolumns/spreadsheet";
|
|
4
|
+
import { DEFAULT_COLUMN_COUNT, DEFAULT_ROW_COUNT, findActiveTableWithinCell, loadWebFont, MAX_COLUMN_COUNT, MAX_ROW_COUNT, useFocusEmbedOrChart, useGetFinalRowHeight, useGetSheetDimensions, useRedrawGrid, } from "@rowsncolumns/spreadsheet";
|
|
5
5
|
import { isSelectionACell, useGetEffectiveValuesFromRange, } from "@rowsncolumns/spreadsheet";
|
|
6
6
|
import { error, getCellFormattedValue, getCellUserEnteredFormat, getCellUserEnteredValue, getExtendedValueBool, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, isNil, iterateCellsInRange, uuidString, } from "@rowsncolumns/utils";
|
|
7
7
|
import { produceWithPatches } from "immer";
|
|
@@ -73,6 +73,7 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
73
73
|
});
|
|
74
74
|
const redrawGrid = useRedrawGrid();
|
|
75
75
|
const getFinalRowHeight = useGetFinalRowHeight();
|
|
76
|
+
const getSheetDimensions = useGetSheetDimensions();
|
|
76
77
|
const { enqueue, processQueue } = useCalculationQueue({ enqueueCalculation });
|
|
77
78
|
return useCallback(async (e, sourceSheetId, destinationSheetId, copiedSelections, activeCell, selections, finalSelections, isCutOperation) => {
|
|
78
79
|
// Paste Special request (values / formats / formulas, operation, skip
|
|
@@ -109,7 +110,7 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
else {
|
|
112
|
-
const pasteResults = await generateDataFromClipboard(e, activeCell, destinationSheetId, activeSheetName, preserveFormatting, locale, idCreationStrategy, forcePlainText, sanitizeHtml);
|
|
113
|
+
const pasteResults = await generateDataFromClipboard(e, activeCell, destinationSheetId, activeSheetName, preserveFormatting, locale, idCreationStrategy, forcePlainText, sanitizeHtml, { imageViewport: getSheetDimensions?.() });
|
|
113
114
|
selectedRowValues = pasteResults?.results ?? [];
|
|
114
115
|
merges = pasteResults?.merges;
|
|
115
116
|
embeds = pasteResults?.embeds;
|
|
@@ -121,6 +122,34 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
121
122
|
if (isNil(selectedRowValues)) {
|
|
122
123
|
return;
|
|
123
124
|
}
|
|
125
|
+
// Floating objects the clipboard carried (the pasted picture(s) of an image paste) — one
|
|
126
|
+
// undo entry, the first one selected, like a freshly inserted chart.
|
|
127
|
+
const insertEmbeds = (saveHistory, pastedEmbeds) => {
|
|
128
|
+
const firstEmbedId = pastedEmbeds[0].embedId;
|
|
129
|
+
onChangeEmbeds?.((prevEmbeds) => {
|
|
130
|
+
const [nextState, patches, inversePatches] = produceWithPatches(prevEmbeds, (draft) => {
|
|
131
|
+
draft.push(...pastedEmbeds);
|
|
132
|
+
});
|
|
133
|
+
saveHistory({
|
|
134
|
+
embeds: { patches, inversePatches },
|
|
135
|
+
selectedEmbedOrChart: { redo: firstEmbedId, undo: undefined },
|
|
136
|
+
});
|
|
137
|
+
return nextState;
|
|
138
|
+
});
|
|
139
|
+
// Selected first embed
|
|
140
|
+
focusEmbedOrChart(firstEmbedId);
|
|
141
|
+
};
|
|
142
|
+
// An image paste writes NO cells: the picture floats over the grid anchored at the active
|
|
143
|
+
// cell (Excel / Google Sheets Ctrl+V of a picture), so it skips the cell-paste pipeline.
|
|
144
|
+
if (!selectedRowValues.length && embeds?.length) {
|
|
145
|
+
const anchorRange = selectionFromActiveCell(activeCell)[0].range;
|
|
146
|
+
if (!canEditCellRange(destinationSheetId, anchorRange)) {
|
|
147
|
+
console.debug("Protected range, You cannot paste on to protected cells.");
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
insertEmbeds(createHistory(), embeds);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
124
153
|
if (pasteSpecial.transpose && selectedRowValues.length) {
|
|
125
154
|
selectedRowValues = transpose(selectedRowValues);
|
|
126
155
|
}
|
|
@@ -668,6 +697,13 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
668
697
|
}
|
|
669
698
|
}
|
|
670
699
|
}
|
|
700
|
+
// The landed block replaces the merge geometry it covers (Excel: pasting a
|
|
701
|
+
// block over a merged cell unmerges it so every pasted value is visible; a
|
|
702
|
+
// cut block's merges travel with it, and a partial cover was refused above).
|
|
703
|
+
// A single copied cell pasted onto a merged cell keeps the merge and fills it.
|
|
704
|
+
if (sheet.merges?.length && rowSpan * colSpan > 1) {
|
|
705
|
+
sheet.merges = sheet.merges.filter((merge) => !areaIntersects(merge, to.range));
|
|
706
|
+
}
|
|
671
707
|
// Update merges
|
|
672
708
|
if (mergesToAdd) {
|
|
673
709
|
sheet.merges = sheet.merges ?? [];
|
|
@@ -717,6 +753,12 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
717
753
|
// Clipboard-provided row heights win.
|
|
718
754
|
if (clipboardSizedRows.has(rowIndex))
|
|
719
755
|
continue;
|
|
756
|
+
// Excel keeps a custom (user-dragged) height: only auto-height
|
|
757
|
+
// rows refit to pasted wrapped / multi-line text. The grid's
|
|
758
|
+
// measurer also skips pinned rows — the guard here keeps the
|
|
759
|
+
// rule at the write site so no measurer can clobber the pin.
|
|
760
|
+
if (sheet.rowMetadata?.[rowIndex]?.resizedByUser)
|
|
761
|
+
continue;
|
|
720
762
|
const rowData = selectedRowValues[dataRowIndex];
|
|
721
763
|
if (!rowData)
|
|
722
764
|
continue;
|
|
@@ -918,19 +960,7 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
918
960
|
}
|
|
919
961
|
// Embeds
|
|
920
962
|
if (embeds?.length) {
|
|
921
|
-
|
|
922
|
-
onChangeEmbeds?.((prevEmbeds) => {
|
|
923
|
-
const [nextState, patches, inversePatches] = produceWithPatches(prevEmbeds, (draft) => {
|
|
924
|
-
draft.push(...embeds);
|
|
925
|
-
});
|
|
926
|
-
saveHistory({
|
|
927
|
-
embeds: { patches, inversePatches },
|
|
928
|
-
selectedEmbedOrChart: { redo: firstEmbedId, undo: undefined },
|
|
929
|
-
});
|
|
930
|
-
return nextState;
|
|
931
|
-
});
|
|
932
|
-
// Selected first embed
|
|
933
|
-
focusEmbedOrChart(embeds[0].embedId);
|
|
963
|
+
insertEmbeds(saveHistory, embeds);
|
|
934
964
|
}
|
|
935
965
|
// Tables
|
|
936
966
|
if (tables?.length) {
|
|
@@ -1091,6 +1121,7 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
1091
1121
|
getUserEnteredValue,
|
|
1092
1122
|
focusEmbedOrChart,
|
|
1093
1123
|
redrawGrid,
|
|
1124
|
+
getSheetDimensions,
|
|
1094
1125
|
processQueue,
|
|
1095
1126
|
enqueue,
|
|
1096
1127
|
isHiddenByFilterRow,
|
|
@@ -7,6 +7,8 @@ import type { UseSpreadsheetProps } from "./use-spreadsheet-state";
|
|
|
7
7
|
import type { SpreadsheetPatch } from "./use-undo-redo";
|
|
8
8
|
type UseOnRenameSheetProps<T extends CellData, S extends Sheet> = {
|
|
9
9
|
locale?: string;
|
|
10
|
+
/** The workbook's sheets — a rename to a title another sheet holds (case-insensitively) is refused. */
|
|
11
|
+
sheets: S[];
|
|
10
12
|
onChangeSheetData: UseSpreadsheetProps<T, S>["onChangeSheetData"];
|
|
11
13
|
onChangeSheets: UseSpreadsheetProps<T, S>["onChangeSheets"];
|
|
12
14
|
onChangeActiveCell(sheetId: number, cell: CellInterface): void;
|
|
@@ -16,6 +18,6 @@ type UseOnRenameSheetProps<T extends CellData, S extends Sheet> = {
|
|
|
16
18
|
createHistory(): (patches: SpreadsheetPatch) => void;
|
|
17
19
|
onCommand?: OnCommand;
|
|
18
20
|
};
|
|
19
|
-
export declare const useOnRenameSheet: <T extends CellData, S extends Sheet>({ locale, onChangeSheetData, onChangeSheets, onChangeActiveCell, getActiveCell, getGraphNodes, getPrecedents, createHistory, onCommand, }: UseOnRenameSheetProps<T, S>) => (sheetId: number, name: string, oldName: string) => void;
|
|
21
|
+
export declare const useOnRenameSheet: <T extends CellData, S extends Sheet>({ locale, sheets, onChangeSheetData, onChangeSheets, onChangeActiveCell, getActiveCell, getGraphNodes, getPrecedents, createHistory, onCommand, }: UseOnRenameSheetProps<T, S>) => (sheetId: number, name: string, oldName: string) => void;
|
|
20
22
|
export {};
|
|
21
23
|
//# sourceMappingURL=use-on-rename-sheet.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-on-rename-sheet.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-rename-sheet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EACV,cAAc,EACd,QAAQ,EACR,aAAa,EACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"use-on-rename-sheet.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-rename-sheet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EACV,cAAc,EACd,QAAQ,EACR,aAAa,EACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAOtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,KAAK,qBAAqB,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,IAAI;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uGAAuG;IACvG,MAAM,EAAE,CAAC,EAAE,CAAC;IACZ,iBAAiB,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAClE,cAAc,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAC5D,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/D,aAAa,IAAI,aAAa,CAAC;IAC/B,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,GAAG,aAAa,GAAG,UAAU,CAAC,CAAC;IACpE,aAAa,CACX,MAAM,EAAE,cAAc,GACrB,CAAC,QAAQ,GAAG,aAAa,GAAG,UAAU,CAAC,EAAE,CAAC;IAC7C,aAAa,IAAI,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACrD,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,mJAWnE,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,eAKhB,MAAM,QAAQ,MAAM,WAAW,MAAM,SAiGlD,CAAC"}
|
|
@@ -1,18 +1,26 @@
|
|
|
1
|
+
import { validateSheetName } from "@rowsncolumns/utils";
|
|
1
2
|
import { produceWithPatches } from "immer";
|
|
2
3
|
import { useCallback } from "react";
|
|
3
4
|
import { updateFormulaSheetReferences } from "../api/rename-sheet";
|
|
4
|
-
import {
|
|
5
|
+
import { useShowError } from "../atoms/error-state.atom";
|
|
5
6
|
import { useCanEditSheet, useCanEditWorkbook } from "./use-can-edit-cellrange";
|
|
6
|
-
export const useOnRenameSheet = ({ locale, onChangeSheetData, onChangeSheets, onChangeActiveCell, getActiveCell, getGraphNodes, getPrecedents, createHistory, onCommand, }) => {
|
|
7
|
+
export const useOnRenameSheet = ({ locale, sheets, onChangeSheetData, onChangeSheets, onChangeActiveCell, getActiveCell, getGraphNodes, getPrecedents, createHistory, onCommand, }) => {
|
|
7
8
|
const canEditSheet = useCanEditSheet();
|
|
8
9
|
const canEditWorkbook = useCanEditWorkbook();
|
|
10
|
+
const showError = useShowError();
|
|
9
11
|
return useCallback((sheetId, name, oldName) => {
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
// Excel's worksheet-name rules (rowsncolumns/spreadsheet#939 U-01): at most 31 characters,
|
|
13
|
+
// none of `\ / ? * [ ] :`, no leading / trailing apostrophe, not `History`, and unique
|
|
14
|
+
// case-insensitively (the calc engine's sheet registry folds case too: `SHEET1` beside
|
|
15
|
+
// `Sheet1` would alias one engine sheet). Every refusal shows Excel's dialog text; a blank
|
|
16
|
+
// name is a silent no-op (the tab editor's "nothing typed").
|
|
17
|
+
const validation = validateSheetName(name, sheets, sheetId);
|
|
18
|
+
if (!validation.ok) {
|
|
19
|
+
if (validation.reason !== "blank") {
|
|
20
|
+
showError({ title: "Error", message: validation.message });
|
|
21
|
+
}
|
|
13
22
|
return;
|
|
14
23
|
}
|
|
15
|
-
const truncatedName = truncateSheetTitle(name);
|
|
16
24
|
if (!canEditWorkbook()) {
|
|
17
25
|
console.debug("Workbook is structurally protected, cannot rename a sheet.");
|
|
18
26
|
return;
|
|
@@ -27,7 +35,7 @@ export const useOnRenameSheet = ({ locale, onChangeSheetData, onChangeSheets, on
|
|
|
27
35
|
const [nextState, patches, inversePatches] = produceWithPatches(prevSheets, (draft) => {
|
|
28
36
|
const sheet = draft.find((sheet) => sheet.sheetId === sheetId);
|
|
29
37
|
if (sheet) {
|
|
30
|
-
sheet.title =
|
|
38
|
+
sheet.title = name;
|
|
31
39
|
}
|
|
32
40
|
});
|
|
33
41
|
// Save sheets history
|
|
@@ -42,7 +50,7 @@ export const useOnRenameSheet = ({ locale, onChangeSheetData, onChangeSheets, on
|
|
|
42
50
|
updateFormulaSheetReferences(draft, {
|
|
43
51
|
sheetId,
|
|
44
52
|
oldName,
|
|
45
|
-
newName:
|
|
53
|
+
newName: name,
|
|
46
54
|
locale,
|
|
47
55
|
getGraphNodes,
|
|
48
56
|
getPrecedents,
|
|
@@ -59,11 +67,12 @@ export const useOnRenameSheet = ({ locale, onChangeSheetData, onChangeSheets, on
|
|
|
59
67
|
onCommand?.({
|
|
60
68
|
command: "rename-sheet",
|
|
61
69
|
sheetId,
|
|
62
|
-
name
|
|
70
|
+
name,
|
|
63
71
|
oldName,
|
|
64
72
|
});
|
|
65
73
|
}, [
|
|
66
74
|
locale,
|
|
75
|
+
sheets,
|
|
67
76
|
onChangeActiveCell,
|
|
68
77
|
onChangeSheetData,
|
|
69
78
|
onChangeSheets,
|
|
@@ -73,6 +82,7 @@ export const useOnRenameSheet = ({ locale, onChangeSheetData, onChangeSheets, on
|
|
|
73
82
|
createHistory,
|
|
74
83
|
canEditSheet,
|
|
75
84
|
canEditWorkbook,
|
|
85
|
+
showError,
|
|
76
86
|
onCommand,
|
|
77
87
|
]);
|
|
78
88
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { GridRange } from "@rowsncolumns/common-types";
|
|
1
2
|
import { type CellData, type Sheet, type SortOrder, type SpreadsheetTheme } from "@rowsncolumns/spreadsheet";
|
|
2
3
|
import type { OnCommand } from "../commands";
|
|
3
4
|
import type { useCalculation } from "./use-calculation";
|
|
@@ -41,6 +42,11 @@ export type UseOnSortColumnProps<T extends CellData, S extends Sheet = Sheet> =
|
|
|
41
42
|
getCellData(sheetId: number, rowIndex: number, columnIndex: number): T | null | undefined;
|
|
42
43
|
/** Length of the sheet's committed data array — the last row a sort touches. */
|
|
43
44
|
getDataRowCount(sheetId: number): number | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* The sheet's merged regions. Excel refuses a sort over merged cells that
|
|
47
|
+
* are not laid out identically on every row of the sorted block.
|
|
48
|
+
*/
|
|
49
|
+
getMerges?(sheetId: number): GridRange[] | null | undefined;
|
|
44
50
|
/**
|
|
45
51
|
* Any hidden row (by the user, a filter, or a collapsed group). Used as
|
|
46
52
|
* the pin predicate only when `isManuallyHiddenRow` is not supplied.
|
|
@@ -74,5 +80,5 @@ export type UseOnSortColumnProps<T extends CellData, S extends Sheet = Sheet> =
|
|
|
74
80
|
* @param param0
|
|
75
81
|
* @returns
|
|
76
82
|
*/
|
|
77
|
-
export declare const useOnSortColumn: <T extends CellData, S extends Sheet = Sheet>({ rowCount, columnCount, locale, sharedStringRegistry, createHistory, enqueueCalculation, enqueueStructureChange, enqueueGraphOperation, onChangeSheetData, onChangeSheets, getCellData, getDataRowCount, isHiddenRow, isManuallyHiddenRow, getDependents, getFrozenRowCount, getSheetName, getEffectiveFormat, theme, enableSortTimingLogs, onCommand, }: UseOnSortColumnProps<T, S>) => (sheetId: number, sortedColumnIndex: number, sortOrder: SortOrder, options?: SortColumnOptions, additionalLevels?: SortColumnLevel[]) => void;
|
|
83
|
+
export declare const useOnSortColumn: <T extends CellData, S extends Sheet = Sheet>({ rowCount, columnCount, locale, sharedStringRegistry, createHistory, enqueueCalculation, enqueueStructureChange, enqueueGraphOperation, onChangeSheetData, onChangeSheets, getCellData, getDataRowCount, getMerges, isHiddenRow, isManuallyHiddenRow, getDependents, getFrozenRowCount, getSheetName, getEffectiveFormat, theme, enableSortTimingLogs, onCommand, }: UseOnSortColumnProps<T, S>) => (sheetId: number, sortedColumnIndex: number, sortOrder: SortOrder, options?: SortColumnOptions, additionalLevels?: SortColumnLevel[]) => void;
|
|
78
84
|
//# sourceMappingURL=use-on-sort-column.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-on-sort-column.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-sort-column.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-on-sort-column.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-sort-column.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import { produceWithPatches } from "immer";
|
|
|
4
4
|
import { useCallback } from "react";
|
|
5
5
|
import { createSheetCellIdentifier } from "../api/formula";
|
|
6
6
|
import { getCellSortValue } from "../api/sort";
|
|
7
|
+
import { getSortMergeRefusal } from "../api/structural-guards";
|
|
7
8
|
import { createSheetDraft } from "../api/immer-utils";
|
|
8
9
|
import { SheetCell } from "../sheet-cell";
|
|
9
10
|
import { useShowError } from "../atoms/error-state.atom";
|
|
@@ -33,7 +34,7 @@ const buildSortValue = (options, fallbackValue, getEffectiveFormat, theme, sheet
|
|
|
33
34
|
* @param param0
|
|
34
35
|
* @returns
|
|
35
36
|
*/
|
|
36
|
-
export const useOnSortColumn = ({ rowCount, columnCount, locale, sharedStringRegistry, createHistory, enqueueCalculation, enqueueStructureChange, enqueueGraphOperation, onChangeSheetData, onChangeSheets, getCellData, getDataRowCount, isHiddenRow, isManuallyHiddenRow, getDependents, getFrozenRowCount, getSheetName, getEffectiveFormat, theme, enableSortTimingLogs, onCommand, }) => {
|
|
37
|
+
export const useOnSortColumn = ({ rowCount, columnCount, locale, sharedStringRegistry, createHistory, enqueueCalculation, enqueueStructureChange, enqueueGraphOperation, onChangeSheetData, onChangeSheets, getCellData, getDataRowCount, getMerges, isHiddenRow, isManuallyHiddenRow, getDependents, getFrozenRowCount, getSheetName, getEffectiveFormat, theme, enableSortTimingLogs, onCommand, }) => {
|
|
37
38
|
const canEditSheet = useCanEditSheet();
|
|
38
39
|
const canPerformSheetAction = useCanPerformSheetAction();
|
|
39
40
|
const showError = useShowError();
|
|
@@ -60,6 +61,21 @@ export const useOnSortColumn = ({ rowCount, columnCount, locale, sharedStringReg
|
|
|
60
61
|
? performance.now.bind(performance)
|
|
61
62
|
: Date.now;
|
|
62
63
|
const activeSheetName = getSheetName(sheetId);
|
|
64
|
+
// Excel refuses to sort a block whose merged cells differ in layout between rows — the
|
|
65
|
+
// anchor values would move while the merge outlines stayed behind.
|
|
66
|
+
const mergeRefusal = getSortMergeRefusal({
|
|
67
|
+
range: {
|
|
68
|
+
startRowIndex: 1,
|
|
69
|
+
endRowIndex: getDataRowCount(sheetId) ?? 0,
|
|
70
|
+
startColumnIndex: 1,
|
|
71
|
+
endColumnIndex: columnCount,
|
|
72
|
+
},
|
|
73
|
+
merges: getMerges?.(sheetId),
|
|
74
|
+
});
|
|
75
|
+
if (mergeRefusal) {
|
|
76
|
+
showError(mergeRefusal);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
63
79
|
// We need to track this for history. Precedent cells
|
|
64
80
|
const recalcCells = new Map();
|
|
65
81
|
// History
|
|
@@ -290,6 +306,7 @@ export const useOnSortColumn = ({ rowCount, columnCount, locale, sharedStringReg
|
|
|
290
306
|
onChangeSheets,
|
|
291
307
|
getCellData,
|
|
292
308
|
getDataRowCount,
|
|
309
|
+
getMerges,
|
|
293
310
|
isHiddenRow,
|
|
294
311
|
isManuallyHiddenRow,
|
|
295
312
|
getDependents,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { SelectionArea } from "@rowsncolumns/common-types";
|
|
1
|
+
import type { GridRange, SelectionArea } from "@rowsncolumns/common-types";
|
|
2
|
+
import { type CellInterface } from "@rowsncolumns/grid";
|
|
2
3
|
import { type CellData, type Sheet, type SelectionAttributes, type SortOrder, type SpreadsheetTheme } from "@rowsncolumns/spreadsheet";
|
|
3
4
|
import type { OnCommand } from "../commands";
|
|
4
5
|
import type { useCalculation } from "./use-calculation";
|
|
@@ -42,6 +43,12 @@ export type UseOnSortRangeProps<T extends CellData, S extends Sheet = Sheet> = {
|
|
|
42
43
|
getDependents: ReturnType<typeof useCalculation>["getDependents"];
|
|
43
44
|
getFrozenRowCount(sheetId: number): number;
|
|
44
45
|
getSheetName(sheetId: number): string;
|
|
46
|
+
/**
|
|
47
|
+
* The sheet's merged regions. A range whose merges are not laid out
|
|
48
|
+
* identically on every row is refused (Excel), because the sort would move
|
|
49
|
+
* the anchor values without their merge outlines.
|
|
50
|
+
*/
|
|
51
|
+
getMerges?(sheetId: number): GridRange[] | null | undefined;
|
|
45
52
|
/**
|
|
46
53
|
* Optional — needed when callers pass per-column specs using
|
|
47
54
|
* `sortBy: "cellColor" | "fontColor" | "icon"`. Without it those sort
|
|
@@ -54,6 +61,13 @@ export type UseOnSortRangeProps<T extends CellData, S extends Sheet = Sheet> = {
|
|
|
54
61
|
*/
|
|
55
62
|
theme: SpreadsheetTheme;
|
|
56
63
|
onCommand?: OnCommand;
|
|
64
|
+
/**
|
|
65
|
+
* The cursor at sort time. When it stands inside the sorted range (and no
|
|
66
|
+
* per-column `specs` are given) its column is the sort key — Excel / Sheets
|
|
67
|
+
* "Sort A to Z" sorts the range by the column the user is in, not by its
|
|
68
|
+
* leftmost column. Without it the legacy leftmost-column-first order applies.
|
|
69
|
+
*/
|
|
70
|
+
getActiveCell?: () => CellInterface | null | undefined;
|
|
57
71
|
};
|
|
58
72
|
/**
|
|
59
73
|
* Sorts a column range.
|
|
@@ -61,5 +75,5 @@ export type UseOnSortRangeProps<T extends CellData, S extends Sheet = Sheet> = {
|
|
|
61
75
|
* @param param0
|
|
62
76
|
* @returns
|
|
63
77
|
*/
|
|
64
|
-
export declare const useOnSortRange: <T extends CellData, S extends Sheet = Sheet>({ locale, sharedStringRegistry, createHistory, enqueueStructureChange, enqueueGraphOperation, enqueueCalculation, onChangeSheetData, onChangeSheets, getCellData, getDependents, isHiddenRow, isManuallyHiddenRow, getFrozenRowCount, getSheetName, getEffectiveFormat, theme, onCommand, }: UseOnSortRangeProps<T, S>) => (sheetId: number, selections: SelectionArea<SelectionAttributes>[], sortOrder: SortOrder, specs?: DimensionSortSpec[]) => void;
|
|
78
|
+
export declare const useOnSortRange: <T extends CellData, S extends Sheet = Sheet>({ locale, sharedStringRegistry, createHistory, enqueueStructureChange, enqueueGraphOperation, enqueueCalculation, onChangeSheetData, onChangeSheets, getCellData, getDependents, isHiddenRow, isManuallyHiddenRow, getFrozenRowCount, getSheetName, getMerges, getEffectiveFormat, theme, onCommand, getActiveCell, }: UseOnSortRangeProps<T, S>) => (sheetId: number, selections: SelectionArea<SelectionAttributes>[], sortOrder: SortOrder, specs?: DimensionSortSpec[]) => void;
|
|
65
79
|
//# sourceMappingURL=use-on-sort-range.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-on-sort-range.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-sort-range.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"use-on-sort-range.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-sort-range.ts"],"names":[],"mappings":"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"}
|