@rowsncolumns/spreadsheet-state 28.0.67 → 28.0.69
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/helpers/sheet-title.d.ts +3 -0
- package/dist/cjs/helpers/sheet-title.d.ts.map +1 -1
- package/dist/cjs/helpers/sheet-title.js +10 -1
- package/dist/cjs/hooks/use-on-copy.d.ts +8 -1
- package/dist/cjs/hooks/use-on-copy.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-copy.js +248 -153
- package/dist/cjs/hooks/use-on-rename-sheet.js +2 -2
- package/dist/cjs/hooks/use-spreadsheet-state.d.ts +1 -1
- package/dist/cjs/interface/delete-column.d.ts.map +1 -1
- package/dist/cjs/interface/delete-column.js +62 -60
- package/dist/cjs/interface/delete-table-column.d.ts.map +1 -1
- package/dist/cjs/interface/delete-table-column.js +4 -3
- package/dist/cjs/interface/delete-table-row.d.ts.map +1 -1
- package/dist/cjs/interface/delete-table-row.js +19 -8
- package/dist/cjs/interface/insert-column.d.ts.map +1 -1
- package/dist/cjs/interface/insert-column.js +5 -4
- package/dist/cjs/interface/insert-table-row.d.ts.map +1 -1
- package/dist/cjs/interface/insert-table-row.js +19 -9
- package/dist/cjs/interface/update-sheet.d.ts.map +1 -1
- package/dist/cjs/interface/update-sheet.js +4 -1
- package/dist/esm/helpers/sheet-title.d.ts +3 -0
- package/dist/esm/helpers/sheet-title.d.ts.map +1 -1
- package/dist/esm/helpers/sheet-title.js +9 -0
- package/dist/esm/hooks/use-on-copy.d.ts +8 -1
- package/dist/esm/hooks/use-on-copy.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-copy.js +196 -145
- package/dist/esm/hooks/use-on-rename-sheet.js +2 -2
- package/dist/esm/hooks/use-spreadsheet-state.d.ts +1 -1
- package/dist/esm/interface/delete-column.d.ts.map +1 -1
- package/dist/esm/interface/delete-column.js +30 -18
- package/dist/esm/interface/delete-table-column.d.ts.map +1 -1
- package/dist/esm/interface/delete-table-column.js +4 -2
- package/dist/esm/interface/delete-table-row.d.ts.map +1 -1
- package/dist/esm/interface/delete-table-row.js +17 -8
- package/dist/esm/interface/insert-column.d.ts.map +1 -1
- package/dist/esm/interface/insert-column.js +5 -3
- package/dist/esm/interface/insert-table-row.d.ts.map +1 -1
- package/dist/esm/interface/insert-table-row.js +17 -9
- package/dist/esm/interface/update-sheet.d.ts.map +1 -1
- package/dist/esm/interface/update-sheet.js +4 -1
- package/package.json +24 -24
|
@@ -2,6 +2,7 @@ import { areaInsideArea, cellIdentifier, } from "@rowsncolumns/grid";
|
|
|
2
2
|
import { getBandedCells, getStringifiedColor, } from "@rowsncolumns/spreadsheet";
|
|
3
3
|
import { cellToAddress, getStyleId, getCellUserEnteredValue, getExtendedValueFormula, isNil, iterateCellsInRange, } from "@rowsncolumns/utils";
|
|
4
4
|
import { useCallback, useMemo } from "react";
|
|
5
|
+
import { useShowError } from "../atoms/error-state.atom";
|
|
5
6
|
import { isStyleReference } from "../sheet-cell";
|
|
6
7
|
const escapeHtmlAttribute = (value) => value
|
|
7
8
|
.replace(/&/g, "&")
|
|
@@ -9,6 +10,46 @@ const escapeHtmlAttribute = (value) => value
|
|
|
9
10
|
.replace(/'/g, "'")
|
|
10
11
|
.replace(/</g, "<")
|
|
11
12
|
.replace(/>/g, ">");
|
|
13
|
+
const MULTIPLE_SELECTIONS_ERROR = "This action won't work on multiple selections.";
|
|
14
|
+
/**
|
|
15
|
+
* Excel/Sheets copy a multi-area selection only when every area spans the same
|
|
16
|
+
* rows (areas sit side by side, left to right) or the same columns (areas stack,
|
|
17
|
+
* top to bottom). Returns the row and column indexes of the merged rectangle, or
|
|
18
|
+
* undefined for any other shape.
|
|
19
|
+
*/
|
|
20
|
+
export const getCopiedRowsAndColumns = (copiedSelections) => {
|
|
21
|
+
const ranges = copiedSelections.map(({ range }) => range);
|
|
22
|
+
const [first] = ranges;
|
|
23
|
+
if (!first) {
|
|
24
|
+
return [[], []];
|
|
25
|
+
}
|
|
26
|
+
const sameRows = ranges.every((range) => range.startRowIndex === first.startRowIndex &&
|
|
27
|
+
range.endRowIndex === first.endRowIndex);
|
|
28
|
+
const sameColumns = ranges.every((range) => range.startColumnIndex === first.startColumnIndex &&
|
|
29
|
+
range.endColumnIndex === first.endColumnIndex);
|
|
30
|
+
if (!sameRows && !sameColumns) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const rowRanges = sameRows
|
|
34
|
+
? [first]
|
|
35
|
+
: [...ranges].sort((a, b) => a.startRowIndex - b.startRowIndex);
|
|
36
|
+
const columnRanges = sameColumns
|
|
37
|
+
? [first]
|
|
38
|
+
: [...ranges].sort((a, b) => a.startColumnIndex - b.startColumnIndex);
|
|
39
|
+
const rows = [];
|
|
40
|
+
for (const { startRowIndex, endRowIndex } of rowRanges) {
|
|
41
|
+
for (let rowIndex = startRowIndex; rowIndex <= endRowIndex; rowIndex++) {
|
|
42
|
+
rows.push(rowIndex);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const columns = [];
|
|
46
|
+
for (const { startColumnIndex, endColumnIndex } of columnRanges) {
|
|
47
|
+
for (let columnIndex = startColumnIndex; columnIndex <= endColumnIndex; columnIndex++) {
|
|
48
|
+
columns.push(columnIndex);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return [rows, columns];
|
|
52
|
+
};
|
|
12
53
|
/**
|
|
13
54
|
* Called when user copies a selection from sheet
|
|
14
55
|
* 1. User can copy from any cell
|
|
@@ -19,7 +60,18 @@ const escapeHtmlAttribute = (value) => value
|
|
|
19
60
|
export const useOnCopy = ({ theme, merges, tables: sheetTables, bandedRanges, getFormattedValue, getCellData, getColumnWidth, getRowHeight, cellXfs, sharedStrings, getEffectiveFormat, isHiddenRow, isColumnHidden, }) => {
|
|
20
61
|
// Merge cell map
|
|
21
62
|
const mergedCellMap = useMergedCellMap(merges);
|
|
22
|
-
|
|
63
|
+
const showError = useShowError();
|
|
64
|
+
return useCallback((e, sheetId, copiedSelections, isCutOperation) => {
|
|
65
|
+
// Excel refuses to cut a multi-area selection, and only copies one whose
|
|
66
|
+
// areas share the same rows or the same columns.
|
|
67
|
+
const rowsAndColumns = isCutOperation && copiedSelections.length > 1
|
|
68
|
+
? undefined
|
|
69
|
+
: getCopiedRowsAndColumns(copiedSelections);
|
|
70
|
+
if (!rowsAndColumns) {
|
|
71
|
+
showError({ message: MULTIPLE_SELECTIONS_ERROR });
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
const [rows, columns] = rowsAndColumns;
|
|
23
75
|
const isRowHidden = isHiddenRow ?? (() => false);
|
|
24
76
|
const isColHidden = isColumnHidden ?? (() => false);
|
|
25
77
|
// Table styling (header fill, banded row/column fills, table borders)
|
|
@@ -70,15 +122,12 @@ export const useOnCopy = ({ theme, merges, tables: sheetTables, bandedRanges, ge
|
|
|
70
122
|
}
|
|
71
123
|
};
|
|
72
124
|
let colGroups = `<colgroup>`;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
colGroups += `<col width="${cellWidth}" />`;
|
|
80
|
-
}
|
|
81
|
-
});
|
|
125
|
+
for (const columnIndex of columns) {
|
|
126
|
+
if (isColHidden(sheetId, columnIndex))
|
|
127
|
+
continue;
|
|
128
|
+
const cellWidth = getColumnWidth(sheetId, columnIndex);
|
|
129
|
+
colGroups += `<col width="${cellWidth}" />`;
|
|
130
|
+
}
|
|
82
131
|
colGroups += `</colgroup>`;
|
|
83
132
|
let htmlString = `<html xmlns:v="urn:schemas-microsoft-com:vml"
|
|
84
133
|
xmlns:o="urn:schemas-microsoft-com:office:office"
|
|
@@ -90,9 +139,9 @@ export const useOnCopy = ({ theme, merges, tables: sheetTables, bandedRanges, ge
|
|
|
90
139
|
</style>
|
|
91
140
|
<style type="text/css"><!--td {border: 1px solid #cccccc;}br {mso-data-placement:same-cell;}--></style><body>
|
|
92
141
|
<table xmlns="http://www.w3.org/1999/xhtml" cellspacing="0" cellpadding="0" dir="ltr" border="1" style="table-layout:fixed;font-size:10pt;font-family:Arial;width:0px;border-collapse:collapse;border:none">${colGroups}<tbody>`;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
142
|
+
/* Check if user is copying a table */
|
|
143
|
+
if (copiedSelections.length === 1) {
|
|
144
|
+
const { range } = copiedSelections[0];
|
|
96
145
|
const table = sheetTables?.find((table) => areaInsideArea(table.range, range) && table.sheetId === sheetId);
|
|
97
146
|
if (table) {
|
|
98
147
|
// We need to set a rowDelta and colDelta
|
|
@@ -105,147 +154,147 @@ export const useOnCopy = ({ theme, merges, tables: sheetTables, bandedRanges, ge
|
|
|
105
154
|
colDelta,
|
|
106
155
|
});
|
|
107
156
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
157
|
+
}
|
|
158
|
+
/* Iterate over all cells */
|
|
159
|
+
for (const rowIndex of rows) {
|
|
160
|
+
if (isRowHidden(sheetId, rowIndex)) {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const rowHeight = getRowHeight(sheetId, rowIndex);
|
|
164
|
+
htmlString += `<tr style="height:${rowHeight}px">`;
|
|
165
|
+
const csvRow = [];
|
|
166
|
+
const jsonRow = [];
|
|
167
|
+
for (const columnIndex of columns) {
|
|
168
|
+
if (isColHidden(sheetId, columnIndex)) {
|
|
111
169
|
continue;
|
|
112
170
|
}
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const jsonRow = [];
|
|
117
|
-
for (let columnIndex = startColumnIndex; columnIndex <= endColumnIndex; columnIndex++) {
|
|
118
|
-
if (isColHidden(sheetId, columnIndex)) {
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
const mergedCellInfo = mergedCellMap.get(cellIdentifier(rowIndex, columnIndex));
|
|
122
|
-
const isMasterCell = mergedCellInfo ? mergedCellInfo[0] : true;
|
|
123
|
-
if (!isMasterCell) {
|
|
124
|
-
jsonRow.push({
|
|
125
|
-
data: undefined,
|
|
126
|
-
});
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
const [rowspan, colspan] = mergedCellInfo
|
|
130
|
-
? mergedCellInfo[1]
|
|
131
|
-
: [1, 1];
|
|
132
|
-
const formattedValue = getFormattedValue(sheetId, rowIndex, columnIndex) ?? "";
|
|
133
|
-
const cellData = getCellData(sheetId, rowIndex, columnIndex);
|
|
134
|
-
let normalizedCellData = cellData;
|
|
135
|
-
if (cellData && typeof cellData === "object") {
|
|
136
|
-
normalizedCellData = { ...cellData };
|
|
137
|
-
if (!isNil(normalizedCellData.ss)) {
|
|
138
|
-
normalizedCellData.ss = collectSharedString(String(normalizedCellData.ss));
|
|
139
|
-
}
|
|
140
|
-
collectCellXfs(normalizedCellData.uf);
|
|
141
|
-
collectCellXfs(normalizedCellData.ef);
|
|
142
|
-
}
|
|
143
|
-
const formula = getExtendedValueFormula(getCellUserEnteredValue(cellData));
|
|
144
|
-
const origin = cellToAddress({ rowIndex, columnIndex }) ??
|
|
145
|
-
`${rowIndex}:${columnIndex}`;
|
|
146
|
-
const formulaAttr = formula
|
|
147
|
-
? ` data-sheets-formula="${escapeHtmlAttribute(formula)}" data-formula="${escapeHtmlAttribute(formula)}" data-sheets-formula-origin="${escapeHtmlAttribute(origin)}" data-formula-origin="${escapeHtmlAttribute(origin)}"`
|
|
148
|
-
: "";
|
|
149
|
-
const effectiveFormat = getEffectiveFormat?.(sheetId, rowIndex, columnIndex);
|
|
150
|
-
const bandedFormat = bandedCells?.get(cellIdentifier(rowIndex, columnIndex));
|
|
151
|
-
const numberFormatType = effectiveFormat?.numberFormat?.type;
|
|
152
|
-
const numberFormatPattern = effectiveFormat?.numberFormat?.pattern;
|
|
153
|
-
const numberFormatAttr = numberFormatType
|
|
154
|
-
? ` data-sheets-numberformat-type="${escapeHtmlAttribute(numberFormatType)}"${numberFormatPattern
|
|
155
|
-
? ` data-sheets-numberformat-pattern="${escapeHtmlAttribute(numberFormatPattern)}"`
|
|
156
|
-
: ""}`
|
|
157
|
-
: "";
|
|
158
|
-
// Alignment is encoded as data attributes so paste doesn't have
|
|
159
|
-
// to trust `getComputedStyle().textAlign`, which fabricates a
|
|
160
|
-
// CSS-spec default of `"start"` even when the value was never set.
|
|
161
|
-
const horizontalAlignment = effectiveFormat?.horizontalAlignment;
|
|
162
|
-
const verticalAlignment = effectiveFormat?.verticalAlignment;
|
|
163
|
-
const alignmentAttr = `${horizontalAlignment
|
|
164
|
-
? ` data-sheets-horizontal-alignment="${escapeHtmlAttribute(horizontalAlignment)}"`
|
|
165
|
-
: ""}${verticalAlignment
|
|
166
|
-
? ` data-sheets-vertical-alignment="${escapeHtmlAttribute(verticalAlignment)}"`
|
|
167
|
-
: ""}`;
|
|
168
|
-
// Csv
|
|
169
|
-
csvRow.push(formattedValue);
|
|
170
|
-
// Style
|
|
171
|
-
const isItalic = effectiveFormat?.textFormat?.italic;
|
|
172
|
-
const isBold = effectiveFormat?.textFormat?.bold;
|
|
173
|
-
const isUnderline = effectiveFormat?.textFormat?.underline;
|
|
174
|
-
const isStrikeThrough = effectiveFormat?.textFormat?.strikethrough;
|
|
175
|
-
const baselineOffset = effectiveFormat?.textFormat?.baselineOffset;
|
|
176
|
-
// Cell-level formatting wins over the banded (table style) layer,
|
|
177
|
-
// matching the canvas grid's merge order.
|
|
178
|
-
const cellBorders = effectiveFormat?.borders ?? bandedFormat?.borders;
|
|
179
|
-
const borderTop = cellBorders?.top;
|
|
180
|
-
const borderBottom = cellBorders?.bottom;
|
|
181
|
-
const borderLeft = cellBorders?.left;
|
|
182
|
-
const borderRight = cellBorders?.right;
|
|
183
|
-
const textDecoration = `${isUnderline ? "underline" : ""} ${isStrikeThrough ? "line-through" : ""}`.trim();
|
|
184
|
-
const wordWrap = effectiveFormat?.wrapStrategy === "wrap";
|
|
185
|
-
const style = theme
|
|
186
|
-
? {
|
|
187
|
-
"background-color": getStringifiedColor(effectiveFormat?.backgroundColor ??
|
|
188
|
-
bandedFormat?.backgroundColor, theme),
|
|
189
|
-
color: getStringifiedColor(effectiveFormat?.textFormat?.color ??
|
|
190
|
-
bandedFormat?.textFormat?.color, theme),
|
|
191
|
-
padding: "2px 3px 2px 3px",
|
|
192
|
-
overflow: "hidden",
|
|
193
|
-
"font-weight": isBold ? "700" : "normal",
|
|
194
|
-
"font-family": effectiveFormat?.textFormat?.fontFamily,
|
|
195
|
-
"font-style": isItalic ? "italic" : "normal",
|
|
196
|
-
"text-decoration": textDecoration
|
|
197
|
-
? textDecoration
|
|
198
|
-
: undefined,
|
|
199
|
-
"font-size": `${effectiveFormat?.textFormat?.fontSize ?? 10}pt`,
|
|
200
|
-
"text-align": effectiveFormat?.horizontalAlignment,
|
|
201
|
-
"vertical-align": effectiveFormat?.verticalAlignment,
|
|
202
|
-
"border-top": borderTop
|
|
203
|
-
? `${borderTop.width}px solid ${getStringifiedColor(borderTop.color, theme)}`
|
|
204
|
-
: undefined,
|
|
205
|
-
"border-left": borderLeft
|
|
206
|
-
? `${borderLeft.width}px solid ${getStringifiedColor(borderLeft.color, theme)}`
|
|
207
|
-
: undefined,
|
|
208
|
-
"border-right": borderRight
|
|
209
|
-
? `${borderRight.width}px solid ${getStringifiedColor(borderRight.color, theme)}`
|
|
210
|
-
: undefined,
|
|
211
|
-
"border-bottom": borderBottom
|
|
212
|
-
? `${borderBottom.width}px solid ${getStringifiedColor(borderBottom.color, theme)}`
|
|
213
|
-
: undefined,
|
|
214
|
-
"text-wrap": wordWrap ? "wrap" : undefined,
|
|
215
|
-
}
|
|
216
|
-
: {};
|
|
217
|
-
// html
|
|
218
|
-
const innerHtml = baselineOffset === "superscript"
|
|
219
|
-
? `<sup>${formattedValue}</sup>`
|
|
220
|
-
: baselineOffset === "subscript"
|
|
221
|
-
? `<sub>${formattedValue}</sub>`
|
|
222
|
-
: formattedValue;
|
|
223
|
-
htmlString +=
|
|
224
|
-
`<td${formulaAttr}${numberFormatAttr}${alignmentAttr} ${rowspan > 1 ? `rowspan="${rowspan}"` : ""} ${colspan > 1 ? `colspan="${colspan}"` : ""} style='${Object.entries(style)
|
|
225
|
-
.filter(([_, v]) => !isNil(v))
|
|
226
|
-
.map(([k, v]) => `${k}:${v}`)
|
|
227
|
-
.join(";")}'>` +
|
|
228
|
-
innerHtml +
|
|
229
|
-
"</td>";
|
|
230
|
-
// json
|
|
171
|
+
const mergedCellInfo = mergedCellMap.get(cellIdentifier(rowIndex, columnIndex));
|
|
172
|
+
const isMasterCell = mergedCellInfo ? mergedCellInfo[0] : true;
|
|
173
|
+
if (!isMasterCell) {
|
|
231
174
|
jsonRow.push({
|
|
232
|
-
data:
|
|
233
|
-
sourceCell: { rowIndex, columnIndex },
|
|
234
|
-
rowspan,
|
|
235
|
-
colspan,
|
|
175
|
+
data: undefined,
|
|
236
176
|
});
|
|
177
|
+
continue;
|
|
237
178
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
179
|
+
const [rowspan, colspan] = mergedCellInfo
|
|
180
|
+
? mergedCellInfo[1]
|
|
181
|
+
: [1, 1];
|
|
182
|
+
const formattedValue = getFormattedValue(sheetId, rowIndex, columnIndex) ?? "";
|
|
183
|
+
const cellData = getCellData(sheetId, rowIndex, columnIndex);
|
|
184
|
+
let normalizedCellData = cellData;
|
|
185
|
+
if (cellData && typeof cellData === "object") {
|
|
186
|
+
normalizedCellData = { ...cellData };
|
|
187
|
+
if (!isNil(normalizedCellData.ss)) {
|
|
188
|
+
normalizedCellData.ss = collectSharedString(String(normalizedCellData.ss));
|
|
189
|
+
}
|
|
190
|
+
collectCellXfs(normalizedCellData.uf);
|
|
191
|
+
collectCellXfs(normalizedCellData.ef);
|
|
192
|
+
}
|
|
193
|
+
const formula = getExtendedValueFormula(getCellUserEnteredValue(cellData));
|
|
194
|
+
const origin = cellToAddress({ rowIndex, columnIndex }) ??
|
|
195
|
+
`${rowIndex}:${columnIndex}`;
|
|
196
|
+
const formulaAttr = formula
|
|
197
|
+
? ` data-sheets-formula="${escapeHtmlAttribute(formula)}" data-formula="${escapeHtmlAttribute(formula)}" data-sheets-formula-origin="${escapeHtmlAttribute(origin)}" data-formula-origin="${escapeHtmlAttribute(origin)}"`
|
|
198
|
+
: "";
|
|
199
|
+
const effectiveFormat = getEffectiveFormat?.(sheetId, rowIndex, columnIndex);
|
|
200
|
+
const bandedFormat = bandedCells?.get(cellIdentifier(rowIndex, columnIndex));
|
|
201
|
+
const numberFormatType = effectiveFormat?.numberFormat?.type;
|
|
202
|
+
const numberFormatPattern = effectiveFormat?.numberFormat?.pattern;
|
|
203
|
+
const numberFormatAttr = numberFormatType
|
|
204
|
+
? ` data-sheets-numberformat-type="${escapeHtmlAttribute(numberFormatType)}"${numberFormatPattern
|
|
205
|
+
? ` data-sheets-numberformat-pattern="${escapeHtmlAttribute(numberFormatPattern)}"`
|
|
206
|
+
: ""}`
|
|
207
|
+
: "";
|
|
208
|
+
// Alignment is encoded as data attributes so paste doesn't have
|
|
209
|
+
// to trust `getComputedStyle().textAlign`, which fabricates a
|
|
210
|
+
// CSS-spec default of `"start"` even when the value was never set.
|
|
211
|
+
const horizontalAlignment = effectiveFormat?.horizontalAlignment;
|
|
212
|
+
const verticalAlignment = effectiveFormat?.verticalAlignment;
|
|
213
|
+
const alignmentAttr = `${horizontalAlignment
|
|
214
|
+
? ` data-sheets-horizontal-alignment="${escapeHtmlAttribute(horizontalAlignment)}"`
|
|
215
|
+
: ""}${verticalAlignment
|
|
216
|
+
? ` data-sheets-vertical-alignment="${escapeHtmlAttribute(verticalAlignment)}"`
|
|
217
|
+
: ""}`;
|
|
218
|
+
// Csv
|
|
219
|
+
csvRow.push(formattedValue);
|
|
220
|
+
// Style
|
|
221
|
+
const isItalic = effectiveFormat?.textFormat?.italic;
|
|
222
|
+
const isBold = effectiveFormat?.textFormat?.bold;
|
|
223
|
+
const isUnderline = effectiveFormat?.textFormat?.underline;
|
|
224
|
+
const isStrikeThrough = effectiveFormat?.textFormat?.strikethrough;
|
|
225
|
+
const baselineOffset = effectiveFormat?.textFormat?.baselineOffset;
|
|
226
|
+
// Cell-level formatting wins over the banded (table style) layer,
|
|
227
|
+
// matching the canvas grid's merge order.
|
|
228
|
+
const cellBorders = effectiveFormat?.borders ?? bandedFormat?.borders;
|
|
229
|
+
const borderTop = cellBorders?.top;
|
|
230
|
+
const borderBottom = cellBorders?.bottom;
|
|
231
|
+
const borderLeft = cellBorders?.left;
|
|
232
|
+
const borderRight = cellBorders?.right;
|
|
233
|
+
const textDecoration = `${isUnderline ? "underline" : ""} ${isStrikeThrough ? "line-through" : ""}`.trim();
|
|
234
|
+
const wordWrap = effectiveFormat?.wrapStrategy === "wrap";
|
|
235
|
+
const style = theme
|
|
236
|
+
? {
|
|
237
|
+
"background-color": getStringifiedColor(effectiveFormat?.backgroundColor ??
|
|
238
|
+
bandedFormat?.backgroundColor, theme),
|
|
239
|
+
color: getStringifiedColor(effectiveFormat?.textFormat?.color ??
|
|
240
|
+
bandedFormat?.textFormat?.color, theme),
|
|
241
|
+
padding: "2px 3px 2px 3px",
|
|
242
|
+
overflow: "hidden",
|
|
243
|
+
"font-weight": isBold ? "700" : "normal",
|
|
244
|
+
"font-family": effectiveFormat?.textFormat?.fontFamily,
|
|
245
|
+
"font-style": isItalic ? "italic" : "normal",
|
|
246
|
+
"text-decoration": textDecoration
|
|
247
|
+
? textDecoration
|
|
248
|
+
: undefined,
|
|
249
|
+
"font-size": `${effectiveFormat?.textFormat?.fontSize ?? 10}pt`,
|
|
250
|
+
"text-align": effectiveFormat?.horizontalAlignment,
|
|
251
|
+
"vertical-align": effectiveFormat?.verticalAlignment,
|
|
252
|
+
"border-top": borderTop
|
|
253
|
+
? `${borderTop.width}px solid ${getStringifiedColor(borderTop.color, theme)}`
|
|
254
|
+
: undefined,
|
|
255
|
+
"border-left": borderLeft
|
|
256
|
+
? `${borderLeft.width}px solid ${getStringifiedColor(borderLeft.color, theme)}`
|
|
257
|
+
: undefined,
|
|
258
|
+
"border-right": borderRight
|
|
259
|
+
? `${borderRight.width}px solid ${getStringifiedColor(borderRight.color, theme)}`
|
|
260
|
+
: undefined,
|
|
261
|
+
"border-bottom": borderBottom
|
|
262
|
+
? `${borderBottom.width}px solid ${getStringifiedColor(borderBottom.color, theme)}`
|
|
263
|
+
: undefined,
|
|
264
|
+
"text-wrap": wordWrap ? "wrap" : undefined,
|
|
265
|
+
}
|
|
266
|
+
: {};
|
|
242
267
|
// html
|
|
243
|
-
|
|
268
|
+
const innerHtml = baselineOffset === "superscript"
|
|
269
|
+
? `<sup>${formattedValue}</sup>`
|
|
270
|
+
: baselineOffset === "subscript"
|
|
271
|
+
? `<sub>${formattedValue}</sub>`
|
|
272
|
+
: formattedValue;
|
|
273
|
+
htmlString +=
|
|
274
|
+
`<td${formulaAttr}${numberFormatAttr}${alignmentAttr} ${rowspan > 1 ? `rowspan="${rowspan}"` : ""} ${colspan > 1 ? `colspan="${colspan}"` : ""} style='${Object.entries(style)
|
|
275
|
+
.filter(([_, v]) => !isNil(v))
|
|
276
|
+
.map(([k, v]) => `${k}:${v}`)
|
|
277
|
+
.join(";")}'>` +
|
|
278
|
+
innerHtml +
|
|
279
|
+
"</td>";
|
|
244
280
|
// json
|
|
245
|
-
|
|
281
|
+
jsonRow.push({
|
|
282
|
+
data: normalizedCellData,
|
|
283
|
+
sourceCell: { rowIndex, columnIndex },
|
|
284
|
+
rowspan,
|
|
285
|
+
colspan,
|
|
286
|
+
});
|
|
246
287
|
}
|
|
247
|
-
|
|
288
|
+
/* Join with ',' for csv */
|
|
289
|
+
csv.push(csvRow.join(","));
|
|
290
|
+
// Plain text
|
|
291
|
+
plainText.push(csvRow.join("\t"));
|
|
292
|
+
// html
|
|
293
|
+
htmlString += "</tr>";
|
|
294
|
+
// json
|
|
295
|
+
json.push(jsonRow);
|
|
248
296
|
}
|
|
297
|
+
htmlString += "<tbody></table></body></html>";
|
|
249
298
|
const csvStr = csv.join("\n");
|
|
250
299
|
const plainTextStr = plainText.join("\n");
|
|
251
300
|
if (copiedSharedStrings.size) {
|
|
@@ -259,7 +308,9 @@ export const useOnCopy = ({ theme, merges, tables: sheetTables, bandedRanges, ge
|
|
|
259
308
|
e?.clipboardData?.setData("text/plain", plainTextStr);
|
|
260
309
|
e?.clipboardData?.setData("text/csv", csvStr);
|
|
261
310
|
e?.clipboardData?.setData("application/json", JSON.stringify(copiedSchema));
|
|
311
|
+
return true;
|
|
262
312
|
}, [
|
|
313
|
+
showError,
|
|
263
314
|
theme,
|
|
264
315
|
sheetTables,
|
|
265
316
|
bandedRanges,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { produceWithPatches } from "immer";
|
|
2
2
|
import { useCallback } from "react";
|
|
3
3
|
import { updateFormulaSheetReferences } from "../api/rename-sheet";
|
|
4
|
-
import { truncateSheetTitle } from "../helpers/sheet-title";
|
|
4
|
+
import { isValidSheetTitle, truncateSheetTitle } from "../helpers/sheet-title";
|
|
5
5
|
import { useCanEditSheet, useCanEditWorkbook } from "./use-can-edit-cellrange";
|
|
6
6
|
export const useOnRenameSheet = ({ locale, onChangeSheetData, onChangeSheets, onChangeActiveCell, getActiveCell, getGraphNodes, getPrecedents, createHistory, onCommand, }) => {
|
|
7
7
|
const canEditSheet = useCanEditSheet();
|
|
8
8
|
const canEditWorkbook = useCanEditWorkbook();
|
|
9
9
|
return useCallback((sheetId, name, oldName) => {
|
|
10
10
|
// Worksheet names cannot be empty or whitespace-only
|
|
11
|
-
if (name
|
|
11
|
+
if (!isValidSheetTitle(name)) {
|
|
12
12
|
console.debug("Sheet name cannot be empty.");
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
@@ -525,7 +525,7 @@ export declare const useSpreadsheetState: <T extends CellData = CellData, S exte
|
|
|
525
525
|
onInsertTableRow: (tableView: TableView, relativeRowIndex?: number, rowData?: Record<string, string | undefined | null>[]) => void;
|
|
526
526
|
onDeleteTableColumn: (tableView: TableView, dimensionIndex: number) => void;
|
|
527
527
|
onDeleteTableRow: (tableView: TableView, rowIndexes: number[]) => void;
|
|
528
|
-
onCopy: (e: ClipboardEvent | undefined, sheetId: number, copiedSelections: import("@rowsncolumns/grid").SelectionArea<SelectionAttributes>[]) =>
|
|
528
|
+
onCopy: (e: ClipboardEvent | undefined, sheetId: number, copiedSelections: import("@rowsncolumns/grid").SelectionArea<SelectionAttributes>[], isCutOperation?: boolean) => boolean;
|
|
529
529
|
onPaste: (e: ClipboardEvent | undefined, sourceSheetId: number | undefined, destinationSheetId: number, copiedSelections: import("@rowsncolumns/grid").SelectionArea<SelectionAttributes>[] | undefined, activeCell: import("@rowsncolumns/grid").CellInterface, selections: import("@rowsncolumns/grid").SelectionArea<SelectionAttributes>[] | undefined, finalSelections: import("@rowsncolumns/grid").SelectionArea<SelectionAttributes>[] | undefined, isCutOperation: boolean) => Promise<void>;
|
|
530
530
|
onCreateBasicFilter: (sheetId: number, activeCell: import("@rowsncolumns/grid").CellInterface, selections: import("@rowsncolumns/grid").SelectionArea<SelectionAttributes>[], basicFilterSpec?: Partial<import("@rowsncolumns/spreadsheet").FilterView>) => void;
|
|
531
531
|
onCreateTable: (sheetId: number, activeCell: import("@rowsncolumns/grid").CellInterface, selections: import("@rowsncolumns/grid").SelectionArea<SelectionAttributes>[], tableSpec?: Partial<TableView>, theme?: import("@rowsncolumns/spreadsheet").TableTheme, bandedRange?: BandedDefinition) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-column.d.ts","sourceRoot":"","sources":["../../../interface/delete-column.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AASjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAG5E,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,qbAyB/D,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,MACrB,SAAS,MAAM,EAAE,eAAe,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"delete-column.d.ts","sourceRoot":"","sources":["../../../interface/delete-column.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AASjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAG5E,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,qbAyB/D,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,MACrB,SAAS,MAAM,EAAE,eAAe,MAAM,EAAE,SAuUjD,CAAC"}
|
|
@@ -71,33 +71,45 @@ export const deleteColumn = ({ rowCount, columnCount, locale, cellXfsRegistry, s
|
|
|
71
71
|
// and table-column splice for partially-overlapped tables.
|
|
72
72
|
onChangeTables?.((prevTables) => {
|
|
73
73
|
const [nextState, patches, inversePatches] = produceWithPatches(prevTables, (draft) => {
|
|
74
|
-
for (
|
|
74
|
+
for (let idx = draft.length - 1; idx >= 0; idx--) {
|
|
75
|
+
const table = draft[idx];
|
|
75
76
|
if (table.sheetId !== sheetId)
|
|
76
77
|
continue;
|
|
77
|
-
|
|
78
|
+
const { startColumnIndex, endColumnIndex } = table.range;
|
|
79
|
+
if (maxColumnIndex < startColumnIndex) {
|
|
78
80
|
moveFilterView(table, count, Direction.Left);
|
|
81
|
+
continue;
|
|
79
82
|
}
|
|
80
|
-
if (minColumnIndex
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
if (minColumnIndex > endColumnIndex)
|
|
84
|
+
continue;
|
|
85
|
+
if (minColumnIndex <= startColumnIndex &&
|
|
86
|
+
maxColumnIndex >= endColumnIndex) {
|
|
87
|
+
draft.splice(idx, 1);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (table.filterSpecs) {
|
|
91
|
+
for (const spec of table.filterSpecs) {
|
|
92
|
+
if (spec.columnIndex >= minColumnIndex) {
|
|
93
|
+
spec.columnIndex -= count;
|
|
87
94
|
}
|
|
88
95
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
}
|
|
97
|
+
if (table.sortSpecs) {
|
|
98
|
+
for (const spec of table.sortSpecs) {
|
|
99
|
+
if (spec.dimensionIndex >= minColumnIndex) {
|
|
100
|
+
spec.dimensionIndex -= count;
|
|
94
101
|
}
|
|
95
102
|
}
|
|
96
|
-
const columnArrayIndex = minColumnIndex - table.range.startColumnIndex;
|
|
97
|
-
table.columns?.splice(columnArrayIndex, count);
|
|
98
|
-
const delta = Math.min(table.range.endColumnIndex - minColumnIndex + 1, count);
|
|
99
|
-
table.range.endColumnIndex -= delta;
|
|
100
103
|
}
|
|
104
|
+
const overlapStart = Math.max(minColumnIndex, startColumnIndex);
|
|
105
|
+
const overlapEnd = Math.min(maxColumnIndex, endColumnIndex);
|
|
106
|
+
const removed = overlapEnd - overlapStart + 1;
|
|
107
|
+
table.columns?.splice(overlapStart - startColumnIndex, removed);
|
|
108
|
+
table.range.startColumnIndex = Math.min(startColumnIndex, minColumnIndex);
|
|
109
|
+
table.range.endColumnIndex =
|
|
110
|
+
table.range.startColumnIndex +
|
|
111
|
+
(endColumnIndex - startColumnIndex) -
|
|
112
|
+
removed;
|
|
101
113
|
}
|
|
102
114
|
});
|
|
103
115
|
saveHistory({ tables: { patches, inversePatches } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-table-column.d.ts","sourceRoot":"","sources":["../../../interface/delete-table-column.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAY5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,6OAepE,IAAI,CACL,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACnB,aAAa,GACb,UAAU,GACV,QAAQ,GACR,iBAAiB,GACjB,sBAAsB,GACtB,cAAc,GACd,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,oBAAoB,GACpB,wBAAwB,GACxB,uBAAuB,GACvB,eAAe,CAClB,MACS,WAAW,SAAS,EAAE,gBAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"delete-table-column.d.ts","sourceRoot":"","sources":["../../../interface/delete-table-column.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAY5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,6OAepE,IAAI,CACL,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACnB,aAAa,GACb,UAAU,GACV,QAAQ,GACR,iBAAiB,GACjB,sBAAsB,GACtB,cAAc,GACd,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,oBAAoB,GACpB,wBAAwB,GACxB,uBAAuB,GACvB,eAAe,CAClB,MACS,WAAW,SAAS,EAAE,gBAAgB,MAAM,SA8VrD,CAAC"}
|
|
@@ -121,9 +121,12 @@ export const deleteTableColumn = ({ columnCount, rowCount, locale, cellXfsRegist
|
|
|
121
121
|
// Sheet data
|
|
122
122
|
onChangeSheetData?.((prevSheetData) => {
|
|
123
123
|
const [nextState, patches, inversePatches] = produceWithPatches(prevSheetData, (draft) => {
|
|
124
|
+
// The moved region is every cell after the deleted column within the table's rows,
|
|
125
|
+
// including any table to the right that sits inside that row band.
|
|
124
126
|
const sourceRange = {
|
|
125
127
|
...range,
|
|
126
128
|
startColumnIndex: referenceColumnIndex + count,
|
|
129
|
+
endColumnIndex: Number.MAX_SAFE_INTEGER,
|
|
127
130
|
};
|
|
128
131
|
const movedKeys = new Set();
|
|
129
132
|
/**
|
|
@@ -233,8 +236,7 @@ export const deleteTableColumn = ({ columnCount, rowCount, locale, cellXfsRegist
|
|
|
233
236
|
continue;
|
|
234
237
|
}
|
|
235
238
|
const startCol = Math.min(Math.max(range.startColumnIndex, 1), dataColumnCount);
|
|
236
|
-
|
|
237
|
-
for (let columnIndex = startCol; columnIndex < endCol; columnIndex++) {
|
|
239
|
+
for (let columnIndex = startCol; columnIndex < dataColumnCount; columnIndex++) {
|
|
238
240
|
const cellData = rowValues?.[columnIndex];
|
|
239
241
|
const hasFormula = !!getExtendedValueFormula(getCellUserEnteredValue(cellData));
|
|
240
242
|
if (!hasFormula) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-table-row.d.ts","sourceRoot":"","sources":["../../../interface/delete-table-row.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAgB5E,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAIjF,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,kSAiBjE,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,MACvB,WAAW,SAAS,EAAE,YAAY,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"delete-table-row.d.ts","sourceRoot":"","sources":["../../../interface/delete-table-row.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAgB5E,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAIjF,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,kSAiBjE,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC,MACvB,WAAW,SAAS,EAAE,YAAY,MAAM,EAAE,SAoYnD,CAAC"}
|
|
@@ -15,6 +15,9 @@ export const deleteTableRow = ({ rowCount, columnCount, locale, cellXfsRegistry,
|
|
|
15
15
|
const saveHistory = createHistory();
|
|
16
16
|
const { 0: minRowIndex, [rowIndexes.length - 1]: maxRowIndex } = rowIndexes;
|
|
17
17
|
const count = rowIndexes.length;
|
|
18
|
+
const { startColumnIndex, endColumnIndex } = tableView.range;
|
|
19
|
+
const isInsideColumnBand = (range) => range.startColumnIndex >= startColumnIndex &&
|
|
20
|
+
range.endColumnIndex <= endColumnIndex;
|
|
18
21
|
enqueueStructureChange?.({
|
|
19
22
|
kind: "delete-table-row",
|
|
20
23
|
sheetId,
|
|
@@ -30,14 +33,15 @@ export const deleteTableRow = ({ rowCount, columnCount, locale, cellXfsRegistry,
|
|
|
30
33
|
onChangeTables?.((prevTables) => {
|
|
31
34
|
const [nextState, patches, inversePatches] = produceWithPatches(prevTables, (draft) => {
|
|
32
35
|
for (const table of draft) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (minRowIndex < startRowIndex) {
|
|
36
|
-
moveFilterView(table, count, Direction.Up);
|
|
36
|
+
if (table.sheetId !== sheetId || !isInsideColumnBand(table.range)) {
|
|
37
|
+
continue;
|
|
37
38
|
}
|
|
38
|
-
if (
|
|
39
|
+
if (table.id === tableView.id) {
|
|
39
40
|
table.range.endRowIndex -= count;
|
|
40
41
|
}
|
|
42
|
+
else if (maxRowIndex < table.range.startRowIndex) {
|
|
43
|
+
moveFilterView(table, count, Direction.Up);
|
|
44
|
+
}
|
|
41
45
|
}
|
|
42
46
|
});
|
|
43
47
|
// Save history
|
|
@@ -52,7 +56,9 @@ export const deleteTableRow = ({ rowCount, columnCount, locale, cellXfsRegistry,
|
|
|
52
56
|
for (let idx = draft.length - 1; idx >= 0; idx--) {
|
|
53
57
|
const rule = draft[idx];
|
|
54
58
|
const ranges = rule.ranges
|
|
55
|
-
?.map((range) =>
|
|
59
|
+
?.map((range) => isInsideColumnBand(range)
|
|
60
|
+
? updateSheetRangeOnDelete(range, "row", minRowIndex, count, sheetId)
|
|
61
|
+
: range)
|
|
56
62
|
.filter((range) => !!range) ?? [];
|
|
57
63
|
if (ranges.length) {
|
|
58
64
|
rule.ranges = ranges;
|
|
@@ -73,7 +79,9 @@ export const deleteTableRow = ({ rowCount, columnCount, locale, cellXfsRegistry,
|
|
|
73
79
|
for (let idx = draft.length - 1; idx >= 0; idx--) {
|
|
74
80
|
const rule = draft[idx];
|
|
75
81
|
const ranges = rule.ranges
|
|
76
|
-
?.map((range) =>
|
|
82
|
+
?.map((range) => isInsideColumnBand(range)
|
|
83
|
+
? updateSheetRangeOnDelete(range, "row", minRowIndex, count, sheetId)
|
|
84
|
+
: range)
|
|
77
85
|
.filter((range) => !!range) ?? [];
|
|
78
86
|
if (ranges.length) {
|
|
79
87
|
rule.ranges = ranges;
|
|
@@ -96,7 +104,8 @@ export const deleteTableRow = ({ rowCount, columnCount, locale, cellXfsRegistry,
|
|
|
96
104
|
if (sheet.rowMetadata) {
|
|
97
105
|
sheet.rowMetadata.splice(minRowIndex, count);
|
|
98
106
|
}
|
|
99
|
-
if (sheet.basicFilter
|
|
107
|
+
if (sheet.basicFilter &&
|
|
108
|
+
isInsideColumnBand(sheet.basicFilter.range)) {
|
|
100
109
|
if (minRowIndex < sheet.basicFilter.range.startRowIndex) {
|
|
101
110
|
moveFilterView(sheet.basicFilter, count, Direction.Up);
|
|
102
111
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insert-column.d.ts","sourceRoot":"","sources":["../../../interface/insert-column.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAoB5E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,qaAyB/D,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,MACrB,SAAS,MAAM,EAAE,sBAAsB,MAAM,EAAE,mBAAc,SA0TtE,CAAC;AAMF,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,qQAiBpE,IAAI,CACL,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACnB,QAAQ,GACR,aAAa,GACb,UAAU,GACV,QAAQ,GACR,iBAAiB,GACjB,sBAAsB,GACtB,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,oBAAoB,GACpB,wBAAwB,GACxB,uBAAuB,GACvB,eAAe,GACf,cAAc,GACd,gBAAgB,CACnB,MAEG,WAAW,SAAS,EACpB,gBAAgB,MAAM,EACtB,WAAW,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"insert-column.d.ts","sourceRoot":"","sources":["../../../interface/insert-column.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAoB5E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,qaAyB/D,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,MACrB,SAAS,MAAM,EAAE,sBAAsB,MAAM,EAAE,mBAAc,SA0TtE,CAAC;AAMF,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,qQAiBpE,IAAI,CACL,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACnB,QAAQ,GACR,aAAa,GACb,UAAU,GACV,QAAQ,GACR,iBAAiB,GACjB,sBAAsB,GACtB,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,oBAAoB,GACpB,wBAAwB,GACxB,uBAAuB,GACvB,eAAe,GACf,cAAc,GACd,gBAAgB,CACnB,MAEG,WAAW,SAAS,EACpB,gBAAgB,MAAM,EACtB,WAAW,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,SA2V9C,CAAC"}
|
|
@@ -259,7 +259,7 @@ export const insertTableColumn = ({ tables, columnCount, rowCount, locale, cellX
|
|
|
259
259
|
onChangeTables?.((prevTables) => {
|
|
260
260
|
const [nextState, patches, inversePatches] = produceWithPatches(prevTables, (draft) => {
|
|
261
261
|
for (const table of draft) {
|
|
262
|
-
if (referenceColumnIndex
|
|
262
|
+
if (referenceColumnIndex <= table.range.startColumnIndex &&
|
|
263
263
|
table.range.startRowIndex >= tableView.range.startRowIndex &&
|
|
264
264
|
table.range.endRowIndex <= tableView.range.endRowIndex &&
|
|
265
265
|
table.id !== tableView.id) {
|
|
@@ -342,9 +342,12 @@ export const insertTableColumn = ({ tables, columnCount, rowCount, locale, cellX
|
|
|
342
342
|
const [nextState, patches, inversePatches] = produceWithPatches(prevSheetData, (draft) => {
|
|
343
343
|
const { range } = tableView;
|
|
344
344
|
const headerRow = tableView.headerRow ?? true;
|
|
345
|
+
// The moved region is every cell at/after the insertion point within the table's
|
|
346
|
+
// rows, including any table to the right that sits inside that row band.
|
|
345
347
|
const sourceRange = {
|
|
346
348
|
...range,
|
|
347
349
|
startColumnIndex: referenceColumnIndex,
|
|
350
|
+
endColumnIndex: Number.MAX_SAFE_INTEGER,
|
|
348
351
|
};
|
|
349
352
|
const movedKeys = new Set();
|
|
350
353
|
// PASS 1
|
|
@@ -427,8 +430,7 @@ export const insertTableColumn = ({ tables, columnCount, rowCount, locale, cellX
|
|
|
427
430
|
for (let rowIndex = range.startRowIndex; rowIndex <= range.endRowIndex; rowIndex++) {
|
|
428
431
|
const dataColumnCount = draft[sheetId]?.[rowIndex]?.values?.length ?? 0;
|
|
429
432
|
const startCol = Math.min(Math.max(referenceColumnIndex, 1), dataColumnCount);
|
|
430
|
-
|
|
431
|
-
for (let columnIndex = startCol; columnIndex < endCol; columnIndex++) {
|
|
433
|
+
for (let columnIndex = startCol; columnIndex < dataColumnCount; columnIndex++) {
|
|
432
434
|
moveFormulaAtPosition({
|
|
433
435
|
draft,
|
|
434
436
|
position: { sheetId, rowIndex, columnIndex },
|