@rowsncolumns/spreadsheet 10.2.74 → 10.2.76

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 (280) hide show
  1. package/dist/cjs/api/excel-validation-kinds.d.ts +71 -0
  2. package/dist/cjs/api/excel-validation-kinds.d.ts.map +1 -0
  3. package/dist/cjs/api/excel-validation-kinds.js +304 -0
  4. package/dist/cjs/api/fill-series.d.ts +38 -0
  5. package/dist/cjs/api/fill-series.d.ts.map +1 -0
  6. package/dist/cjs/api/fill-series.js +89 -0
  7. package/dist/cjs/api/go-to-special.d.ts +32 -0
  8. package/dist/cjs/api/go-to-special.d.ts.map +1 -0
  9. package/dist/cjs/api/go-to-special.js +111 -0
  10. package/dist/cjs/api/spreadsheet-api.d.ts +6 -2
  11. package/dist/cjs/api/spreadsheet-api.d.ts.map +1 -1
  12. package/dist/cjs/api/spreadsheet-api.js +9 -3
  13. package/dist/cjs/api/validation-tooltip.d.ts +17 -0
  14. package/dist/cjs/api/validation-tooltip.d.ts.map +1 -0
  15. package/dist/cjs/api/validation-tooltip.js +42 -0
  16. package/dist/cjs/atoms/advanced-filter-dialog.atom.d.ts +28 -0
  17. package/dist/cjs/atoms/advanced-filter-dialog.atom.d.ts.map +1 -0
  18. package/dist/cjs/atoms/advanced-filter-dialog.atom.js +32 -0
  19. package/dist/cjs/atoms/fill-options.atom.d.ts +36 -0
  20. package/dist/cjs/atoms/fill-options.atom.d.ts.map +1 -0
  21. package/dist/cjs/atoms/fill-options.atom.js +11 -0
  22. package/dist/cjs/atoms/fill-series-dialog.atom.d.ts +26 -0
  23. package/dist/cjs/atoms/fill-series-dialog.atom.d.ts.map +1 -0
  24. package/dist/cjs/atoms/fill-series-dialog.atom.js +14 -0
  25. package/dist/cjs/atoms/go-to-dialog.atom.d.ts +11 -1
  26. package/dist/cjs/atoms/go-to-dialog.atom.d.ts.map +1 -1
  27. package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts +29 -0
  28. package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts.map +1 -0
  29. package/dist/cjs/atoms/goal-seek-dialog.atom.js +30 -0
  30. package/dist/cjs/atoms/index.d.ts +3 -0
  31. package/dist/cjs/atoms/index.d.ts.map +1 -1
  32. package/dist/cjs/atoms/index.js +3 -0
  33. package/dist/cjs/atoms/subtotal-dialog.atom.d.ts +39 -0
  34. package/dist/cjs/atoms/subtotal-dialog.atom.d.ts.map +1 -0
  35. package/dist/cjs/atoms/subtotal-dialog.atom.js +30 -0
  36. package/dist/cjs/atoms/text-to-columns-dialog.atom.d.ts +34 -0
  37. package/dist/cjs/atoms/text-to-columns-dialog.atom.d.ts.map +1 -0
  38. package/dist/cjs/atoms/text-to-columns-dialog.atom.js +36 -0
  39. package/dist/cjs/atoms/watch-window.atom.d.ts +37 -0
  40. package/dist/cjs/atoms/watch-window.atom.d.ts.map +1 -0
  41. package/dist/cjs/atoms/watch-window.atom.js +61 -0
  42. package/dist/cjs/components/advanced-filter-dialog/index.d.ts +28 -0
  43. package/dist/cjs/components/advanced-filter-dialog/index.d.ts.map +1 -0
  44. package/dist/cjs/components/advanced-filter-dialog/index.js +134 -0
  45. package/dist/cjs/components/calculation-options-dialog/index.d.ts +33 -0
  46. package/dist/cjs/components/calculation-options-dialog/index.d.ts.map +1 -0
  47. package/dist/cjs/components/calculation-options-dialog/index.js +69 -0
  48. package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
  49. package/dist/cjs/components/canvas-grid/index.js +328 -71
  50. package/dist/cjs/components/canvas-grid/typings.d.ts +31 -5
  51. package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
  52. package/dist/cjs/components/cell/alignment.d.ts +30 -0
  53. package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
  54. package/dist/cjs/components/cell/alignment.js +56 -1
  55. package/dist/cjs/components/cell/index.d.ts.map +1 -1
  56. package/dist/cjs/components/cell/index.js +15 -7
  57. package/dist/cjs/components/cell-diff/index.d.ts +3 -2
  58. package/dist/cjs/components/cell-diff/index.d.ts.map +1 -1
  59. package/dist/cjs/components/cell-editor/helpers.d.ts +9 -0
  60. package/dist/cjs/components/cell-editor/helpers.d.ts.map +1 -1
  61. package/dist/cjs/components/cell-editor/helpers.js +8 -1
  62. package/dist/cjs/components/cell-editor/helpers.spec.js +14 -0
  63. package/dist/cjs/components/cell-editor/index.d.ts.map +1 -1
  64. package/dist/cjs/components/cell-editor/index.js +7 -3
  65. package/dist/cjs/components/context-menu/index.d.ts +6 -1
  66. package/dist/cjs/components/context-menu/index.d.ts.map +1 -1
  67. package/dist/cjs/components/context-menu/index.js +146 -3
  68. package/dist/cjs/components/embeds/embed-component.d.ts.map +1 -1
  69. package/dist/cjs/components/embeds/embed-component.js +16 -1
  70. package/dist/cjs/components/fill-series-dialog/index.d.ts +29 -0
  71. package/dist/cjs/components/fill-series-dialog/index.d.ts.map +1 -0
  72. package/dist/cjs/components/fill-series-dialog/index.js +156 -0
  73. package/dist/cjs/components/go-to-dialog/index.d.ts +11 -1
  74. package/dist/cjs/components/go-to-dialog/index.d.ts.map +1 -1
  75. package/dist/cjs/components/go-to-dialog/index.js +67 -24
  76. package/dist/cjs/components/goal-seek-dialog/index.d.ts +32 -0
  77. package/dist/cjs/components/goal-seek-dialog/index.d.ts.map +1 -0
  78. package/dist/cjs/components/goal-seek-dialog/index.js +149 -0
  79. package/dist/cjs/components/selection/fill-options-menu.d.ts +32 -0
  80. package/dist/cjs/components/selection/fill-options-menu.d.ts.map +1 -0
  81. package/dist/cjs/components/selection/fill-options-menu.js +65 -0
  82. package/dist/cjs/components/selection/index.d.ts +1 -1
  83. package/dist/cjs/components/selection/index.d.ts.map +1 -1
  84. package/dist/cjs/components/selection/index.js +4 -2
  85. package/dist/cjs/components/selection/types.d.ts +11 -1
  86. package/dist/cjs/components/selection/types.d.ts.map +1 -1
  87. package/dist/cjs/components/subtotal-dialog/index.d.ts +30 -0
  88. package/dist/cjs/components/subtotal-dialog/index.d.ts.map +1 -0
  89. package/dist/cjs/components/subtotal-dialog/index.js +126 -0
  90. package/dist/cjs/components/text-to-columns-dialog/index.d.ts +37 -0
  91. package/dist/cjs/components/text-to-columns-dialog/index.d.ts.map +1 -0
  92. package/dist/cjs/components/text-to-columns-dialog/index.js +166 -0
  93. package/dist/cjs/components/toolbar/background-color-selector.d.ts +13 -1
  94. package/dist/cjs/components/toolbar/background-color-selector.d.ts.map +1 -1
  95. package/dist/cjs/components/toolbar/background-color-selector.js +57 -11
  96. package/dist/cjs/components/toolbar/cell-style-selector.d.ts +15 -2
  97. package/dist/cjs/components/toolbar/cell-style-selector.d.ts.map +1 -1
  98. package/dist/cjs/components/toolbar/cell-style-selector.js +56 -3
  99. package/dist/cjs/components/toolbar/fill-selectors.d.ts +49 -0
  100. package/dist/cjs/components/toolbar/fill-selectors.d.ts.map +1 -0
  101. package/dist/cjs/components/toolbar/fill-selectors.js +196 -0
  102. package/dist/cjs/components/toolbar/index.d.ts +1 -0
  103. package/dist/cjs/components/toolbar/index.d.ts.map +1 -1
  104. package/dist/cjs/components/toolbar/index.js +1 -0
  105. package/dist/cjs/components/toolbar/text-format-selector.d.ts +9 -0
  106. package/dist/cjs/components/toolbar/text-format-selector.d.ts.map +1 -1
  107. package/dist/cjs/components/toolbar/text-format-selector.js +15 -3
  108. package/dist/cjs/components/toolbar/text-horizontal-align-selector.d.ts +8 -0
  109. package/dist/cjs/components/toolbar/text-horizontal-align-selector.d.ts.map +1 -1
  110. package/dist/cjs/components/toolbar/text-horizontal-align-selector.js +23 -4
  111. package/dist/cjs/components/watch-window/index.d.ts +25 -0
  112. package/dist/cjs/components/watch-window/index.d.ts.map +1 -0
  113. package/dist/cjs/components/watch-window/index.js +63 -0
  114. package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
  115. package/dist/cjs/hooks/use-cell-renderer.js +17 -6
  116. package/dist/cjs/hooks/use-editable.d.ts +11 -2
  117. package/dist/cjs/hooks/use-editable.d.ts.map +1 -1
  118. package/dist/cjs/hooks/use-editable.js +8 -0
  119. package/dist/cjs/hooks/use-editor-submit.d.ts +32 -3
  120. package/dist/cjs/hooks/use-editor-submit.d.ts.map +1 -1
  121. package/dist/cjs/hooks/use-editor-submit.js +111 -2
  122. package/dist/cjs/hooks/use-get-tooltip.d.ts.map +1 -1
  123. package/dist/cjs/hooks/use-get-tooltip.js +7 -2
  124. package/dist/cjs/hooks/use-keyboard-handler.d.ts.map +1 -1
  125. package/dist/cjs/hooks/use-keyboard-handler.js +27 -14
  126. package/dist/cjs/hooks/use-selection-renderer.d.ts +13 -2
  127. package/dist/cjs/hooks/use-selection-renderer.d.ts.map +1 -1
  128. package/dist/cjs/hooks/use-selection-renderer.js +21 -4
  129. package/dist/cjs/hooks/use-selection.d.ts +54 -4
  130. package/dist/cjs/hooks/use-selection.d.ts.map +1 -1
  131. package/dist/cjs/hooks/use-selection.js +232 -37
  132. package/dist/cjs/index.d.ts +12 -0
  133. package/dist/cjs/index.d.ts.map +1 -1
  134. package/dist/cjs/index.js +11 -0
  135. package/dist/cjs/release-date.js +1 -1
  136. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  137. package/dist/cjs/types.d.ts +156 -5
  138. package/dist/cjs/types.d.ts.map +1 -1
  139. package/dist/cjs/types.js +19 -1
  140. package/dist/esm/api/excel-validation-kinds.d.ts +71 -0
  141. package/dist/esm/api/excel-validation-kinds.d.ts.map +1 -0
  142. package/dist/esm/api/excel-validation-kinds.js +287 -0
  143. package/dist/esm/api/fill-series.d.ts +38 -0
  144. package/dist/esm/api/fill-series.d.ts.map +1 -0
  145. package/dist/esm/api/fill-series.js +78 -0
  146. package/dist/esm/api/go-to-special.d.ts +32 -0
  147. package/dist/esm/api/go-to-special.d.ts.map +1 -0
  148. package/dist/esm/api/go-to-special.js +96 -0
  149. package/dist/esm/api/spreadsheet-api.d.ts +6 -2
  150. package/dist/esm/api/spreadsheet-api.d.ts.map +1 -1
  151. package/dist/esm/api/spreadsheet-api.js +8 -3
  152. package/dist/esm/api/validation-tooltip.d.ts +17 -0
  153. package/dist/esm/api/validation-tooltip.d.ts.map +1 -0
  154. package/dist/esm/api/validation-tooltip.js +34 -0
  155. package/dist/esm/atoms/advanced-filter-dialog.atom.d.ts +28 -0
  156. package/dist/esm/atoms/advanced-filter-dialog.atom.d.ts.map +1 -0
  157. package/dist/esm/atoms/advanced-filter-dialog.atom.js +21 -0
  158. package/dist/esm/atoms/fill-options.atom.d.ts +36 -0
  159. package/dist/esm/atoms/fill-options.atom.d.ts.map +1 -0
  160. package/dist/esm/atoms/fill-options.atom.js +5 -0
  161. package/dist/esm/atoms/fill-series-dialog.atom.d.ts +26 -0
  162. package/dist/esm/atoms/fill-series-dialog.atom.d.ts.map +1 -0
  163. package/dist/esm/atoms/fill-series-dialog.atom.js +9 -0
  164. package/dist/esm/atoms/go-to-dialog.atom.d.ts +11 -1
  165. package/dist/esm/atoms/go-to-dialog.atom.d.ts.map +1 -1
  166. package/dist/esm/atoms/goal-seek-dialog.atom.d.ts +29 -0
  167. package/dist/esm/atoms/goal-seek-dialog.atom.d.ts.map +1 -0
  168. package/dist/esm/atoms/goal-seek-dialog.atom.js +21 -0
  169. package/dist/esm/atoms/index.d.ts +3 -0
  170. package/dist/esm/atoms/index.d.ts.map +1 -1
  171. package/dist/esm/atoms/index.js +3 -0
  172. package/dist/esm/atoms/subtotal-dialog.atom.d.ts +39 -0
  173. package/dist/esm/atoms/subtotal-dialog.atom.d.ts.map +1 -0
  174. package/dist/esm/atoms/subtotal-dialog.atom.js +21 -0
  175. package/dist/esm/atoms/text-to-columns-dialog.atom.d.ts +34 -0
  176. package/dist/esm/atoms/text-to-columns-dialog.atom.d.ts.map +1 -0
  177. package/dist/esm/atoms/text-to-columns-dialog.atom.js +25 -0
  178. package/dist/esm/atoms/watch-window.atom.d.ts +37 -0
  179. package/dist/esm/atoms/watch-window.atom.d.ts.map +1 -0
  180. package/dist/esm/atoms/watch-window.atom.js +37 -0
  181. package/dist/esm/components/advanced-filter-dialog/index.d.ts +28 -0
  182. package/dist/esm/components/advanced-filter-dialog/index.d.ts.map +1 -0
  183. package/dist/esm/components/advanced-filter-dialog/index.js +125 -0
  184. package/dist/esm/components/calculation-options-dialog/index.d.ts +33 -0
  185. package/dist/esm/components/calculation-options-dialog/index.d.ts.map +1 -0
  186. package/dist/esm/components/calculation-options-dialog/index.js +61 -0
  187. package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
  188. package/dist/esm/components/canvas-grid/index.js +266 -26
  189. package/dist/esm/components/canvas-grid/typings.d.ts +31 -5
  190. package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
  191. package/dist/esm/components/cell/alignment.d.ts +30 -0
  192. package/dist/esm/components/cell/alignment.d.ts.map +1 -1
  193. package/dist/esm/components/cell/alignment.js +51 -0
  194. package/dist/esm/components/cell/index.d.ts.map +1 -1
  195. package/dist/esm/components/cell/index.js +16 -8
  196. package/dist/esm/components/cell-diff/index.d.ts +3 -2
  197. package/dist/esm/components/cell-diff/index.d.ts.map +1 -1
  198. package/dist/esm/components/cell-editor/helpers.d.ts +9 -0
  199. package/dist/esm/components/cell-editor/helpers.d.ts.map +1 -1
  200. package/dist/esm/components/cell-editor/helpers.js +6 -0
  201. package/dist/esm/components/cell-editor/helpers.spec.js +15 -1
  202. package/dist/esm/components/cell-editor/index.d.ts.map +1 -1
  203. package/dist/esm/components/cell-editor/index.js +8 -4
  204. package/dist/esm/components/context-menu/index.d.ts +6 -1
  205. package/dist/esm/components/context-menu/index.d.ts.map +1 -1
  206. package/dist/esm/components/context-menu/index.js +139 -4
  207. package/dist/esm/components/embeds/embed-component.d.ts.map +1 -1
  208. package/dist/esm/components/embeds/embed-component.js +17 -1
  209. package/dist/esm/components/fill-series-dialog/index.d.ts +29 -0
  210. package/dist/esm/components/fill-series-dialog/index.d.ts.map +1 -0
  211. package/dist/esm/components/fill-series-dialog/index.js +151 -0
  212. package/dist/esm/components/go-to-dialog/index.d.ts +11 -1
  213. package/dist/esm/components/go-to-dialog/index.d.ts.map +1 -1
  214. package/dist/esm/components/go-to-dialog/index.js +63 -23
  215. package/dist/esm/components/goal-seek-dialog/index.d.ts +32 -0
  216. package/dist/esm/components/goal-seek-dialog/index.d.ts.map +1 -0
  217. package/dist/esm/components/goal-seek-dialog/index.js +125 -0
  218. package/dist/esm/components/selection/fill-options-menu.d.ts +32 -0
  219. package/dist/esm/components/selection/fill-options-menu.d.ts.map +1 -0
  220. package/dist/esm/components/selection/fill-options-menu.js +63 -0
  221. package/dist/esm/components/selection/index.d.ts +1 -1
  222. package/dist/esm/components/selection/index.d.ts.map +1 -1
  223. package/dist/esm/components/selection/index.js +4 -2
  224. package/dist/esm/components/selection/types.d.ts +11 -1
  225. package/dist/esm/components/selection/types.d.ts.map +1 -1
  226. package/dist/esm/components/subtotal-dialog/index.d.ts +30 -0
  227. package/dist/esm/components/subtotal-dialog/index.d.ts.map +1 -0
  228. package/dist/esm/components/subtotal-dialog/index.js +115 -0
  229. package/dist/esm/components/text-to-columns-dialog/index.d.ts +37 -0
  230. package/dist/esm/components/text-to-columns-dialog/index.d.ts.map +1 -0
  231. package/dist/esm/components/text-to-columns-dialog/index.js +147 -0
  232. package/dist/esm/components/toolbar/background-color-selector.d.ts +13 -1
  233. package/dist/esm/components/toolbar/background-color-selector.d.ts.map +1 -1
  234. package/dist/esm/components/toolbar/background-color-selector.js +61 -11
  235. package/dist/esm/components/toolbar/cell-style-selector.d.ts +15 -2
  236. package/dist/esm/components/toolbar/cell-style-selector.d.ts.map +1 -1
  237. package/dist/esm/components/toolbar/cell-style-selector.js +46 -2
  238. package/dist/esm/components/toolbar/fill-selectors.d.ts +49 -0
  239. package/dist/esm/components/toolbar/fill-selectors.d.ts.map +1 -0
  240. package/dist/esm/components/toolbar/fill-selectors.js +162 -0
  241. package/dist/esm/components/toolbar/index.d.ts +1 -0
  242. package/dist/esm/components/toolbar/index.d.ts.map +1 -1
  243. package/dist/esm/components/toolbar/index.js +1 -0
  244. package/dist/esm/components/toolbar/text-format-selector.d.ts +9 -0
  245. package/dist/esm/components/toolbar/text-format-selector.d.ts.map +1 -1
  246. package/dist/esm/components/toolbar/text-format-selector.js +14 -2
  247. package/dist/esm/components/toolbar/text-horizontal-align-selector.d.ts +8 -0
  248. package/dist/esm/components/toolbar/text-horizontal-align-selector.d.ts.map +1 -1
  249. package/dist/esm/components/toolbar/text-horizontal-align-selector.js +21 -5
  250. package/dist/esm/components/watch-window/index.d.ts +25 -0
  251. package/dist/esm/components/watch-window/index.d.ts.map +1 -0
  252. package/dist/esm/components/watch-window/index.js +54 -0
  253. package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
  254. package/dist/esm/hooks/use-cell-renderer.js +17 -6
  255. package/dist/esm/hooks/use-editable.d.ts +11 -2
  256. package/dist/esm/hooks/use-editable.d.ts.map +1 -1
  257. package/dist/esm/hooks/use-editable.js +8 -0
  258. package/dist/esm/hooks/use-editor-submit.d.ts +32 -3
  259. package/dist/esm/hooks/use-editor-submit.d.ts.map +1 -1
  260. package/dist/esm/hooks/use-editor-submit.js +82 -3
  261. package/dist/esm/hooks/use-get-tooltip.d.ts.map +1 -1
  262. package/dist/esm/hooks/use-get-tooltip.js +7 -2
  263. package/dist/esm/hooks/use-keyboard-handler.d.ts.map +1 -1
  264. package/dist/esm/hooks/use-keyboard-handler.js +27 -14
  265. package/dist/esm/hooks/use-selection-renderer.d.ts +13 -2
  266. package/dist/esm/hooks/use-selection-renderer.d.ts.map +1 -1
  267. package/dist/esm/hooks/use-selection-renderer.js +22 -5
  268. package/dist/esm/hooks/use-selection.d.ts +54 -4
  269. package/dist/esm/hooks/use-selection.d.ts.map +1 -1
  270. package/dist/esm/hooks/use-selection.js +220 -36
  271. package/dist/esm/index.d.ts +12 -0
  272. package/dist/esm/index.d.ts.map +1 -1
  273. package/dist/esm/index.js +11 -0
  274. package/dist/esm/release-date.js +1 -1
  275. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  276. package/dist/esm/types.d.ts +156 -5
  277. package/dist/esm/types.d.ts.map +1 -1
  278. package/dist/esm/types.js +18 -0
  279. package/dist/spreadsheet.min.css +1 -1
  280. package/package.json +7 -7
@@ -1,5 +1,5 @@
1
1
  import { tokenize as defaultFormulaTokenizer } from "@rowsncolumns/calculator";
2
- import { Direction, isAreasEqual } from "@rowsncolumns/grid";
2
+ import { cellToArea, Direction, isAreasEqual } from "@rowsncolumns/grid";
3
3
  import { canUseDOM } from "@rowsncolumns/grid";
4
4
  import { getBoundedCells, MouseButtonCodes } from "@rowsncolumns/grid";
5
5
  import { isCellWithinBounds } from "@rowsncolumns/grid";
@@ -10,15 +10,19 @@ import { cellToAddress, getCellEffectiveFormat, getContrastColor, isConditionalF
10
10
  import { useStore } from "jotai";
11
11
  import merge from "lodash/merge";
12
12
  import throttle from "lodash/throttle";
13
- import React, { forwardRef, memo, startTransition, useCallback, useMemo, useRef, useState, } from "react";
13
+ import React, { forwardRef, memo, startTransition, useCallback, useEffect, useMemo, useRef, useState, } from "react";
14
14
  import { getBandedCells } from "../../api/banded-ranges";
15
15
  import { CF_INITIAL_WINDOW, cfWindowForViewport, isSameCfWindow, } from "../../api/cf-window";
16
16
  import { generateSelectionsFromFormula } from "../../api/selections";
17
17
  import { SpreadsheetApi } from "../../api/spreadsheet-api";
18
18
  import { findActiveTableWithinCell } from "../../api/table";
19
+ import { getDataValidationTooltipContent } from "../../api/validation-tooltip";
20
+ import { resolveGoToSpecial } from "../../api/go-to-special";
21
+ import { checkExcelValidationValue, isFormulaEntry, } from "../../api/excel-validation-kinds";
19
22
  import { checkBooleanRule, decideValidationCommit, isCellLockedUnderProtection, isProtectedCell, isProtectedSheet, showValidationDropdownArrow, } from "../../api/validation";
20
- import { useFormulaModeValue, useIsEvaluateFormulaDialogMounted, useIsGoToDialogMounted, useIsPasteSpecialDialogMounted, useOpenEvaluateFormulaDialog, useOpenGoToDialog, useOpenPasteSpecialDialog, useSetNoteEditorCell, useSetPinnedTooltip, useShowPasteMenu, useShowValidationAlert, } from "../../atoms";
23
+ import { useFormulaModeValue, useIsEvaluateFormulaDialogMounted, useIsGoToDialogMounted, useIsPasteSpecialDialogMounted, useOpenEvaluateFormulaDialog, useOpenGoToDialog, useOpenPasteSpecialDialog, useSetNoteEditorCell, useSetPinnedTooltip, useFillOptionsState, useOpenFillSeriesDialog, useShowPasteMenu, useShowValidationAlert, } from "../../atoms";
21
24
  import { useActiveEditor } from "../../atoms/active-editor.atom";
25
+ import { useAddWatch, useIsWatchWindowMounted, useSetWatchWindowContext, } from "../../atoms/watch-window.atom";
22
26
  import { useEditingCell } from "../../atoms/editing-cell.atom";
23
27
  import { useCellEditorInstance, useSetFormulabarEditorValue, useSetFormulaBarTextFormatRuns, } from "../../atoms/formula-bar-editor-value.atom";
24
28
  import { useFormulaCanSelectCells, useFormulaSelectionMode, useSetFormulaSelectionState, } from "../../atoms/formula-selection-state.atom";
@@ -65,7 +69,7 @@ import { useRaf } from "../../hooks/use-raf";
65
69
  import { useResizeObserver } from "../../hooks/use-resize-observer";
66
70
  import { useScaleListener } from "../../hooks/use-scale-listener";
67
71
  import { useSelectedRowsColumns } from "../../hooks/use-selected-rows-columns";
68
- import { useSelection } from "../../hooks/use-selection";
72
+ import { useSelection, } from "../../hooks/use-selection";
69
73
  import { useSelectionChange } from "../../hooks/use-selection-change";
70
74
  import { useSelectionInterceptors } from "../../hooks/use-selection-interceptors";
71
75
  import { useSelectionMove } from "../../hooks/use-selection-move";
@@ -82,6 +86,7 @@ import { useTouch } from "../../hooks/use-touch";
82
86
  import { multiInstanceStore } from "../../providers/spreadsheet-provider";
83
87
  import { scrollSubscriber } from "../../signals/scroll-subscriber";
84
88
  import { getStringifiedColor } from "../../themes";
89
+ import { fillRangeForSeriesSpec, seedRangeForSeriesSpec } from "../../api/fill-series";
85
90
  import { Cell as DefaultCell } from "../cell";
86
91
  import { CellEditor as DefaultCellEditor } from "../cell-editor";
87
92
  import { ContextMenu as DefaultContextMenu } from "../context-menu";
@@ -100,7 +105,7 @@ import { getNestedPropertyNames } from "./helpers";
100
105
  * @returns
101
106
  */
102
107
  function CanvasGridComponent(props, forwardedRef) {
103
- const { licenseKey, sheetId, instanceId, activeCell = DEFAULT_ACTIVE_CELL, selections = DEFAULT_ARRAY, frozenColumnCount = 0, frozenRowCount = 0, rowCount = DEFAULT_ROW_COUNT, columnCount = DEFAULT_COLUMN_COUNT, autoFocus, basicFilter, tables, namedRanges, bandedRanges = DEFAULT_ARRAY, tableBorderColor = "#008000", filterIconColor = "#008000", conditionalFormats, showFilterIcon = true, showCalculatedColumnIcon = true, showHeaders = true, defaultColumnWidth = DEFAULT_COLUMN_WIDTH, defaultRowHeight = DEFAULT_ROW_HEIGHT, columnHeaderHeight = COLUMN_HEADER_HEIGHT, rowHeaderWidth = ROW_HEADER_WIDTH, gridLineColor = GRIDLINE_COLOR, cellBackgroundColor = DEFAULT_CELL_BACKGROUND_COLOR, cellColor = DEFAULT_CELL_COLOR, headerBorderColor = DEFAULT_HEADER_BORDER_COLOR, headerBackgroundColor = DEFAULT_HEADER_BG, headerColor = DEFAULT_HEADER_COLOR, headerActiveBackgroundColor = DEFAULT_HEADER_ACTIVE_BG, headerSelectedBackgroundColor = DEFAULT_HEADER_SELECTED_BG, headerSelectedColor = "white", headerTableBackgroundColor = DEFAULT_HEADER_TABLE_BG, headerTableActiveBackgroundColor = DEFAULT_HEADER_ACTIVE_TABLE_BG, headerTableSelectedBackgroundColor = DEFAULT_HEADER_SELECTED_TABLE_BG, frozenShadowColor = headerBorderColor, frozenShadowThickness = 1, selectionBackgroundColor = SELECTION_BG, selectionBorderColor = SELECTION_BORDER, selectionDragBorderColor = SELECTION_BORDER, chartSelectedColor, chipBackgroundColor = CHIP_COLOR, merges = DEFAULT_ARRAY, borderStyles, protectedRanges, isWorkbookProtected: isWorkbookProtectedProp = false, getSheetProtection, pivotTables, charts, embeds, slicers, rowMetadata = DEFAULT_ARRAY, columnMetadata = DEFAULT_ARRAY, scale = 1, zoomSpeed = 1, overscanCount = 3, enableEditOnEnterKey = true, enableTextOverflow = true, showGridLines: _showGridLines, showFormulas = false, protectFormulas = false, showFrozenSeparator = true, HeaderCell = DefaultHeaderCell, Cell = DefaultCell, SelectionTitleComponent = SelectionTitle, CellEditor = DefaultCellEditor, CellTooltip, ContextMenu = DefaultContextMenu, ContextMenuWrapper = DefaultContextMenuWrapper, FilterBox = DefaultFilterBox, HeaderMoveDragComponent = DefaultHeaderMoveDragComponent, SuggestionsDropdown, stickyEditor = true, scrollSnap = false, scrollThrottleTimeout, preventBrowserDefaultScroll, mouseMoveThrottleTimeout = 60, tooltipIntentInterval = 60, selectionPolicy, users, userId, renderCollaboratorCursor, functionDescriptions, showHeaderMenuButton = true, scrollbarSize = SCROLLBAR_SIZE, theme = defaultSpreadsheetTheme, showNotes = true, showComments = true, locale, agentSuggestions, onReviewSuggestion, onShowFormulas, getDataRowCount, getChartComponent, getEmbedComponent, getSlicerComponent, onChange, onChangeBatch, onExpandCollapse, onPivotDrillDown, onDelete, onChangeEditorValue, onFill, onRequestCalculate, onChangeActiveCell, onChangeActiveSheet, onChangeSelections, getSheetName, getSheetId, getCellData, getNote: getNoteProp, getTextFormatRuns, getDataValidation, getEffectiveFormat, getFormattedValue: getFormattedValueProp, getTooltipContent, errorResolutionComponent, getEffectiveValue: getEffectiveValueProp, getUserEnteredExtendedValue, getEffectiveExtendedValue, getSheetRowCount, getSheetColumnCount, getCellPopoverContent, onScroll, onViewPortChange, windowConditionalFormats = false, engineConditionalFormatResults = false, onResize, onAutoResize, onHideColumn, onHideRow, onShowColumn, onShowRow, onGroupRows, onUngroupRows, onCollapseRowGroup, onExpandRowGroup, onGroupColumns, onUngroupColumns, onCollapseColumnGroup, onExpandColumnGroup, onSetOutlineDepth, onDeleteRow, onDeleteColumn, onInsertRow, onInsertColumn, onInsertCellsShiftDown, onInsertCellsShiftRight, onDeleteCellsShiftLeft, onDeleteCellsShiftUp, onClearContents, onMoveColumns, onMoveRows, onSelectNextSheet, onSelectPreviousSheet, onCreateNewSheet, onKeyDown, onChangeFormatting, onRepeatFormatting, onClearFormatting, onRequestEditProtectedRange, onMoveChart, onResizeChart, onDeleteChart, onMoveEmbed, onResizeEmbed, onDeleteEmbed, onRequestEditEmbed, onMoveSlicer, onResizeSlicer, onDeleteSlicer, onRequestEditSlicer, onFillRange, disableFillRightShortcut, keymap, onCalculateNow, onRequestGoTo, onMoveSelection, onInsertTime, onInsertDate, onInsertDateTime, onInsertAutoSum, onUndo, onRedo, onPaste, onCopy, onCut, onSortColumn, onSortTable, onFilterTable, onFilterPivot, onResizeTable, onRequestEditTable, onRequestEditPivotTable, onRequestDeletePivotTable, onRemoveTable, onCreateTable, onInsertTableColumn, onDeleteTableColumn, onInsertTableRow, onDeleteTableRow, onCreateBasicFilter, onRequestDefineNamedRange, onRequestFormatCells, onRequestConditionalFormat, onRequestDataValidation, onRequestInsertComment, onRequestInsertLink, onFreezeColumn, onFreezeRow, onUpdateNote, onProtectRange, onUnProtectRange, onSortRange, onRequestSearch, onRequestReplace, onRequestResize, getRowHeaderText = getDefaultRowHeader, getColumnHeaderText = getDefaultColumnHeader, getAdditionalCellSpacing, tokenizer: defaultTokenizer = defaultFormulaTokenizer, onChangeScale, onRemoveLink, onSelectLink, onSplitTextToColumns, onRemoveDuplicates, onRequestExpand, cellExpandPredicate, StructuredResult = DefaultStructuredResult, getMentions, getStructuredProperties: getStructuredPropertiesProp, getFunctionParameterSuggestions, shouldFetchFunctionParameters, MentionTagComponent, MentionDropdownItemComponent, showSelectionResizeHandles = true, enableMagicFill, enableQuickEdit = true, MagicFillComponent, MagicFillContent, QuickEdit, PasteMenu, SuggestionAction, HiddenRowMarkers, HiddenColumnMarkers, enableResizerOverflow, className, defaultFontSizePoint = DEFAULT_FONT_SIZE_PT, readonly, isComparing = false, getCellDiff, enableDataBoundaryNavigation, footerHeight, footerComponent, arrowComponents,
108
+ const { licenseKey, sheetId, instanceId, activeCell = DEFAULT_ACTIVE_CELL, selections = DEFAULT_ARRAY, frozenColumnCount = 0, frozenRowCount = 0, rowCount = DEFAULT_ROW_COUNT, columnCount = DEFAULT_COLUMN_COUNT, autoFocus, basicFilter, tables, namedRanges, bandedRanges = DEFAULT_ARRAY, tableBorderColor = "#008000", filterIconColor = "#008000", conditionalFormats, showFilterIcon = true, showCalculatedColumnIcon = true, showHeaders = true, defaultColumnWidth = DEFAULT_COLUMN_WIDTH, defaultRowHeight = DEFAULT_ROW_HEIGHT, columnHeaderHeight = COLUMN_HEADER_HEIGHT, rowHeaderWidth = ROW_HEADER_WIDTH, gridLineColor = GRIDLINE_COLOR, cellBackgroundColor = DEFAULT_CELL_BACKGROUND_COLOR, cellColor = DEFAULT_CELL_COLOR, headerBorderColor = DEFAULT_HEADER_BORDER_COLOR, headerBackgroundColor = DEFAULT_HEADER_BG, headerColor = DEFAULT_HEADER_COLOR, headerActiveBackgroundColor = DEFAULT_HEADER_ACTIVE_BG, headerSelectedBackgroundColor = DEFAULT_HEADER_SELECTED_BG, headerSelectedColor = "white", headerTableBackgroundColor = DEFAULT_HEADER_TABLE_BG, headerTableActiveBackgroundColor = DEFAULT_HEADER_ACTIVE_TABLE_BG, headerTableSelectedBackgroundColor = DEFAULT_HEADER_SELECTED_TABLE_BG, frozenShadowColor = headerBorderColor, frozenShadowThickness = 1, selectionBackgroundColor = SELECTION_BG, selectionBorderColor = SELECTION_BORDER, selectionDragBorderColor = SELECTION_BORDER, chartSelectedColor, chipBackgroundColor = CHIP_COLOR, merges = DEFAULT_ARRAY, borderStyles, protectedRanges, isWorkbookProtected: isWorkbookProtectedProp = false, getSheetProtection, pivotTables, charts, embeds, slicers, rowMetadata = DEFAULT_ARRAY, columnMetadata = DEFAULT_ARRAY, scale = 1, zoomSpeed = 1, overscanCount = 3, enableEditOnEnterKey = true, enableTextOverflow = true, showGridLines: _showGridLines, showFormulas = false, protectFormulas = false, showFrozenSeparator = true, HeaderCell = DefaultHeaderCell, Cell = DefaultCell, SelectionTitleComponent = SelectionTitle, CellEditor = DefaultCellEditor, CellTooltip, ContextMenu = DefaultContextMenu, ContextMenuWrapper = DefaultContextMenuWrapper, FilterBox = DefaultFilterBox, HeaderMoveDragComponent = DefaultHeaderMoveDragComponent, SuggestionsDropdown, stickyEditor = true, scrollSnap = false, scrollThrottleTimeout, preventBrowserDefaultScroll, mouseMoveThrottleTimeout = 60, tooltipIntentInterval = 60, selectionPolicy, users, userId, renderCollaboratorCursor, functionDescriptions, showHeaderMenuButton = true, scrollbarSize = SCROLLBAR_SIZE, theme = defaultSpreadsheetTheme, showNotes = true, showComments = true, locale, agentSuggestions, onReviewSuggestion, onShowFormulas, getDataRowCount, getChartComponent, getEmbedComponent, getSlicerComponent, onChange, onChangeBatch, onExpandCollapse, onPivotDrillDown, onDelete, onChangeEditorValue, onFill, onRequestCalculate, onChangeActiveCell, onChangeActiveSheet, onChangeSelections, getSheetName, getSheetId, getCellData, getNote: getNoteProp, getTextFormatRuns, getDataValidation, getEffectiveFormat, getFormattedValue: getFormattedValueProp, getTooltipContent, errorResolutionComponent, getEffectiveValue: getEffectiveValueProp, getUserEnteredExtendedValue, getEffectiveExtendedValue, getSheetRowCount, getSheetColumnCount, getCellPopoverContent, onScroll, onViewPortChange, windowConditionalFormats = false, engineConditionalFormatResults = false, onResize, onAutoResize, onHideColumn, onHideRow, onShowColumn, onShowRow, onGroupRows, onUngroupRows, onCollapseRowGroup, onExpandRowGroup, onGroupColumns, onUngroupColumns, onCollapseColumnGroup, onExpandColumnGroup, onSetOutlineDepth, onDeleteRow, onDeleteColumn, onInsertRow, onInsertColumn, onInsertCellsShiftDown, onInsertCellsShiftRight, onDeleteCellsShiftLeft, onDeleteCellsShiftUp, onClearContents, onMoveColumns, onMoveRows, onSelectNextSheet, onSelectPreviousSheet, onCreateNewSheet, onKeyDown, onChangeFormatting, onRepeatFormatting, onClearFormatting, onRequestEditProtectedRange, onMoveChart, onResizeChart, onDeleteChart, onMoveEmbed, onResizeEmbed, onDeleteEmbed, onRequestEditEmbed, onMoveSlicer, onResizeSlicer, onDeleteSlicer, onRequestEditSlicer, onFillRange, disableFillRightShortcut, keymap, onCalculateNow, onRequestGoTo, onMoveSelection, onInsertTime, onInsertDate, onInsertDateTime, onInsertAutoSum, onUndo, onRedo, onPaste, onCopy, onCut, onSortColumn, onSortTable, onFilterTable, onFilterPivot, onResizeTable, onRequestEditTable, onRequestEditPivotTable, onRequestDeletePivotTable, onRemoveTable, onCreateTable, onInsertTableColumn, onDeleteTableColumn, onInsertTableRow, onDeleteTableRow, onCreateBasicFilter, onRequestDefineNamedRange, onRequestFormatCells, onRequestConditionalFormat, onRequestDataValidation, onRequestInsertComment, onRequestInsertLink, onFreezeColumn, onFreezeRow, onUpdateNote, onProtectRange, onUnProtectRange, onSortRange, onRequestSearch, onRequestReplace, onRequestResize, getRowHeaderText = getDefaultRowHeader, getColumnHeaderText = getDefaultColumnHeader, getAdditionalCellSpacing, tokenizer: defaultTokenizer = defaultFormulaTokenizer, onChangeScale, onRemoveLink, onSelectLink, onSplitTextToColumns, onRemoveDuplicates, onGoalSeek, onSubtotal, onAdvancedFilter, onRequestExpand, cellExpandPredicate, StructuredResult = DefaultStructuredResult, getMentions, getStructuredProperties: getStructuredPropertiesProp, getFunctionParameterSuggestions, shouldFetchFunctionParameters, MentionTagComponent, MentionDropdownItemComponent, showSelectionResizeHandles = true, enableMagicFill, enableQuickEdit = true, MagicFillComponent, MagicFillContent, QuickEdit, PasteMenu, SuggestionAction, HiddenRowMarkers, HiddenColumnMarkers, enableResizerOverflow, className, defaultFontSizePoint = DEFAULT_FONT_SIZE_PT, readonly, isComparing = false, getCellDiff, enableDataBoundaryNavigation, footerHeight, footerComponent, arrowComponents,
104
109
  // Host-driven filter props. `hostHiddenRowRanges`
105
110
  // supplies compact [start, end] hidden-row tuples; `getFilterValues` supplies a
106
111
  // column's distinct values. Both let a million-row filter render without scanning
@@ -188,6 +193,9 @@ function CanvasGridComponent(props, forwardedRef) {
188
193
  const cellEditorInstance = useCellEditorInstance();
189
194
  // Paste menu
190
195
  const [showPasteMenu, setShowPasteMenu] = useShowPasteMenu();
196
+ // Auto Fill Options smart tag / right-drag fill menu + Series dialog
197
+ const [fillOptions, setFillOptions] = useFillOptionsState();
198
+ const openFillSeriesDialog = useOpenFillSeriesDialog();
191
199
  // Shared state
192
200
  const formulaMode = useFormulaModeValue();
193
201
  const formulaSelections = useFormulaSelections();
@@ -1304,6 +1312,23 @@ function CanvasGridComponent(props, forwardedRef) {
1304
1312
  if (rule.allowBlank && isBlank) {
1305
1313
  return undefined;
1306
1314
  }
1315
+ // A typed formula is validated on its RESULT once the calculator has
1316
+ // run (Excel enters `=5` into a whole-number cell and checks the 5) —
1317
+ // its text can never be decided here, so it stays flag-only.
1318
+ if (isFormulaEntry(value)) {
1319
+ return undefined;
1320
+ }
1321
+ // Excel's Whole number / Time / Text length kinds (authored or imported
1322
+ // with `xlsxSource`) are decided synchronously from the typed text when
1323
+ // their bounds are literals — Excel blocks a decimal in a whole-number
1324
+ // cell at entry, not after a recalc.
1325
+ const excelKindVerdict = checkExcelValidationValue(rule, value);
1326
+ if (excelKindVerdict !== undefined) {
1327
+ const excelDecision = decideValidationCommit(alert, excelKindVerdict);
1328
+ return excelDecision === "proceed"
1329
+ ? undefined
1330
+ : { decision: excelDecision, alert };
1331
+ }
1307
1332
  if (isDataValidationFormulaRule(rule)) {
1308
1333
  // Enforce synchronously only where `checkBooleanRule` can decide the typed
1309
1334
  // value without the calculator: CUSTOM_FORMULA's sync branch is a stub, the
@@ -1841,28 +1866,17 @@ function CanvasGridComponent(props, forwardedRef) {
1841
1866
  * shown in tooltip
1842
1867
  */
1843
1868
  /**
1844
- * Compose host tooltip content with the data-validation input message.
1845
- * Host-provided content wins; otherwise, when the cell is not already showing
1846
- * an error / invalid marker, surface the rule's input message (Excel's
1847
- * "show input message when cell is selected").
1869
+ * Compose host tooltip content with the data-validation messages. Host-
1870
+ * provided content wins; otherwise the rule's input message (Excel's "show
1871
+ * input message when cell is selected") or, on an Invalid cell, the rule's
1872
+ * custom error alert text see `getDataValidationTooltipContent`.
1848
1873
  */
1849
1874
  const getTooltipContentWithValidation = useCallback((tooltipSheetId, rowIndex, columnIndex) => {
1850
1875
  const hostContent = getTooltipContent?.(tooltipSheetId, rowIndex, columnIndex);
1851
1876
  if (hostContent != null) {
1852
1877
  return hostContent;
1853
1878
  }
1854
- const error = getErrorValue(tooltipSheetId, rowIndex, columnIndex);
1855
- if (error?.type === "Error" || error?.type === "Invalid") {
1856
- return undefined;
1857
- }
1858
- const rule = getDataValidationRule(tooltipSheetId, rowIndex, columnIndex);
1859
- const inputMessage = rule?.inputMessage;
1860
- if (!inputMessage || (!inputMessage.title && !inputMessage.message)) {
1861
- return undefined;
1862
- }
1863
- return (React.createElement("div", { className: "bg-rnc-background text-rnc-foreground p-2 shadow-md rounded-md border-l-4 border-solid border-l-blue-700 max-w-[300px] flex flex-col gap-0.5" },
1864
- inputMessage.title ? (React.createElement("div", { className: "font-bold font-system text-sm" }, inputMessage.title)) : null,
1865
- inputMessage.message ? (React.createElement("div", { className: "text-xs font-system whitespace-pre-wrap" }, inputMessage.message)) : null));
1879
+ return getDataValidationTooltipContent(getDataValidationRule(tooltipSheetId, rowIndex, columnIndex), getErrorValue(tooltipSheetId, rowIndex, columnIndex));
1866
1880
  }, [getTooltipContent, getErrorValue, getDataValidationRule]);
1867
1881
  const getTooltip = useGetTooltip({
1868
1882
  sheetId,
@@ -1887,10 +1901,151 @@ function CanvasGridComponent(props, forwardedRef) {
1887
1901
  const dataRegionBoundaries = useMemo(() => tables
1888
1902
  ?.filter((table) => table.sheetId === sheetId)
1889
1903
  .map((table) => table.range), [tables, sheetId]);
1904
+ /**
1905
+ * True when a source cell of a fill is date-formatted — the fill menu then
1906
+ * adds Fill Days / Weekdays / Months / Years (Excel shows them only for
1907
+ * date sources). Reads the cell's own format first, then the effective
1908
+ * (style-plane) format so rnc-backed cells count too.
1909
+ */
1910
+ const sourceHasDates = useCallback((fillSheetId, sources) => {
1911
+ let visited = 0;
1912
+ for (const { range } of sources) {
1913
+ for (let r = range.startRowIndex; r <= range.endRowIndex; r++) {
1914
+ for (let c = range.startColumnIndex; c <= range.endColumnIndex; c++) {
1915
+ // Bounded scan: a whole-column source would otherwise cost a full walk.
1916
+ if (++visited > 256)
1917
+ return false;
1918
+ const uf = getCellData?.(fillSheetId, r, c)?.userEnteredFormat;
1919
+ const type = (uf && "numberFormat" in uf ? uf.numberFormat?.type : undefined) ??
1920
+ getEffectiveFormat?.(fillSheetId, r, c)?.numberFormat?.type;
1921
+ if (type === "DATE" || type === "DATE_TIME")
1922
+ return true;
1923
+ }
1924
+ }
1925
+ }
1926
+ return false;
1927
+ }, [getCellData, getEffectiveFormat]);
1928
+ /**
1929
+ * A fill-handle drag ended: park the gesture so the Auto Fill Options smart
1930
+ * tag (left drag — already filled) or the right-drag fill menu (nothing
1931
+ * filled yet) can re-choose the fill type.
1932
+ */
1933
+ const handleFillHandleRelease = useCallback((release) => {
1934
+ if (readonly)
1935
+ return;
1936
+ setFillOptions({
1937
+ sheetId: release.sheetId,
1938
+ activeCell: release.activeCell,
1939
+ fillSelection: release.fillSelection,
1940
+ selections: release.selections,
1941
+ fillType: undefined,
1942
+ hasDates: sourceHasDates(release.sheetId, release.selections.length
1943
+ ? release.selections
1944
+ : [{ range: cellToArea(release.activeCell) }]),
1945
+ mode: release.button === "right" ? "menu" : "smart-tag",
1946
+ });
1947
+ }, [readonly, setFillOptions, sourceHasDates]);
1948
+ /**
1949
+ * An entry of the fill menu was picked: re-issue the fill from the (still
1950
+ * intact) source with the explicit type. The target is simply overwritten
1951
+ * with the new result — no undo round-trip needed because the source
1952
+ * selection is never touched by a fill.
1953
+ */
1954
+ const handleChooseFillType = useCallback((fillType) => {
1955
+ if (!fillOptions)
1956
+ return;
1957
+ onFill?.(fillOptions.sheetId, fillOptions.activeCell, fillOptions.fillSelection, fillOptions.selections, undefined, fillType);
1958
+ setFillOptions({ ...fillOptions, fillType, mode: "smart-tag" });
1959
+ focusSheet();
1960
+ }, [fillOptions, onFill, setFillOptions, focusSheet]);
1961
+ const handleCloseFillOptions = useCallback(() => {
1962
+ // Only the right-drag menu is "cancel on close"; the smart tag stays.
1963
+ if (fillOptions?.mode === "menu")
1964
+ setFillOptions(null);
1965
+ }, [fillOptions, setFillOptions]);
1966
+ /**
1967
+ * Run Excel's Series dialog result: the target range's first row (Series
1968
+ * in Columns) / first column (Rows) is the seed line; `stop` may shrink or
1969
+ * extend the target along the axis from the seed's last value.
1970
+ */
1971
+ const applyFillSeriesSpec = useCallback((fillSheetId, cell, target, spec) => {
1972
+ const seed = seedRangeForSeriesSpec(target.range, spec);
1973
+ const fillRange = fillRangeForSeriesSpec({
1974
+ target: target.range,
1975
+ seed,
1976
+ spec,
1977
+ getSeedValue: (r, c) => {
1978
+ const value = getEffectiveValue(fillSheetId, r, c);
1979
+ return typeof value === "number" ? value : undefined;
1980
+ },
1981
+ rowCount,
1982
+ columnCount,
1983
+ });
1984
+ if (!fillRange)
1985
+ return;
1986
+ const fillType = spec.type === "linear"
1987
+ ? spec.trend
1988
+ ? "LinearTrend"
1989
+ : "FillSeries"
1990
+ : spec.type === "growth"
1991
+ ? "GrowthTrend"
1992
+ : spec.type === "date"
1993
+ ? spec.dateUnit === "weekday"
1994
+ ? "FillWeekdays"
1995
+ : spec.dateUnit === "month"
1996
+ ? "FillMonths"
1997
+ : spec.dateUnit === "year"
1998
+ ? "FillYears"
1999
+ : "FillDays"
2000
+ : undefined;
2001
+ onFill?.(fillSheetId, cell, { range: fillRange }, [{ ...target, range: seed }], undefined, fillType, { series: spec });
2002
+ onChangeSelections?.(fillSheetId, [{ ...target, range: fillRange }]);
2003
+ }, [getEffectiveValue, onFill, onChangeSelections, rowCount, columnCount]);
2004
+ /** Open the Series dialog for a range (the current selection by default). */
2005
+ const openFillSeriesDialogFor = useCallback((target, initialIn) => {
2006
+ const selection = target ??
2007
+ selections[selections.length - 1] ??
2008
+ { range: cellToArea(activeCell) };
2009
+ openFillSeriesDialog({
2010
+ sheetId,
2011
+ activeCell,
2012
+ selection,
2013
+ initialIn,
2014
+ onApply: (spec) => applyFillSeriesSpec(sheetId, activeCell, selection, spec),
2015
+ });
2016
+ }, [selections, activeCell, sheetId, openFillSeriesDialog, applyFillSeriesSpec]);
2017
+ /** "Series…" on the right-drag fill menu: the drag's target is the range, its axis the default. */
2018
+ const handleOpenFillSeriesDialog = useCallback(() => {
2019
+ if (!fillOptions)
2020
+ return;
2021
+ const { range } = fillOptions.fillSelection;
2022
+ const source = fillOptions.selections[0]?.range;
2023
+ const initialIn = source &&
2024
+ (range.endRowIndex > source.endRowIndex ||
2025
+ range.startRowIndex < source.startRowIndex)
2026
+ ? "columns"
2027
+ : "rows";
2028
+ setFillOptions(null);
2029
+ openFillSeriesDialogFor({ range }, initialIn);
2030
+ }, [fillOptions, setFillOptions, openFillSeriesDialogFor]);
2031
+ // The smart tag belongs to one fill; moving on (a new active cell) drops it.
2032
+ // Keyed on the cell's coordinates, not the object — a re-created `activeCell`
2033
+ // with the same coordinates must not dismiss it.
2034
+ useEffect(() => {
2035
+ setFillOptions(null);
2036
+ }, [activeCell.rowIndex, activeCell.columnIndex, sheetId, setFillOptions]);
2037
+ /**
2038
+ * Fill handle dragged BACK inside the selection (Excel): the dragged-over cells lose their
2039
+ * contents — formats stay unless Ctrl/Cmd was held — through the same `onDelete` path as the
2040
+ * Delete key, so both engines (legacy `useOnDelete`, rnc `delete-cells`) clear identically.
2041
+ */
2042
+ const handleFillShrink = useCallback((sheetId, activeCell, clearRange, options) => {
2043
+ onDelete?.(sheetId, activeCell, [{ range: clearRange }], options?.modifier === "toggle" ? "all" : "contents");
2044
+ }, [onDelete]);
1890
2045
  /**
1891
2046
  * Handle grid selections
1892
2047
  */
1893
- const { onMouseDown: onMouseDownSelection, onPointerDown: onPointerDownSelection, onKeyDown: onKeyDownSelection, fillSelection, onFillHandleMouseDown, onFillHandleDoubleClick, isDragging, isFilling, isSelectionInProgress, draggedSelection, onSelectionMouseDown, setActiveCell, initialDraggedSelection, updateSelectionStartEndReference, selectColumn, getContentfulGridRangeAroundCell, newSelection, modifySelection, clearSelections, } = useSelection({
2048
+ const { onMouseDown: onMouseDownSelection, onPointerDown: onPointerDownSelection, onKeyDown: onKeyDownSelection, fillSelection, fillShrink, onFillHandleMouseDown, onFillHandleDoubleClick, isDragging, isFilling, isSelectionInProgress, draggedSelection, onSelectionMouseDown, setActiveCell, initialDraggedSelection, updateSelectionStartEndReference, selectColumn, getContentfulGridRangeAroundCell, newSelection, modifySelection, clearSelections, } = useSelection({
1894
2049
  sheetId,
1895
2050
  getDataRowCount,
1896
2051
  enableDataBoundaryNavigation,
@@ -1918,6 +2073,8 @@ function CanvasGridComponent(props, forwardedRef) {
1918
2073
  scrollToCell,
1919
2074
  isMergedCell,
1920
2075
  onFill,
2076
+ onFillHandleRelease: handleFillHandleRelease,
2077
+ onFillShrink: handleFillShrink,
1921
2078
  onMoveSelection,
1922
2079
  isHiddenColumn,
1923
2080
  isHiddenRow,
@@ -1991,6 +2148,19 @@ function CanvasGridComponent(props, forwardedRef) {
1991
2148
  getSheetName,
1992
2149
  onRequestCalculate,
1993
2150
  ]);
2151
+ /**
2152
+ * Watch Window: "Add to Watch Window" is offered only while a
2153
+ * `WatchWindowHost` is mounted; the live getters are published below once
2154
+ * `navigateToSheetRange` exists.
2155
+ */
2156
+ const addWatch = useAddWatch();
2157
+ const isWatchWindowMounted = useIsWatchWindowMounted();
2158
+ const setWatchWindowContext = useSetWatchWindowContext();
2159
+ const requestAddWatch = useMemo(() => {
2160
+ if (!isWatchWindowMounted)
2161
+ return undefined;
2162
+ return (watchSheetId, cell) => addWatch({ sheetId: watchSheetId, ...cell });
2163
+ }, [isWatchWindowMounted, addWatch]);
1994
2164
  /**
1995
2165
  * Go To (Ctrl+G / F5). A host `onRequestGoTo` wins; otherwise the built-in
1996
2166
  * dialog opens — but only while a `GoToDialogHost` is mounted, so a host
@@ -2077,6 +2247,8 @@ function CanvasGridComponent(props, forwardedRef) {
2077
2247
  onChange,
2078
2248
  getCommitValidation,
2079
2249
  showValidationAlert,
2250
+ selections,
2251
+ onChangeBatch,
2080
2252
  });
2081
2253
  /**
2082
2254
  * User cancels editing the cell
@@ -2165,7 +2337,7 @@ function CanvasGridComponent(props, forwardedRef) {
2165
2337
  * Get context Menu component
2166
2338
  */
2167
2339
  const getContextMenu = useCallback((cell) => {
2168
- return (React.createElement(ContextMenu, { activeCell: activeCell, selections: selections, sheetId: sheetId, frozenRows: frozenRows, frozenColumns: frozenColumns, onHideColumn: isRestricted ? undefined : onHideColumn, onShowColumn: isRestricted ? undefined : onShowColumn, onShowRow: isRestricted ? undefined : onShowRow, onHideRow: isRestricted ? undefined : onHideRow, onGroupRows: isRestricted ? undefined : onGroupRows, onUngroupRows: isRestricted ? undefined : onUngroupRows, onGroupColumns: isRestricted ? undefined : onGroupColumns, onUngroupColumns: isRestricted ? undefined : onUngroupColumns, isHiddenColumn: isHiddenColumn, isHiddenRow: isHiddenRow, onDeleteColumn: onDeleteColumn, onDeleteRow: onDeleteRow, onInsertRow: onInsertRow, onInsertColumn: onInsertColumn, onInsertCellsShiftDown: onInsertCellsShiftDown, onInsertCellsShiftRight: onInsertCellsShiftRight, onDeleteCellsShiftLeft: onDeleteCellsShiftLeft, onDeleteCellsShiftUp: onDeleteCellsShiftUp, onClearContents: onClearContents, onFreezeColumn: onFreezeColumn, onFreezeRow: onFreezeRow, focusSheet: focusSheet, onSortColumn: onSortColumn, onInsertNote: onInsertNote, onProtectRange: onProtectRange, onUnProtectRange: onUnProtectRange, onSortRange: onSortRange, onRequestDefineNamedRange: onRequestDefineNamedRange, protectedRanges: protectedRanges, isRowHeader: isRowHeader(cell.columnIndex), isColumnHeader: isColumnHeader(cell.rowIndex), selectedRowHeadersIds: selectedRowHeadersIds, selectedColumnHeadersIds: selectedColumnHeadersIds, onCopy: copy, onCut: cut, onPaste: paste, onRequestPasteSpecial: requestPasteSpecial, onRequestEvaluateFormula: requestEvaluateFormula, isActiveCellFormula: Boolean(getFormulaValue(sheetId, activeCell.rowIndex, activeCell.columnIndex)), onRequestResize: onRequestResize, isSheetFocused: isSheetFocused, tables: activeTables, pivotTables: pivotTables, basicFilter: basicFilter, onRequestEditTable: onRequestEditTable, onRequestEditPivotTable: onRequestEditPivotTable, onRemoveTable: onRemoveTable, onRequestDeletePivotTable: onRequestDeletePivotTable, onPivotDrillDown: onPivotDrillDown, onRequestFormatCells: onRequestFormatCells, onRequestConditionalFormat: onRequestConditionalFormat, onRequestDataValidation: onRequestDataValidation, onClearFormatting: onClearFormatting, onCreateTable: onCreateTable, onCreateBasicFilter: onCreateBasicFilter, onInsertTableColumn: onInsertTableColumn, onDeleteTableColumn: onDeleteTableColumn, onInsertTableRow: onInsertTableRow, onDeleteTableRow: onDeleteTableRow, onFilterTable: onFilterTable, onSortTable: onSortTable, getFormattedValue: getFormattedValue, getFormattedValuesFromRange: getFormattedValuesFromRange, isTableHeader: isTableHeader, readonly: readonly, onSplitTextToColumns: onSplitTextToColumns, onRemoveDuplicates: onRemoveDuplicates, onChange: onChange, getCellData: getCellData, onAddQuickEdit: onAddQuickEdit, enableMagicFill: enableMagicFill }));
2340
+ return (React.createElement(ContextMenu, { activeCell: activeCell, selections: selections, sheetId: sheetId, frozenRows: frozenRows, frozenColumns: frozenColumns, onHideColumn: isRestricted ? undefined : onHideColumn, onShowColumn: isRestricted ? undefined : onShowColumn, onShowRow: isRestricted ? undefined : onShowRow, onHideRow: isRestricted ? undefined : onHideRow, onGroupRows: isRestricted ? undefined : onGroupRows, onUngroupRows: isRestricted ? undefined : onUngroupRows, onGroupColumns: isRestricted ? undefined : onGroupColumns, onUngroupColumns: isRestricted ? undefined : onUngroupColumns, isHiddenColumn: isHiddenColumn, isHiddenRow: isHiddenRow, onDeleteColumn: onDeleteColumn, onDeleteRow: onDeleteRow, onInsertRow: onInsertRow, onInsertColumn: onInsertColumn, onInsertCellsShiftDown: onInsertCellsShiftDown, onInsertCellsShiftRight: onInsertCellsShiftRight, onDeleteCellsShiftLeft: onDeleteCellsShiftLeft, onDeleteCellsShiftUp: onDeleteCellsShiftUp, onClearContents: onClearContents, onFreezeColumn: onFreezeColumn, onFreezeRow: onFreezeRow, focusSheet: focusSheet, onSortColumn: onSortColumn, onInsertNote: onInsertNote, onProtectRange: onProtectRange, onUnProtectRange: onUnProtectRange, onSortRange: onSortRange, onRequestDefineNamedRange: onRequestDefineNamedRange, protectedRanges: protectedRanges, isRowHeader: isRowHeader(cell.columnIndex), isColumnHeader: isColumnHeader(cell.rowIndex), selectedRowHeadersIds: selectedRowHeadersIds, selectedColumnHeadersIds: selectedColumnHeadersIds, onCopy: copy, onCut: cut, onPaste: paste, onRequestPasteSpecial: requestPasteSpecial, onRequestEvaluateFormula: requestEvaluateFormula, onRequestAddWatch: requestAddWatch, isActiveCellFormula: Boolean(getFormulaValue(sheetId, activeCell.rowIndex, activeCell.columnIndex)), onRequestResize: onRequestResize, isSheetFocused: isSheetFocused, tables: activeTables, pivotTables: pivotTables, basicFilter: basicFilter, onRequestEditTable: onRequestEditTable, onRequestEditPivotTable: onRequestEditPivotTable, onRemoveTable: onRemoveTable, onRequestDeletePivotTable: onRequestDeletePivotTable, onPivotDrillDown: onPivotDrillDown, onRequestFormatCells: onRequestFormatCells, onRequestConditionalFormat: onRequestConditionalFormat, onRequestDataValidation: onRequestDataValidation, onClearFormatting: onClearFormatting, onCreateTable: onCreateTable, onCreateBasicFilter: onCreateBasicFilter, onInsertTableColumn: onInsertTableColumn, onDeleteTableColumn: onDeleteTableColumn, onInsertTableRow: onInsertTableRow, onDeleteTableRow: onDeleteTableRow, onFilterTable: onFilterTable, onSortTable: onSortTable, getFormattedValue: getFormattedValue, getFormattedValuesFromRange: getFormattedValuesFromRange, isTableHeader: isTableHeader, readonly: readonly, onSplitTextToColumns: onSplitTextToColumns, onRemoveDuplicates: onRemoveDuplicates, onGoalSeek: onGoalSeek, onSubtotal: onSubtotal, onAdvancedFilter: onAdvancedFilter, onChange: onChange, getCellData: getCellData, onAddQuickEdit: onAddQuickEdit, enableMagicFill: enableMagicFill }));
2169
2341
  }, [
2170
2342
  isRestricted,
2171
2343
  activeCell,
@@ -2233,6 +2405,9 @@ function CanvasGridComponent(props, forwardedRef) {
2233
2405
  enableMagicFill,
2234
2406
  onSplitTextToColumns,
2235
2407
  onRemoveDuplicates,
2408
+ onGoalSeek,
2409
+ onSubtotal,
2410
+ onAdvancedFilter,
2236
2411
  onChange,
2237
2412
  getCellData,
2238
2413
  onRequestDeletePivotTable,
@@ -2696,6 +2871,8 @@ function CanvasGridComponent(props, forwardedRef) {
2696
2871
  hideCellPopover();
2697
2872
  // Hide paste mnenu
2698
2873
  setShowPasteMenu(false);
2874
+ // Hide the Auto Fill Options smart tag (its own mousedown never reaches here)
2875
+ setFillOptions(null);
2699
2876
  // Remove pinned tooltip
2700
2877
  onUnpinTooltip();
2701
2878
  }, [
@@ -2707,6 +2884,7 @@ function CanvasGridComponent(props, forwardedRef) {
2707
2884
  setFormulaState,
2708
2885
  hideCellPopover,
2709
2886
  setShowPasteMenu,
2887
+ setFillOptions,
2710
2888
  onUnpinTooltip,
2711
2889
  focusSheet,
2712
2890
  ]);
@@ -2958,9 +3136,12 @@ function CanvasGridComponent(props, forwardedRef) {
2958
3136
  /**
2959
3137
  * Selection Renderer
2960
3138
  */
3139
+ // The drag-back preview reuses the fill overlay geometry but greys the cells about to be cleared.
3140
+ const fillShrinkOverlay = useMemo(() => (fillShrink ? { range: fillShrink.clearRange } : undefined), [fillShrink]);
2961
3141
  const selectionRenderer = useSelectionRenderer({
2962
3142
  sheetId,
2963
3143
  scale,
3144
+ isFillShrink: fillShrink !== undefined,
2964
3145
  onSelectionMouseDown: onSelectionElementMouseDown,
2965
3146
  onMouseDownResizeHandle: onMouseDownResizeHandle,
2966
3147
  onMouseDownMoveSelection: onMouseDownMoveSelection,
@@ -2989,6 +3170,10 @@ function CanvasGridComponent(props, forwardedRef) {
2989
3170
  readonly,
2990
3171
  onSplitTextToColumns,
2991
3172
  showPasteMenu,
3173
+ fillOptions,
3174
+ onChooseFillType: handleChooseFillType,
3175
+ onOpenFillSeriesDialog: handleOpenFillSeriesDialog,
3176
+ onCloseFillOptions: handleCloseFillOptions,
2992
3177
  hoveredCell: delayedHoveredCell,
2993
3178
  onRemoveQuickEdit,
2994
3179
  onAddQuickEdit,
@@ -3062,9 +3247,19 @@ function CanvasGridComponent(props, forwardedRef) {
3062
3247
  setActiveCell,
3063
3248
  flash,
3064
3249
  });
3065
- // Built-in Go To: resolve against the workbook, then select + scroll.
3250
+ // Built-in Go To: resolve against the workbook, then select + scroll. Go
3251
+ // To Special scans the current selection (the whole sheet for a single
3252
+ // cell) through the host's `getCellData`.
3066
3253
  useIsomorphicLayoutEffect(() => {
3067
- builtInGoToRef.current = (goToSheetId, goToActiveCell) => {
3254
+ builtInGoToRef.current = (goToSheetId, goToActiveCell, goToSelections) => {
3255
+ const scanRange = goToSelections?.length && goToSelections[0]
3256
+ ? goToSelections[0].range
3257
+ : {
3258
+ startRowIndex: 1,
3259
+ endRowIndex: Math.max(1, sheetRowCount - 1),
3260
+ startColumnIndex: 1,
3261
+ endColumnIndex: Math.max(1, sheetColumnCount - 1),
3262
+ };
3068
3263
  openGoToDialog({
3069
3264
  sheetId: goToSheetId,
3070
3265
  activeCell: goToActiveCell,
@@ -3077,9 +3272,52 @@ function CanvasGridComponent(props, forwardedRef) {
3077
3272
  navigateToSheetRange(range, { enableFlash: false });
3078
3273
  focusSheet();
3079
3274
  },
3275
+ special: getCellData
3276
+ ? {
3277
+ resolve: (kind) => resolveGoToSpecial(kind, {
3278
+ sheetId: goToSheetId,
3279
+ range: scanRange,
3280
+ getCellData,
3281
+ isRowHidden: isHiddenRow,
3282
+ isColumnHidden: isHiddenColumn,
3283
+ }),
3284
+ onSelectRanges: (ranges) => {
3285
+ const first = ranges[0];
3286
+ if (!first)
3287
+ return;
3288
+ setActiveCell(goToSheetId, {
3289
+ rowIndex: first.startRowIndex,
3290
+ columnIndex: first.startColumnIndex,
3291
+ });
3292
+ onChangeSelections?.(goToSheetId, ranges.map((range) => ({ range })));
3293
+ focusSheet();
3294
+ },
3295
+ }
3296
+ : undefined,
3080
3297
  });
3081
3298
  };
3082
3299
  });
3300
+ // Watch Window live getters — republished per render while a host is
3301
+ // mounted so the panel tracks recalculation.
3302
+ useIsomorphicLayoutEffect(() => {
3303
+ if (!isWatchWindowMounted)
3304
+ return;
3305
+ setWatchWindowContext({
3306
+ getSheetName,
3307
+ getFormattedValue,
3308
+ getFormula: getFormulaValue,
3309
+ onNavigate: (cell) => {
3310
+ navigateToSheetRange({
3311
+ sheetId: cell.sheetId,
3312
+ startRowIndex: cell.rowIndex,
3313
+ endRowIndex: cell.rowIndex,
3314
+ startColumnIndex: cell.columnIndex,
3315
+ endColumnIndex: cell.columnIndex,
3316
+ }, { enableFlash: false });
3317
+ focusSheet();
3318
+ },
3319
+ });
3320
+ });
3083
3321
  // Dispatch keyboard event
3084
3322
  const dispatchEvent = useCallback((event) => {
3085
3323
  gridRef.current?.container?.dispatchEvent(event);
@@ -3246,12 +3484,14 @@ function CanvasGridComponent(props, forwardedRef) {
3246
3484
  });
3247
3485
  // props reference for spreadsheet api
3248
3486
  propsReferenceRef.current = props;
3487
+ const openFillSeriesDialogForRef = useStableRef(openFillSeriesDialogFor);
3249
3488
  // Expose a spreadsheet API
3250
3489
  useIsomorphicLayoutEffect(() => {
3251
3490
  const stableMethods = {
3252
3491
  getUserEnteredValue: getUserEnteredStringValueStable,
3253
3492
  scrollToCell,
3254
3493
  commit,
3494
+ openFillSeriesDialog: () => openFillSeriesDialogForRef.current?.(),
3255
3495
  };
3256
3496
  setSpreadsheetApi(new SpreadsheetApi(propsReferenceRef, stableMethods, store, instanceStore, instanceId));
3257
3497
  }, []);
@@ -3333,7 +3573,7 @@ function CanvasGridComponent(props, forwardedRef) {
3333
3573
  width === 0 || height === 0 ? (React.createElement("div", { className: "flex border-solid border-rnc-border border border-t border-b flex-1 justify-center items-center" },
3334
3574
  React.createElement("div", { className: "space-y-2" },
3335
3575
  React.createElement(Skeleton, { className: "h-4 w-[250px]" }),
3336
- React.createElement(Skeleton, { className: "h-4 w-[250px]" })))) : (React.createElement(BaseGrid, { ref: gridRef, overscanCount: overscanCount, rowCount: sheetRowCount, columnCount: sheetColumnCount, rowHeight: rowHeight, columnWidth: columnWidth, itemRenderer: cellRenderer, headerRenderer: headerCellRenderer, selectionRenderer: selectionRenderer, gridLineColor: gridLineColor, gridLineWidth: gridLineWidth, borderStyles: finalBorderStyles, mergedCells: merges, scale: scale, width: width, height: height, frozenColumns: frozenColumns, frozenRows: frozenRows, activeCell: activeCell, selections: formulaMode ? formulaSelections : selections, FillHandle: FillHandle, showFillHandle: showFillHandle, fillHandleSize: fillHandleSize, showGridLines: showGridLines, enableCellOverlay: true, enableCellBackground: true, enableSelectionDrag: enableSelectionDrag, showFrozenColumnShadow: showFrozenSeparator, showFrozenRowShadow: showFrozenSeparator, selectionBorderColor: selectionBorderColor, selectionBackgroundColor: selectionBackgroundColor, fillhandleBorderColor: cellBackgroundColor, isDraggingSelection: isDragging, fillSelection: fillSelection, onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onMouseDown: handleMouseDown, onDoubleClick: handleDoubleClick, onFillHandleMouseDown: onFillHandleMouseDown, onFillHandleDoubleClick: onFillHandleDoubleClick,
3576
+ React.createElement(Skeleton, { className: "h-4 w-[250px]" })))) : (React.createElement(BaseGrid, { ref: gridRef, overscanCount: overscanCount, rowCount: sheetRowCount, columnCount: sheetColumnCount, rowHeight: rowHeight, columnWidth: columnWidth, itemRenderer: cellRenderer, headerRenderer: headerCellRenderer, selectionRenderer: selectionRenderer, gridLineColor: gridLineColor, gridLineWidth: gridLineWidth, borderStyles: finalBorderStyles, mergedCells: merges, scale: scale, width: width, height: height, frozenColumns: frozenColumns, frozenRows: frozenRows, activeCell: activeCell, selections: formulaMode ? formulaSelections : selections, FillHandle: FillHandle, showFillHandle: showFillHandle, fillHandleSize: fillHandleSize, showGridLines: showGridLines, enableCellOverlay: true, enableCellBackground: true, enableSelectionDrag: enableSelectionDrag, showFrozenColumnShadow: showFrozenSeparator, showFrozenRowShadow: showFrozenSeparator, selectionBorderColor: selectionBorderColor, selectionBackgroundColor: selectionBackgroundColor, fillhandleBorderColor: cellBackgroundColor, isDraggingSelection: isDragging, fillSelection: fillShrinkOverlay ?? fillSelection, onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onMouseDown: handleMouseDown, onDoubleClick: handleDoubleClick, onFillHandleMouseDown: onFillHandleMouseDown, onFillHandleDoubleClick: onFillHandleDoubleClick,
3337
3577
  // Dimension of fill handle
3338
3578
  scrollToCellOffset: 4, scrollbarSize: scrollbarSize, isHiddenCell: isHiddenCell, isHiddenColumn: isHiddenColumn, isHiddenRow: isHiddenRow, visibleRowRanges: visibleRowRanges, isHiddenOverlay: isHiddenOverlay, isHiddenBackground: isHiddenBackground, overlayRenderer: cellOverlayRenderer, backgroundRenderer: cellBackgroundRenderer, shadowSettings: shadowSettings, onScroll: handleScroll, onViewPortChange: handleViewPortChange, autoFocus: autoFocus, snap: scrollSnap, scrollThrottleTimeout: scrollThrottleTimeout, preventBrowserDefaultScroll: preventBrowserDefaultScroll, showHeaders: showHeaders, gridChildren: gridChildren, onTouchStart: onTouchStart, onDimensionsChange: onDimensionsChange, extendScrollSize: isTouchDevice || isFirefox, isTouchDevice: isTouchDevice, frozenShadowThickness: frozenShadowThickness, onAfterScrollToCell: onAfterScrollToCell, estimatedRowHeight: defaultRowHeight, estimatedColumnWidth: defaultColumnWidth, footerHeight: footerHeight, footerComponent: footerComponent, getOverflowBuffer: getOverflowBuffer, getFrozenColumnOverflowCells: getFrozenColumnOverflowCells })),
3339
3579
  tooltipComponent,
@@ -13,8 +13,8 @@ import type { useFlash } from "../../hooks/use-flash";
13
13
  import type { useNavigateToSheetRange } from "../../hooks/use-navigate-sheet-range";
14
14
  import type { UseSelectionOptions } from "../../hooks/use-selection";
15
15
  import type { GetCellDimensionsOptions as SizerGetCellDimensionsOptions, useSizer } from "../../hooks/use-sizer";
16
- import type { AgentSuggestion, BandedDefinition, BandedRange, BorderStyle, CellFormat, Collaborator, Color, ColorFilterCriteria, ConditionType, ConditionValue, DataValidationRule, DataValidationRuleRecord, EmbeddedObject, IconFilterCriteria, Maybe, NamedRange, ParsedToken, PivotTable, ProtectedRange, RemoveDuplicatesOptions, Sheet, SheetCoordinate, SheetProtection, SheetRange, Slicer, SortOrder, SortSpecs, TableTheme, TableView } from "../../types";
17
- import type { AXIS, CellData, ConditionalFormatRule, EmbeddedChart, FilterView } from "../../types";
16
+ import type { AgentSuggestion, BandedDefinition, BandedRange, BorderStyle, CellFormat, Collaborator, Color, ColorFilterCriteria, ConditionType, ConditionValue, DataValidationRule, DataValidationRuleRecord, EmbeddedObject, IconFilterCriteria, Maybe, NamedRange, ParsedToken, PivotTable, ProtectedRange, RemoveDuplicatesOptions, AdvancedFilterOptions, AdvancedFilterResult, GoalSeekResult, SplitTextOptions, SubtotalOptions, SubtotalResult, Sheet, SheetCoordinate, SheetProtection, SheetRange, Slicer, SortOrder, SortSpecs, TableTheme, TableView } from "../../types";
17
+ import type { AXIS, AutoFillType, CellData, ConditionalFormatRule, EmbeddedChart, FillOptions, FilterView } from "../../types";
18
18
  import type { CellProps } from "../cell/typings";
19
19
  import type { CellEditorProps } from "../cell-editor";
20
20
  import type { StructuredResultProps } from "../cell-structured/types";
@@ -670,8 +670,11 @@ export type CanvasGridProps<T extends CellData = CellData<any, any>> = {
670
670
  * @param sheetId
671
671
  * @param cell
672
672
  * @param selections
673
+ * @param clearType what to clear — `"contents"` (default; values/formulas, formats kept),
674
+ * `"formats"`, or `"all"`. A fill-handle drag-back inside the selection clears `"contents"`
675
+ * (`"all"` with Ctrl), matching Excel.
673
676
  */
674
- onDelete?(sheetId: number, cell: CellInterface, selections: SelectionArea<SelectionAttributes>[]): void;
677
+ onDelete?(sheetId: number, cell: CellInterface, selections: SelectionArea<SelectionAttributes>[], clearType?: "all" | "contents" | "formats"): void;
675
678
  /**
676
679
  * When user changes editor value
677
680
  * @param value
@@ -697,8 +700,14 @@ export type CanvasGridProps<T extends CellData = CellData<any, any>> = {
697
700
  * Fill
698
701
  * @param cell
699
702
  * @param selections
703
+ * @param fillableSelections Optional pre-drag selections (used for undo
704
+ * bookkeeping by the state layer); the grid passes `undefined`.
705
+ * @param fillType Explicit fill type — from the Auto Fill Options / right-drag
706
+ * menu. Omitted for a plain drag (the engine auto-detects).
707
+ * @param options Modifier held on the handle (`{ modifier: "toggle" }` for
708
+ * Ctrl/Cmd+drag) and/or the Series dialog's parameters.
700
709
  */
701
- onFill?(sheetId: number, cell: CellInterface, fillSelection: SelectionArea<SelectionAttributes>, selections: SelectionArea<SelectionAttributes>[]): void;
710
+ onFill?(sheetId: number, cell: CellInterface, fillSelection: SelectionArea<SelectionAttributes>, selections: SelectionArea<SelectionAttributes>[], fillableSelections?: SelectionArea<SelectionAttributes>[], fillType?: AutoFillType, options?: FillOptions): void;
702
711
  /**
703
712
  * Callback when user moves a selection
704
713
  * @param from
@@ -1527,7 +1536,7 @@ export type CanvasGridProps<T extends CellData = CellData<any, any>> = {
1527
1536
  * @param delimiter
1528
1537
  * @returns
1529
1538
  */
1530
- onSplitTextToColumns?: (sheetId: number, activeCell: CellInterface, selections?: SelectionArea<SelectionAttributes>[], delimiter?: string) => void;
1539
+ onSplitTextToColumns?: (sheetId: number, activeCell: CellInterface, selections?: SelectionArea<SelectionAttributes>[], delimiter?: string, options?: SplitTextOptions) => void;
1531
1540
  /**
1532
1541
  * Remove duplicate rows
1533
1542
  * @param sheetId
@@ -1536,6 +1545,23 @@ export type CanvasGridProps<T extends CellData = CellData<any, any>> = {
1536
1545
  * @returns
1537
1546
  */
1538
1547
  onRemoveDuplicates?: (sheetId: number, activeCell: CellInterface, selections?: SelectionArea<SelectionAttributes>[], options?: RemoveDuplicatesOptions) => void;
1548
+ /**
1549
+ * Excel's Goal Seek: find the `changingCell` value that makes the formula in
1550
+ * `setCell` evaluate to `targetValue`, then commit it. Resolves to the
1551
+ * search result (status + value), or `undefined` when the engine reports
1552
+ * no result (the rnc engine iterates natively) or the set cell has no formula.
1553
+ */
1554
+ onGoalSeek?: (sheetId: number, setCell: CellInterface, targetValue: number, changingCell: CellInterface) => Promise<GoalSeekResult | undefined>;
1555
+ /**
1556
+ * Excel's Data → Subtotal: insert "<group> Total" / "Grand Total" rows with
1557
+ * `SUBTOTAL(...)` formulas and outline the groups.
1558
+ */
1559
+ onSubtotal?: (sheetId: number, options: SubtotalOptions) => SubtotalResult | undefined;
1560
+ /**
1561
+ * Excel's Data → Advanced filter: filter a list in place (hide non-matching
1562
+ * rows) or copy the matching records elsewhere, driven by a criteria range.
1563
+ */
1564
+ onAdvancedFilter?: (sheetId: number, options: AdvancedFilterOptions) => AdvancedFilterResult | undefined;
1539
1565
  /**
1540
1566
  * Callback to get effective value of a cell
1541
1567
  * @param sheetId