@rowsncolumns/spreadsheet-state 29.1.4 → 29.1.7

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.
Files changed (225) hide show
  1. package/dist/cjs/api/circular-reference.d.ts +31 -0
  2. package/dist/cjs/api/circular-reference.d.ts.map +1 -0
  3. package/dist/cjs/api/circular-reference.js +85 -0
  4. package/dist/cjs/api/copy-paste.d.ts +6 -0
  5. package/dist/cjs/api/copy-paste.d.ts.map +1 -1
  6. package/dist/cjs/api/copy-paste.js +24 -15
  7. package/dist/cjs/api/datatype.d.ts +2 -0
  8. package/dist/cjs/api/datatype.d.ts.map +1 -1
  9. package/dist/cjs/api/datatype.js +61 -35
  10. package/dist/cjs/api/date.d.ts.map +1 -1
  11. package/dist/cjs/api/date.js +23 -14
  12. package/dist/cjs/api/decimals.d.ts +10 -0
  13. package/dist/cjs/api/decimals.d.ts.map +1 -1
  14. package/dist/cjs/api/decimals.js +34 -11
  15. package/dist/cjs/api/dependency.d.ts +19 -1
  16. package/dist/cjs/api/dependency.d.ts.map +1 -1
  17. package/dist/cjs/api/dependency.js +30 -14
  18. package/dist/cjs/api/filter-condition.d.ts +58 -0
  19. package/dist/cjs/api/filter-condition.d.ts.map +1 -0
  20. package/dist/cjs/api/filter-condition.js +157 -0
  21. package/dist/cjs/api/formula.d.ts.map +1 -1
  22. package/dist/cjs/api/formula.js +9 -7
  23. package/dist/cjs/api/image-embed.d.ts +41 -0
  24. package/dist/cjs/api/image-embed.d.ts.map +1 -0
  25. package/dist/cjs/api/image-embed.js +55 -0
  26. package/dist/cjs/api/immer-utils.d.ts.map +1 -1
  27. package/dist/cjs/api/immer-utils.js +43 -15
  28. package/dist/cjs/api/named-range-structural.d.ts +29 -3
  29. package/dist/cjs/api/named-range-structural.d.ts.map +1 -1
  30. package/dist/cjs/api/named-range-structural.js +36 -11
  31. package/dist/cjs/api/parse-html.d.ts.map +1 -1
  32. package/dist/cjs/api/parse-html.js +11 -5
  33. package/dist/cjs/api/structural-formula-update.d.ts +20 -1
  34. package/dist/cjs/api/structural-formula-update.d.ts.map +1 -1
  35. package/dist/cjs/api/structural-formula-update.js +264 -90
  36. package/dist/cjs/api/structural-guards.d.ts +11 -0
  37. package/dist/cjs/api/structural-guards.d.ts.map +1 -1
  38. package/dist/cjs/api/structural-guards.js +45 -1
  39. package/dist/cjs/api/structural-table-refs.d.ts +15 -2
  40. package/dist/cjs/api/structural-table-refs.d.ts.map +1 -1
  41. package/dist/cjs/api/structural-table-refs.js +79 -35
  42. package/dist/cjs/commands.d.ts +17 -3
  43. package/dist/cjs/commands.d.ts.map +1 -1
  44. package/dist/cjs/components/editors/conditional-format-rule-editor.d.ts.map +1 -1
  45. package/dist/cjs/components/editors/conditional-format-rule-editor.js +19 -7
  46. package/dist/cjs/constants.d.ts +4 -1
  47. package/dist/cjs/constants.d.ts.map +1 -1
  48. package/dist/cjs/constants.js +4 -0
  49. package/dist/cjs/helpers/sheet-title.d.ts +2 -1
  50. package/dist/cjs/helpers/sheet-title.d.ts.map +1 -1
  51. package/dist/cjs/helpers/sheet-title.js +3 -1
  52. package/dist/cjs/hooks/use-can-edit-cellrange.d.ts +1 -1
  53. package/dist/cjs/hooks/use-can-edit-cellrange.d.ts.map +1 -1
  54. package/dist/cjs/hooks/use-can-edit-cellrange.js +1 -1
  55. package/dist/cjs/hooks/use-on-calculation-success.d.ts +5 -1
  56. package/dist/cjs/hooks/use-on-calculation-success.d.ts.map +1 -1
  57. package/dist/cjs/hooks/use-on-calculation-success.js +20 -3
  58. package/dist/cjs/hooks/use-on-copy.d.ts.map +1 -1
  59. package/dist/cjs/hooks/use-on-copy.js +23 -25
  60. package/dist/cjs/hooks/use-on-create-sheet.d.ts.map +1 -1
  61. package/dist/cjs/hooks/use-on-create-sheet.js +11 -1
  62. package/dist/cjs/hooks/use-on-delete.d.ts.map +1 -1
  63. package/dist/cjs/hooks/use-on-delete.js +15 -3
  64. package/dist/cjs/hooks/use-on-drag-n-drop.d.ts +5 -0
  65. package/dist/cjs/hooks/use-on-drag-n-drop.d.ts.map +1 -1
  66. package/dist/cjs/hooks/use-on-drag-n-drop.js +6 -5
  67. package/dist/cjs/hooks/use-on-filter-table.d.ts.map +1 -1
  68. package/dist/cjs/hooks/use-on-filter-table.js +6 -1
  69. package/dist/cjs/hooks/use-on-find-replace.d.ts.map +1 -1
  70. package/dist/cjs/hooks/use-on-find-replace.js +111 -23
  71. package/dist/cjs/hooks/use-on-insert-image.d.ts.map +1 -1
  72. package/dist/cjs/hooks/use-on-insert-image.js +20 -33
  73. package/dist/cjs/hooks/use-on-paste.d.ts +2 -1
  74. package/dist/cjs/hooks/use-on-paste.d.ts.map +1 -1
  75. package/dist/cjs/hooks/use-on-paste.js +53 -24
  76. package/dist/cjs/hooks/use-on-rename-sheet.d.ts +3 -1
  77. package/dist/cjs/hooks/use-on-rename-sheet.d.ts.map +1 -1
  78. package/dist/cjs/hooks/use-on-rename-sheet.js +19 -9
  79. package/dist/cjs/hooks/use-on-sort-column.d.ts +7 -1
  80. package/dist/cjs/hooks/use-on-sort-column.d.ts.map +1 -1
  81. package/dist/cjs/hooks/use-on-sort-column.js +25 -8
  82. package/dist/cjs/hooks/use-on-sort-range.d.ts +16 -2
  83. package/dist/cjs/hooks/use-on-sort-range.d.ts.map +1 -1
  84. package/dist/cjs/hooks/use-on-sort-range.js +72 -40
  85. package/dist/cjs/hooks/use-on-sort-table.d.ts +7 -2
  86. package/dist/cjs/hooks/use-on-sort-table.d.ts.map +1 -1
  87. package/dist/cjs/hooks/use-on-sort-table.js +25 -4
  88. package/dist/cjs/hooks/use-spreadsheet-state.d.ts +5 -3
  89. package/dist/cjs/hooks/use-spreadsheet-state.d.ts.map +1 -1
  90. package/dist/cjs/hooks/use-spreadsheet-state.js +7 -0
  91. package/dist/cjs/hooks/utils/sort-rows.d.ts +15 -0
  92. package/dist/cjs/hooks/utils/sort-rows.d.ts.map +1 -1
  93. package/dist/cjs/hooks/utils/sort-rows.js +16 -0
  94. package/dist/cjs/index.d.ts +3 -0
  95. package/dist/cjs/index.d.ts.map +1 -1
  96. package/dist/cjs/index.js +3 -0
  97. package/dist/cjs/interface/delete-column.d.ts.map +1 -1
  98. package/dist/cjs/interface/delete-column.js +254 -101
  99. package/dist/cjs/interface/delete-row.d.ts.map +1 -1
  100. package/dist/cjs/interface/delete-row.js +233 -81
  101. package/dist/cjs/interface/duplicate-sheet.d.ts.map +1 -1
  102. package/dist/cjs/interface/duplicate-sheet.js +4 -9
  103. package/dist/cjs/interface/insert-column.d.ts.map +1 -1
  104. package/dist/cjs/interface/insert-column.js +1 -1
  105. package/dist/cjs/interface/insert-row.d.ts.map +1 -1
  106. package/dist/cjs/interface/insert-row.js +1 -1
  107. package/dist/cjs/interface/new-sheet.d.ts.map +1 -1
  108. package/dist/cjs/interface/new-sheet.js +6 -13
  109. package/dist/cjs/sheet-cell.d.ts +9 -0
  110. package/dist/cjs/sheet-cell.d.ts.map +1 -1
  111. package/dist/cjs/sheet-cell.js +46 -9
  112. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  113. package/dist/esm/api/circular-reference.d.ts +31 -0
  114. package/dist/esm/api/circular-reference.d.ts.map +1 -0
  115. package/dist/esm/api/circular-reference.js +55 -0
  116. package/dist/esm/api/copy-paste.d.ts +6 -0
  117. package/dist/esm/api/copy-paste.d.ts.map +1 -1
  118. package/dist/esm/api/copy-paste.js +26 -14
  119. package/dist/esm/api/datatype.d.ts +2 -0
  120. package/dist/esm/api/datatype.d.ts.map +1 -1
  121. package/dist/esm/api/datatype.js +61 -35
  122. package/dist/esm/api/date.d.ts.map +1 -1
  123. package/dist/esm/api/date.js +23 -14
  124. package/dist/esm/api/decimals.d.ts +10 -0
  125. package/dist/esm/api/decimals.d.ts.map +1 -1
  126. package/dist/esm/api/decimals.js +31 -10
  127. package/dist/esm/api/dependency.d.ts +19 -1
  128. package/dist/esm/api/dependency.d.ts.map +1 -1
  129. package/dist/esm/api/dependency.js +15 -10
  130. package/dist/esm/api/filter-condition.d.ts +58 -0
  131. package/dist/esm/api/filter-condition.d.ts.map +1 -0
  132. package/dist/esm/api/filter-condition.js +146 -0
  133. package/dist/esm/api/formula.d.ts.map +1 -1
  134. package/dist/esm/api/formula.js +9 -7
  135. package/dist/esm/api/image-embed.d.ts +41 -0
  136. package/dist/esm/api/image-embed.d.ts.map +1 -0
  137. package/dist/esm/api/image-embed.js +52 -0
  138. package/dist/esm/api/immer-utils.d.ts.map +1 -1
  139. package/dist/esm/api/immer-utils.js +43 -14
  140. package/dist/esm/api/named-range-structural.d.ts +29 -3
  141. package/dist/esm/api/named-range-structural.d.ts.map +1 -1
  142. package/dist/esm/api/named-range-structural.js +35 -11
  143. package/dist/esm/api/parse-html.d.ts.map +1 -1
  144. package/dist/esm/api/parse-html.js +14 -5
  145. package/dist/esm/api/structural-formula-update.d.ts +20 -1
  146. package/dist/esm/api/structural-formula-update.d.ts.map +1 -1
  147. package/dist/esm/api/structural-formula-update.js +151 -55
  148. package/dist/esm/api/structural-guards.d.ts +11 -0
  149. package/dist/esm/api/structural-guards.d.ts.map +1 -1
  150. package/dist/esm/api/structural-guards.js +31 -0
  151. package/dist/esm/api/structural-table-refs.d.ts +15 -2
  152. package/dist/esm/api/structural-table-refs.d.ts.map +1 -1
  153. package/dist/esm/api/structural-table-refs.js +49 -18
  154. package/dist/esm/commands.d.ts +17 -3
  155. package/dist/esm/commands.d.ts.map +1 -1
  156. package/dist/esm/components/editors/conditional-format-rule-editor.d.ts.map +1 -1
  157. package/dist/esm/components/editors/conditional-format-rule-editor.js +18 -7
  158. package/dist/esm/constants.d.ts +4 -1
  159. package/dist/esm/constants.d.ts.map +1 -1
  160. package/dist/esm/constants.js +4 -0
  161. package/dist/esm/helpers/sheet-title.d.ts +2 -1
  162. package/dist/esm/helpers/sheet-title.d.ts.map +1 -1
  163. package/dist/esm/helpers/sheet-title.js +3 -1
  164. package/dist/esm/hooks/use-can-edit-cellrange.d.ts +1 -1
  165. package/dist/esm/hooks/use-can-edit-cellrange.d.ts.map +1 -1
  166. package/dist/esm/hooks/use-can-edit-cellrange.js +1 -1
  167. package/dist/esm/hooks/use-on-calculation-success.d.ts +5 -1
  168. package/dist/esm/hooks/use-on-calculation-success.d.ts.map +1 -1
  169. package/dist/esm/hooks/use-on-calculation-success.js +19 -3
  170. package/dist/esm/hooks/use-on-copy.d.ts.map +1 -1
  171. package/dist/esm/hooks/use-on-copy.js +17 -17
  172. package/dist/esm/hooks/use-on-create-sheet.d.ts.map +1 -1
  173. package/dist/esm/hooks/use-on-create-sheet.js +11 -1
  174. package/dist/esm/hooks/use-on-delete.d.ts.map +1 -1
  175. package/dist/esm/hooks/use-on-delete.js +15 -3
  176. package/dist/esm/hooks/use-on-drag-n-drop.d.ts +5 -0
  177. package/dist/esm/hooks/use-on-drag-n-drop.d.ts.map +1 -1
  178. package/dist/esm/hooks/use-on-drag-n-drop.js +7 -4
  179. package/dist/esm/hooks/use-on-filter-table.d.ts.map +1 -1
  180. package/dist/esm/hooks/use-on-filter-table.js +13 -2
  181. package/dist/esm/hooks/use-on-find-replace.d.ts.map +1 -1
  182. package/dist/esm/hooks/use-on-find-replace.js +111 -23
  183. package/dist/esm/hooks/use-on-insert-image.d.ts.map +1 -1
  184. package/dist/esm/hooks/use-on-insert-image.js +15 -25
  185. package/dist/esm/hooks/use-on-paste.d.ts +2 -1
  186. package/dist/esm/hooks/use-on-paste.d.ts.map +1 -1
  187. package/dist/esm/hooks/use-on-paste.js +46 -15
  188. package/dist/esm/hooks/use-on-rename-sheet.d.ts +3 -1
  189. package/dist/esm/hooks/use-on-rename-sheet.d.ts.map +1 -1
  190. package/dist/esm/hooks/use-on-rename-sheet.js +19 -9
  191. package/dist/esm/hooks/use-on-sort-column.d.ts +7 -1
  192. package/dist/esm/hooks/use-on-sort-column.d.ts.map +1 -1
  193. package/dist/esm/hooks/use-on-sort-column.js +18 -1
  194. package/dist/esm/hooks/use-on-sort-range.d.ts +16 -2
  195. package/dist/esm/hooks/use-on-sort-range.d.ts.map +1 -1
  196. package/dist/esm/hooks/use-on-sort-range.js +30 -3
  197. package/dist/esm/hooks/use-on-sort-table.d.ts +7 -2
  198. package/dist/esm/hooks/use-on-sort-table.d.ts.map +1 -1
  199. package/dist/esm/hooks/use-on-sort-table.js +25 -4
  200. package/dist/esm/hooks/use-spreadsheet-state.d.ts +5 -3
  201. package/dist/esm/hooks/use-spreadsheet-state.d.ts.map +1 -1
  202. package/dist/esm/hooks/use-spreadsheet-state.js +7 -0
  203. package/dist/esm/hooks/utils/sort-rows.d.ts +15 -0
  204. package/dist/esm/hooks/utils/sort-rows.d.ts.map +1 -1
  205. package/dist/esm/hooks/utils/sort-rows.js +15 -0
  206. package/dist/esm/index.d.ts +3 -0
  207. package/dist/esm/index.d.ts.map +1 -1
  208. package/dist/esm/index.js +3 -0
  209. package/dist/esm/interface/delete-column.d.ts.map +1 -1
  210. package/dist/esm/interface/delete-column.js +111 -80
  211. package/dist/esm/interface/delete-row.d.ts.map +1 -1
  212. package/dist/esm/interface/delete-row.js +91 -59
  213. package/dist/esm/interface/duplicate-sheet.d.ts.map +1 -1
  214. package/dist/esm/interface/duplicate-sheet.js +4 -9
  215. package/dist/esm/interface/insert-column.d.ts.map +1 -1
  216. package/dist/esm/interface/insert-column.js +1 -1
  217. package/dist/esm/interface/insert-row.d.ts.map +1 -1
  218. package/dist/esm/interface/insert-row.js +1 -1
  219. package/dist/esm/interface/new-sheet.d.ts.map +1 -1
  220. package/dist/esm/interface/new-sheet.js +6 -13
  221. package/dist/esm/sheet-cell.d.ts +9 -0
  222. package/dist/esm/sheet-cell.d.ts.map +1 -1
  223. package/dist/esm/sheet-cell.js +46 -7
  224. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  225. package/package.json +9 -9
@@ -38,7 +38,17 @@ export declare const collectUniqueDependentsForRange: <T extends CellData>(param
38
38
  rowIndex: number;
39
39
  columnIndex: number;
40
40
  }>;
41
- export declare const moveFormulaAtPosition: <T extends CellData>({ draft, position, destinationSheetId, activeSheetName, enqueueCalculation, enqueueGraphOperation, recalcCells, movedKeys, rowDelta, columnDelta, sourceRange, deletedRange, destinationPosition, locale, rowCount, columnCount, cellXfsRegistry, sharedStringRegistry, }: {
41
+ /**
42
+ * One reference shift of a structural edit: the references inside `sourceRange` move by the
43
+ * deltas, those inside `deletedRange` break to `#REF!`.
44
+ */
45
+ export type FormulaMoveStep = {
46
+ rowDelta: number;
47
+ columnDelta: number;
48
+ sourceRange?: GridRange;
49
+ deletedRange?: GridRange;
50
+ };
51
+ export declare const moveFormulaAtPosition: <T extends CellData>({ draft, position, destinationSheetId, activeSheetName, enqueueCalculation, enqueueGraphOperation, recalcCells, movedKeys, rowDelta, columnDelta, sourceRange, deletedRange, steps, destinationPosition, locale, rowCount, columnCount, cellXfsRegistry, sharedStringRegistry, }: {
42
52
  draft: Draft<SheetData<T>>;
43
53
  position: {
44
54
  sheetId: number;
@@ -56,6 +66,14 @@ export declare const moveFormulaAtPosition: <T extends CellData>({ draft, positi
56
66
  sourceRange?: GridRange;
57
67
  /** Cells removed by a delete-cells shift — references into it become `#REF!` (SHF-09). */
58
68
  deletedRange?: GridRange;
69
+ /**
70
+ * Several shifts applied to the formula text in order, one per deleted band of a
71
+ * non-contiguous delete (Ctrl-selected rows 2 and 4): each step shifts the references inside
72
+ * its own `sourceRange` by its delta and breaks those inside its `deletedRange`. Replaces the
73
+ * single `rowDelta` / `columnDelta` / `sourceRange` / `deletedRange` shift when given; pass
74
+ * `destinationPosition` with it (the cell's own move is not any single step's delta).
75
+ */
76
+ steps?: FormulaMoveStep[];
59
77
  /**
60
78
  * Where the formula cell itself ends up. Defaults to `position + delta` (the cell moves with the
61
79
  * shift). A dependent OUTSIDE the shifted band keeps its place while its references into the
@@ -1 +1 @@
1
- {"version":3,"file":"dependency.d.ts","sourceRoot":"","sources":["../../../api/dependency.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dependency.d.ts","sourceRoot":"","sources":["../../../api/dependency.ts"],"names":[],"mappings":"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"}
@@ -232,29 +232,45 @@ export var collectUniqueDependentsForRange = function (params) {
232
232
  };
233
233
  // Process a single formula move at a specific position with the specified deltas.
234
234
  export var moveFormulaAtPosition = function (_a) {
235
- var _b, _c, _d, _e;
236
- var draft = _a.draft, position = _a.position, destinationSheetId = _a.destinationSheetId, activeSheetName = _a.activeSheetName, enqueueCalculation = _a.enqueueCalculation, enqueueGraphOperation = _a.enqueueGraphOperation, recalcCells = _a.recalcCells, movedKeys = _a.movedKeys, _f = _a.rowDelta, rowDelta = _f === void 0 ? 0 : _f, _g = _a.columnDelta, columnDelta = _g === void 0 ? 0 : _g, sourceRange = _a.sourceRange, deletedRange = _a.deletedRange, destinationPosition = _a.destinationPosition, locale = _a.locale, rowCount = _a.rowCount, columnCount = _a.columnCount, cellXfsRegistry = _a.cellXfsRegistry, sharedStringRegistry = _a.sharedStringRegistry;
235
+ var e_3, _b;
236
+ var _c, _d, _e, _f;
237
+ var draft = _a.draft, position = _a.position, destinationSheetId = _a.destinationSheetId, activeSheetName = _a.activeSheetName, enqueueCalculation = _a.enqueueCalculation, enqueueGraphOperation = _a.enqueueGraphOperation, recalcCells = _a.recalcCells, movedKeys = _a.movedKeys, _g = _a.rowDelta, rowDelta = _g === void 0 ? 0 : _g, _h = _a.columnDelta, columnDelta = _h === void 0 ? 0 : _h, sourceRange = _a.sourceRange, deletedRange = _a.deletedRange, steps = _a.steps, destinationPosition = _a.destinationPosition, locale = _a.locale, rowCount = _a.rowCount, columnCount = _a.columnCount, cellXfsRegistry = _a.cellXfsRegistry, sharedStringRegistry = _a.sharedStringRegistry;
237
238
  var sheetCell = new SheetCell();
238
239
  var currentSheet = createSheetDraft(draft, position.sheetId, position.rowIndex);
239
- var cellData = (_c = (_b = currentSheet[position.rowIndex]) === null || _b === void 0 ? void 0 : _b.values) === null || _c === void 0 ? void 0 : _c[position.columnIndex];
240
+ var cellData = (_d = (_c = currentSheet[position.rowIndex]) === null || _c === void 0 ? void 0 : _c.values) === null || _d === void 0 ? void 0 : _d[position.columnIndex];
240
241
  sheetCell.assign(position.sheetId, { rowIndex: position.rowIndex, columnIndex: position.columnIndex }, cellData, { locale: locale, cellXfsRegistry: cellXfsRegistry, sharedStringRegistry: sharedStringRegistry });
241
242
  if (!movedKeys.has(sheetCell.key) && sheetCell.isFormula()) {
242
243
  movedKeys.add(sheetCell.key);
243
244
  var previousFormula = sheetCell.formula;
244
- var newRowIndex = (_d = destinationPosition === null || destinationPosition === void 0 ? void 0 : destinationPosition.rowIndex) !== null && _d !== void 0 ? _d : position.rowIndex + rowDelta;
245
- var newColumnIndex = (_e = destinationPosition === null || destinationPosition === void 0 ? void 0 : destinationPosition.columnIndex) !== null && _e !== void 0 ? _e : position.columnIndex + columnDelta;
245
+ var newRowIndex = (_e = destinationPosition === null || destinationPosition === void 0 ? void 0 : destinationPosition.rowIndex) !== null && _e !== void 0 ? _e : position.rowIndex + rowDelta;
246
+ var newColumnIndex = (_f = destinationPosition === null || destinationPosition === void 0 ? void 0 : destinationPosition.columnIndex) !== null && _f !== void 0 ? _f : position.columnIndex + columnDelta;
246
247
  var resolvedSheetName = activeSheetName !== null && activeSheetName !== void 0 ? activeSheetName : "";
247
248
  // The delta is applied to the references inside `sourceRange`; the formula cell's own
248
249
  // destination (for the graph re-key) may differ when it does not move itself.
249
- sheetCell.moveFormula({ rowIndex: position.rowIndex, columnIndex: position.columnIndex }, {
250
- rowIndex: position.rowIndex + rowDelta,
251
- columnIndex: position.columnIndex + columnDelta,
252
- }, resolvedSheetName, {
253
- exclusionRange: sourceRange,
254
- deletedRange: deletedRange,
255
- rowCount: rowCount,
256
- columnCount: columnCount,
257
- });
250
+ var moves = steps !== null && steps !== void 0 ? steps : [
251
+ { rowDelta: rowDelta, columnDelta: columnDelta, sourceRange: sourceRange, deletedRange: deletedRange },
252
+ ];
253
+ try {
254
+ for (var moves_1 = __values(moves), moves_1_1 = moves_1.next(); !moves_1_1.done; moves_1_1 = moves_1.next()) {
255
+ var move = moves_1_1.value;
256
+ sheetCell.moveFormula({ rowIndex: position.rowIndex, columnIndex: position.columnIndex }, {
257
+ rowIndex: position.rowIndex + move.rowDelta,
258
+ columnIndex: position.columnIndex + move.columnDelta,
259
+ }, resolvedSheetName, {
260
+ exclusionRange: move.sourceRange,
261
+ deletedRange: move.deletedRange,
262
+ rowCount: rowCount,
263
+ columnCount: columnCount,
264
+ });
265
+ }
266
+ }
267
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
268
+ finally {
269
+ try {
270
+ if (moves_1_1 && !moves_1_1.done && (_b = moves_1.return)) _b.call(moves_1);
271
+ }
272
+ finally { if (e_3) throw e_3.error; }
273
+ }
258
274
  if (previousFormula !== sheetCell.formula) {
259
275
  // Set cell data at old position (formula updated prior to structural move)
260
276
  currentSheet[position.rowIndex].values[position.columnIndex] =
@@ -0,0 +1,58 @@
1
+ import type { BooleanCondition, ConditionType } from "@rowsncolumns/spreadsheet";
2
+ export declare const isDateFilterCondition: (type: ConditionType | string | null | undefined) => boolean;
3
+ /**
4
+ * Whether a filter clause compares the cell's NUMBER — a Number Filter or a
5
+ * Date Filter comparison. Text (even numeric-looking text such as `'500`),
6
+ * booleans, errors and blanks never satisfy such a clause.
7
+ */
8
+ export declare const isNumericFilterCondition: (type: ConditionType | string | null | undefined) => boolean;
9
+ /** A cell value that takes part in a Number / Date Filter: a finite number. */
10
+ export declare const isNumericFilterCellValue: (value: unknown) => value is number;
11
+ /**
12
+ * How a Number / Date Filter criterion (`userEnteredValue`, the free text
13
+ * typed into the filter dialog) reads.
14
+ *
15
+ * - `empty`: nothing typed — the clause is inactive.
16
+ * - `number`: a typed literal — number, `50%`, currency, or a date / time in
17
+ * the document locale — as its numeric value (a date is its serial, exactly
18
+ * what the cell holds).
19
+ * - `formula`: `=…` or a cell reference; only the calculator can resolve it.
20
+ * - `text`: anything else; no number satisfies it.
21
+ */
22
+ export type FilterCriterion = {
23
+ kind: "empty";
24
+ } | {
25
+ kind: "number";
26
+ value: number;
27
+ } | {
28
+ kind: "formula";
29
+ } | {
30
+ kind: "text";
31
+ };
32
+ /**
33
+ * Classify a filter criterion the way Excel's Custom AutoFilter reads the typed
34
+ * box — as a cell entry in the workbook `locale` (`1/15/2024` is Jan 15 in
35
+ * en-US, `15.1.2024` in de-DE, `2024-02-01` anywhere, `6,5` is 6.5 in de-DE),
36
+ * so a Date Filter compares serials instead of quoting the text.
37
+ */
38
+ export declare const classifyFilterCriterion: (raw: string | undefined | null, locale?: string) => FilterCriterion;
39
+ /**
40
+ * Decide one Number Filter / Date Filter clause against a cell's typed value,
41
+ * the way Excel does — without the calculator:
42
+ *
43
+ * - Only NUMBERS take part. Text (including numeric-looking text such as
44
+ * `'500`), booleans, errors and blanks never satisfy `> 500` / `after
45
+ * 1/15/2024` and are hidden (`false`). The calculator's coercion would say
46
+ * text > number is TRUE and a blank is 0 — neither is Excel. "Does not
47
+ * equal" is the complement of "equals": text and blanks stay visible.
48
+ * - A typed date criterion is read in the document `locale` and compared as a
49
+ * SERIAL; Date Filters compare calendar days (`INT`), so `1/15/2024 14:00`
50
+ * equals `1/15/2024` and is not after it.
51
+ * - A `=…` / reference criterion is `undefined` — left to the calculator, which
52
+ * then compares a number (the cell-type gate has already run). An empty
53
+ * criterion is `undefined` too (an inactive clause).
54
+ *
55
+ * `undefined` for a condition type this evaluator does not own.
56
+ */
57
+ export declare const evaluateNumericFilterCondition: (condition: BooleanCondition | null | undefined, value: unknown, locale?: string) => boolean | undefined;
58
+ //# sourceMappingURL=filter-condition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-condition.d.ts","sourceRoot":"","sources":["../../../api/filter-condition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACd,MAAM,2BAA2B,CAAC;AA4CnC,eAAO,MAAM,qBAAqB,GAChC,MAAM,aAAa,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,KAC9C,OACsE,CAAC;AAE1E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,MAAM,aAAa,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,KAC9C,OAKA,CAAC;AAEJ,+EAA+E;AAC/E,eAAO,MAAM,wBAAwB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MACd,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAClC,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI,EAC9B,SAAS,MAAM,KACd,eAcF,CAAC;AAKF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,8BAA8B,GACzC,WAAW,gBAAgB,GAAG,IAAI,GAAG,SAAS,EAC9C,OAAO,OAAO,EACd,SAAS,MAAM,KACd,OAAO,GAAG,SA2DZ,CAAC"}
@@ -0,0 +1,157 @@
1
+ import { __read } from "tslib";
2
+ import { checkIfStringIsReference } from "@rowsncolumns/utils";
3
+ import { detectValueTypeAndPattern } from "./datatype";
4
+ /**
5
+ * Excel's Number Filters and Date Filters — the AutoFilter clauses that act on
6
+ * the cell's NUMBER (a date is its serial) and hide every non-numeric cell.
7
+ * Twin of `is_numeric_filter_kind` in the Rust engine (`rnc-store/support.rs`);
8
+ * the shared table `libs/common-types/fixtures/filter-evaluator-table.json`
9
+ * (`numeric`) keeps the two evaluators identical.
10
+ */
11
+ var NUMBER_FILTER_CONDITION_TYPES = new Set([
12
+ "NUMBER_EQ",
13
+ "NUMBER_NOT_EQ",
14
+ "NUMBER_GREATER",
15
+ "NUMBER_GREATER_THAN_EQ",
16
+ "NUMBER_LESS",
17
+ "NUMBER_LESS_THAN_EQ",
18
+ "NUMBER_BETWEEN",
19
+ "NUMBER_NOT_BETWEEN",
20
+ ]);
21
+ var DATE_FILTER_CONDITION_TYPES = new Set([
22
+ "DATE_EQ",
23
+ "DATE_NOT_EQ",
24
+ "DATE_BEFORE",
25
+ "DATE_AFTER",
26
+ "DATE_ON_OR_BEFORE",
27
+ "DATE_ON_OR_AFTER",
28
+ "DATE_BETWEEN",
29
+ "DATE_NOT_BETWEEN",
30
+ ]);
31
+ var TWO_OPERAND_FILTER_CONDITION_TYPES = new Set([
32
+ "NUMBER_BETWEEN",
33
+ "NUMBER_NOT_BETWEEN",
34
+ "DATE_BETWEEN",
35
+ "DATE_NOT_BETWEEN",
36
+ ]);
37
+ export var isDateFilterCondition = function (type) {
38
+ return Boolean(type && DATE_FILTER_CONDITION_TYPES.has(type));
39
+ };
40
+ /**
41
+ * Whether a filter clause compares the cell's NUMBER — a Number Filter or a
42
+ * Date Filter comparison. Text (even numeric-looking text such as `'500`),
43
+ * booleans, errors and blanks never satisfy such a clause.
44
+ */
45
+ export var isNumericFilterCondition = function (type) {
46
+ return Boolean(type &&
47
+ (NUMBER_FILTER_CONDITION_TYPES.has(type) ||
48
+ DATE_FILTER_CONDITION_TYPES.has(type)));
49
+ };
50
+ /** A cell value that takes part in a Number / Date Filter: a finite number. */
51
+ export var isNumericFilterCellValue = function (value) {
52
+ return typeof value === "number" && Number.isFinite(value);
53
+ };
54
+ /**
55
+ * Classify a filter criterion the way Excel's Custom AutoFilter reads the typed
56
+ * box — as a cell entry in the workbook `locale` (`1/15/2024` is Jan 15 in
57
+ * en-US, `15.1.2024` in de-DE, `2024-02-01` anywhere, `6,5` is 6.5 in de-DE),
58
+ * so a Date Filter compares serials instead of quoting the text.
59
+ */
60
+ export var classifyFilterCriterion = function (raw, locale) {
61
+ var _a;
62
+ var trimmed = (_a = raw === null || raw === void 0 ? void 0 : raw.trim()) !== null && _a !== void 0 ? _a : "";
63
+ if (!trimmed)
64
+ return { kind: "empty" };
65
+ if (trimmed.startsWith("=") || checkIfStringIsReference(trimmed)) {
66
+ return { kind: "formula" };
67
+ }
68
+ var _b = __read(detectValueTypeAndPattern(trimmed, locale !== null && locale !== void 0 ? locale : "en-US"), 3), formatValue = _b[0], numberValue = _b[2];
69
+ if (formatValue === "numberValue" && isNumericFilterCellValue(numberValue)) {
70
+ return { kind: "number", value: numberValue };
71
+ }
72
+ return { kind: "text" };
73
+ };
74
+ var numbersEqual = function (a, b) {
75
+ return Math.abs(a - b) <= 1e-9 * Math.max(Math.abs(a), Math.abs(b), 1);
76
+ };
77
+ /**
78
+ * Decide one Number Filter / Date Filter clause against a cell's typed value,
79
+ * the way Excel does — without the calculator:
80
+ *
81
+ * - Only NUMBERS take part. Text (including numeric-looking text such as
82
+ * `'500`), booleans, errors and blanks never satisfy `> 500` / `after
83
+ * 1/15/2024` and are hidden (`false`). The calculator's coercion would say
84
+ * text > number is TRUE and a blank is 0 — neither is Excel. "Does not
85
+ * equal" is the complement of "equals": text and blanks stay visible.
86
+ * - A typed date criterion is read in the document `locale` and compared as a
87
+ * SERIAL; Date Filters compare calendar days (`INT`), so `1/15/2024 14:00`
88
+ * equals `1/15/2024` and is not after it.
89
+ * - A `=…` / reference criterion is `undefined` — left to the calculator, which
90
+ * then compares a number (the cell-type gate has already run). An empty
91
+ * criterion is `undefined` too (an inactive clause).
92
+ *
93
+ * `undefined` for a condition type this evaluator does not own.
94
+ */
95
+ export var evaluateNumericFilterCondition = function (condition, value, locale) {
96
+ var _a, _b, _c, _d, _e;
97
+ var type = condition === null || condition === void 0 ? void 0 : condition.type;
98
+ if (!type || !isNumericFilterCondition(type))
99
+ return undefined;
100
+ var values = (_a = condition === null || condition === void 0 ? void 0 : condition.values) !== null && _a !== void 0 ? _a : [];
101
+ if (!isNumericFilterCellValue(value)) {
102
+ // "Does not equal" is the complement of "equals" over the whole column: a
103
+ // text cell or a blank does not equal 500 and stays visible (a text cell
104
+ // whose display text IS the criterion hides).
105
+ if (type === "NUMBER_NOT_EQ" || type === "DATE_NOT_EQ") {
106
+ var shown = value === undefined || value === null ? "" : String(value);
107
+ return (shown.trim().toLowerCase() !==
108
+ ((_c = (_b = values[0]) === null || _b === void 0 ? void 0 : _b.userEnteredValue) !== null && _c !== void 0 ? _c : "").trim().toLowerCase());
109
+ }
110
+ return false;
111
+ }
112
+ var first = classifyFilterCriterion((_d = values[0]) === null || _d === void 0 ? void 0 : _d.userEnteredValue, locale);
113
+ var second = TWO_OPERAND_FILTER_CONDITION_TYPES.has(type)
114
+ ? classifyFilterCriterion((_e = values[1]) === null || _e === void 0 ? void 0 : _e.userEnteredValue, locale)
115
+ : { kind: "number", value: 0 };
116
+ if (first.kind === "empty" || second.kind === "empty")
117
+ return undefined;
118
+ if (first.kind === "formula" || second.kind === "formula")
119
+ return undefined;
120
+ if (first.kind !== "number" || second.kind !== "number")
121
+ return false;
122
+ // Date Filters compare calendar days; Number Filters the exact values.
123
+ var day = isDateFilterCondition(type)
124
+ ? function (n) { return Math.floor(n); }
125
+ : function (n) { return n; };
126
+ var a = day(value);
127
+ var lo = day(first.value);
128
+ var hi = day(second.value);
129
+ switch (type) {
130
+ case "NUMBER_EQ":
131
+ case "DATE_EQ":
132
+ return numbersEqual(a, lo);
133
+ case "NUMBER_NOT_EQ":
134
+ case "DATE_NOT_EQ":
135
+ return !numbersEqual(a, lo);
136
+ case "NUMBER_GREATER":
137
+ case "DATE_AFTER":
138
+ return a > lo;
139
+ case "NUMBER_GREATER_THAN_EQ":
140
+ case "DATE_ON_OR_AFTER":
141
+ return a >= lo;
142
+ case "NUMBER_LESS":
143
+ case "DATE_BEFORE":
144
+ return a < lo;
145
+ case "NUMBER_LESS_THAN_EQ":
146
+ case "DATE_ON_OR_BEFORE":
147
+ return a <= lo;
148
+ case "NUMBER_BETWEEN":
149
+ case "DATE_BETWEEN":
150
+ return a >= lo && a <= hi;
151
+ case "NUMBER_NOT_BETWEEN":
152
+ case "DATE_NOT_BETWEEN":
153
+ return a < lo || a > hi;
154
+ default:
155
+ return undefined;
156
+ }
157
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"formula.d.ts","sourceRoot":"","sources":["../../../api/formula.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"formula.d.ts","sourceRoot":"","sources":["../../../api/formula.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { __assign, __read, __spreadArray, __values } from "tslib";
2
2
  import { cleanupColumnName, cleanupSpecialItem, cleanupTableName, detectCurrentRow, isRangeToken, lexify, stripPropertyFromCellRef, tokenVocabulary, } from "@rowsncolumns/calculator";
3
- import { addressToCell, alpha2number, cellToAddress, desanitizeSheetName, number2Alpha, sanitizeSheetName, } from "@rowsncolumns/utils";
3
+ import { addressToCell, alpha2number, cellToAddress, desanitizeSheetName, escapeCharacters, number2Alpha, sanitizeSheetName, } from "@rowsncolumns/utils";
4
4
  export { ERROR_CIRCULAR_DEPENDENCY, ERROR_REFERENCE, formulaToRelativeReference, } from "@rowsncolumns/calculator";
5
5
  /**
6
6
  * Update sheet name in formula
@@ -12,22 +12,24 @@ export var updateSheetName = function (formulaValue, newName, oldName) {
12
12
  var e_1, _a;
13
13
  var tokens = cloneTokens(lexify(formulaValue).tokens);
14
14
  var newTokens = [];
15
+ // Sheet names compare case-insensitively (Excel's rule); the old name is a literal, not a pattern —
16
+ // `Q1 (2024)` or `Sheet.2` must match exactly that title.
17
+ var isOldName = new RegExp("^" + escapeCharacters(oldName) + "$", "i");
15
18
  try {
19
+ // `sanitizeSheetName` re-quotes the new name the way Excel writes it — `'2024'!A1`, `'A1'!A1`,
20
+ // `'TRUE'!A1` — and drops quotes a plain identifier no longer needs (rowsncolumns/spreadsheet#939 K-10).
16
21
  for (var tokens_1 = __values(tokens), tokens_1_1 = tokens_1.next(); !tokens_1_1.done; tokens_1_1 = tokens_1.next()) {
17
22
  var token = tokens_1_1.value;
18
23
  if (token.tokenType.name === tokenVocabulary.Sheet.name) {
19
24
  token.image =
20
- sanitizeSheetName(token.image
21
- .slice(0, -1)
22
- .replace(new RegExp("^" + oldName + "$", "gi"), newName)) + "!";
25
+ sanitizeSheetName(token.image.slice(0, -1).replace(isOldName, newName)) +
26
+ "!";
23
27
  }
24
28
  if (token.tokenType.name === tokenVocabulary.SheetQuoted.name) {
25
29
  var cleanSheetName = desanitizeSheetName(token.image);
26
30
  if (cleanSheetName) {
27
31
  token.image =
28
- sanitizeSheetName(cleanSheetName
29
- .slice(0, -1)
30
- .replace(new RegExp("^" + oldName + "$", "gi"), newName)) + "!";
32
+ sanitizeSheetName(cleanSheetName.slice(0, -1).replace(isOldName, newName)) + "!";
31
33
  }
32
34
  }
33
35
  newTokens.push(token);
@@ -0,0 +1,41 @@
1
+ import type { CellInterface } from "@rowsncolumns/common-types";
2
+ import type { EmbeddedObject } from "@rowsncolumns/spreadsheet";
3
+ import type { UseSpreadsheetProps } from "../hooks/use-spreadsheet-state";
4
+ /**
5
+ * Upper bound (px) for a floating image's longer side when the grid's viewport is unknown — a
6
+ * paste or drop outside a mounted `CanvasGrid` (no `getSheetDimensions`). With a viewport the image
7
+ * is capped to the viewport instead, so a picture is never larger than what the user can see.
8
+ */
9
+ export declare const DEFAULT_IMAGE_EMBED_MAX_DIMENSION = 800;
10
+ /** The visible grid area in pixels — `CanvasGrid`'s `getSheetDimensions()` (width, height). */
11
+ export type ImageViewport = readonly [width: number, height: number];
12
+ export type ImageEmbedSize = {
13
+ widthPixels: number;
14
+ heightPixels: number;
15
+ };
16
+ /**
17
+ * Excel / Google Sheets default size for an inserted picture: its natural pixel size, only scaled
18
+ * DOWN (aspect ratio kept) when it would not fit the viewport. Never scales up. An image with an
19
+ * unknown / degenerate size (0 or NaN) is left as-is so the caller can still place it.
20
+ */
21
+ export declare const fitImageToViewport: (width: number, height: number, viewport?: ImageViewport | null) => ImageEmbedSize;
22
+ export type CreateImageEmbedOptions = {
23
+ sheetId: number;
24
+ /** The cell the picture's top-left corner is anchored to (Excel anchors a pasted picture at the active cell). */
25
+ anchorCell: CellInterface;
26
+ imageUrl: string;
27
+ /** Natural image size in pixels; fitted to `viewport` by {@link fitImageToViewport}. */
28
+ width: number;
29
+ height: number;
30
+ viewport?: ImageViewport | null;
31
+ /** A fixed id (replacing an existing embed keeps its id); defaults to `idCreationStrategy("embed")` / a uuid. */
32
+ embedId?: EmbeddedObject["embedId"];
33
+ idCreationStrategy?: UseSpreadsheetProps["idCreationStrategy"];
34
+ };
35
+ /**
36
+ * The ONE way a picture becomes a floating object over the cells — shared by the clipboard paste,
37
+ * the file drop, the Insert → Image dialog and the engine command handlers, so every entry point
38
+ * produces the same movable, resizable, aspect-locked embed anchored at the target cell.
39
+ */
40
+ export declare const createImageEmbed: ({ sheetId, anchorCell, imageUrl, width, height, viewport, embedId, idCreationStrategy, }: CreateImageEmbedOptions) => EmbeddedObject;
41
+ //# sourceMappingURL=image-embed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-embed.d.ts","sourceRoot":"","sources":["../../../api/image-embed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAE1E;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,MAAM,CAAC;AAErD,+FAA+F;AAC/F,MAAM,MAAM,aAAa,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAErE,MAAM,MAAM,cAAc,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,OAAO,MAAM,EACb,QAAQ,MAAM,EACd,WAAW,aAAa,GAAG,IAAI,KAC9B,cAaF,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,iHAAiH;IACjH,UAAU,EAAE,aAAa,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,wFAAwF;IACxF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,iHAAiH;IACjH,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;IACpC,kBAAkB,CAAC,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CAChE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,0FAS9B,uBAAuB,KAAG,cAyB5B,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { __read } from "tslib";
2
+ import { uuid } from "@rowsncolumns/utils";
3
+ /**
4
+ * Upper bound (px) for a floating image's longer side when the grid's viewport is unknown — a
5
+ * paste or drop outside a mounted `CanvasGrid` (no `getSheetDimensions`). With a viewport the image
6
+ * is capped to the viewport instead, so a picture is never larger than what the user can see.
7
+ */
8
+ export var DEFAULT_IMAGE_EMBED_MAX_DIMENSION = 800;
9
+ /**
10
+ * Excel / Google Sheets default size for an inserted picture: its natural pixel size, only scaled
11
+ * DOWN (aspect ratio kept) when it would not fit the viewport. Never scales up. An image with an
12
+ * unknown / degenerate size (0 or NaN) is left as-is so the caller can still place it.
13
+ */
14
+ export var fitImageToViewport = function (width, height, viewport) {
15
+ if (!(width > 0) || !(height > 0)) {
16
+ return { widthPixels: width, heightPixels: height };
17
+ }
18
+ var _a = __read(viewport && viewport[0] > 0 && viewport[1] > 0
19
+ ? viewport
20
+ : [DEFAULT_IMAGE_EMBED_MAX_DIMENSION, DEFAULT_IMAGE_EMBED_MAX_DIMENSION], 2), maxWidth = _a[0], maxHeight = _a[1];
21
+ var scale = Math.min(1, maxWidth / width, maxHeight / height);
22
+ return {
23
+ widthPixels: Math.round(width * scale),
24
+ heightPixels: Math.round(height * scale),
25
+ };
26
+ };
27
+ /**
28
+ * The ONE way a picture becomes a floating object over the cells — shared by the clipboard paste,
29
+ * the file drop, the Insert → Image dialog and the engine command handlers, so every entry point
30
+ * produces the same movable, resizable, aspect-locked embed anchored at the target cell.
31
+ */
32
+ export var createImageEmbed = function (_a) {
33
+ var _b;
34
+ var sheetId = _a.sheetId, anchorCell = _a.anchorCell, imageUrl = _a.imageUrl, width = _a.width, height = _a.height, viewport = _a.viewport, embedId = _a.embedId, idCreationStrategy = _a.idCreationStrategy;
35
+ var _c = fitImageToViewport(width, height, viewport), widthPixels = _c.widthPixels, heightPixels = _c.heightPixels;
36
+ return {
37
+ embedId: (_b = embedId !== null && embedId !== void 0 ? embedId : idCreationStrategy === null || idCreationStrategy === void 0 ? void 0 : idCreationStrategy("embed")) !== null && _b !== void 0 ? _b : uuid(),
38
+ position: {
39
+ sheetId: sheetId,
40
+ overlayPosition: {
41
+ anchorCell: { rowIndex: anchorCell.rowIndex, columnIndex: anchorCell.columnIndex },
42
+ widthPixels: widthPixels,
43
+ heightPixels: heightPixels,
44
+ offsetXPixels: 0,
45
+ offsetYPixels: 0,
46
+ },
47
+ },
48
+ borderColor: "transparent",
49
+ lockAspectRatio: true,
50
+ spec: {
51
+ type: "image",
52
+ imageUrl: imageUrl,
53
+ },
54
+ };
55
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"immer-utils.d.ts","sourceRoot":"","sources":["../../../api/immer-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"immer-utils.d.ts","sourceRoot":"","sources":["../../../api/immer-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,IAAI,2BAA2B,EAC/C,SAAS,IAAI,oBAAoB,EAClC,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAI7E,OAAO,KAAK,EACV,QAAQ,EACR,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACZ,MAAM,2BAA2B,CAAC;AASnC,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAQxE,KAAK,SAAS,CAAC,CAAC,SAAS,QAAQ,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAC7D,KAAK,gBAAgB,CAAC,CAAC,SAAS,QAAQ,GAAG,IAAI,GAAG,SAAS,IACzD,2BAA2B,CAAC,CAAC,CAAC,CAAC;AAEjC,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,QAAQ,EACjD,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAC1B,SAAS,MAAM,EACf,WAAW,MAAM,KAgBD,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,EAC9D,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,GACrC,UAAU,SAAS,CAAC,mBAAmB,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAC7D,gBAAgB,MAAM,KACrB,mBAAmB,GAAG,SAUxB,CAAC;AAGF,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,QAAQ,EACvD,SAAS,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,KACjE,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAa9C,CAAC;AAGF,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAAS,QAAQ,EACxD,UAAU,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,oBAItC,CAAC;AA2UF,eAAO,MAAM,2BAA2B,GAAI,SAAS,MAAM,aAW1D,CAAC;AA0IF,eAAO,MAAM,yCAAyC,GAAI,CAAC,SAAS,QAAQ,EAC1E,SAAS,MAAM,GAAG,SAAc,EAChC,YAAY,CAAC,QAAQ,GAAG,aAAa,GAAG,UAAU,CAAC,EAAE,EACrD,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EACzC,WAAW,CAAC,GAAG,EAAE,MAAM,KAAK,WAAW,EAAE,EACzC,SAAS,MAAM,EACf,UAAU,MAAM,EAChB,aAAa,MAAM,EACnB,QAAQ,MAAM,GAAG,SAAS,EAC1B,YAAY,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EACzC,kBAAkB,eAAe,EACjC,wBAAwB,UAAU,CAChC,OAAO,kBAAkB,CAC1B,CAAC,uBAAuB,CAAC,EAC1B,kBAAkB,MAAM,GAAG,MAAM,GAAG,IAAI;AACxC;;;;;;;;GAQG;AACH,+BAA+B,CAC7B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,KAChB,YAAY,GAAG,SAAS,GAAG,IAAI,KACnC,YAAY,GAAG,SAAS,GAAG,IAwZ7B,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,sCAAsC,GAAI,CAAC,SAAS,QAAQ,EACvE,SAAS,MAAM,GAAG,SAAS,EAC3B,SAAS,MAAM,EACf,UAAU,MAAM,EAChB,aAAa,MAAM,EACnB,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EACzC,WAAW,CAAC,GAAG,EAAE,MAAM,KAAK,WAAW,EAAE,EACzC,YAAY,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EACzC,SAAS,MAAM,EACf,kBAAkB,eAAe,EACjC,wBAAwB,UAAU,CAChC,OAAO,kBAAkB,CAC1B,CAAC,uBAAuB,CAAC,EAC1B,kBAAkB,MAAM,GAAG,MAAM,GAAG,IAAI,KACvC,YAAY,GAAG,SAAS,GAAG,IA0C7B,CAAC;AAipBF;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,GAAI,CAAC,SAAS,QAAQ,EAC/D,SAAS,MAAM,EACf,qBAAqB,YAAY,EACjC,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EACzC,WAAW,CAAC,GAAG,EAAE,MAAM,KAAK,WAAW,EAAE,EACzC,SAAS,MAAM,EACf,YAAY,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EACzC,kBAAkB,eAAe,EACjC,wBAAwB,UAAU,CAChC,OAAO,kBAAkB,CAC1B,CAAC,uBAAuB,CAAC,KACzB,gBAAgB,GAAG,SAarB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,GAAI,CAAC,SAAS,QAAQ,EAC9D,SAAS,MAAM,EACf,qBAAqB,YAAY,EACjC,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EACzC,WAAW,CAAC,GAAG,EAAE,MAAM,KAAK,WAAW,EAAE,EACzC,SAAS,MAAM,EACf,YAAY,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EACzC,kBAAkB,eAAe,EACjC,wBAAwB,UAAU,CAChC,OAAO,kBAAkB,CAC1B,CAAC,uBAAuB,CAAC,EAC1B,SAAS,MAAM,KACd,YAAY,GAAG,SAoDjB,CAAC;AAGF,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,QAAQ,EACjD,OAAO,WAAW,GAAG,SAAS,EAC9B,SAAS,MAAM,EACf,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EACzC,kBAAkB,eAAe,EACjC,wBAAwB,UAAU,CAChC,OAAO,kBAAkB,CAC1B,CAAC,uBAAuB,CAAC,YAc3B,CAAC;AAGF,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,QAAQ,EAC3C,OAAO,WAAW,GAAG,SAAS,EAC9B,SAAS,MAAM,EACf,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EACzC,kBAAkB,eAAe,EACjC,wBAAwB,UAAU,CAChC,OAAO,kBAAkB,CAC1B,CAAC,uBAAuB,CAAC,YAc3B,CAAC;AAkFF;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,UAAU,gBAAgB,CAAC,CAAC,CAAC;;;;;;;;;CAY5D,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,QAAQ,EACzD,SAAS,MAAM,GAAG,SAAc,EAChC,YAAY,CAAC,QAAQ,GAAG,aAAa,GAAG,UAAU,CAAC,EAAE,EACrD,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EACzC,SAAS,MAAM,EACf,QAAQ,MAAM,GAAG,SAAS,EAC1B,kBAAkB,eAAe,gCA2ClC,CAAC"}
@@ -62,6 +62,12 @@ export var cloneCellWithFormatting = function (celLData) {
62
62
  * first-specific-wins merging rule in `processPrecedentCell`.
63
63
  */
64
64
  var isGenericNumberFormatType = function (type) { return !type || type === "NUMBER" || type === "GENERAL"; };
65
+ /**
66
+ * Whether a number format carries a real pattern — `General` (or a missing
67
+ * pattern) is "no format", the shape a plain typed number and an
68
+ * unformatted formula result have in Excel.
69
+ */
70
+ var hasConcretePattern = function (format) { return !!(format === null || format === void 0 ? void 0 : format.pattern) && format.pattern !== "General"; };
65
71
  /**
66
72
  * Date-family types — when the derived (resolved) type is one of these
67
73
  * and the precedent's type is also in this set, we preserve the
@@ -494,6 +500,8 @@ resolvePrecedentNumberFormat) {
494
500
  }
495
501
  // Priority
496
502
  // NUMBER -> PERCENTAGE -> CURRENCY
503
+ // Assigned inside `processPrecedentCell`; the cast keeps TypeScript from
504
+ // narrowing the declaration to `undefined` for the reads below.
497
505
  var numFormat = undefined;
498
506
  // Expected return type from function
499
507
  var expectedOutputType = undefined;
@@ -613,8 +621,13 @@ resolvePrecedentNumberFormat) {
613
621
  // specific format is locked in we don't let a different specific
614
622
  // format override it (e.g. PERCENT then CURRENCY → keep PERCENT,
615
623
  // matching Excel; previously priority-based merging picked the
616
- // higher-priority one regardless of position).
617
- if (!numFormat || isGenericNumberFormatType(numFormat.type)) {
624
+ // higher-priority one regardless of position). Among generics, a
625
+ // pattern-less one (a General cell) never displaces an earlier one
626
+ // that carries a real pattern (`0.0`) — that pattern is the format
627
+ // Excel would inherit.
628
+ if (!numFormat ||
629
+ (isGenericNumberFormatType(numFormat.type) &&
630
+ !(hasConcretePattern(numFormat) && !hasConcretePattern(curNumFormat)))) {
618
631
  numFormat = curNumFormat;
619
632
  }
620
633
  }
@@ -654,11 +667,11 @@ resolvePrecedentNumberFormat) {
654
667
  if (typeof calculatedValue === "number") {
655
668
  maxDecimals = Math.max(maxDecimals, calculatedDecimals !== null && calculatedDecimals !== void 0 ? calculatedDecimals : 0);
656
669
  }
657
- if (!numFormat && maxDecimals > 0) {
658
- numFormat = { type: "NUMBER" };
659
- }
670
+ // A result with no formatted precedent is General, as in Excel: `=1/3`
671
+ // displays `0.333333333`, `=PI()` `3.141592654`. Decimals in the computed
672
+ // value are never a reason to manufacture a NUMBER pattern — a General
673
+ // result used to get `0.000` here and paint `0.333`.
660
674
  var applyDecimalHeuristic = function (format) {
661
- var _a;
662
675
  // `#` is the implicit integer pattern inferred from plain numeric cells,
663
676
  // but it suppresses zero. Formula results should still display a derived
664
677
  // zero; an explicitly formatted formula cell returned above remains
@@ -681,21 +694,36 @@ resolvePrecedentNumberFormat) {
681
694
  return __assign(__assign({}, format), { pattern: changeDecimals(format.pattern, calculatedDecimals, false) });
682
695
  }
683
696
  }
684
- // Original heuristic for NUMBER type
685
- if ((format === null || format === void 0 ? void 0 : format.type) === "NUMBER" && maxDecimals > 0) {
686
- var basePattern = (_a = format.pattern) !== null && _a !== void 0 ? _a : "0";
687
- return __assign(__assign({}, format), { pattern: changeDecimals(basePattern, Math.min(maxDecimals, 3), false) });
697
+ // NUMBER decimals are only ever adjusted on a pattern a precedent
698
+ // actually carries (`0.0` → `0.00`). A NUMBER type without one — from
699
+ // General precedents, or from the AST reducing CURRENCY ÷ CURRENCY /
700
+ // DATE − DATE to a plain number — stays pattern-less and displays
701
+ // through General (`=D1/D2` → `1.5`, not `1.50`).
702
+ if ((format === null || format === void 0 ? void 0 : format.type) === "NUMBER" &&
703
+ hasConcretePattern(format) &&
704
+ maxDecimals > 0) {
705
+ return __assign(__assign({}, format), { pattern: changeDecimals(format.pattern, Math.min(maxDecimals, 3), false) });
688
706
  }
689
707
  return format;
690
708
  };
691
709
  // Useful for Percentages
692
710
  // 20% x 50 => number
693
- if (numFormat) {
694
- // Does not support structured references as of now
695
- var astDerivedNumberFormat = getNumberFormatFromFormulaAst(formula, numFormat, draft, tokenizer, sheetId, getSheetId, cellXfsRegistry, getDataValidationById, locale);
696
- if (astDerivedNumberFormat) {
697
- return applyDecimalHeuristic(astDerivedNumberFormat);
711
+ // The AST runs even when no precedent carried a format: it knows that
712
+ // `=NOW()-TODAY()` is a plain number where the function-return-type scan
713
+ // below would call it DATE_TIME. A General placeholder stands in for the
714
+ // missing precedent format and comes back as a pattern-less NUMBER for a
715
+ // General result. Does not support structured references as of now.
716
+ var astDerivedNumberFormat = getNumberFormatFromFormulaAst(formula, numFormat !== null && numFormat !== void 0 ? numFormat : { type: "NUMBER" }, draft, tokenizer, sheetId, getSheetId, cellXfsRegistry, getDataValidationById, locale);
717
+ if (astDerivedNumberFormat) {
718
+ if (!numFormat &&
719
+ astDerivedNumberFormat.type === "NUMBER" &&
720
+ !astDerivedNumberFormat.pattern) {
721
+ // The placeholder came back unchanged: a General result with no
722
+ // formatted precedent has no format at all (`=1/3`, `=B1` of a plain
723
+ // cell, `=NOW()-TODAY()`).
724
+ return undefined;
698
725
  }
726
+ return applyDecimalHeuristic(astDerivedNumberFormat);
699
727
  }
700
728
  // If we could not derive from function
701
729
  if (expectedOutputType === undefined) {