@rowsncolumns/spreadsheet 10.2.73 → 10.2.75

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 (270) hide show
  1. package/dist/cjs/api/evaluate-formula.d.ts +17 -0
  2. package/dist/cjs/api/evaluate-formula.d.ts.map +1 -0
  3. package/dist/cjs/api/evaluate-formula.js +141 -0
  4. package/dist/cjs/api/excel-validation-kinds.d.ts +71 -0
  5. package/dist/cjs/api/excel-validation-kinds.d.ts.map +1 -0
  6. package/dist/cjs/api/excel-validation-kinds.js +304 -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/go-to.d.ts +19 -0
  11. package/dist/cjs/api/go-to.d.ts.map +1 -0
  12. package/dist/cjs/api/go-to.js +49 -0
  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/evaluate-formula-dialog.atom.d.ts +36 -0
  20. package/dist/cjs/atoms/evaluate-formula-dialog.atom.d.ts.map +1 -0
  21. package/dist/cjs/atoms/evaluate-formula-dialog.atom.js +36 -0
  22. package/dist/cjs/atoms/go-to-dialog.atom.d.ts +46 -0
  23. package/dist/cjs/atoms/go-to-dialog.atom.d.ts.map +1 -0
  24. package/dist/cjs/atoms/go-to-dialog.atom.js +34 -0
  25. package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts +29 -0
  26. package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts.map +1 -0
  27. package/dist/cjs/atoms/goal-seek-dialog.atom.js +30 -0
  28. package/dist/cjs/atoms/index.d.ts +5 -0
  29. package/dist/cjs/atoms/index.d.ts.map +1 -1
  30. package/dist/cjs/atoms/index.js +5 -0
  31. package/dist/cjs/atoms/paste-special-dialog.atom.d.ts +29 -0
  32. package/dist/cjs/atoms/paste-special-dialog.atom.d.ts.map +1 -0
  33. package/dist/cjs/atoms/paste-special-dialog.atom.js +34 -0
  34. package/dist/cjs/atoms/remove-duplicates-dialog.atom.d.ts +45 -0
  35. package/dist/cjs/atoms/remove-duplicates-dialog.atom.d.ts.map +1 -0
  36. package/dist/cjs/atoms/remove-duplicates-dialog.atom.js +37 -0
  37. package/dist/cjs/atoms/subtotal-dialog.atom.d.ts +39 -0
  38. package/dist/cjs/atoms/subtotal-dialog.atom.d.ts.map +1 -0
  39. package/dist/cjs/atoms/subtotal-dialog.atom.js +30 -0
  40. package/dist/cjs/atoms/text-to-columns-dialog.atom.d.ts +34 -0
  41. package/dist/cjs/atoms/text-to-columns-dialog.atom.d.ts.map +1 -0
  42. package/dist/cjs/atoms/text-to-columns-dialog.atom.js +36 -0
  43. package/dist/cjs/atoms/watch-window.atom.d.ts +37 -0
  44. package/dist/cjs/atoms/watch-window.atom.d.ts.map +1 -0
  45. package/dist/cjs/atoms/watch-window.atom.js +61 -0
  46. package/dist/cjs/components/advanced-filter-dialog/index.d.ts +28 -0
  47. package/dist/cjs/components/advanced-filter-dialog/index.d.ts.map +1 -0
  48. package/dist/cjs/components/advanced-filter-dialog/index.js +134 -0
  49. package/dist/cjs/components/calculation-options-dialog/index.d.ts +33 -0
  50. package/dist/cjs/components/calculation-options-dialog/index.d.ts.map +1 -0
  51. package/dist/cjs/components/calculation-options-dialog/index.js +69 -0
  52. package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
  53. package/dist/cjs/components/canvas-grid/index.js +208 -19
  54. package/dist/cjs/components/canvas-grid/typings.d.ts +72 -9
  55. package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
  56. package/dist/cjs/components/cell/alignment.d.ts +30 -0
  57. package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
  58. package/dist/cjs/components/cell/alignment.js +56 -1
  59. package/dist/cjs/components/cell/index.d.ts.map +1 -1
  60. package/dist/cjs/components/cell/index.js +15 -7
  61. package/dist/cjs/components/cell-diff/index.d.ts +3 -2
  62. package/dist/cjs/components/cell-diff/index.d.ts.map +1 -1
  63. package/dist/cjs/components/cell-editor/index.d.ts.map +1 -1
  64. package/dist/cjs/components/cell-editor/index.js +2 -1
  65. package/dist/cjs/components/context-menu/index.d.ts +21 -3
  66. package/dist/cjs/components/context-menu/index.d.ts.map +1 -1
  67. package/dist/cjs/components/context-menu/index.js +256 -6
  68. package/dist/cjs/components/context-menu/total-row-functions.d.ts +32 -0
  69. package/dist/cjs/components/context-menu/total-row-functions.d.ts.map +1 -0
  70. package/dist/cjs/components/context-menu/total-row-functions.js +62 -0
  71. package/dist/cjs/components/embeds/embed-component.d.ts.map +1 -1
  72. package/dist/cjs/components/embeds/embed-component.js +16 -1
  73. package/dist/cjs/components/evaluate-formula-dialog/index.d.ts +34 -0
  74. package/dist/cjs/components/evaluate-formula-dialog/index.d.ts.map +1 -0
  75. package/dist/cjs/components/evaluate-formula-dialog/index.js +106 -0
  76. package/dist/cjs/components/go-to-dialog/index.d.ts +45 -0
  77. package/dist/cjs/components/go-to-dialog/index.d.ts.map +1 -0
  78. package/dist/cjs/components/go-to-dialog/index.js +136 -0
  79. package/dist/cjs/components/goal-seek-dialog/index.d.ts +32 -0
  80. package/dist/cjs/components/goal-seek-dialog/index.d.ts.map +1 -0
  81. package/dist/cjs/components/goal-seek-dialog/index.js +149 -0
  82. package/dist/cjs/components/paste-special-dialog/index.d.ts +29 -0
  83. package/dist/cjs/components/paste-special-dialog/index.d.ts.map +1 -0
  84. package/dist/cjs/components/paste-special-dialog/index.js +99 -0
  85. package/dist/cjs/components/remove-duplicates-dialog/index.d.ts +37 -0
  86. package/dist/cjs/components/remove-duplicates-dialog/index.d.ts.map +1 -0
  87. package/dist/cjs/components/remove-duplicates-dialog/index.js +91 -0
  88. package/dist/cjs/components/subtotal-dialog/index.d.ts +30 -0
  89. package/dist/cjs/components/subtotal-dialog/index.d.ts.map +1 -0
  90. package/dist/cjs/components/subtotal-dialog/index.js +126 -0
  91. package/dist/cjs/components/text-to-columns-dialog/index.d.ts +37 -0
  92. package/dist/cjs/components/text-to-columns-dialog/index.d.ts.map +1 -0
  93. package/dist/cjs/components/text-to-columns-dialog/index.js +166 -0
  94. package/dist/cjs/components/toolbar/background-color-selector.d.ts +13 -1
  95. package/dist/cjs/components/toolbar/background-color-selector.d.ts.map +1 -1
  96. package/dist/cjs/components/toolbar/background-color-selector.js +57 -11
  97. package/dist/cjs/components/toolbar/cell-style-selector.d.ts +15 -2
  98. package/dist/cjs/components/toolbar/cell-style-selector.d.ts.map +1 -1
  99. package/dist/cjs/components/toolbar/cell-style-selector.js +56 -3
  100. package/dist/cjs/components/toolbar/fill-selectors.d.ts +49 -0
  101. package/dist/cjs/components/toolbar/fill-selectors.d.ts.map +1 -0
  102. package/dist/cjs/components/toolbar/fill-selectors.js +196 -0
  103. package/dist/cjs/components/toolbar/index.d.ts +2 -0
  104. package/dist/cjs/components/toolbar/index.d.ts.map +1 -1
  105. package/dist/cjs/components/toolbar/index.js +2 -0
  106. package/dist/cjs/components/toolbar/text-horizontal-align-selector.d.ts +8 -0
  107. package/dist/cjs/components/toolbar/text-horizontal-align-selector.d.ts.map +1 -1
  108. package/dist/cjs/components/toolbar/text-horizontal-align-selector.js +23 -4
  109. package/dist/cjs/components/toolbar/text-rotation-selector.d.ts +29 -0
  110. package/dist/cjs/components/toolbar/text-rotation-selector.d.ts.map +1 -0
  111. package/dist/cjs/components/toolbar/text-rotation-selector.js +78 -0
  112. package/dist/cjs/components/toolbar/text-wrap-selector.d.ts +7 -1
  113. package/dist/cjs/components/toolbar/text-wrap-selector.d.ts.map +1 -1
  114. package/dist/cjs/components/toolbar/text-wrap-selector.js +10 -3
  115. package/dist/cjs/components/watch-window/index.d.ts +25 -0
  116. package/dist/cjs/components/watch-window/index.d.ts.map +1 -0
  117. package/dist/cjs/components/watch-window/index.js +63 -0
  118. package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
  119. package/dist/cjs/hooks/use-cell-renderer.js +17 -6
  120. package/dist/cjs/hooks/use-copy-paste-cut.d.ts +20 -1
  121. package/dist/cjs/hooks/use-copy-paste-cut.d.ts.map +1 -1
  122. package/dist/cjs/hooks/use-copy-paste-cut.js +25 -20
  123. package/dist/cjs/hooks/use-get-tooltip.d.ts.map +1 -1
  124. package/dist/cjs/hooks/use-get-tooltip.js +7 -2
  125. package/dist/cjs/hooks/use-keyboard-handler.d.ts +17 -2
  126. package/dist/cjs/hooks/use-keyboard-handler.d.ts.map +1 -1
  127. package/dist/cjs/hooks/use-keyboard-handler.js +206 -31
  128. package/dist/cjs/index.d.ts +14 -1
  129. package/dist/cjs/index.d.ts.map +1 -1
  130. package/dist/cjs/index.js +15 -1
  131. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  132. package/dist/cjs/types.d.ts +289 -4
  133. package/dist/cjs/types.d.ts.map +1 -1
  134. package/dist/cjs/types.js +19 -1
  135. package/dist/esm/api/evaluate-formula.d.ts +17 -0
  136. package/dist/esm/api/evaluate-formula.d.ts.map +1 -0
  137. package/dist/esm/api/evaluate-formula.js +109 -0
  138. package/dist/esm/api/excel-validation-kinds.d.ts +71 -0
  139. package/dist/esm/api/excel-validation-kinds.d.ts.map +1 -0
  140. package/dist/esm/api/excel-validation-kinds.js +287 -0
  141. package/dist/esm/api/go-to-special.d.ts +32 -0
  142. package/dist/esm/api/go-to-special.d.ts.map +1 -0
  143. package/dist/esm/api/go-to-special.js +96 -0
  144. package/dist/esm/api/go-to.d.ts +19 -0
  145. package/dist/esm/api/go-to.d.ts.map +1 -0
  146. package/dist/esm/api/go-to.js +41 -0
  147. package/dist/esm/api/validation-tooltip.d.ts +17 -0
  148. package/dist/esm/api/validation-tooltip.d.ts.map +1 -0
  149. package/dist/esm/api/validation-tooltip.js +34 -0
  150. package/dist/esm/atoms/advanced-filter-dialog.atom.d.ts +28 -0
  151. package/dist/esm/atoms/advanced-filter-dialog.atom.d.ts.map +1 -0
  152. package/dist/esm/atoms/advanced-filter-dialog.atom.js +21 -0
  153. package/dist/esm/atoms/evaluate-formula-dialog.atom.d.ts +36 -0
  154. package/dist/esm/atoms/evaluate-formula-dialog.atom.d.ts.map +1 -0
  155. package/dist/esm/atoms/evaluate-formula-dialog.atom.js +25 -0
  156. package/dist/esm/atoms/go-to-dialog.atom.d.ts +46 -0
  157. package/dist/esm/atoms/go-to-dialog.atom.d.ts.map +1 -0
  158. package/dist/esm/atoms/go-to-dialog.atom.js +25 -0
  159. package/dist/esm/atoms/goal-seek-dialog.atom.d.ts +29 -0
  160. package/dist/esm/atoms/goal-seek-dialog.atom.d.ts.map +1 -0
  161. package/dist/esm/atoms/goal-seek-dialog.atom.js +21 -0
  162. package/dist/esm/atoms/index.d.ts +5 -0
  163. package/dist/esm/atoms/index.d.ts.map +1 -1
  164. package/dist/esm/atoms/index.js +5 -0
  165. package/dist/esm/atoms/paste-special-dialog.atom.d.ts +29 -0
  166. package/dist/esm/atoms/paste-special-dialog.atom.d.ts.map +1 -0
  167. package/dist/esm/atoms/paste-special-dialog.atom.js +25 -0
  168. package/dist/esm/atoms/remove-duplicates-dialog.atom.d.ts +45 -0
  169. package/dist/esm/atoms/remove-duplicates-dialog.atom.d.ts.map +1 -0
  170. package/dist/esm/atoms/remove-duplicates-dialog.atom.js +26 -0
  171. package/dist/esm/atoms/subtotal-dialog.atom.d.ts +39 -0
  172. package/dist/esm/atoms/subtotal-dialog.atom.d.ts.map +1 -0
  173. package/dist/esm/atoms/subtotal-dialog.atom.js +21 -0
  174. package/dist/esm/atoms/text-to-columns-dialog.atom.d.ts +34 -0
  175. package/dist/esm/atoms/text-to-columns-dialog.atom.d.ts.map +1 -0
  176. package/dist/esm/atoms/text-to-columns-dialog.atom.js +25 -0
  177. package/dist/esm/atoms/watch-window.atom.d.ts +37 -0
  178. package/dist/esm/atoms/watch-window.atom.d.ts.map +1 -0
  179. package/dist/esm/atoms/watch-window.atom.js +37 -0
  180. package/dist/esm/components/advanced-filter-dialog/index.d.ts +28 -0
  181. package/dist/esm/components/advanced-filter-dialog/index.d.ts.map +1 -0
  182. package/dist/esm/components/advanced-filter-dialog/index.js +125 -0
  183. package/dist/esm/components/calculation-options-dialog/index.d.ts +33 -0
  184. package/dist/esm/components/calculation-options-dialog/index.d.ts.map +1 -0
  185. package/dist/esm/components/calculation-options-dialog/index.js +61 -0
  186. package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
  187. package/dist/esm/components/canvas-grid/index.js +202 -19
  188. package/dist/esm/components/canvas-grid/typings.d.ts +72 -9
  189. package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
  190. package/dist/esm/components/cell/alignment.d.ts +30 -0
  191. package/dist/esm/components/cell/alignment.d.ts.map +1 -1
  192. package/dist/esm/components/cell/alignment.js +51 -0
  193. package/dist/esm/components/cell/index.d.ts.map +1 -1
  194. package/dist/esm/components/cell/index.js +16 -8
  195. package/dist/esm/components/cell-diff/index.d.ts +3 -2
  196. package/dist/esm/components/cell-diff/index.d.ts.map +1 -1
  197. package/dist/esm/components/cell-editor/index.d.ts.map +1 -1
  198. package/dist/esm/components/cell-editor/index.js +2 -1
  199. package/dist/esm/components/context-menu/index.d.ts +21 -3
  200. package/dist/esm/components/context-menu/index.d.ts.map +1 -1
  201. package/dist/esm/components/context-menu/index.js +251 -9
  202. package/dist/esm/components/context-menu/total-row-functions.d.ts +32 -0
  203. package/dist/esm/components/context-menu/total-row-functions.d.ts.map +1 -0
  204. package/dist/esm/components/context-menu/total-row-functions.js +50 -0
  205. package/dist/esm/components/embeds/embed-component.d.ts.map +1 -1
  206. package/dist/esm/components/embeds/embed-component.js +17 -1
  207. package/dist/esm/components/evaluate-formula-dialog/index.d.ts +34 -0
  208. package/dist/esm/components/evaluate-formula-dialog/index.d.ts.map +1 -0
  209. package/dist/esm/components/evaluate-formula-dialog/index.js +86 -0
  210. package/dist/esm/components/go-to-dialog/index.d.ts +45 -0
  211. package/dist/esm/components/go-to-dialog/index.d.ts.map +1 -0
  212. package/dist/esm/components/go-to-dialog/index.js +124 -0
  213. package/dist/esm/components/goal-seek-dialog/index.d.ts +32 -0
  214. package/dist/esm/components/goal-seek-dialog/index.d.ts.map +1 -0
  215. package/dist/esm/components/goal-seek-dialog/index.js +125 -0
  216. package/dist/esm/components/paste-special-dialog/index.d.ts +29 -0
  217. package/dist/esm/components/paste-special-dialog/index.d.ts.map +1 -0
  218. package/dist/esm/components/paste-special-dialog/index.js +90 -0
  219. package/dist/esm/components/remove-duplicates-dialog/index.d.ts +37 -0
  220. package/dist/esm/components/remove-duplicates-dialog/index.d.ts.map +1 -0
  221. package/dist/esm/components/remove-duplicates-dialog/index.js +82 -0
  222. package/dist/esm/components/subtotal-dialog/index.d.ts +30 -0
  223. package/dist/esm/components/subtotal-dialog/index.d.ts.map +1 -0
  224. package/dist/esm/components/subtotal-dialog/index.js +115 -0
  225. package/dist/esm/components/text-to-columns-dialog/index.d.ts +37 -0
  226. package/dist/esm/components/text-to-columns-dialog/index.d.ts.map +1 -0
  227. package/dist/esm/components/text-to-columns-dialog/index.js +147 -0
  228. package/dist/esm/components/toolbar/background-color-selector.d.ts +13 -1
  229. package/dist/esm/components/toolbar/background-color-selector.d.ts.map +1 -1
  230. package/dist/esm/components/toolbar/background-color-selector.js +61 -11
  231. package/dist/esm/components/toolbar/cell-style-selector.d.ts +15 -2
  232. package/dist/esm/components/toolbar/cell-style-selector.d.ts.map +1 -1
  233. package/dist/esm/components/toolbar/cell-style-selector.js +46 -2
  234. package/dist/esm/components/toolbar/fill-selectors.d.ts +49 -0
  235. package/dist/esm/components/toolbar/fill-selectors.d.ts.map +1 -0
  236. package/dist/esm/components/toolbar/fill-selectors.js +162 -0
  237. package/dist/esm/components/toolbar/index.d.ts +2 -0
  238. package/dist/esm/components/toolbar/index.d.ts.map +1 -1
  239. package/dist/esm/components/toolbar/index.js +2 -0
  240. package/dist/esm/components/toolbar/text-horizontal-align-selector.d.ts +8 -0
  241. package/dist/esm/components/toolbar/text-horizontal-align-selector.d.ts.map +1 -1
  242. package/dist/esm/components/toolbar/text-horizontal-align-selector.js +21 -5
  243. package/dist/esm/components/toolbar/text-rotation-selector.d.ts +29 -0
  244. package/dist/esm/components/toolbar/text-rotation-selector.d.ts.map +1 -0
  245. package/dist/esm/components/toolbar/text-rotation-selector.js +71 -0
  246. package/dist/esm/components/toolbar/text-wrap-selector.d.ts +7 -1
  247. package/dist/esm/components/toolbar/text-wrap-selector.d.ts.map +1 -1
  248. package/dist/esm/components/toolbar/text-wrap-selector.js +10 -3
  249. package/dist/esm/components/watch-window/index.d.ts +25 -0
  250. package/dist/esm/components/watch-window/index.d.ts.map +1 -0
  251. package/dist/esm/components/watch-window/index.js +54 -0
  252. package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
  253. package/dist/esm/hooks/use-cell-renderer.js +17 -6
  254. package/dist/esm/hooks/use-copy-paste-cut.d.ts +20 -1
  255. package/dist/esm/hooks/use-copy-paste-cut.d.ts.map +1 -1
  256. package/dist/esm/hooks/use-copy-paste-cut.js +8 -3
  257. package/dist/esm/hooks/use-get-tooltip.d.ts.map +1 -1
  258. package/dist/esm/hooks/use-get-tooltip.js +7 -2
  259. package/dist/esm/hooks/use-keyboard-handler.d.ts +17 -2
  260. package/dist/esm/hooks/use-keyboard-handler.d.ts.map +1 -1
  261. package/dist/esm/hooks/use-keyboard-handler.js +193 -31
  262. package/dist/esm/index.d.ts +14 -1
  263. package/dist/esm/index.d.ts.map +1 -1
  264. package/dist/esm/index.js +13 -0
  265. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  266. package/dist/esm/types.d.ts +289 -4
  267. package/dist/esm/types.d.ts.map +1 -1
  268. package/dist/esm/types.js +18 -0
  269. package/dist/spreadsheet.min.css +1 -1
  270. package/package.json +6 -6
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EvaluateFormulaDialogHost = exports.EvaluateFormulaDialog = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var calculator_1 = require("@rowsncolumns/calculator");
6
+ var ui_1 = require("@rowsncolumns/ui");
7
+ var utils_1 = require("@rowsncolumns/utils");
8
+ var react_1 = tslib_1.__importStar(require("react"));
9
+ var evaluate_formula_dialog_atom_1 = require("../../atoms/evaluate-formula-dialog.atom");
10
+ var CANNOT_EVALUATE = "This formula cannot be stepped through. Check it for syntax errors.";
11
+ /**
12
+ * Excel's Evaluate Formula dialog: a read-only stepper that underlines the
13
+ * next sub-expression the calculator would resolve and, on Evaluate,
14
+ * replaces it with its value until only the result remains. Nothing is
15
+ * written to the sheet.
16
+ */
17
+ exports.EvaluateFormulaDialog = (0, react_1.memo)(function (_a) {
18
+ var open = _a.open, onOpenChange = _a.onOpenChange, reference = _a.reference, formula = _a.formula, evaluate = _a.evaluate;
19
+ var _b = tslib_1.__read((0, react_1.useState)(function () { return (0, calculator_1.createFormulaEvaluation)(formula); }), 2), state = _b[0], setState = _b[1];
20
+ var _c = tslib_1.__read((0, react_1.useState)(false), 2), busy = _c[0], setBusy = _c[1];
21
+ var _d = tslib_1.__read((0, react_1.useState)(undefined), 2), failure = _d[0], setFailure = _d[1];
22
+ var step = (0, react_1.useCallback)(function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
23
+ var _a, err_1;
24
+ return tslib_1.__generator(this, function (_b) {
25
+ switch (_b.label) {
26
+ case 0:
27
+ if (!state || state.done || busy)
28
+ return [2 /*return*/];
29
+ setBusy(true);
30
+ _b.label = 1;
31
+ case 1:
32
+ _b.trys.push([1, 3, 4, 5]);
33
+ _a = setState;
34
+ return [4 /*yield*/, (0, calculator_1.advanceFormulaEvaluation)(state, evaluate)];
35
+ case 2:
36
+ _a.apply(void 0, [_b.sent()]);
37
+ setFailure(undefined);
38
+ return [3 /*break*/, 5];
39
+ case 3:
40
+ err_1 = _b.sent();
41
+ setFailure(err_1 instanceof Error ? err_1.message : "The expression could not be evaluated.");
42
+ return [3 /*break*/, 5];
43
+ case 4:
44
+ setBusy(false);
45
+ return [7 /*endfinally*/];
46
+ case 5: return [2 /*return*/];
47
+ }
48
+ });
49
+ }); }, [state, busy, evaluate]);
50
+ var restart = (0, react_1.useCallback)(function () {
51
+ setState((0, calculator_1.createFormulaEvaluation)(formula));
52
+ setFailure(undefined);
53
+ }, [formula]);
54
+ var target = state === null || state === void 0 ? void 0 : state.target;
55
+ var before = state && target ? state.text.slice(0, target.start) : "";
56
+ var underlined = state && target ? state.text.slice(target.start, target.end + 1) : "";
57
+ var after = state && target ? state.text.slice(target.end + 1) : "";
58
+ return (react_1.default.createElement(ui_1.Dialog, { open: open, onOpenChange: onOpenChange, modal: true },
59
+ react_1.default.createElement(ui_1.DialogContent, { className: "w-[520px] max-w-[92vw] pointer-events-auto" },
60
+ react_1.default.createElement(ui_1.DialogTitle, null, "Evaluate Formula"),
61
+ react_1.default.createElement(ui_1.DialogCloseButton, null),
62
+ react_1.default.createElement(ui_1.DialogBody, { className: "flex flex-col gap-3" },
63
+ react_1.default.createElement("div", { className: "grid grid-cols-[auto_1fr] gap-x-4 gap-y-1 text-xs" },
64
+ react_1.default.createElement("span", { className: "font-medium" }, "Reference:"),
65
+ react_1.default.createElement("span", { className: "font-mono" }, reference),
66
+ react_1.default.createElement("span", { className: "font-medium" }, "Evaluation:"),
67
+ react_1.default.createElement("div", { "data-testid": "evaluate-formula-expression", className: "font-mono whitespace-pre-wrap break-all rounded border border-rnc-border px-2 py-1.5 min-h-[64px]" }, state ? (state.done ? (react_1.default.createElement("span", { className: "italic" },
68
+ "= ",
69
+ state.text)) : (react_1.default.createElement(react_1.default.Fragment, null,
70
+ "= ",
71
+ before,
72
+ react_1.default.createElement("u", { "data-testid": "evaluate-formula-target" }, underlined),
73
+ after))) : (react_1.default.createElement("span", { className: "text-rnc-destructive" }, CANNOT_EVALUATE)))),
74
+ failure ? (react_1.default.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, failure)) : null,
75
+ react_1.default.createElement("p", { className: "text-xs text-rnc-foreground/70" }, "To show the result of the underlined expression, click Evaluate. The final result appears italicized."),
76
+ react_1.default.createElement(ui_1.Separator, null),
77
+ react_1.default.createElement("div", { className: "flex justify-end gap-2" },
78
+ react_1.default.createElement(ui_1.Button, { variant: "outline", size: "sm", onClick: function () { return onOpenChange(false); } }, "Close"),
79
+ (state === null || state === void 0 ? void 0 : state.done) ? (react_1.default.createElement(ui_1.Button, { size: "sm", onClick: restart }, "Restart")) : (react_1.default.createElement(ui_1.Button, { size: "sm", onClick: step, disabled: !state || busy }, "Evaluate")))))));
80
+ });
81
+ exports.EvaluateFormulaDialog.displayName = "EvaluateFormulaDialog";
82
+ var referenceOf = function (request) {
83
+ var _a;
84
+ var address = (_a = (0, utils_1.cellToAddress)(request.cell, true, true)) !== null && _a !== void 0 ? _a : "";
85
+ var sheetName = (0, utils_1.sanitizeSheetName)(request.sheetName);
86
+ return sheetName ? "".concat(sheetName, "!").concat(address) : address;
87
+ };
88
+ /**
89
+ * Host-mounted, atom-driven wrapper around {@link EvaluateFormulaDialog}.
90
+ * Mount it once in the host alongside the other editor dialogs; the grid
91
+ * opens it from the context menu ("Evaluate formula…") for a formula cell.
92
+ * Keyed per request so each opening restarts from the cell's formula.
93
+ */
94
+ var EvaluateFormulaDialogHost = function () {
95
+ (0, evaluate_formula_dialog_atom_1.useRegisterEvaluateFormulaDialogHost)();
96
+ var _a = tslib_1.__read((0, evaluate_formula_dialog_atom_1.useEvaluateFormulaDialogState)(), 2), request = _a[0], setRequest = _a[1];
97
+ var close = (0, react_1.useCallback)(function () { return setRequest(null); }, [setRequest]);
98
+ if (!request)
99
+ return null;
100
+ return (react_1.default.createElement(exports.EvaluateFormulaDialog, { key: "".concat(request.sheetId, ":").concat(request.cell.rowIndex, ":").concat(request.cell.columnIndex, ":").concat(request.formula), open: true, onOpenChange: function (open) {
101
+ if (!open)
102
+ close();
103
+ }, reference: referenceOf(request), formula: request.formula, evaluate: request.evaluate }));
104
+ };
105
+ exports.EvaluateFormulaDialogHost = EvaluateFormulaDialogHost;
106
+ exports.EvaluateFormulaDialogHost.displayName = "EvaluateFormulaDialogHost";
@@ -0,0 +1,45 @@
1
+ import type { GridRange } from "@rowsncolumns/grid";
2
+ import React from "react";
3
+ import { type GoToSpecialKind } from "../../api/go-to-special";
4
+ import type { NamedRange, SheetRange } from "../../types";
5
+ export type GoToDialogProps = {
6
+ /** Controls visibility. */
7
+ open: boolean;
8
+ onOpenChange(open: boolean): void;
9
+ /** Defined names listed in the "Go to" box; picking one fills the reference. */
10
+ namedRanges?: NamedRange[] | null;
11
+ /** Shown as the placeholder of the reference box (the current location). */
12
+ currentAddress?: string;
13
+ /**
14
+ * Resolves the typed text to a range, or `undefined` when it is not a
15
+ * valid reference / name (the dialog then shows Excel's error).
16
+ */
17
+ resolve(reference: string): SheetRange | undefined;
18
+ /** Receives the resolved range; the host selects and scrolls to it. */
19
+ onNavigate(range: SheetRange): void;
20
+ /**
21
+ * Go To Special. `resolve` returns the matching cell runs for a category;
22
+ * `onSelectRanges` receives them. Omit to hide the "Special…" panel.
23
+ */
24
+ special?: {
25
+ resolve(kind: GoToSpecialKind): GridRange[];
26
+ onSelectRanges(ranges: GridRange[]): void;
27
+ };
28
+ };
29
+ /**
30
+ * Excel's Go To dialog (`Ctrl+G` / `F5`): type a cell or range reference,
31
+ * optionally sheet-qualified, or pick a defined name, and the selection
32
+ * jumps there. Resolution is delegated to `resolve` so the dialog stays
33
+ * UI-only.
34
+ */
35
+ export declare const GoToDialog: React.MemoExoticComponent<({ open, onOpenChange, namedRanges, currentAddress, resolve, onNavigate, special, }: GoToDialogProps) => React.JSX.Element>;
36
+ /**
37
+ * Host-mounted, atom-driven wrapper around {@link GoToDialog}. Mount it once
38
+ * in the host alongside the other editor dialogs; the grid opens it on
39
+ * `Ctrl+G` / `F5` (unless the host handles `onRequestGoTo` itself).
40
+ */
41
+ export declare const GoToDialogHost: {
42
+ (): React.JSX.Element | null;
43
+ displayName: string;
44
+ };
45
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/go-to-dialog/index.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,KAAsC,MAAM,OAAO,CAAC;AAG3D,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,gFAAgF;IAChF,WAAW,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAClC,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACnD,uEAAuE;IACvE,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,EAAE,CAAC;QAC5C,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;KAC3C,CAAC;CACH,CAAC;AAKF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,iHASlB,eAAe,uBA0MnB,CAAC;AAUF;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;CA+B1B,CAAC"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GoToDialogHost = exports.GoToDialog = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var ui_1 = require("@rowsncolumns/ui");
6
+ var utils_1 = require("@rowsncolumns/utils");
7
+ var react_1 = tslib_1.__importStar(require("react"));
8
+ var go_to_1 = require("../../api/go-to");
9
+ var go_to_special_1 = require("../../api/go-to-special");
10
+ var go_to_dialog_atom_1 = require("../../atoms/go-to-dialog.atom");
11
+ var INVALID_REFERENCE = "Reference is not valid.";
12
+ var NO_CELLS_FOUND = "No cells were found.";
13
+ /**
14
+ * Excel's Go To dialog (`Ctrl+G` / `F5`): type a cell or range reference,
15
+ * optionally sheet-qualified, or pick a defined name, and the selection
16
+ * jumps there. Resolution is delegated to `resolve` so the dialog stays
17
+ * UI-only.
18
+ */
19
+ exports.GoToDialog = (0, react_1.memo)(function (_a) {
20
+ var open = _a.open, onOpenChange = _a.onOpenChange, namedRanges = _a.namedRanges, currentAddress = _a.currentAddress, resolve = _a.resolve, onNavigate = _a.onNavigate, special = _a.special;
21
+ var _b = tslib_1.__read((0, react_1.useState)(""), 2), reference = _b[0], setReference = _b[1];
22
+ var _c = tslib_1.__read((0, react_1.useState)(undefined), 2), error = _c[0], setError = _c[1];
23
+ var _d = tslib_1.__read((0, react_1.useState)(false), 2), showSpecial = _d[0], setShowSpecial = _d[1];
24
+ var _e = tslib_1.__read((0, react_1.useState)("blanks"), 2), specialKind = _e[0], setSpecialKind = _e[1];
25
+ var selectSpecial = (0, react_1.useCallback)(function () {
26
+ if (!special)
27
+ return;
28
+ var ranges = special.resolve(specialKind);
29
+ if (!ranges.length) {
30
+ setError(NO_CELLS_FOUND);
31
+ return;
32
+ }
33
+ special.onSelectRanges(ranges);
34
+ onOpenChange(false);
35
+ }, [special, specialKind, onOpenChange]);
36
+ var navigate = (0, react_1.useCallback)(function (text) {
37
+ var range = resolve(text);
38
+ if (!range) {
39
+ setError(INVALID_REFERENCE);
40
+ return;
41
+ }
42
+ onNavigate(range);
43
+ onOpenChange(false);
44
+ }, [resolve, onNavigate, onOpenChange]);
45
+ var names = (namedRanges !== null && namedRanges !== void 0 ? namedRanges : []).filter(function (range) { return range.range && !range.hidden; });
46
+ return (react_1.default.createElement(ui_1.Dialog, { open: open, onOpenChange: onOpenChange, modal: true },
47
+ react_1.default.createElement(ui_1.DialogContent, { className: "w-[360px] max-w-[92vw] pointer-events-auto" },
48
+ react_1.default.createElement(ui_1.DialogTitle, null, showSpecial ? "Go To Special" : "Go To"),
49
+ react_1.default.createElement(ui_1.DialogCloseButton, null),
50
+ react_1.default.createElement(ui_1.DialogBody, { className: "flex flex-col gap-3" }, showSpecial && special ? (react_1.default.createElement("form", { className: "flex flex-col gap-3", onSubmit: function (e) {
51
+ e.preventDefault();
52
+ selectSpecial();
53
+ } },
54
+ react_1.default.createElement("fieldset", { className: "flex flex-col gap-1 border-0 p-0 m-0" },
55
+ react_1.default.createElement("legend", { className: "text-xs font-medium pb-1" }, "Select"),
56
+ go_to_special_1.GO_TO_SPECIAL_OPTIONS.map(function (_a) {
57
+ var kind = _a.kind, label = _a.label;
58
+ return (react_1.default.createElement("label", { key: kind, className: "flex items-center gap-2 text-xs cursor-pointer" },
59
+ react_1.default.createElement("input", { type: "radio", name: "goToSpecial", value: kind, checked: specialKind === kind, onChange: function () {
60
+ setSpecialKind(kind);
61
+ setError(undefined);
62
+ } }),
63
+ label));
64
+ })),
65
+ error ? (react_1.default.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
66
+ react_1.default.createElement(ui_1.Separator, null),
67
+ react_1.default.createElement("div", { className: "flex justify-between gap-2" },
68
+ react_1.default.createElement(ui_1.Button, { type: "button", variant: "ghost", size: "sm", onClick: function () {
69
+ setShowSpecial(false);
70
+ setError(undefined);
71
+ } }, "Back"),
72
+ react_1.default.createElement("div", { className: "flex gap-2" },
73
+ react_1.default.createElement(ui_1.Button, { type: "button", variant: "outline", size: "sm", onClick: function () { return onOpenChange(false); } }, "Cancel"),
74
+ react_1.default.createElement(ui_1.Button, { type: "submit", size: "sm" }, "OK"))))) : (react_1.default.createElement("form", { className: "flex flex-col gap-3", onSubmit: function (e) {
75
+ e.preventDefault();
76
+ navigate(reference);
77
+ } },
78
+ react_1.default.createElement("div", { className: "flex flex-col gap-1" },
79
+ react_1.default.createElement("span", { className: "text-xs font-medium" }, "Go to:"),
80
+ react_1.default.createElement("div", { role: "listbox", "aria-label": "Defined names", className: "h-[140px] overflow-auto rounded border border-rnc-border text-xs" }, names.length === 0 ? (react_1.default.createElement("div", { className: "px-2 py-1.5 text-rnc-foreground/60" }, "No defined names")) : (names.map(function (range) { return (react_1.default.createElement("div", { key: String(range.namedRangeId), role: "option", "aria-selected": reference === range.name, className: (0, ui_1.cn)("px-2 py-1 cursor-default select-none hover:bg-rnc-accent", reference === range.name && "bg-rnc-accent"), onClick: function () {
81
+ setReference(range.name);
82
+ setError(undefined);
83
+ }, onDoubleClick: function () { return navigate(range.name); } }, range.name)); })))),
84
+ react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
85
+ "Reference:",
86
+ react_1.default.createElement(ui_1.Input, { autoFocus: true, value: reference, placeholder: currentAddress, "aria-invalid": error ? true : undefined, onChange: function (e) {
87
+ setReference(e.target.value);
88
+ setError(undefined);
89
+ } })),
90
+ error ? (react_1.default.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
91
+ react_1.default.createElement(ui_1.Separator, null),
92
+ react_1.default.createElement("div", { className: "flex justify-between gap-2" },
93
+ special ? (react_1.default.createElement(ui_1.Button, { type: "button", variant: "ghost", size: "sm", onClick: function () {
94
+ setShowSpecial(true);
95
+ setError(undefined);
96
+ } }, "Special\u2026")) : (react_1.default.createElement("span", null)),
97
+ react_1.default.createElement("div", { className: "flex gap-2" },
98
+ react_1.default.createElement(ui_1.Button, { type: "button", variant: "outline", size: "sm", onClick: function () { return onOpenChange(false); } }, "Cancel"),
99
+ react_1.default.createElement(ui_1.Button, { type: "submit", size: "sm", disabled: !reference.trim() }, "OK")))))))));
100
+ });
101
+ exports.GoToDialog.displayName = "GoToDialog";
102
+ var currentAddressOf = function (request) {
103
+ var _a, _b;
104
+ var address = (_a = (0, utils_1.cellToAddress)(request.activeCell)) !== null && _a !== void 0 ? _a : "";
105
+ var sheetName = (_b = request.getSheetName) === null || _b === void 0 ? void 0 : _b.call(request, request.sheetId);
106
+ return sheetName ? "".concat(sheetName, "!").concat(address) : address;
107
+ };
108
+ /**
109
+ * Host-mounted, atom-driven wrapper around {@link GoToDialog}. Mount it once
110
+ * in the host alongside the other editor dialogs; the grid opens it on
111
+ * `Ctrl+G` / `F5` (unless the host handles `onRequestGoTo` itself).
112
+ */
113
+ var GoToDialogHost = function () {
114
+ (0, go_to_dialog_atom_1.useRegisterGoToDialogHost)();
115
+ var _a = tslib_1.__read((0, go_to_dialog_atom_1.useGoToDialogState)(), 2), request = _a[0], setRequest = _a[1];
116
+ var close = (0, react_1.useCallback)(function () { return setRequest(null); }, [setRequest]);
117
+ var resolve = (0, react_1.useCallback)(function (reference) {
118
+ return request
119
+ ? (0, go_to_1.resolveGoToReference)(reference, {
120
+ sheetId: request.sheetId,
121
+ namedRanges: request.namedRanges,
122
+ getSheetId: request.getSheetId,
123
+ rowCount: request.rowCount,
124
+ columnCount: request.columnCount,
125
+ })
126
+ : undefined;
127
+ }, [request]);
128
+ if (!request)
129
+ return null;
130
+ return (react_1.default.createElement(exports.GoToDialog, { open: true, onOpenChange: function (open) {
131
+ if (!open)
132
+ close();
133
+ }, namedRanges: request.namedRanges, currentAddress: currentAddressOf(request), resolve: resolve, onNavigate: request.onNavigate, special: request.special }));
134
+ };
135
+ exports.GoToDialogHost = GoToDialogHost;
136
+ exports.GoToDialogHost.displayName = "GoToDialogHost";
@@ -0,0 +1,32 @@
1
+ import React from "react";
2
+ import type { GoalSeekResult } from "../../types";
3
+ export type GoalSeekDialogProps = {
4
+ /** Controls visibility. */
5
+ open: boolean;
6
+ onOpenChange(open: boolean): void;
7
+ /** Default "Set cell" (A1 reference of the active cell). */
8
+ initialSetCell: string;
9
+ /**
10
+ * Runs the search with the three fields (A1 references + the numeric
11
+ * target). Resolves to the result, or `undefined` when the engine reports
12
+ * none (the rnc engine iterates natively and streams the cells back).
13
+ */
14
+ onApply(setCell: string, targetValue: number, changingCell: string): Promise<GoalSeekResult | undefined>;
15
+ };
16
+ /** Excel's status sentence for a finished search. */
17
+ export declare const goalSeekStatusText: (setCell: string, result: GoalSeekResult | undefined) => string;
18
+ /**
19
+ * Excel's Goal Seek dialog: Set cell / To value / By changing cell, then the
20
+ * Goal Seek Status sentence with target and current value.
21
+ */
22
+ export declare const GoalSeekDialog: React.MemoExoticComponent<({ open, onOpenChange, initialSetCell, onApply }: GoalSeekDialogProps) => React.JSX.Element>;
23
+ /**
24
+ * Host-mounted, atom-driven wrapper around {@link GoalSeekDialog}. Mount
25
+ * once in the host; the context menu opens it via `useOpenGoalSeekDialog`
26
+ * and only offers the item while a host is mounted.
27
+ */
28
+ export declare const GoalSeekDialogHost: {
29
+ (): React.JSX.Element;
30
+ displayName: string;
31
+ };
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/goal-seek-dialog/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAMtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,mBAAmB,GAAG;IAChC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,4DAA4D;IAC5D,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,OAAO,CACL,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;CACxC,CAAC;AAKF,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,EACf,QAAQ,cAAc,GAAG,SAAS,KACjC,MAKF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,8EACyB,mBAAmB,uBAyJtE,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;CAkB9B,CAAC"}
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GoalSeekDialogHost = exports.GoalSeekDialog = exports.goalSeekStatusText = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var icons_1 = require("@rowsncolumns/icons");
6
+ var ui_1 = require("@rowsncolumns/ui");
7
+ var utils_1 = require("@rowsncolumns/utils");
8
+ var react_1 = tslib_1.__importStar(require("react"));
9
+ var goal_seek_dialog_atom_1 = require("../../atoms/goal-seek-dialog.atom");
10
+ var isCellReference = function (text) {
11
+ return /^\$?[A-Za-z]{1,3}\$?\d+$/.test(text.trim()) && (0, utils_1.addressToCell)(text.trim()) != null;
12
+ };
13
+ /** Excel's status sentence for a finished search. */
14
+ var goalSeekStatusText = function (setCell, result) {
15
+ if (!result)
16
+ return "Goal Seeking with Cell ".concat(setCell, " finished.");
17
+ return result.status === "found"
18
+ ? "Goal Seeking with Cell ".concat(setCell, " found a solution.")
19
+ : "Goal Seeking with Cell ".concat(setCell, " may not have found a solution.");
20
+ };
21
+ exports.goalSeekStatusText = goalSeekStatusText;
22
+ /**
23
+ * Excel's Goal Seek dialog: Set cell / To value / By changing cell, then the
24
+ * Goal Seek Status sentence with target and current value.
25
+ */
26
+ exports.GoalSeekDialog = (0, react_1.memo)(function (_a) {
27
+ var open = _a.open, onOpenChange = _a.onOpenChange, initialSetCell = _a.initialSetCell, onApply = _a.onApply;
28
+ var _b = tslib_1.__read((0, react_1.useState)(initialSetCell), 2), setCell = _b[0], setSetCell = _b[1];
29
+ var _c = tslib_1.__read((0, react_1.useState)(""), 2), target = _c[0], setTarget = _c[1];
30
+ var _d = tslib_1.__read((0, react_1.useState)(""), 2), changingCell = _d[0], setChangingCell = _d[1];
31
+ var _e = tslib_1.__read((0, react_1.useState)(undefined), 2), error = _e[0], setError = _e[1];
32
+ var _f = tslib_1.__read((0, react_1.useState)(false), 2), busy = _f[0], setBusy = _f[1];
33
+ var _g = tslib_1.__read((0, react_1.useState)(undefined), 2), result = _g[0], setResult = _g[1];
34
+ (0, react_1.useEffect)(function () {
35
+ if (open) {
36
+ setSetCell(initialSetCell);
37
+ setTarget("");
38
+ setChangingCell("");
39
+ setError(undefined);
40
+ setBusy(false);
41
+ setResult(undefined);
42
+ }
43
+ // Only reset on open transitions.
44
+ // eslint-disable-next-line react-hooks/exhaustive-deps
45
+ }, [open]);
46
+ var submit = (0, react_1.useCallback)(function (event) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
47
+ var targetValue, outcome, err_1;
48
+ return tslib_1.__generator(this, function (_a) {
49
+ switch (_a.label) {
50
+ case 0:
51
+ event.preventDefault();
52
+ targetValue = Number(target.trim());
53
+ if (!isCellReference(setCell)) {
54
+ setError("Set cell must be a single cell reference, e.g. B4.");
55
+ return [2 /*return*/];
56
+ }
57
+ if (target.trim() === "" || !Number.isFinite(targetValue)) {
58
+ setError("To value must be a number.");
59
+ return [2 /*return*/];
60
+ }
61
+ if (!isCellReference(changingCell)) {
62
+ setError("By changing cell must be a single cell reference, e.g. A1.");
63
+ return [2 /*return*/];
64
+ }
65
+ setError(undefined);
66
+ setBusy(true);
67
+ _a.label = 1;
68
+ case 1:
69
+ _a.trys.push([1, 3, 4, 5]);
70
+ return [4 /*yield*/, onApply(setCell.trim().toUpperCase(), targetValue, changingCell.trim().toUpperCase())];
71
+ case 2:
72
+ outcome = _a.sent();
73
+ setResult({ setCell: setCell.trim().toUpperCase(), result: outcome });
74
+ return [3 /*break*/, 5];
75
+ case 3:
76
+ err_1 = _a.sent();
77
+ setError(err_1 instanceof Error ? err_1.message : "Goal Seek failed.");
78
+ return [3 /*break*/, 5];
79
+ case 4:
80
+ setBusy(false);
81
+ return [7 /*endfinally*/];
82
+ case 5: return [2 /*return*/];
83
+ }
84
+ });
85
+ }); }, [setCell, target, changingCell, onApply]);
86
+ return (react_1.default.createElement(ui_1.Dialog, { open: open, onOpenChange: onOpenChange },
87
+ react_1.default.createElement(ui_1.DialogContent, { className: "w-[360px] max-w-[92vw] pointer-events-auto" },
88
+ react_1.default.createElement(ui_1.DialogTitle, null, result ? "Goal Seek Status" : "Goal Seek"),
89
+ react_1.default.createElement(ui_1.DialogDescription, null, "Find the input value that makes a formula reach a target."),
90
+ react_1.default.createElement(ui_1.DialogCloseButton, { onClick: function () { return onOpenChange(false); } },
91
+ react_1.default.createElement(icons_1.Cross1Icon, null)),
92
+ react_1.default.createElement(ui_1.DialogBody, { className: "flex flex-col gap-3 font-system text-sm" }, result ? (react_1.default.createElement("div", { className: "flex flex-col gap-2", role: "status" },
93
+ react_1.default.createElement("div", null, (0, exports.goalSeekStatusText)(result.setCell, result.result)),
94
+ result.result ? (react_1.default.createElement("dl", { className: "grid grid-cols-2 gap-1 text-xs" },
95
+ react_1.default.createElement("dt", { className: "text-rnc-foreground/70" }, "Target value:"),
96
+ react_1.default.createElement("dd", null, result.result.targetValue),
97
+ react_1.default.createElement("dt", { className: "text-rnc-foreground/70" }, "Current value:"),
98
+ react_1.default.createElement("dd", null, result.result.currentValue === undefined
99
+ ? "—"
100
+ : String(result.result.currentValue)))) : null,
101
+ react_1.default.createElement(ui_1.Separator, null),
102
+ react_1.default.createElement("div", { className: "flex justify-end gap-2" },
103
+ react_1.default.createElement(ui_1.Button, { size: "sm", type: "button", onClick: function () { return onOpenChange(false); } }, "OK")))) : (react_1.default.createElement("form", { className: "flex flex-col gap-3", onSubmit: submit },
104
+ react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
105
+ "Set cell:",
106
+ react_1.default.createElement(ui_1.Input, { autoFocus: true, value: setCell, "aria-label": "Set cell", onChange: function (e) {
107
+ setSetCell(e.target.value);
108
+ setError(undefined);
109
+ } })),
110
+ react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
111
+ "To value:",
112
+ react_1.default.createElement(ui_1.Input, { value: target, "aria-label": "To value", inputMode: "decimal", onChange: function (e) {
113
+ setTarget(e.target.value);
114
+ setError(undefined);
115
+ } })),
116
+ react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
117
+ "By changing cell:",
118
+ react_1.default.createElement(ui_1.Input, { value: changingCell, "aria-label": "By changing cell", onChange: function (e) {
119
+ setChangingCell(e.target.value);
120
+ setError(undefined);
121
+ } })),
122
+ error ? (react_1.default.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
123
+ react_1.default.createElement(ui_1.Separator, null),
124
+ react_1.default.createElement("div", { className: "flex justify-end gap-2" },
125
+ react_1.default.createElement(ui_1.Button, { type: "button", variant: "outline", size: "sm", onClick: function () { return onOpenChange(false); } }, "Cancel"),
126
+ react_1.default.createElement(ui_1.Button, { type: "submit", size: "sm", disabled: busy }, busy ? "Seeking…" : "OK"))))))));
127
+ });
128
+ exports.GoalSeekDialog.displayName = "GoalSeekDialog";
129
+ /**
130
+ * Host-mounted, atom-driven wrapper around {@link GoalSeekDialog}. Mount
131
+ * once in the host; the context menu opens it via `useOpenGoalSeekDialog`
132
+ * and only offers the item while a host is mounted.
133
+ */
134
+ var GoalSeekDialogHost = function () {
135
+ var _a;
136
+ (0, goal_seek_dialog_atom_1.useRegisterGoalSeekDialogHost)();
137
+ var _b = tslib_1.__read((0, goal_seek_dialog_atom_1.useGoalSeekDialogState)(), 2), request = _b[0], setRequest = _b[1];
138
+ var close = (0, react_1.useCallback)(function () { return setRequest(null); }, [setRequest]);
139
+ return (react_1.default.createElement(exports.GoalSeekDialog, { open: request != null, onOpenChange: function (open) {
140
+ if (!open)
141
+ close();
142
+ }, initialSetCell: (_a = request === null || request === void 0 ? void 0 : request.setCell) !== null && _a !== void 0 ? _a : "", onApply: function (setCell, targetValue, changingCell) {
143
+ return request
144
+ ? request.onApply(setCell, targetValue, changingCell)
145
+ : Promise.resolve(undefined);
146
+ } }));
147
+ };
148
+ exports.GoalSeekDialogHost = GoalSeekDialogHost;
149
+ exports.GoalSeekDialogHost.displayName = "GoalSeekDialogHost";
@@ -0,0 +1,29 @@
1
+ import React from "react";
2
+ import type { PasteSpecialOptions } from "../../hooks/use-copy-paste-cut";
3
+ export type PasteSpecialDialogProps = {
4
+ /** Controls visibility. */
5
+ open: boolean;
6
+ onOpenChange(open: boolean): void;
7
+ /**
8
+ * Emits the assembled request. The host routes it to the grid's
9
+ * `paste(options)`; the dialog never touches the clipboard itself.
10
+ */
11
+ onApply(options: PasteSpecialOptions): void;
12
+ };
13
+ /**
14
+ * Excel's Paste Special dialog: what to paste (all / formulas / values /
15
+ * formats), an arithmetic operation against the destination, skip blanks and
16
+ * transpose. Every choice composes into one `PasteSpecialOptions` request.
17
+ */
18
+ export declare const PasteSpecialDialog: React.MemoExoticComponent<({ open, onOpenChange, onApply }: PasteSpecialDialogProps) => React.JSX.Element>;
19
+ /**
20
+ * Host-mounted, atom-driven wrapper around {@link PasteSpecialDialog}. Mount
21
+ * it once in the host alongside the other editor dialogs; the grid opens it
22
+ * from the context menu ("Paste special…") and `Ctrl+Alt+V`. Remounted per
23
+ * request so each opening starts from Excel's defaults.
24
+ */
25
+ export declare const PasteSpecialDialogHost: {
26
+ (): React.JSX.Element | null;
27
+ displayName: string;
28
+ };
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/paste-special-dialog/index.tsx"],"names":[],"mappings":"AASA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAM3D,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,gCAAgC,CAAC;AAoBxC,MAAM,MAAM,uBAAuB,GAAG;IACpC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAC7C,CAAC;AAyCF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,8DACK,uBAAuB,uBA2F1D,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;CAclC,CAAC"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PasteSpecialDialogHost = exports.PasteSpecialDialog = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var ui_1 = require("@rowsncolumns/ui");
6
+ var react_1 = tslib_1.__importStar(require("react"));
7
+ var paste_special_dialog_atom_1 = require("../../atoms/paste-special-dialog.atom");
8
+ var PASTE_MODES = [
9
+ { value: "all", label: "All" },
10
+ { value: "formulas", label: "Formulas" },
11
+ { value: "values", label: "Values" },
12
+ { value: "formats", label: "Formats" },
13
+ ];
14
+ var OPERATIONS = [
15
+ { value: "none", label: "None" },
16
+ { value: "add", label: "Add" },
17
+ { value: "subtract", label: "Subtract" },
18
+ { value: "multiply", label: "Multiply" },
19
+ { value: "divide", label: "Divide" },
20
+ ];
21
+ var RadioGroup = function (_a) {
22
+ var name = _a.name, legend = _a.legend, value = _a.value, options = _a.options, onChange = _a.onChange, disabled = _a.disabled;
23
+ return (react_1.default.createElement("fieldset", { className: "flex flex-col gap-1 min-w-0 disabled:opacity-50", disabled: disabled },
24
+ react_1.default.createElement("legend", { className: "text-xs font-medium mb-1" }, legend),
25
+ options.map(function (option) { return (react_1.default.createElement("label", { key: option.value, className: "flex items-center gap-2 text-xs py-0.5 cursor-pointer" },
26
+ react_1.default.createElement("input", { type: "radio", name: name, value: option.value, checked: value === option.value, disabled: disabled, onChange: function () { return onChange(option.value); } }),
27
+ option.label)); })));
28
+ };
29
+ /**
30
+ * Excel's Paste Special dialog: what to paste (all / formulas / values /
31
+ * formats), an arithmetic operation against the destination, skip blanks and
32
+ * transpose. Every choice composes into one `PasteSpecialOptions` request.
33
+ */
34
+ exports.PasteSpecialDialog = (0, react_1.memo)(function (_a) {
35
+ var open = _a.open, onOpenChange = _a.onOpenChange, onApply = _a.onApply;
36
+ var _b = tslib_1.__read((0, react_1.useState)("all"), 2), paste = _b[0], setPaste = _b[1];
37
+ var _c = tslib_1.__read((0, react_1.useState)("none"), 2), operation = _c[0], setOperation = _c[1];
38
+ var _d = tslib_1.__read((0, react_1.useState)(false), 2), skipBlanks = _d[0], setSkipBlanks = _d[1];
39
+ var _e = tslib_1.__read((0, react_1.useState)(false), 2), transpose = _e[0], setTranspose = _e[1];
40
+ // Excel greys Operation out under Paste → Formats (a formats paste never
41
+ // changes destination values); the choice is kept but not applied.
42
+ var operationDisabled = paste === "formats";
43
+ var commit = (0, react_1.useCallback)(function () {
44
+ onApply({
45
+ paste: paste,
46
+ operation: operation === "none" || operationDisabled ? undefined : operation,
47
+ skipBlanks: skipBlanks,
48
+ transpose: transpose,
49
+ });
50
+ onOpenChange(false);
51
+ }, [
52
+ onApply,
53
+ onOpenChange,
54
+ paste,
55
+ operation,
56
+ operationDisabled,
57
+ skipBlanks,
58
+ transpose,
59
+ ]);
60
+ return (react_1.default.createElement(ui_1.Dialog, { open: open, onOpenChange: onOpenChange, modal: true },
61
+ react_1.default.createElement(ui_1.DialogContent, { className: "w-[380px] max-w-[92vw] pointer-events-auto" },
62
+ react_1.default.createElement(ui_1.DialogTitle, null, "Paste Special"),
63
+ react_1.default.createElement(ui_1.DialogCloseButton, null),
64
+ react_1.default.createElement(ui_1.DialogBody, { className: "flex flex-col gap-4" },
65
+ react_1.default.createElement("div", { className: "grid grid-cols-2 gap-4" },
66
+ react_1.default.createElement(RadioGroup, { name: "paste-special-paste", legend: "Paste", value: paste, options: PASTE_MODES, onChange: setPaste }),
67
+ react_1.default.createElement(RadioGroup, { name: "paste-special-operation", legend: "Operation", value: operation, options: OPERATIONS, onChange: setOperation, disabled: operationDisabled })),
68
+ react_1.default.createElement("div", { className: "flex flex-col gap-1" },
69
+ react_1.default.createElement("label", { className: "flex items-center gap-2 text-xs py-0.5 cursor-pointer" },
70
+ react_1.default.createElement("input", { type: "checkbox", checked: skipBlanks, onChange: function (e) { return setSkipBlanks(e.target.checked); } }),
71
+ "Skip blanks"),
72
+ react_1.default.createElement("label", { className: "flex items-center gap-2 text-xs py-0.5 cursor-pointer" },
73
+ react_1.default.createElement("input", { type: "checkbox", checked: transpose, onChange: function (e) { return setTranspose(e.target.checked); } }),
74
+ "Transpose")),
75
+ react_1.default.createElement(ui_1.Separator, null),
76
+ react_1.default.createElement("div", { className: "flex justify-end gap-2" },
77
+ react_1.default.createElement(ui_1.Button, { variant: "outline", size: "sm", onClick: function () { return onOpenChange(false); } }, "Cancel"),
78
+ react_1.default.createElement(ui_1.Button, { size: "sm", onClick: commit }, "OK"))))));
79
+ });
80
+ exports.PasteSpecialDialog.displayName = "PasteSpecialDialog";
81
+ /**
82
+ * Host-mounted, atom-driven wrapper around {@link PasteSpecialDialog}. Mount
83
+ * it once in the host alongside the other editor dialogs; the grid opens it
84
+ * from the context menu ("Paste special…") and `Ctrl+Alt+V`. Remounted per
85
+ * request so each opening starts from Excel's defaults.
86
+ */
87
+ var PasteSpecialDialogHost = function () {
88
+ (0, paste_special_dialog_atom_1.useRegisterPasteSpecialDialogHost)();
89
+ var _a = tslib_1.__read((0, paste_special_dialog_atom_1.usePasteSpecialDialogState)(), 2), request = _a[0], setRequest = _a[1];
90
+ var close = (0, react_1.useCallback)(function () { return setRequest(null); }, [setRequest]);
91
+ if (!request)
92
+ return null;
93
+ return (react_1.default.createElement(exports.PasteSpecialDialog, { open: true, onOpenChange: function (open) {
94
+ if (!open)
95
+ close();
96
+ }, onApply: request.onApply }));
97
+ };
98
+ exports.PasteSpecialDialogHost = PasteSpecialDialogHost;
99
+ exports.PasteSpecialDialogHost.displayName = "PasteSpecialDialogHost";