@rowsncolumns/spreadsheet-state 28.0.68 → 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.
@@ -5,6 +5,13 @@ import type { BandedRange, TableView } from "@rowsncolumns/spreadsheet";
5
5
  import { type CellData, type CellFormat, type SelectionAttributes } from "@rowsncolumns/spreadsheet";
6
6
  import type { CellXfs, SharedStringValue, SharedStrings } from "../types";
7
7
  import type { useSheetProperties } from "./use-sheet-properties";
8
+ /**
9
+ * Excel/Sheets copy a multi-area selection only when every area spans the same
10
+ * rows (areas sit side by side, left to right) or the same columns (areas stack,
11
+ * top to bottom). Returns the row and column indexes of the merged rectangle, or
12
+ * undefined for any other shape.
13
+ */
14
+ export declare const getCopiedRowsAndColumns: (copiedSelections: SelectionArea<SelectionAttributes>[]) => [rows: number[], columns: number[]] | undefined;
8
15
  type UseOnCopyProps<T extends CellData> = {
9
16
  theme?: SpreadsheetTheme;
10
17
  merges?: GridRange[] | null;
@@ -43,7 +50,7 @@ export type CopySchema<T extends CellData> = {
43
50
  * @param param0
44
51
  * @returns
45
52
  */
46
- export declare const useOnCopy: <T extends CellData>({ theme, merges, tables: sheetTables, bandedRanges, getFormattedValue, getCellData, getColumnWidth, getRowHeight, cellXfs, sharedStrings, getEffectiveFormat, isHiddenRow, isColumnHidden, }: UseOnCopyProps<T>) => (e: ClipboardEvent | undefined, sheetId: number, copiedSelections: SelectionArea<SelectionAttributes>[]) => void;
53
+ export declare const useOnCopy: <T extends CellData>({ theme, merges, tables: sheetTables, bandedRanges, getFormattedValue, getCellData, getColumnWidth, getRowHeight, cellXfs, sharedStrings, getEffectiveFormat, isHiddenRow, isColumnHidden, }: UseOnCopyProps<T>) => (e: ClipboardEvent | undefined, sheetId: number, copiedSelections: SelectionArea<SelectionAttributes>[], isCutOperation?: boolean) => boolean;
47
54
  export declare const useMergedCellMap: (merges?: GridRange[] | null) => Map<string, [isMasterCell: boolean, readonly [rowspan: number, colspan: number]]>;
48
55
  export {};
49
56
  //# sourceMappingURL=use-on-copy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-on-copy.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-copy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-on-copy.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-copy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,UAAU,EAGf,KAAK,mBAAmB,EACzB,MAAM,2BAA2B,CAAC;AAanC,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAajE;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAClC,kBAAkB,aAAa,CAAC,mBAAmB,CAAC,EAAE,KACrD,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,SA0CxC,CAAC;AAEF,KAAK,cAAc,CAAC,CAAC,SAAS,QAAQ,IAAI;IACxC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACpC,iBAAiB,EAAE,CACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,KAChB,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC/B,WAAW,CACT,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC;IACxB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7D,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IACxD,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,kBAAkB,CAAC,EAAE,UAAU,CAC7B,OAAO,kBAAkB,CAC1B,CAAC,oBAAoB,CAAC,CAAC;IACxB,WAAW,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACzD,cAAc,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;CAChE,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,IAAI,EAAE,CAAC,CAAC;IACR,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,QAAQ,IAAI;IAC3C,MAAM,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC9B,SAAS,EAAE,gBAAgB,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC;CACnE,CAAC;AAEF;;;;;;GAMG;AAEH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,QAAQ,EAAE,8LAc3C,cAAc,CAAC,CAAC,CAAC,SAOX,cAAc,GAAG,SAAS,WACpB,MAAM,oBACG,aAAa,CAAC,mBAAmB,CAAC,EAAE,mBACrC,OAAO,YAqX7B,CAAC;AAGF,eAAO,MAAM,gBAAgB,GAAI,SAAS,SAAS,EAAE,GAAG,IAAI,sFA4B3D,CAAC"}
@@ -1,8 +1,9 @@
1
- import { __assign, __read, __values } from "tslib";
1
+ import { __assign, __read, __spreadArray, __values } from "tslib";
2
2
  import { areaInsideArea, cellIdentifier, } from "@rowsncolumns/grid";
3
3
  import { getBandedCells, getStringifiedColor, } from "@rowsncolumns/spreadsheet";
4
4
  import { cellToAddress, getStyleId, getCellUserEnteredValue, getExtendedValueFormula, isNil, iterateCellsInRange, } from "@rowsncolumns/utils";
5
5
  import { useCallback, useMemo } from "react";
6
+ import { useShowError } from "../atoms/error-state.atom";
6
7
  import { isStyleReference } from "../sheet-cell";
7
8
  var escapeHtmlAttribute = function (value) {
8
9
  return value
@@ -12,6 +13,74 @@ var escapeHtmlAttribute = function (value) {
12
13
  .replace(/</g, "&lt;")
13
14
  .replace(/>/g, "&gt;");
14
15
  };
16
+ var MULTIPLE_SELECTIONS_ERROR = "This action won't work on multiple selections.";
17
+ /**
18
+ * Excel/Sheets copy a multi-area selection only when every area spans the same
19
+ * rows (areas sit side by side, left to right) or the same columns (areas stack,
20
+ * top to bottom). Returns the row and column indexes of the merged rectangle, or
21
+ * undefined for any other shape.
22
+ */
23
+ export var getCopiedRowsAndColumns = function (copiedSelections) {
24
+ var e_1, _a, e_2, _b;
25
+ var ranges = copiedSelections.map(function (_a) {
26
+ var range = _a.range;
27
+ return range;
28
+ });
29
+ var _c = __read(ranges, 1), first = _c[0];
30
+ if (!first) {
31
+ return [[], []];
32
+ }
33
+ var sameRows = ranges.every(function (range) {
34
+ return range.startRowIndex === first.startRowIndex &&
35
+ range.endRowIndex === first.endRowIndex;
36
+ });
37
+ var sameColumns = ranges.every(function (range) {
38
+ return range.startColumnIndex === first.startColumnIndex &&
39
+ range.endColumnIndex === first.endColumnIndex;
40
+ });
41
+ if (!sameRows && !sameColumns) {
42
+ return undefined;
43
+ }
44
+ var rowRanges = sameRows
45
+ ? [first]
46
+ : __spreadArray([], __read(ranges), false).sort(function (a, b) { return a.startRowIndex - b.startRowIndex; });
47
+ var columnRanges = sameColumns
48
+ ? [first]
49
+ : __spreadArray([], __read(ranges), false).sort(function (a, b) { return a.startColumnIndex - b.startColumnIndex; });
50
+ var rows = [];
51
+ try {
52
+ for (var rowRanges_1 = __values(rowRanges), rowRanges_1_1 = rowRanges_1.next(); !rowRanges_1_1.done; rowRanges_1_1 = rowRanges_1.next()) {
53
+ var _d = rowRanges_1_1.value, startRowIndex = _d.startRowIndex, endRowIndex = _d.endRowIndex;
54
+ for (var rowIndex = startRowIndex; rowIndex <= endRowIndex; rowIndex++) {
55
+ rows.push(rowIndex);
56
+ }
57
+ }
58
+ }
59
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
60
+ finally {
61
+ try {
62
+ if (rowRanges_1_1 && !rowRanges_1_1.done && (_a = rowRanges_1.return)) _a.call(rowRanges_1);
63
+ }
64
+ finally { if (e_1) throw e_1.error; }
65
+ }
66
+ var columns = [];
67
+ try {
68
+ for (var columnRanges_1 = __values(columnRanges), columnRanges_1_1 = columnRanges_1.next(); !columnRanges_1_1.done; columnRanges_1_1 = columnRanges_1.next()) {
69
+ var _e = columnRanges_1_1.value, startColumnIndex = _e.startColumnIndex, endColumnIndex = _e.endColumnIndex;
70
+ for (var columnIndex = startColumnIndex; columnIndex <= endColumnIndex; columnIndex++) {
71
+ columns.push(columnIndex);
72
+ }
73
+ }
74
+ }
75
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
76
+ finally {
77
+ try {
78
+ if (columnRanges_1_1 && !columnRanges_1_1.done && (_b = columnRanges_1.return)) _b.call(columnRanges_1);
79
+ }
80
+ finally { if (e_2) throw e_2.error; }
81
+ }
82
+ return [rows, columns];
83
+ };
15
84
  /**
16
85
  * Called when user copies a selection from sheet
17
86
  * 1. User can copy from any cell
@@ -23,9 +92,20 @@ export var useOnCopy = function (_a) {
23
92
  var theme = _a.theme, merges = _a.merges, sheetTables = _a.tables, bandedRanges = _a.bandedRanges, getFormattedValue = _a.getFormattedValue, getCellData = _a.getCellData, getColumnWidth = _a.getColumnWidth, getRowHeight = _a.getRowHeight, cellXfs = _a.cellXfs, sharedStrings = _a.sharedStrings, getEffectiveFormat = _a.getEffectiveFormat, isHiddenRow = _a.isHiddenRow, isColumnHidden = _a.isColumnHidden;
24
93
  // Merge cell map
25
94
  var mergedCellMap = useMergedCellMap(merges);
26
- return useCallback(function (e, sheetId, copiedSelections) {
27
- var e_1, _a;
28
- var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
95
+ var showError = useShowError();
96
+ return useCallback(function (e, sheetId, copiedSelections, isCutOperation) {
97
+ var e_3, _a, e_4, _b, e_5, _c;
98
+ var _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
99
+ // Excel refuses to cut a multi-area selection, and only copies one whose
100
+ // areas share the same rows or the same columns.
101
+ var rowsAndColumns = isCutOperation && copiedSelections.length > 1
102
+ ? undefined
103
+ : getCopiedRowsAndColumns(copiedSelections);
104
+ if (!rowsAndColumns) {
105
+ showError({ message: MULTIPLE_SELECTIONS_ERROR });
106
+ return false;
107
+ }
108
+ var _0 = __read(rowsAndColumns, 2), rows = _0[0], columns = _0[1];
29
109
  var isRowHidden = isHiddenRow !== null && isHiddenRow !== void 0 ? isHiddenRow : (function () { return false; });
30
110
  var isColHidden = isColumnHidden !== null && isColumnHidden !== void 0 ? isColumnHidden : (function () { return false; });
31
111
  // Table styling (header fill, banded row/column fills, table borders)
@@ -76,33 +156,42 @@ export var useOnCopy = function (_a) {
76
156
  }
77
157
  };
78
158
  var colGroups = "<colgroup>";
79
- copiedSelections.forEach(function (_a) {
80
- var range = _a.range;
81
- var startColumnIndex = range.startColumnIndex, endColumnIndex = range.endColumnIndex;
82
- for (var columnIndex = startColumnIndex; columnIndex <= endColumnIndex; columnIndex++) {
159
+ try {
160
+ for (var columns_1 = __values(columns), columns_1_1 = columns_1.next(); !columns_1_1.done; columns_1_1 = columns_1.next()) {
161
+ var columnIndex = columns_1_1.value;
83
162
  if (isColHidden(sheetId, columnIndex))
84
163
  continue;
85
164
  var cellWidth = getColumnWidth(sheetId, columnIndex);
86
165
  colGroups += "<col width=\"".concat(cellWidth, "\" />");
87
166
  }
88
- });
167
+ }
168
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
169
+ finally {
170
+ try {
171
+ if (columns_1_1 && !columns_1_1.done && (_a = columns_1.return)) _a.call(columns_1);
172
+ }
173
+ finally { if (e_3) throw e_3.error; }
174
+ }
89
175
  colGroups += "</colgroup>";
90
176
  var htmlString = "<html xmlns:v=\"urn:schemas-microsoft-com:vml\"\n xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n xmlns=\"http://www.w3.org/TR/REC-html40\">\n <meta http-equiv=Content-Type content=\"text/html; charset=utf-8\">\n <style>\n <!--table{mso-displayed-decimal-separator:\".\"; mso-displayed-thousand-separator:\",\";}tr{mso-height-source:auto;}col{mso-width-source:auto;}-->\n </style>\n <style type=\"text/css\"><!--td {border: 1px solid #cccccc;}br {mso-data-placement:same-cell;}--></style><body>\n <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\">".concat(colGroups, "<tbody>");
91
- var _loop_1 = function (range) {
92
- var startRowIndex = range.startRowIndex, startColumnIndex = range.startColumnIndex, endColumnIndex = range.endColumnIndex, endRowIndex = range.endRowIndex;
93
- /* Check if user is copying a table */
177
+ /* Check if user is copying a table */
178
+ if (copiedSelections.length === 1) {
179
+ var range_1 = copiedSelections[0].range;
94
180
  var table = sheetTables === null || sheetTables === void 0 ? void 0 : sheetTables.find(function (table) {
95
- return areaInsideArea(table.range, range) && table.sheetId === sheetId;
181
+ return areaInsideArea(table.range, range_1) && table.sheetId === sheetId;
96
182
  });
97
183
  if (table) {
98
184
  // We need to set a rowDelta and colDelta
99
- var rowDelta = table.range.startRowIndex - range.startRowIndex;
100
- var colDelta = table.range.startColumnIndex - range.startColumnIndex;
185
+ var rowDelta = table.range.startRowIndex - range_1.startRowIndex;
186
+ var colDelta = table.range.startColumnIndex - range_1.startColumnIndex;
101
187
  // Add table
102
188
  tables.push(__assign(__assign({}, table), { rowDelta: rowDelta, colDelta: colDelta }));
103
189
  }
190
+ }
191
+ try {
104
192
  /* Iterate over all cells */
105
- for (var rowIndex = startRowIndex; rowIndex <= endRowIndex; rowIndex++) {
193
+ for (var rows_1 = __values(rows), rows_1_1 = rows_1.next(); !rows_1_1.done; rows_1_1 = rows_1.next()) {
194
+ var rowIndex = rows_1_1.value;
106
195
  if (isRowHidden(sheetId, rowIndex)) {
107
196
  continue;
108
197
  }
@@ -110,129 +199,139 @@ export var useOnCopy = function (_a) {
110
199
  htmlString += "<tr style=\"height:".concat(rowHeight, "px\">");
111
200
  var csvRow = [];
112
201
  var jsonRow = [];
113
- for (var columnIndex = startColumnIndex; columnIndex <= endColumnIndex; columnIndex++) {
114
- if (isColHidden(sheetId, columnIndex)) {
115
- continue;
116
- }
117
- var mergedCellInfo = mergedCellMap.get(cellIdentifier(rowIndex, columnIndex));
118
- var isMasterCell = mergedCellInfo ? mergedCellInfo[0] : true;
119
- if (!isMasterCell) {
202
+ try {
203
+ for (var columns_2 = (e_5 = void 0, __values(columns)), columns_2_1 = columns_2.next(); !columns_2_1.done; columns_2_1 = columns_2.next()) {
204
+ var columnIndex = columns_2_1.value;
205
+ if (isColHidden(sheetId, columnIndex)) {
206
+ continue;
207
+ }
208
+ var mergedCellInfo = mergedCellMap.get(cellIdentifier(rowIndex, columnIndex));
209
+ var isMasterCell = mergedCellInfo ? mergedCellInfo[0] : true;
210
+ if (!isMasterCell) {
211
+ jsonRow.push({
212
+ data: undefined,
213
+ });
214
+ continue;
215
+ }
216
+ var _1 = __read(mergedCellInfo
217
+ ? mergedCellInfo[1]
218
+ : [1, 1], 2), rowspan = _1[0], colspan = _1[1];
219
+ var formattedValue = (_d = getFormattedValue(sheetId, rowIndex, columnIndex)) !== null && _d !== void 0 ? _d : "";
220
+ var cellData = getCellData(sheetId, rowIndex, columnIndex);
221
+ var normalizedCellData = cellData;
222
+ if (cellData && typeof cellData === "object") {
223
+ normalizedCellData = __assign({}, cellData);
224
+ if (!isNil(normalizedCellData.ss)) {
225
+ normalizedCellData.ss = collectSharedString(String(normalizedCellData.ss));
226
+ }
227
+ collectCellXfs(normalizedCellData.uf);
228
+ collectCellXfs(normalizedCellData.ef);
229
+ }
230
+ var formula = getExtendedValueFormula(getCellUserEnteredValue(cellData));
231
+ var origin_1 = (_e = cellToAddress({ rowIndex: rowIndex, columnIndex: columnIndex })) !== null && _e !== void 0 ? _e : "".concat(rowIndex, ":").concat(columnIndex);
232
+ var formulaAttr = formula
233
+ ? " data-sheets-formula=\"".concat(escapeHtmlAttribute(formula), "\" data-formula=\"").concat(escapeHtmlAttribute(formula), "\" data-sheets-formula-origin=\"").concat(escapeHtmlAttribute(origin_1), "\" data-formula-origin=\"").concat(escapeHtmlAttribute(origin_1), "\"")
234
+ : "";
235
+ var effectiveFormat = getEffectiveFormat === null || getEffectiveFormat === void 0 ? void 0 : getEffectiveFormat(sheetId, rowIndex, columnIndex);
236
+ var bandedFormat = bandedCells === null || bandedCells === void 0 ? void 0 : bandedCells.get(cellIdentifier(rowIndex, columnIndex));
237
+ var numberFormatType = (_f = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.numberFormat) === null || _f === void 0 ? void 0 : _f.type;
238
+ var numberFormatPattern = (_g = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.numberFormat) === null || _g === void 0 ? void 0 : _g.pattern;
239
+ var numberFormatAttr = numberFormatType
240
+ ? " data-sheets-numberformat-type=\"".concat(escapeHtmlAttribute(numberFormatType), "\"").concat(numberFormatPattern
241
+ ? " data-sheets-numberformat-pattern=\"".concat(escapeHtmlAttribute(numberFormatPattern), "\"")
242
+ : "")
243
+ : "";
244
+ // Alignment is encoded as data attributes so paste doesn't have
245
+ // to trust `getComputedStyle().textAlign`, which fabricates a
246
+ // CSS-spec default of `"start"` even when the value was never set.
247
+ var horizontalAlignment = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.horizontalAlignment;
248
+ var verticalAlignment = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.verticalAlignment;
249
+ var alignmentAttr = "".concat(horizontalAlignment
250
+ ? " data-sheets-horizontal-alignment=\"".concat(escapeHtmlAttribute(horizontalAlignment), "\"")
251
+ : "").concat(verticalAlignment
252
+ ? " data-sheets-vertical-alignment=\"".concat(escapeHtmlAttribute(verticalAlignment), "\"")
253
+ : "");
254
+ // Csv
255
+ csvRow.push(formattedValue);
256
+ // Style
257
+ var isItalic = (_h = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _h === void 0 ? void 0 : _h.italic;
258
+ var isBold = (_j = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _j === void 0 ? void 0 : _j.bold;
259
+ var isUnderline = (_k = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _k === void 0 ? void 0 : _k.underline;
260
+ var isStrikeThrough = (_l = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _l === void 0 ? void 0 : _l.strikethrough;
261
+ var baselineOffset = (_m = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _m === void 0 ? void 0 : _m.baselineOffset;
262
+ // Cell-level formatting wins over the banded (table style) layer,
263
+ // matching the canvas grid's merge order.
264
+ var cellBorders = (_o = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.borders) !== null && _o !== void 0 ? _o : bandedFormat === null || bandedFormat === void 0 ? void 0 : bandedFormat.borders;
265
+ var borderTop = cellBorders === null || cellBorders === void 0 ? void 0 : cellBorders.top;
266
+ var borderBottom = cellBorders === null || cellBorders === void 0 ? void 0 : cellBorders.bottom;
267
+ var borderLeft = cellBorders === null || cellBorders === void 0 ? void 0 : cellBorders.left;
268
+ var borderRight = cellBorders === null || cellBorders === void 0 ? void 0 : cellBorders.right;
269
+ var textDecoration = "".concat(isUnderline ? "underline" : "", " ").concat(isStrikeThrough ? "line-through" : "").trim();
270
+ var wordWrap = (effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.wrapStrategy) === "wrap";
271
+ var style = theme
272
+ ? {
273
+ "background-color": getStringifiedColor((_p = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.backgroundColor) !== null && _p !== void 0 ? _p : bandedFormat === null || bandedFormat === void 0 ? void 0 : bandedFormat.backgroundColor, theme),
274
+ color: getStringifiedColor((_r = (_q = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _q === void 0 ? void 0 : _q.color) !== null && _r !== void 0 ? _r : (_s = bandedFormat === null || bandedFormat === void 0 ? void 0 : bandedFormat.textFormat) === null || _s === void 0 ? void 0 : _s.color, theme),
275
+ padding: "2px 3px 2px 3px",
276
+ overflow: "hidden",
277
+ "font-weight": isBold ? "700" : "normal",
278
+ "font-family": (_t = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _t === void 0 ? void 0 : _t.fontFamily,
279
+ "font-style": isItalic ? "italic" : "normal",
280
+ "text-decoration": textDecoration
281
+ ? textDecoration
282
+ : undefined,
283
+ "font-size": "".concat((_v = (_u = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _u === void 0 ? void 0 : _u.fontSize) !== null && _v !== void 0 ? _v : 10, "pt"),
284
+ "text-align": effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.horizontalAlignment,
285
+ "vertical-align": effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.verticalAlignment,
286
+ "border-top": borderTop
287
+ ? "".concat(borderTop.width, "px solid ").concat(getStringifiedColor(borderTop.color, theme))
288
+ : undefined,
289
+ "border-left": borderLeft
290
+ ? "".concat(borderLeft.width, "px solid ").concat(getStringifiedColor(borderLeft.color, theme))
291
+ : undefined,
292
+ "border-right": borderRight
293
+ ? "".concat(borderRight.width, "px solid ").concat(getStringifiedColor(borderRight.color, theme))
294
+ : undefined,
295
+ "border-bottom": borderBottom
296
+ ? "".concat(borderBottom.width, "px solid ").concat(getStringifiedColor(borderBottom.color, theme))
297
+ : undefined,
298
+ "text-wrap": wordWrap ? "wrap" : undefined,
299
+ }
300
+ : {};
301
+ // html
302
+ var innerHtml = baselineOffset === "superscript"
303
+ ? "<sup>".concat(formattedValue, "</sup>")
304
+ : baselineOffset === "subscript"
305
+ ? "<sub>".concat(formattedValue, "</sub>")
306
+ : formattedValue;
307
+ htmlString +=
308
+ "<td".concat(formulaAttr).concat(numberFormatAttr).concat(alignmentAttr, " ").concat(rowspan > 1 ? "rowspan=\"".concat(rowspan, "\"") : "", " ").concat(colspan > 1 ? "colspan=\"".concat(colspan, "\"") : "", " style='").concat(Object.entries(style)
309
+ .filter(function (_a) {
310
+ var _b = __read(_a, 2), _ = _b[0], v = _b[1];
311
+ return !isNil(v);
312
+ })
313
+ .map(function (_a) {
314
+ var _b = __read(_a, 2), k = _b[0], v = _b[1];
315
+ return "".concat(k, ":").concat(v);
316
+ })
317
+ .join(";"), "'>") +
318
+ innerHtml +
319
+ "</td>";
320
+ // json
120
321
  jsonRow.push({
121
- data: undefined,
322
+ data: normalizedCellData,
323
+ sourceCell: { rowIndex: rowIndex, columnIndex: columnIndex },
324
+ rowspan: rowspan,
325
+ colspan: colspan,
122
326
  });
123
- continue;
124
327
  }
125
- var _y = __read(mergedCellInfo
126
- ? mergedCellInfo[1]
127
- : [1, 1], 2), rowspan = _y[0], colspan = _y[1];
128
- var formattedValue = (_b = getFormattedValue(sheetId, rowIndex, columnIndex)) !== null && _b !== void 0 ? _b : "";
129
- var cellData = getCellData(sheetId, rowIndex, columnIndex);
130
- var normalizedCellData = cellData;
131
- if (cellData && typeof cellData === "object") {
132
- normalizedCellData = __assign({}, cellData);
133
- if (!isNil(normalizedCellData.ss)) {
134
- normalizedCellData.ss = collectSharedString(String(normalizedCellData.ss));
135
- }
136
- collectCellXfs(normalizedCellData.uf);
137
- collectCellXfs(normalizedCellData.ef);
328
+ }
329
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
330
+ finally {
331
+ try {
332
+ if (columns_2_1 && !columns_2_1.done && (_c = columns_2.return)) _c.call(columns_2);
138
333
  }
139
- var formula = getExtendedValueFormula(getCellUserEnteredValue(cellData));
140
- var origin_1 = (_c = cellToAddress({ rowIndex: rowIndex, columnIndex: columnIndex })) !== null && _c !== void 0 ? _c : "".concat(rowIndex, ":").concat(columnIndex);
141
- var formulaAttr = formula
142
- ? " data-sheets-formula=\"".concat(escapeHtmlAttribute(formula), "\" data-formula=\"").concat(escapeHtmlAttribute(formula), "\" data-sheets-formula-origin=\"").concat(escapeHtmlAttribute(origin_1), "\" data-formula-origin=\"").concat(escapeHtmlAttribute(origin_1), "\"")
143
- : "";
144
- var effectiveFormat = getEffectiveFormat === null || getEffectiveFormat === void 0 ? void 0 : getEffectiveFormat(sheetId, rowIndex, columnIndex);
145
- var bandedFormat = bandedCells === null || bandedCells === void 0 ? void 0 : bandedCells.get(cellIdentifier(rowIndex, columnIndex));
146
- var numberFormatType = (_d = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.numberFormat) === null || _d === void 0 ? void 0 : _d.type;
147
- var numberFormatPattern = (_e = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.numberFormat) === null || _e === void 0 ? void 0 : _e.pattern;
148
- var numberFormatAttr = numberFormatType
149
- ? " data-sheets-numberformat-type=\"".concat(escapeHtmlAttribute(numberFormatType), "\"").concat(numberFormatPattern
150
- ? " data-sheets-numberformat-pattern=\"".concat(escapeHtmlAttribute(numberFormatPattern), "\"")
151
- : "")
152
- : "";
153
- // Alignment is encoded as data attributes so paste doesn't have
154
- // to trust `getComputedStyle().textAlign`, which fabricates a
155
- // CSS-spec default of `"start"` even when the value was never set.
156
- var horizontalAlignment = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.horizontalAlignment;
157
- var verticalAlignment = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.verticalAlignment;
158
- var alignmentAttr = "".concat(horizontalAlignment
159
- ? " data-sheets-horizontal-alignment=\"".concat(escapeHtmlAttribute(horizontalAlignment), "\"")
160
- : "").concat(verticalAlignment
161
- ? " data-sheets-vertical-alignment=\"".concat(escapeHtmlAttribute(verticalAlignment), "\"")
162
- : "");
163
- // Csv
164
- csvRow.push(formattedValue);
165
- // Style
166
- var isItalic = (_f = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _f === void 0 ? void 0 : _f.italic;
167
- var isBold = (_g = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _g === void 0 ? void 0 : _g.bold;
168
- var isUnderline = (_h = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _h === void 0 ? void 0 : _h.underline;
169
- var isStrikeThrough = (_j = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _j === void 0 ? void 0 : _j.strikethrough;
170
- var baselineOffset = (_k = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _k === void 0 ? void 0 : _k.baselineOffset;
171
- // Cell-level formatting wins over the banded (table style) layer,
172
- // matching the canvas grid's merge order.
173
- var cellBorders = (_l = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.borders) !== null && _l !== void 0 ? _l : bandedFormat === null || bandedFormat === void 0 ? void 0 : bandedFormat.borders;
174
- var borderTop = cellBorders === null || cellBorders === void 0 ? void 0 : cellBorders.top;
175
- var borderBottom = cellBorders === null || cellBorders === void 0 ? void 0 : cellBorders.bottom;
176
- var borderLeft = cellBorders === null || cellBorders === void 0 ? void 0 : cellBorders.left;
177
- var borderRight = cellBorders === null || cellBorders === void 0 ? void 0 : cellBorders.right;
178
- var textDecoration = "".concat(isUnderline ? "underline" : "", " ").concat(isStrikeThrough ? "line-through" : "").trim();
179
- var wordWrap = (effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.wrapStrategy) === "wrap";
180
- var style = theme
181
- ? {
182
- "background-color": getStringifiedColor((_m = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.backgroundColor) !== null && _m !== void 0 ? _m : bandedFormat === null || bandedFormat === void 0 ? void 0 : bandedFormat.backgroundColor, theme),
183
- color: getStringifiedColor((_p = (_o = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _o === void 0 ? void 0 : _o.color) !== null && _p !== void 0 ? _p : (_q = bandedFormat === null || bandedFormat === void 0 ? void 0 : bandedFormat.textFormat) === null || _q === void 0 ? void 0 : _q.color, theme),
184
- padding: "2px 3px 2px 3px",
185
- overflow: "hidden",
186
- "font-weight": isBold ? "700" : "normal",
187
- "font-family": (_r = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _r === void 0 ? void 0 : _r.fontFamily,
188
- "font-style": isItalic ? "italic" : "normal",
189
- "text-decoration": textDecoration
190
- ? textDecoration
191
- : undefined,
192
- "font-size": "".concat((_t = (_s = effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.textFormat) === null || _s === void 0 ? void 0 : _s.fontSize) !== null && _t !== void 0 ? _t : 10, "pt"),
193
- "text-align": effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.horizontalAlignment,
194
- "vertical-align": effectiveFormat === null || effectiveFormat === void 0 ? void 0 : effectiveFormat.verticalAlignment,
195
- "border-top": borderTop
196
- ? "".concat(borderTop.width, "px solid ").concat(getStringifiedColor(borderTop.color, theme))
197
- : undefined,
198
- "border-left": borderLeft
199
- ? "".concat(borderLeft.width, "px solid ").concat(getStringifiedColor(borderLeft.color, theme))
200
- : undefined,
201
- "border-right": borderRight
202
- ? "".concat(borderRight.width, "px solid ").concat(getStringifiedColor(borderRight.color, theme))
203
- : undefined,
204
- "border-bottom": borderBottom
205
- ? "".concat(borderBottom.width, "px solid ").concat(getStringifiedColor(borderBottom.color, theme))
206
- : undefined,
207
- "text-wrap": wordWrap ? "wrap" : undefined,
208
- }
209
- : {};
210
- // html
211
- var innerHtml = baselineOffset === "superscript"
212
- ? "<sup>".concat(formattedValue, "</sup>")
213
- : baselineOffset === "subscript"
214
- ? "<sub>".concat(formattedValue, "</sub>")
215
- : formattedValue;
216
- htmlString +=
217
- "<td".concat(formulaAttr).concat(numberFormatAttr).concat(alignmentAttr, " ").concat(rowspan > 1 ? "rowspan=\"".concat(rowspan, "\"") : "", " ").concat(colspan > 1 ? "colspan=\"".concat(colspan, "\"") : "", " style='").concat(Object.entries(style)
218
- .filter(function (_a) {
219
- var _b = __read(_a, 2), _ = _b[0], v = _b[1];
220
- return !isNil(v);
221
- })
222
- .map(function (_a) {
223
- var _b = __read(_a, 2), k = _b[0], v = _b[1];
224
- return "".concat(k, ":").concat(v);
225
- })
226
- .join(";"), "'>") +
227
- innerHtml +
228
- "</td>";
229
- // json
230
- jsonRow.push({
231
- data: normalizedCellData,
232
- sourceCell: { rowIndex: rowIndex, columnIndex: columnIndex },
233
- rowspan: rowspan,
234
- colspan: colspan,
235
- });
334
+ finally { if (e_5) throw e_5.error; }
236
335
  }
237
336
  /* Join with ',' for csv */
238
337
  csv.push(csvRow.join(","));
@@ -243,21 +342,15 @@ export var useOnCopy = function (_a) {
243
342
  // json
244
343
  json.push(jsonRow);
245
344
  }
246
- htmlString += "<tbody></table></body></html>";
247
- };
248
- try {
249
- for (var copiedSelections_1 = __values(copiedSelections), copiedSelections_1_1 = copiedSelections_1.next(); !copiedSelections_1_1.done; copiedSelections_1_1 = copiedSelections_1.next()) {
250
- var range = copiedSelections_1_1.value.range;
251
- _loop_1(range);
252
- }
253
345
  }
254
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
346
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
255
347
  finally {
256
348
  try {
257
- if (copiedSelections_1_1 && !copiedSelections_1_1.done && (_a = copiedSelections_1.return)) _a.call(copiedSelections_1);
349
+ if (rows_1_1 && !rows_1_1.done && (_b = rows_1.return)) _b.call(rows_1);
258
350
  }
259
- finally { if (e_1) throw e_1.error; }
351
+ finally { if (e_4) throw e_4.error; }
260
352
  }
353
+ htmlString += "<tbody></table></body></html>";
261
354
  var csvStr = csv.join("\n");
262
355
  var plainTextStr = plainText.join("\n");
263
356
  if (copiedSharedStrings.size) {
@@ -267,11 +360,13 @@ export var useOnCopy = function (_a) {
267
360
  if (copiedCellXfs.size) {
268
361
  copiedSchema.cellXfs = Array.from(copiedCellXfs.entries());
269
362
  }
270
- (_u = e === null || e === void 0 ? void 0 : e.clipboardData) === null || _u === void 0 ? void 0 : _u.setData("text/html", htmlString);
271
- (_v = e === null || e === void 0 ? void 0 : e.clipboardData) === null || _v === void 0 ? void 0 : _v.setData("text/plain", plainTextStr);
272
- (_w = e === null || e === void 0 ? void 0 : e.clipboardData) === null || _w === void 0 ? void 0 : _w.setData("text/csv", csvStr);
273
- (_x = e === null || e === void 0 ? void 0 : e.clipboardData) === null || _x === void 0 ? void 0 : _x.setData("application/json", JSON.stringify(copiedSchema));
363
+ (_w = e === null || e === void 0 ? void 0 : e.clipboardData) === null || _w === void 0 ? void 0 : _w.setData("text/html", htmlString);
364
+ (_x = e === null || e === void 0 ? void 0 : e.clipboardData) === null || _x === void 0 ? void 0 : _x.setData("text/plain", plainTextStr);
365
+ (_y = e === null || e === void 0 ? void 0 : e.clipboardData) === null || _y === void 0 ? void 0 : _y.setData("text/csv", csvStr);
366
+ (_z = e === null || e === void 0 ? void 0 : e.clipboardData) === null || _z === void 0 ? void 0 : _z.setData("application/json", JSON.stringify(copiedSchema));
367
+ return true;
274
368
  }, [
369
+ showError,
275
370
  theme,
276
371
  sheetTables,
277
372
  bandedRanges,
@@ -290,14 +385,14 @@ export var useOnCopy = function (_a) {
290
385
  // Merge cell map
291
386
  export var useMergedCellMap = function (merges) {
292
387
  return useMemo(function () {
293
- var e_2, _a;
388
+ var e_6, _a;
294
389
  var mergedCellMap = new Map();
295
390
  var finalMerges = merges !== null && merges !== void 0 ? merges : [];
296
391
  for (var i = 0; i < finalMerges.length; i++) {
297
392
  var range = finalMerges[i];
298
393
  var startRowIndex = range.startRowIndex, startColumnIndex = range.startColumnIndex, endColumnIndex = range.endColumnIndex, endRowIndex = range.endRowIndex;
299
394
  try {
300
- for (var _b = (e_2 = void 0, __values(iterateCellsInRange(range))), _c = _b.next(); !_c.done; _c = _b.next()) {
395
+ for (var _b = (e_6 = void 0, __values(iterateCellsInRange(range))), _c = _b.next(); !_c.done; _c = _b.next()) {
301
396
  var _d = __read(_c.value, 2), rowIndex = _d[0], columnIndex = _d[1];
302
397
  var isMasterCell = rowIndex === startRowIndex && columnIndex === startColumnIndex;
303
398
  var spans = isMasterCell
@@ -312,12 +407,12 @@ export var useMergedCellMap = function (merges) {
312
407
  ]);
313
408
  }
314
409
  }
315
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
410
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
316
411
  finally {
317
412
  try {
318
413
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
319
414
  }
320
- finally { if (e_2) throw e_2.error; }
415
+ finally { if (e_6) throw e_6.error; }
321
416
  }
322
417
  }
323
418
  return mergedCellMap;
@@ -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>[]) => void;
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;
@@ -5,6 +5,13 @@ import type { BandedRange, TableView } from "@rowsncolumns/spreadsheet";
5
5
  import { type CellData, type CellFormat, type SelectionAttributes } from "@rowsncolumns/spreadsheet";
6
6
  import type { CellXfs, SharedStringValue, SharedStrings } from "../types";
7
7
  import type { useSheetProperties } from "./use-sheet-properties";
8
+ /**
9
+ * Excel/Sheets copy a multi-area selection only when every area spans the same
10
+ * rows (areas sit side by side, left to right) or the same columns (areas stack,
11
+ * top to bottom). Returns the row and column indexes of the merged rectangle, or
12
+ * undefined for any other shape.
13
+ */
14
+ export declare const getCopiedRowsAndColumns: (copiedSelections: SelectionArea<SelectionAttributes>[]) => [rows: number[], columns: number[]] | undefined;
8
15
  type UseOnCopyProps<T extends CellData> = {
9
16
  theme?: SpreadsheetTheme;
10
17
  merges?: GridRange[] | null;
@@ -43,7 +50,7 @@ export type CopySchema<T extends CellData> = {
43
50
  * @param param0
44
51
  * @returns
45
52
  */
46
- export declare const useOnCopy: <T extends CellData>({ theme, merges, tables: sheetTables, bandedRanges, getFormattedValue, getCellData, getColumnWidth, getRowHeight, cellXfs, sharedStrings, getEffectiveFormat, isHiddenRow, isColumnHidden, }: UseOnCopyProps<T>) => (e: ClipboardEvent | undefined, sheetId: number, copiedSelections: SelectionArea<SelectionAttributes>[]) => void;
53
+ export declare const useOnCopy: <T extends CellData>({ theme, merges, tables: sheetTables, bandedRanges, getFormattedValue, getCellData, getColumnWidth, getRowHeight, cellXfs, sharedStrings, getEffectiveFormat, isHiddenRow, isColumnHidden, }: UseOnCopyProps<T>) => (e: ClipboardEvent | undefined, sheetId: number, copiedSelections: SelectionArea<SelectionAttributes>[], isCutOperation?: boolean) => boolean;
47
54
  export declare const useMergedCellMap: (merges?: GridRange[] | null) => Map<string, [isMasterCell: boolean, readonly [rowspan: number, colspan: number]]>;
48
55
  export {};
49
56
  //# sourceMappingURL=use-on-copy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-on-copy.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-copy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-on-copy.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-copy.ts"],"names":[],"mappings":"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"}
@@ -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, "&amp;")
@@ -9,6 +10,46 @@ const escapeHtmlAttribute = (value) => value
9
10
  .replace(/'/g, "&#39;")
10
11
  .replace(/</g, "&lt;")
11
12
  .replace(/>/g, "&gt;");
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
- return useCallback((e, sheetId, copiedSelections) => {
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
- copiedSelections.forEach(({ range }) => {
74
- const { startColumnIndex, endColumnIndex } = range;
75
- for (let columnIndex = startColumnIndex; columnIndex <= endColumnIndex; columnIndex++) {
76
- if (isColHidden(sheetId, columnIndex))
77
- continue;
78
- const cellWidth = getColumnWidth(sheetId, columnIndex);
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
- for (const { range } of copiedSelections) {
94
- const { startRowIndex, startColumnIndex, endColumnIndex, endRowIndex } = range;
95
- /* Check if user is copying a table */
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
- /* Iterate over all cells */
109
- for (let rowIndex = startRowIndex; rowIndex <= endRowIndex; rowIndex++) {
110
- if (isRowHidden(sheetId, rowIndex)) {
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 rowHeight = getRowHeight(sheetId, rowIndex);
114
- htmlString += `<tr style="height:${rowHeight}px">`;
115
- const csvRow = [];
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: normalizedCellData,
233
- sourceCell: { rowIndex, columnIndex },
234
- rowspan,
235
- colspan,
175
+ data: undefined,
236
176
  });
177
+ continue;
237
178
  }
238
- /* Join with ',' for csv */
239
- csv.push(csvRow.join(","));
240
- // Plain text
241
- plainText.push(csvRow.join("\t"));
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
- htmlString += "</tr>";
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
- json.push(jsonRow);
281
+ jsonRow.push({
282
+ data: normalizedCellData,
283
+ sourceCell: { rowIndex, columnIndex },
284
+ rowspan,
285
+ colspan,
286
+ });
246
287
  }
247
- htmlString += "<tbody></table></body></html>";
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,
@@ -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>[]) => void;
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowsncolumns/spreadsheet-state",
3
- "version": "28.0.68",
3
+ "version": "28.0.69",
4
4
  "main": "./dist/cjs/index.js",
5
5
  "module": "./dist/esm/index.js",
6
6
  "types": "./dist/esm/index.d.ts",
@@ -58,7 +58,7 @@
58
58
  "@rowsncolumns/fast-formula-parser": "6.2.33",
59
59
  "@rowsncolumns/grid": ">=13.2.33",
60
60
  "@rowsncolumns/icons": ">=7.2.31",
61
- "@rowsncolumns/spreadsheet": ">=10.2.68",
61
+ "@rowsncolumns/spreadsheet": ">=10.2.70",
62
62
  "@rowsncolumns/toolkit": ">=24.4.2",
63
63
  "@rowsncolumns/ui": ">=15.0.39",
64
64
  "@rowsncolumns/utils": ">=9.2.37"
@@ -70,7 +70,7 @@
70
70
  "@rowsncolumns/fast-formula-parser": ">=6.2.33",
71
71
  "@rowsncolumns/grid": ">=13.2.33",
72
72
  "@rowsncolumns/icons": ">=7.2.31",
73
- "@rowsncolumns/spreadsheet": ">=10.2.68",
73
+ "@rowsncolumns/spreadsheet": ">=10.2.70",
74
74
  "@rowsncolumns/ui": ">=15.0.39",
75
75
  "@rowsncolumns/utils": ">=9.2.37"
76
76
  },