@rowsncolumns/spreadsheet-state 29.1.4 → 29.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) 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 +50 -27
  10. package/dist/cjs/api/decimals.d.ts +10 -0
  11. package/dist/cjs/api/decimals.d.ts.map +1 -1
  12. package/dist/cjs/api/decimals.js +34 -11
  13. package/dist/cjs/api/dependency.d.ts +19 -1
  14. package/dist/cjs/api/dependency.d.ts.map +1 -1
  15. package/dist/cjs/api/dependency.js +30 -14
  16. package/dist/cjs/api/filter-condition.d.ts +58 -0
  17. package/dist/cjs/api/filter-condition.d.ts.map +1 -0
  18. package/dist/cjs/api/filter-condition.js +157 -0
  19. package/dist/cjs/api/formula.d.ts.map +1 -1
  20. package/dist/cjs/api/formula.js +9 -7
  21. package/dist/cjs/api/image-embed.d.ts +41 -0
  22. package/dist/cjs/api/image-embed.d.ts.map +1 -0
  23. package/dist/cjs/api/image-embed.js +55 -0
  24. package/dist/cjs/api/immer-utils.d.ts.map +1 -1
  25. package/dist/cjs/api/immer-utils.js +43 -15
  26. package/dist/cjs/api/named-range-structural.d.ts +29 -3
  27. package/dist/cjs/api/named-range-structural.d.ts.map +1 -1
  28. package/dist/cjs/api/named-range-structural.js +36 -11
  29. package/dist/cjs/api/parse-html.d.ts.map +1 -1
  30. package/dist/cjs/api/parse-html.js +11 -5
  31. package/dist/cjs/api/structural-formula-update.d.ts +20 -1
  32. package/dist/cjs/api/structural-formula-update.d.ts.map +1 -1
  33. package/dist/cjs/api/structural-formula-update.js +264 -90
  34. package/dist/cjs/api/structural-guards.d.ts +11 -0
  35. package/dist/cjs/api/structural-guards.d.ts.map +1 -1
  36. package/dist/cjs/api/structural-guards.js +45 -1
  37. package/dist/cjs/api/structural-table-refs.d.ts +15 -2
  38. package/dist/cjs/api/structural-table-refs.d.ts.map +1 -1
  39. package/dist/cjs/api/structural-table-refs.js +79 -35
  40. package/dist/cjs/commands.d.ts +17 -3
  41. package/dist/cjs/commands.d.ts.map +1 -1
  42. package/dist/cjs/components/editors/conditional-format-rule-editor.d.ts.map +1 -1
  43. package/dist/cjs/components/editors/conditional-format-rule-editor.js +19 -7
  44. package/dist/cjs/constants.d.ts +4 -1
  45. package/dist/cjs/constants.d.ts.map +1 -1
  46. package/dist/cjs/constants.js +4 -0
  47. package/dist/cjs/helpers/sheet-title.d.ts +2 -1
  48. package/dist/cjs/helpers/sheet-title.d.ts.map +1 -1
  49. package/dist/cjs/helpers/sheet-title.js +3 -1
  50. package/dist/cjs/hooks/use-can-edit-cellrange.d.ts +1 -1
  51. package/dist/cjs/hooks/use-can-edit-cellrange.d.ts.map +1 -1
  52. package/dist/cjs/hooks/use-can-edit-cellrange.js +1 -1
  53. package/dist/cjs/hooks/use-on-calculation-success.d.ts +5 -1
  54. package/dist/cjs/hooks/use-on-calculation-success.d.ts.map +1 -1
  55. package/dist/cjs/hooks/use-on-calculation-success.js +20 -3
  56. package/dist/cjs/hooks/use-on-copy.d.ts.map +1 -1
  57. package/dist/cjs/hooks/use-on-copy.js +23 -25
  58. package/dist/cjs/hooks/use-on-create-sheet.d.ts.map +1 -1
  59. package/dist/cjs/hooks/use-on-create-sheet.js +11 -1
  60. package/dist/cjs/hooks/use-on-delete.d.ts.map +1 -1
  61. package/dist/cjs/hooks/use-on-delete.js +15 -3
  62. package/dist/cjs/hooks/use-on-drag-n-drop.d.ts +5 -0
  63. package/dist/cjs/hooks/use-on-drag-n-drop.d.ts.map +1 -1
  64. package/dist/cjs/hooks/use-on-drag-n-drop.js +6 -5
  65. package/dist/cjs/hooks/use-on-filter-table.d.ts.map +1 -1
  66. package/dist/cjs/hooks/use-on-filter-table.js +6 -1
  67. package/dist/cjs/hooks/use-on-find-replace.d.ts.map +1 -1
  68. package/dist/cjs/hooks/use-on-find-replace.js +111 -23
  69. package/dist/cjs/hooks/use-on-insert-image.d.ts.map +1 -1
  70. package/dist/cjs/hooks/use-on-insert-image.js +20 -33
  71. package/dist/cjs/hooks/use-on-paste.d.ts +2 -1
  72. package/dist/cjs/hooks/use-on-paste.d.ts.map +1 -1
  73. package/dist/cjs/hooks/use-on-paste.js +53 -24
  74. package/dist/cjs/hooks/use-on-rename-sheet.d.ts +3 -1
  75. package/dist/cjs/hooks/use-on-rename-sheet.d.ts.map +1 -1
  76. package/dist/cjs/hooks/use-on-rename-sheet.js +19 -9
  77. package/dist/cjs/hooks/use-on-sort-column.d.ts +7 -1
  78. package/dist/cjs/hooks/use-on-sort-column.d.ts.map +1 -1
  79. package/dist/cjs/hooks/use-on-sort-column.js +25 -8
  80. package/dist/cjs/hooks/use-on-sort-range.d.ts +16 -2
  81. package/dist/cjs/hooks/use-on-sort-range.d.ts.map +1 -1
  82. package/dist/cjs/hooks/use-on-sort-range.js +72 -40
  83. package/dist/cjs/hooks/use-on-sort-table.d.ts +7 -2
  84. package/dist/cjs/hooks/use-on-sort-table.d.ts.map +1 -1
  85. package/dist/cjs/hooks/use-on-sort-table.js +25 -4
  86. package/dist/cjs/hooks/use-spreadsheet-state.d.ts +5 -3
  87. package/dist/cjs/hooks/use-spreadsheet-state.d.ts.map +1 -1
  88. package/dist/cjs/hooks/use-spreadsheet-state.js +7 -0
  89. package/dist/cjs/hooks/utils/sort-rows.d.ts +15 -0
  90. package/dist/cjs/hooks/utils/sort-rows.d.ts.map +1 -1
  91. package/dist/cjs/hooks/utils/sort-rows.js +16 -0
  92. package/dist/cjs/index.d.ts +3 -0
  93. package/dist/cjs/index.d.ts.map +1 -1
  94. package/dist/cjs/index.js +3 -0
  95. package/dist/cjs/interface/delete-column.d.ts.map +1 -1
  96. package/dist/cjs/interface/delete-column.js +254 -101
  97. package/dist/cjs/interface/delete-row.d.ts.map +1 -1
  98. package/dist/cjs/interface/delete-row.js +233 -81
  99. package/dist/cjs/interface/duplicate-sheet.d.ts.map +1 -1
  100. package/dist/cjs/interface/duplicate-sheet.js +4 -9
  101. package/dist/cjs/interface/insert-column.d.ts.map +1 -1
  102. package/dist/cjs/interface/insert-column.js +1 -1
  103. package/dist/cjs/interface/insert-row.d.ts.map +1 -1
  104. package/dist/cjs/interface/insert-row.js +1 -1
  105. package/dist/cjs/interface/new-sheet.d.ts.map +1 -1
  106. package/dist/cjs/interface/new-sheet.js +6 -13
  107. package/dist/cjs/sheet-cell.d.ts +9 -0
  108. package/dist/cjs/sheet-cell.d.ts.map +1 -1
  109. package/dist/cjs/sheet-cell.js +46 -9
  110. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  111. package/dist/esm/api/circular-reference.d.ts +31 -0
  112. package/dist/esm/api/circular-reference.d.ts.map +1 -0
  113. package/dist/esm/api/circular-reference.js +55 -0
  114. package/dist/esm/api/copy-paste.d.ts +6 -0
  115. package/dist/esm/api/copy-paste.d.ts.map +1 -1
  116. package/dist/esm/api/copy-paste.js +26 -14
  117. package/dist/esm/api/datatype.d.ts +2 -0
  118. package/dist/esm/api/datatype.d.ts.map +1 -1
  119. package/dist/esm/api/datatype.js +50 -27
  120. package/dist/esm/api/decimals.d.ts +10 -0
  121. package/dist/esm/api/decimals.d.ts.map +1 -1
  122. package/dist/esm/api/decimals.js +31 -10
  123. package/dist/esm/api/dependency.d.ts +19 -1
  124. package/dist/esm/api/dependency.d.ts.map +1 -1
  125. package/dist/esm/api/dependency.js +15 -10
  126. package/dist/esm/api/filter-condition.d.ts +58 -0
  127. package/dist/esm/api/filter-condition.d.ts.map +1 -0
  128. package/dist/esm/api/filter-condition.js +146 -0
  129. package/dist/esm/api/formula.d.ts.map +1 -1
  130. package/dist/esm/api/formula.js +9 -7
  131. package/dist/esm/api/image-embed.d.ts +41 -0
  132. package/dist/esm/api/image-embed.d.ts.map +1 -0
  133. package/dist/esm/api/image-embed.js +52 -0
  134. package/dist/esm/api/immer-utils.d.ts.map +1 -1
  135. package/dist/esm/api/immer-utils.js +43 -14
  136. package/dist/esm/api/named-range-structural.d.ts +29 -3
  137. package/dist/esm/api/named-range-structural.d.ts.map +1 -1
  138. package/dist/esm/api/named-range-structural.js +35 -11
  139. package/dist/esm/api/parse-html.d.ts.map +1 -1
  140. package/dist/esm/api/parse-html.js +14 -5
  141. package/dist/esm/api/structural-formula-update.d.ts +20 -1
  142. package/dist/esm/api/structural-formula-update.d.ts.map +1 -1
  143. package/dist/esm/api/structural-formula-update.js +151 -55
  144. package/dist/esm/api/structural-guards.d.ts +11 -0
  145. package/dist/esm/api/structural-guards.d.ts.map +1 -1
  146. package/dist/esm/api/structural-guards.js +31 -0
  147. package/dist/esm/api/structural-table-refs.d.ts +15 -2
  148. package/dist/esm/api/structural-table-refs.d.ts.map +1 -1
  149. package/dist/esm/api/structural-table-refs.js +49 -18
  150. package/dist/esm/commands.d.ts +17 -3
  151. package/dist/esm/commands.d.ts.map +1 -1
  152. package/dist/esm/components/editors/conditional-format-rule-editor.d.ts.map +1 -1
  153. package/dist/esm/components/editors/conditional-format-rule-editor.js +18 -7
  154. package/dist/esm/constants.d.ts +4 -1
  155. package/dist/esm/constants.d.ts.map +1 -1
  156. package/dist/esm/constants.js +4 -0
  157. package/dist/esm/helpers/sheet-title.d.ts +2 -1
  158. package/dist/esm/helpers/sheet-title.d.ts.map +1 -1
  159. package/dist/esm/helpers/sheet-title.js +3 -1
  160. package/dist/esm/hooks/use-can-edit-cellrange.d.ts +1 -1
  161. package/dist/esm/hooks/use-can-edit-cellrange.d.ts.map +1 -1
  162. package/dist/esm/hooks/use-can-edit-cellrange.js +1 -1
  163. package/dist/esm/hooks/use-on-calculation-success.d.ts +5 -1
  164. package/dist/esm/hooks/use-on-calculation-success.d.ts.map +1 -1
  165. package/dist/esm/hooks/use-on-calculation-success.js +19 -3
  166. package/dist/esm/hooks/use-on-copy.d.ts.map +1 -1
  167. package/dist/esm/hooks/use-on-copy.js +17 -17
  168. package/dist/esm/hooks/use-on-create-sheet.d.ts.map +1 -1
  169. package/dist/esm/hooks/use-on-create-sheet.js +11 -1
  170. package/dist/esm/hooks/use-on-delete.d.ts.map +1 -1
  171. package/dist/esm/hooks/use-on-delete.js +15 -3
  172. package/dist/esm/hooks/use-on-drag-n-drop.d.ts +5 -0
  173. package/dist/esm/hooks/use-on-drag-n-drop.d.ts.map +1 -1
  174. package/dist/esm/hooks/use-on-drag-n-drop.js +7 -4
  175. package/dist/esm/hooks/use-on-filter-table.d.ts.map +1 -1
  176. package/dist/esm/hooks/use-on-filter-table.js +13 -2
  177. package/dist/esm/hooks/use-on-find-replace.d.ts.map +1 -1
  178. package/dist/esm/hooks/use-on-find-replace.js +111 -23
  179. package/dist/esm/hooks/use-on-insert-image.d.ts.map +1 -1
  180. package/dist/esm/hooks/use-on-insert-image.js +15 -25
  181. package/dist/esm/hooks/use-on-paste.d.ts +2 -1
  182. package/dist/esm/hooks/use-on-paste.d.ts.map +1 -1
  183. package/dist/esm/hooks/use-on-paste.js +46 -15
  184. package/dist/esm/hooks/use-on-rename-sheet.d.ts +3 -1
  185. package/dist/esm/hooks/use-on-rename-sheet.d.ts.map +1 -1
  186. package/dist/esm/hooks/use-on-rename-sheet.js +19 -9
  187. package/dist/esm/hooks/use-on-sort-column.d.ts +7 -1
  188. package/dist/esm/hooks/use-on-sort-column.d.ts.map +1 -1
  189. package/dist/esm/hooks/use-on-sort-column.js +18 -1
  190. package/dist/esm/hooks/use-on-sort-range.d.ts +16 -2
  191. package/dist/esm/hooks/use-on-sort-range.d.ts.map +1 -1
  192. package/dist/esm/hooks/use-on-sort-range.js +30 -3
  193. package/dist/esm/hooks/use-on-sort-table.d.ts +7 -2
  194. package/dist/esm/hooks/use-on-sort-table.d.ts.map +1 -1
  195. package/dist/esm/hooks/use-on-sort-table.js +25 -4
  196. package/dist/esm/hooks/use-spreadsheet-state.d.ts +5 -3
  197. package/dist/esm/hooks/use-spreadsheet-state.d.ts.map +1 -1
  198. package/dist/esm/hooks/use-spreadsheet-state.js +7 -0
  199. package/dist/esm/hooks/utils/sort-rows.d.ts +15 -0
  200. package/dist/esm/hooks/utils/sort-rows.d.ts.map +1 -1
  201. package/dist/esm/hooks/utils/sort-rows.js +15 -0
  202. package/dist/esm/index.d.ts +3 -0
  203. package/dist/esm/index.d.ts.map +1 -1
  204. package/dist/esm/index.js +3 -0
  205. package/dist/esm/interface/delete-column.d.ts.map +1 -1
  206. package/dist/esm/interface/delete-column.js +111 -80
  207. package/dist/esm/interface/delete-row.d.ts.map +1 -1
  208. package/dist/esm/interface/delete-row.js +91 -59
  209. package/dist/esm/interface/duplicate-sheet.d.ts.map +1 -1
  210. package/dist/esm/interface/duplicate-sheet.js +4 -9
  211. package/dist/esm/interface/insert-column.d.ts.map +1 -1
  212. package/dist/esm/interface/insert-column.js +1 -1
  213. package/dist/esm/interface/insert-row.d.ts.map +1 -1
  214. package/dist/esm/interface/insert-row.js +1 -1
  215. package/dist/esm/interface/new-sheet.d.ts.map +1 -1
  216. package/dist/esm/interface/new-sheet.js +6 -13
  217. package/dist/esm/sheet-cell.d.ts +9 -0
  218. package/dist/esm/sheet-cell.d.ts.map +1 -1
  219. package/dist/esm/sheet-cell.js +46 -7
  220. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  221. package/package.json +9 -9
@@ -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":"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"}
@@ -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) {
@@ -2,6 +2,21 @@ import type { NamedRange, SheetPrintSettings } from "@rowsncolumns/spreadsheet";
2
2
  import type { WritableDraft } from "immer";
3
3
  export type StructuralAxis = "row" | "column";
4
4
  export type StructuralOp = "insert" | "delete";
5
+ /**
6
+ * The edited axis's extent, so a band can be recognised as UNBOUNDED on it:
7
+ * a whole-column name is modelled as `B1:B<rowCount>` and a whole-row name
8
+ * as `A1:<columnCount>1`, and Excel keeps `$B:$B` / `$1:$1` whole through
9
+ * every insert / delete on that axis.
10
+ */
11
+ export type StructuralAxisBounds = {
12
+ /** The sheet's row / column count on the edited axis before the edit. */
13
+ length: number;
14
+ /**
15
+ * The hard cap the grid never grows past (`maxRowCount` / `maxColumnCount`);
16
+ * a band's end is clamped to it and a band pushed past it is `#REF!`.
17
+ */
18
+ max?: number;
19
+ };
5
20
  /**
6
21
  * The `value` a defined name carries once every cell of its range has been
7
22
  * deleted. Excel keeps the name in the Name Manager as `=Sheet1!#REF!` and
@@ -22,8 +37,15 @@ export declare const isRefErrorNamedRange: (namedRange: Pick<NamedRange, "range"
22
37
  * - insert at the boundary directly below → unchanged;
23
38
  * - delete wholly above → shifts back; delete overlapping → shrinks by the
24
39
  * deleted indices inside the band; delete covering the band → `null`.
40
+ *
41
+ * With `bounds`, a band that spans the whole axis (`1..length` — a
42
+ * whole-column `$B:$B` / whole-row `$1:$1` name) is unbounded on it: an
43
+ * insert anywhere keeps its start at 1 and stretches its end with the grid
44
+ * (Excel never turns `$B:$B` into `$B$2:$B$1001`), a delete only shrinks the
45
+ * end with the grid. Ends never pass `bounds.max`; a band whose start would
46
+ * is `null` (`#REF!`), like a cell reference pushed off the sheet.
25
47
  */
26
- export declare const shiftNamedBand: (start: number, end: number, op: StructuralOp, index: number, count: number) => [number, number] | null;
48
+ export declare const shiftNamedBand: (start: number, end: number, op: StructuralOp, index: number, count: number, bounds?: StructuralAxisBounds) => [number, number] | null;
27
49
  export type NamedRangeStructuralUpdate<N extends NamedRange> = {
28
50
  /** Names whose range moved, grew, or shrank. */
29
51
  changed: N[];
@@ -41,13 +63,17 @@ export type NamedRangeStructuralUpdate<N extends NamedRange> = {
41
63
  * A name whose entire range is deleted is NOT dropped: it keeps its entry
42
64
  * with `range` cleared and `value: "#REF!"`, so `=SUM(Data)` evaluates to
43
65
  * `#REF!` like Excel rather than `#NAME?`.
66
+ *
67
+ * `bounds` (the edited sheet's row / column count on the edited axis) lets a
68
+ * whole-column / whole-row name keep its whole-axis geometry — see
69
+ * {@link shiftNamedBand}.
44
70
  */
45
- export declare const updateNamedRangesOnStructuralChange: (draft: WritableDraft<NamedRange>[], axis: StructuralAxis, op: StructuralOp, index: number, count: number, sheetId: number) => NamedRangeStructuralUpdate<WritableDraft<NamedRange>>;
71
+ export declare const updateNamedRangesOnStructuralChange: (draft: WritableDraft<NamedRange>[], axis: StructuralAxis, op: StructuralOp, index: number, count: number, sheetId: number, bounds?: StructuralAxisBounds) => NamedRangeStructuralUpdate<WritableDraft<NamedRange>>;
46
72
  /**
47
73
  * Pure variant of {@link updateNamedRangesOnStructuralChange}: returns the
48
74
  * adjusted list (sharing untouched entries) plus the names that changed.
49
75
  */
50
- export declare const shiftNamedRangesOnStructuralChange: <N extends NamedRange>(namedRanges: readonly N[], axis: StructuralAxis, op: StructuralOp, index: number, count: number, sheetId: number) => {
76
+ export declare const shiftNamedRangesOnStructuralChange: <N extends NamedRange>(namedRanges: readonly N[], axis: StructuralAxis, op: StructuralOp, index: number, count: number, sheetId: number, bounds?: StructuralAxisBounds) => {
51
77
  next: N[];
52
78
  } & NamedRangeStructuralUpdate<N>;
53
79
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"named-range-structural.d.ts","sourceRoot":"","sources":["../../../api/named-range-structural.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EAEV,kBAAkB,EACnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,QAAQ,CAAC;AAC9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,UAAU,CAAC;AAE7C,eAAO,MAAM,oBAAoB,GAC/B,YAAY,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,YACmB,CAAC;AAErE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,GACzB,OAAO,MAAM,EACb,KAAK,MAAM,EACX,IAAI,YAAY,EAChB,OAAO,MAAM,EACb,OAAO,MAAM,KACZ,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAgBrB,CAAC;AAmBF,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,UAAU,IAAI;IAC7D,gDAAgD;IAChD,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,gEAAgE;IAChE,UAAU,EAAE,CAAC,EAAE,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mCAAmC,GAC9C,OAAO,aAAa,CAAC,UAAU,CAAC,EAAE,EAClC,MAAM,cAAc,EACpB,IAAI,YAAY,EAChB,OAAO,MAAM,EACb,OAAO,MAAM,EACb,SAAS,MAAM,KACd,0BAA0B,CAAC,aAAa,CAAC,UAAU,CAAC,CAmBtD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kCAAkC,GAAI,CAAC,SAAS,UAAU,EACrE,aAAa,SAAS,CAAC,EAAE,EACzB,MAAM,cAAc,EACpB,IAAI,YAAY,EAChB,OAAO,MAAM,EACb,OAAO,MAAM,EACb,SAAS,MAAM,KACd;IAAE,IAAI,EAAE,CAAC,EAAE,CAAA;CAAE,GAAG,0BAA0B,CAAC,CAAC,CAsB9C,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qCAAqC,GAChD,eAAe,aAAa,CAAC,kBAAkB,CAAC,EAChD,MAAM,cAAc,EACpB,IAAI,YAAY,EAChB,OAAO,MAAM,EACb,OAAO,MAAM,KACZ,OAiDF,CAAC"}
1
+ {"version":3,"file":"named-range-structural.d.ts","sourceRoot":"","sources":["../../../api/named-range-structural.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EAEV,kBAAkB,EACnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,QAAQ,CAAC;AAC9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,UAAU,CAAC;AAE7C,eAAO,MAAM,oBAAoB,GAC/B,YAAY,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,YACmB,CAAC;AAErE;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,cAAc,GACzB,OAAO,MAAM,EACb,KAAK,MAAM,EACX,IAAI,YAAY,EAChB,OAAO,MAAM,EACb,OAAO,MAAM,EACb,SAAS,oBAAoB,KAC5B,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IA2BrB,CAAC;AA2BF,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,UAAU,IAAI;IAC7D,gDAAgD;IAChD,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,gEAAgE;IAChE,UAAU,EAAE,CAAC,EAAE,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,mCAAmC,GAC9C,OAAO,aAAa,CAAC,UAAU,CAAC,EAAE,EAClC,MAAM,cAAc,EACpB,IAAI,YAAY,EAChB,OAAO,MAAM,EACb,OAAO,MAAM,EACb,SAAS,MAAM,EACf,SAAS,oBAAoB,KAC5B,0BAA0B,CAAC,aAAa,CAAC,UAAU,CAAC,CAmBtD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kCAAkC,GAAI,CAAC,SAAS,UAAU,EACrE,aAAa,SAAS,CAAC,EAAE,EACzB,MAAM,cAAc,EACpB,IAAI,YAAY,EAChB,OAAO,MAAM,EACb,OAAO,MAAM,EACb,SAAS,MAAM,EACf,SAAS,oBAAoB,KAC5B;IAAE,IAAI,EAAE,CAAC,EAAE,CAAA;CAAE,GAAG,0BAA0B,CAAC,CAAC,CAsB9C,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qCAAqC,GAChD,eAAe,aAAa,CAAC,kBAAkB,CAAC,EAChD,MAAM,cAAc,EACpB,IAAI,YAAY,EAChB,OAAO,MAAM,EACb,OAAO,MAAM,KACZ,OAiDF,CAAC"}