@rowsncolumns/spreadsheet 10.6.5 → 10.7.0

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 (284) hide show
  1. package/dist/cjs/api/autocomplete.d.ts +42 -0
  2. package/dist/cjs/api/autocomplete.d.ts.map +1 -0
  3. package/dist/cjs/api/autocomplete.js +114 -0
  4. package/dist/cjs/api/banded-ranges.d.ts.map +1 -1
  5. package/dist/cjs/api/banded-ranges.js +51 -1
  6. package/dist/cjs/api/error-checking.d.ts +82 -0
  7. package/dist/cjs/api/error-checking.d.ts.map +1 -0
  8. package/dist/cjs/api/error-checking.js +207 -0
  9. package/dist/cjs/api/move-overwrite.d.ts +8 -2
  10. package/dist/cjs/api/move-overwrite.d.ts.map +1 -1
  11. package/dist/cjs/api/move-overwrite.js +19 -3
  12. package/dist/cjs/api/selections.d.ts +2 -2
  13. package/dist/cjs/api/validation.d.ts +39 -1
  14. package/dist/cjs/api/validation.d.ts.map +1 -1
  15. package/dist/cjs/api/validation.js +87 -1
  16. package/dist/cjs/atoms/cell-input-context.atom.d.ts +4 -1
  17. package/dist/cjs/atoms/cell-input-context.atom.d.ts.map +1 -1
  18. package/dist/cjs/atoms/enter-key-direction.atom.d.ts +11 -0
  19. package/dist/cjs/atoms/enter-key-direction.atom.d.ts.map +1 -0
  20. package/dist/cjs/atoms/enter-key-direction.atom.js +13 -0
  21. package/dist/cjs/atoms/index.d.ts +1 -0
  22. package/dist/cjs/atoms/index.d.ts.map +1 -1
  23. package/dist/cjs/atoms/index.js +1 -0
  24. package/dist/cjs/atoms/paste-menu.atom.d.ts +22 -0
  25. package/dist/cjs/atoms/paste-menu.atom.d.ts.map +1 -1
  26. package/dist/cjs/atoms/paste-menu.atom.js +13 -1
  27. package/dist/cjs/atoms/pick-list.atom.d.ts +15 -0
  28. package/dist/cjs/atoms/pick-list.atom.d.ts.map +1 -0
  29. package/dist/cjs/atoms/pick-list.atom.js +7 -0
  30. package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
  31. package/dist/cjs/components/canvas-grid/index.js +305 -70
  32. package/dist/cjs/components/canvas-grid/typings.d.ts +96 -11
  33. package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
  34. package/dist/cjs/components/cell/index.d.ts.map +1 -1
  35. package/dist/cjs/components/cell/index.js +7 -8
  36. package/dist/cjs/components/cell/typings.d.ts +9 -0
  37. package/dist/cjs/components/cell/typings.d.ts.map +1 -1
  38. package/dist/cjs/components/cell-editor/helpers.d.ts +22 -2
  39. package/dist/cjs/components/cell-editor/helpers.d.ts.map +1 -1
  40. package/dist/cjs/components/cell-editor/helpers.js +32 -8
  41. package/dist/cjs/components/cell-editor/index.d.ts +7 -1
  42. package/dist/cjs/components/cell-editor/index.d.ts.map +1 -1
  43. package/dist/cjs/components/cell-editor/index.js +85 -13
  44. package/dist/cjs/components/cell-indicator/index.d.ts +41 -0
  45. package/dist/cjs/components/cell-indicator/index.d.ts.map +1 -0
  46. package/dist/cjs/components/cell-indicator/index.js +90 -0
  47. package/dist/cjs/components/cell-input/cell-input.d.ts +10 -2
  48. package/dist/cjs/components/cell-input/cell-input.d.ts.map +1 -1
  49. package/dist/cjs/components/cell-input/cell-input.js +5 -3
  50. package/dist/cjs/components/cell-input/formula-bar-cell-input.d.ts.map +1 -1
  51. package/dist/cjs/components/cell-input/formula-bar-cell-input.js +9 -2
  52. package/dist/cjs/components/cell-structured/sparkline-math.d.ts +27 -1
  53. package/dist/cjs/components/cell-structured/sparkline-math.d.ts.map +1 -1
  54. package/dist/cjs/components/cell-structured/sparkline-math.js +48 -1
  55. package/dist/cjs/components/cell-structured/sparkline.d.ts +1 -1
  56. package/dist/cjs/components/cell-structured/sparkline.d.ts.map +1 -1
  57. package/dist/cjs/components/cell-structured/sparkline.js +36 -92
  58. package/dist/cjs/components/cell-structured/types.d.ts +6 -0
  59. package/dist/cjs/components/cell-structured/types.d.ts.map +1 -1
  60. package/dist/cjs/components/data-table-dialog/index.d.ts +22 -0
  61. package/dist/cjs/components/data-table-dialog/index.d.ts.map +1 -0
  62. package/dist/cjs/components/data-table-dialog/index.js +93 -0
  63. package/dist/cjs/components/error-check-smart-tag/index.d.ts +27 -0
  64. package/dist/cjs/components/error-check-smart-tag/index.d.ts.map +1 -0
  65. package/dist/cjs/components/error-check-smart-tag/index.js +39 -0
  66. package/dist/cjs/components/forecast-sheet-dialog/index.d.ts +26 -0
  67. package/dist/cjs/components/forecast-sheet-dialog/index.d.ts.map +1 -0
  68. package/dist/cjs/components/forecast-sheet-dialog/index.js +92 -0
  69. package/dist/cjs/components/paste-special-dialog/index.d.ts +3 -3
  70. package/dist/cjs/components/paste-special-dialog/index.d.ts.map +1 -1
  71. package/dist/cjs/components/paste-special-dialog/index.js +61 -23
  72. package/dist/cjs/components/protect-sheet-dialog/allow-edit-ranges-dialog.d.ts +57 -0
  73. package/dist/cjs/components/protect-sheet-dialog/allow-edit-ranges-dialog.d.ts.map +1 -0
  74. package/dist/cjs/components/protect-sheet-dialog/allow-edit-ranges-dialog.js +196 -0
  75. package/dist/cjs/components/protect-sheet-dialog/constants.d.ts +3 -0
  76. package/dist/cjs/components/protect-sheet-dialog/constants.d.ts.map +1 -0
  77. package/dist/cjs/components/protect-sheet-dialog/constants.js +5 -0
  78. package/dist/cjs/components/protect-sheet-dialog/index.d.ts +2 -2
  79. package/dist/cjs/components/protect-sheet-dialog/index.d.ts.map +1 -1
  80. package/dist/cjs/components/protect-sheet-dialog/index.js +5 -3
  81. package/dist/cjs/components/scenario-manager-dialog/index.d.ts +51 -0
  82. package/dist/cjs/components/scenario-manager-dialog/index.d.ts.map +1 -0
  83. package/dist/cjs/components/scenario-manager-dialog/index.js +257 -0
  84. package/dist/cjs/components/selection/index.d.ts +1 -1
  85. package/dist/cjs/components/selection/index.d.ts.map +1 -1
  86. package/dist/cjs/components/selection/index.js +9 -4
  87. package/dist/cjs/components/selection/paste-menu.d.ts +14 -1
  88. package/dist/cjs/components/selection/paste-menu.d.ts.map +1 -1
  89. package/dist/cjs/components/selection/paste-menu.js +78 -6
  90. package/dist/cjs/components/selection/paste-options.d.ts +28 -0
  91. package/dist/cjs/components/selection/paste-options.d.ts.map +1 -0
  92. package/dist/cjs/components/selection/paste-options.js +70 -0
  93. package/dist/cjs/components/selection/types.d.ts +12 -1
  94. package/dist/cjs/components/selection/types.d.ts.map +1 -1
  95. package/dist/cjs/components/selection-drop-menu/index.d.ts +18 -0
  96. package/dist/cjs/components/selection-drop-menu/index.d.ts.map +1 -0
  97. package/dist/cjs/components/selection-drop-menu/index.js +62 -0
  98. package/dist/cjs/components/solver-dialog/index.d.ts +57 -0
  99. package/dist/cjs/components/solver-dialog/index.d.ts.map +1 -0
  100. package/dist/cjs/components/solver-dialog/index.js +204 -0
  101. package/dist/cjs/components/toolbar/sparkline-actions.d.ts +3 -2
  102. package/dist/cjs/components/toolbar/sparkline-actions.d.ts.map +1 -1
  103. package/dist/cjs/components/toolbar/sparkline-actions.js +6 -2
  104. package/dist/cjs/components/toolbar/table-style-selector.d.ts.map +1 -1
  105. package/dist/cjs/components/toolbar/table-style-selector.js +33 -2
  106. package/dist/cjs/config.d.ts +5 -4
  107. package/dist/cjs/config.d.ts.map +1 -1
  108. package/dist/cjs/config.js +13 -9
  109. package/dist/cjs/hooks/use-cell-renderer.d.ts +12 -1
  110. package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
  111. package/dist/cjs/hooks/use-cell-renderer.js +6 -3
  112. package/dist/cjs/hooks/use-copy-paste-cut.d.ts +36 -2
  113. package/dist/cjs/hooks/use-copy-paste-cut.d.ts.map +1 -1
  114. package/dist/cjs/hooks/use-copy-paste-cut.js +131 -5
  115. package/dist/cjs/hooks/use-editable.d.ts +6 -0
  116. package/dist/cjs/hooks/use-editable.d.ts.map +1 -1
  117. package/dist/cjs/hooks/use-editor-submit.d.ts +45 -3
  118. package/dist/cjs/hooks/use-editor-submit.d.ts.map +1 -1
  119. package/dist/cjs/hooks/use-editor-submit.js +91 -7
  120. package/dist/cjs/hooks/use-keyboard-handler.d.ts +5 -1
  121. package/dist/cjs/hooks/use-keyboard-handler.d.ts.map +1 -1
  122. package/dist/cjs/hooks/use-keyboard-handler.js +10 -1
  123. package/dist/cjs/hooks/use-selection-drag-copy.d.ts +55 -0
  124. package/dist/cjs/hooks/use-selection-drag-copy.d.ts.map +1 -0
  125. package/dist/cjs/hooks/use-selection-drag-copy.js +274 -0
  126. package/dist/cjs/hooks/use-selection-renderer.d.ts +8 -1
  127. package/dist/cjs/hooks/use-selection-renderer.d.ts.map +1 -1
  128. package/dist/cjs/hooks/use-selection-renderer.js +7 -2
  129. package/dist/cjs/hooks/use-selection.d.ts +59 -1
  130. package/dist/cjs/hooks/use-selection.d.ts.map +1 -1
  131. package/dist/cjs/hooks/use-selection.js +270 -61
  132. package/dist/cjs/index.d.ts +6 -1
  133. package/dist/cjs/index.d.ts.map +1 -1
  134. package/dist/cjs/index.js +5 -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 +50 -1
  138. package/dist/cjs/types.d.ts.map +1 -1
  139. package/dist/esm/api/autocomplete.d.ts +42 -0
  140. package/dist/esm/api/autocomplete.d.ts.map +1 -0
  141. package/dist/esm/api/autocomplete.js +91 -0
  142. package/dist/esm/api/banded-ranges.d.ts.map +1 -1
  143. package/dist/esm/api/banded-ranges.js +52 -2
  144. package/dist/esm/api/error-checking.d.ts +82 -0
  145. package/dist/esm/api/error-checking.d.ts.map +1 -0
  146. package/dist/esm/api/error-checking.js +156 -0
  147. package/dist/esm/api/move-overwrite.d.ts +8 -2
  148. package/dist/esm/api/move-overwrite.d.ts.map +1 -1
  149. package/dist/esm/api/move-overwrite.js +17 -2
  150. package/dist/esm/api/selections.d.ts +2 -2
  151. package/dist/esm/api/validation.d.ts +39 -1
  152. package/dist/esm/api/validation.d.ts.map +1 -1
  153. package/dist/esm/api/validation.js +70 -0
  154. package/dist/esm/atoms/cell-input-context.atom.d.ts +4 -1
  155. package/dist/esm/atoms/cell-input-context.atom.d.ts.map +1 -1
  156. package/dist/esm/atoms/enter-key-direction.atom.d.ts +11 -0
  157. package/dist/esm/atoms/enter-key-direction.atom.d.ts.map +1 -0
  158. package/dist/esm/atoms/enter-key-direction.atom.js +8 -0
  159. package/dist/esm/atoms/index.d.ts +1 -0
  160. package/dist/esm/atoms/index.d.ts.map +1 -1
  161. package/dist/esm/atoms/index.js +1 -0
  162. package/dist/esm/atoms/paste-menu.atom.d.ts +22 -0
  163. package/dist/esm/atoms/paste-menu.atom.d.ts.map +1 -1
  164. package/dist/esm/atoms/paste-menu.atom.js +10 -1
  165. package/dist/esm/atoms/pick-list.atom.d.ts +15 -0
  166. package/dist/esm/atoms/pick-list.atom.d.ts.map +1 -0
  167. package/dist/esm/atoms/pick-list.atom.js +3 -0
  168. package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
  169. package/dist/esm/components/canvas-grid/index.js +239 -13
  170. package/dist/esm/components/canvas-grid/typings.d.ts +96 -11
  171. package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
  172. package/dist/esm/components/cell/index.d.ts.map +1 -1
  173. package/dist/esm/components/cell/index.js +8 -9
  174. package/dist/esm/components/cell/typings.d.ts +9 -0
  175. package/dist/esm/components/cell/typings.d.ts.map +1 -1
  176. package/dist/esm/components/cell-editor/helpers.d.ts +22 -2
  177. package/dist/esm/components/cell-editor/helpers.d.ts.map +1 -1
  178. package/dist/esm/components/cell-editor/helpers.js +25 -7
  179. package/dist/esm/components/cell-editor/index.d.ts +7 -1
  180. package/dist/esm/components/cell-editor/index.d.ts.map +1 -1
  181. package/dist/esm/components/cell-editor/index.js +80 -9
  182. package/dist/esm/components/cell-indicator/index.d.ts +41 -0
  183. package/dist/esm/components/cell-indicator/index.d.ts.map +1 -0
  184. package/dist/esm/components/cell-indicator/index.js +76 -0
  185. package/dist/esm/components/cell-input/cell-input.d.ts +10 -2
  186. package/dist/esm/components/cell-input/cell-input.d.ts.map +1 -1
  187. package/dist/esm/components/cell-input/cell-input.js +5 -3
  188. package/dist/esm/components/cell-input/formula-bar-cell-input.d.ts.map +1 -1
  189. package/dist/esm/components/cell-input/formula-bar-cell-input.js +9 -2
  190. package/dist/esm/components/cell-structured/sparkline-math.d.ts +27 -1
  191. package/dist/esm/components/cell-structured/sparkline-math.d.ts.map +1 -1
  192. package/dist/esm/components/cell-structured/sparkline-math.js +35 -0
  193. package/dist/esm/components/cell-structured/sparkline.d.ts +1 -1
  194. package/dist/esm/components/cell-structured/sparkline.d.ts.map +1 -1
  195. package/dist/esm/components/cell-structured/sparkline.js +34 -88
  196. package/dist/esm/components/cell-structured/types.d.ts +6 -0
  197. package/dist/esm/components/cell-structured/types.d.ts.map +1 -1
  198. package/dist/esm/components/data-table-dialog/index.d.ts +22 -0
  199. package/dist/esm/components/data-table-dialog/index.d.ts.map +1 -0
  200. package/dist/esm/components/data-table-dialog/index.js +75 -0
  201. package/dist/esm/components/error-check-smart-tag/index.d.ts +27 -0
  202. package/dist/esm/components/error-check-smart-tag/index.d.ts.map +1 -0
  203. package/dist/esm/components/error-check-smart-tag/index.js +33 -0
  204. package/dist/esm/components/forecast-sheet-dialog/index.d.ts +26 -0
  205. package/dist/esm/components/forecast-sheet-dialog/index.d.ts.map +1 -0
  206. package/dist/esm/components/forecast-sheet-dialog/index.js +83 -0
  207. package/dist/esm/components/paste-special-dialog/index.d.ts +3 -3
  208. package/dist/esm/components/paste-special-dialog/index.d.ts.map +1 -1
  209. package/dist/esm/components/paste-special-dialog/index.js +58 -23
  210. package/dist/esm/components/protect-sheet-dialog/allow-edit-ranges-dialog.d.ts +57 -0
  211. package/dist/esm/components/protect-sheet-dialog/allow-edit-ranges-dialog.d.ts.map +1 -0
  212. package/dist/esm/components/protect-sheet-dialog/allow-edit-ranges-dialog.js +177 -0
  213. package/dist/esm/components/protect-sheet-dialog/constants.d.ts +3 -0
  214. package/dist/esm/components/protect-sheet-dialog/constants.d.ts.map +1 -0
  215. package/dist/esm/components/protect-sheet-dialog/constants.js +2 -0
  216. package/dist/esm/components/protect-sheet-dialog/index.d.ts +2 -2
  217. package/dist/esm/components/protect-sheet-dialog/index.d.ts.map +1 -1
  218. package/dist/esm/components/protect-sheet-dialog/index.js +3 -2
  219. package/dist/esm/components/scenario-manager-dialog/index.d.ts +51 -0
  220. package/dist/esm/components/scenario-manager-dialog/index.d.ts.map +1 -0
  221. package/dist/esm/components/scenario-manager-dialog/index.js +213 -0
  222. package/dist/esm/components/selection/index.d.ts +1 -1
  223. package/dist/esm/components/selection/index.d.ts.map +1 -1
  224. package/dist/esm/components/selection/index.js +9 -4
  225. package/dist/esm/components/selection/paste-menu.d.ts +14 -1
  226. package/dist/esm/components/selection/paste-menu.d.ts.map +1 -1
  227. package/dist/esm/components/selection/paste-menu.js +76 -8
  228. package/dist/esm/components/selection/paste-options.d.ts +28 -0
  229. package/dist/esm/components/selection/paste-options.d.ts.map +1 -0
  230. package/dist/esm/components/selection/paste-options.js +62 -0
  231. package/dist/esm/components/selection/types.d.ts +12 -1
  232. package/dist/esm/components/selection/types.d.ts.map +1 -1
  233. package/dist/esm/components/selection-drop-menu/index.d.ts +18 -0
  234. package/dist/esm/components/selection-drop-menu/index.d.ts.map +1 -0
  235. package/dist/esm/components/selection-drop-menu/index.js +56 -0
  236. package/dist/esm/components/solver-dialog/index.d.ts +57 -0
  237. package/dist/esm/components/solver-dialog/index.d.ts.map +1 -0
  238. package/dist/esm/components/solver-dialog/index.js +176 -0
  239. package/dist/esm/components/toolbar/sparkline-actions.d.ts +3 -2
  240. package/dist/esm/components/toolbar/sparkline-actions.d.ts.map +1 -1
  241. package/dist/esm/components/toolbar/sparkline-actions.js +6 -2
  242. package/dist/esm/components/toolbar/table-style-selector.d.ts.map +1 -1
  243. package/dist/esm/components/toolbar/table-style-selector.js +29 -3
  244. package/dist/esm/config.d.ts +5 -4
  245. package/dist/esm/config.d.ts.map +1 -1
  246. package/dist/esm/config.js +12 -8
  247. package/dist/esm/hooks/use-cell-renderer.d.ts +12 -1
  248. package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
  249. package/dist/esm/hooks/use-cell-renderer.js +5 -2
  250. package/dist/esm/hooks/use-copy-paste-cut.d.ts +36 -2
  251. package/dist/esm/hooks/use-copy-paste-cut.d.ts.map +1 -1
  252. package/dist/esm/hooks/use-copy-paste-cut.js +117 -6
  253. package/dist/esm/hooks/use-editable.d.ts +6 -0
  254. package/dist/esm/hooks/use-editable.d.ts.map +1 -1
  255. package/dist/esm/hooks/use-editor-submit.d.ts +45 -3
  256. package/dist/esm/hooks/use-editor-submit.d.ts.map +1 -1
  257. package/dist/esm/hooks/use-editor-submit.js +81 -6
  258. package/dist/esm/hooks/use-keyboard-handler.d.ts +5 -1
  259. package/dist/esm/hooks/use-keyboard-handler.d.ts.map +1 -1
  260. package/dist/esm/hooks/use-keyboard-handler.js +10 -1
  261. package/dist/esm/hooks/use-selection-drag-copy.d.ts +55 -0
  262. package/dist/esm/hooks/use-selection-drag-copy.d.ts.map +1 -0
  263. package/dist/esm/hooks/use-selection-drag-copy.js +245 -0
  264. package/dist/esm/hooks/use-selection-renderer.d.ts +8 -1
  265. package/dist/esm/hooks/use-selection-renderer.d.ts.map +1 -1
  266. package/dist/esm/hooks/use-selection-renderer.js +7 -2
  267. package/dist/esm/hooks/use-selection.d.ts +59 -1
  268. package/dist/esm/hooks/use-selection.d.ts.map +1 -1
  269. package/dist/esm/hooks/use-selection.js +245 -52
  270. package/dist/esm/index.d.ts +6 -1
  271. package/dist/esm/index.d.ts.map +1 -1
  272. package/dist/esm/index.js +5 -0
  273. package/dist/esm/release-date.js +1 -1
  274. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  275. package/dist/esm/types.d.ts +50 -1
  276. package/dist/esm/types.d.ts.map +1 -1
  277. package/dist/spreadsheet.min.css +1 -1
  278. package/package.json +6 -5
  279. package/dist/cjs/components/cell-error/index.d.ts +0 -14
  280. package/dist/cjs/components/cell-error/index.d.ts.map +0 -1
  281. package/dist/cjs/components/cell-error/index.js +0 -24
  282. package/dist/esm/components/cell-error/index.d.ts +0 -14
  283. package/dist/esm/components/cell-error/index.d.ts.map +0 -1
  284. package/dist/esm/components/cell-error/index.js +0 -18
@@ -1,12 +1,38 @@
1
1
  import { Button, Dialog, DialogBody, DialogCloseButton, DialogContent, DialogTitle, Separator, } from "@rowsncolumns/ui";
2
2
  import React, { memo, useCallback, useState } from "react";
3
3
  import { usePasteSpecialDialogState, useRegisterPasteSpecialDialogHost, } from "../../atoms/paste-special-dialog.atom";
4
- const PASTE_MODES = [
5
- { value: "all", label: "All" },
6
- { value: "formulas", label: "Formulas" },
7
- { value: "values", label: "Values" },
8
- { value: "formats", label: "Formats" },
4
+ /**
5
+ * Excel's Paste group, in its two columns (support.microsoft.com, "Paste
6
+ * special"): what the left column pastes, then the composites on the right.
7
+ */
8
+ const PASTE_MODE_COLUMNS = [
9
+ [
10
+ { value: "all", label: "All" },
11
+ { value: "formulas", label: "Formulas" },
12
+ { value: "values", label: "Values" },
13
+ { value: "formats", label: "Formats" },
14
+ { value: "commentsAndNotes", label: "Comments and Notes" },
15
+ { value: "validation", label: "Validation" },
16
+ ],
17
+ [
18
+ { value: "allUsingSourceTheme", label: "All using Source theme" },
19
+ { value: "allExceptBorders", label: "All except borders" },
20
+ { value: "columnWidths", label: "Column widths" },
21
+ { value: "formulasAndNumberFormats", label: "Formulas and number formats" },
22
+ { value: "valuesAndNumberFormats", label: "Values and number formats" },
23
+ {
24
+ value: "allMergingConditionalFormats",
25
+ label: "All merging conditional formats",
26
+ },
27
+ ],
9
28
  ];
29
+ /** The modes that never change destination values: Excel greys Operation out under them. */
30
+ const NO_OPERATION_MODES = new Set([
31
+ "formats",
32
+ "commentsAndNotes",
33
+ "validation",
34
+ "columnWidths",
35
+ ]);
10
36
  const OPERATIONS = [
11
37
  { value: "none", label: "None" },
12
38
  { value: "add", label: "Add" },
@@ -14,24 +40,26 @@ const OPERATIONS = [
14
40
  { value: "multiply", label: "Multiply" },
15
41
  { value: "divide", label: "Divide" },
16
42
  ];
17
- const RadioGroup = ({ name, legend, value, options, onChange, disabled, }) => (React.createElement("fieldset", { className: "flex flex-col gap-1 min-w-0 disabled:opacity-50", disabled: disabled },
43
+ const RadioOption = ({ name, option, checked, disabled, onChange, }) => (React.createElement("label", { className: "flex items-center gap-2 text-xs py-0.5 cursor-pointer" },
44
+ React.createElement("input", { type: "radio", name: name, value: option.value, checked: checked, disabled: disabled, onChange: () => onChange(option.value) }),
45
+ option.label));
46
+ const RadioGroup = ({ name, legend, value, columns, onChange, disabled, }) => (React.createElement("fieldset", { className: "flex flex-col gap-1 min-w-0 disabled:opacity-50", disabled: disabled },
18
47
  React.createElement("legend", { className: "text-xs font-medium mb-1" }, legend),
19
- options.map((option) => (React.createElement("label", { key: option.value, className: "flex items-center gap-2 text-xs py-0.5 cursor-pointer" },
20
- React.createElement("input", { type: "radio", name: name, value: option.value, checked: value === option.value, disabled: disabled, onChange: () => onChange(option.value) }),
21
- option.label)))));
48
+ React.createElement("div", { className: "grid grid-flow-col auto-cols-fr gap-x-4" }, columns.map((column, index) => (React.createElement("div", { key: index, className: "flex flex-col gap-1 min-w-0" }, column.map((option) => (React.createElement(RadioOption, { key: option.value, name: name, option: option, checked: value === option.value, disabled: disabled, onChange: onChange })))))))));
22
49
  /**
23
- * Excel's Paste Special dialog: what to paste (all / formulas / values /
24
- * formats), an arithmetic operation against the destination, skip blanks and
25
- * transpose. Every choice composes into one `PasteSpecialOptions` request.
50
+ * Excel's Paste Special dialog: what to paste (Excel's twelve Paste choices),
51
+ * an arithmetic operation against the destination, skip blanks, transpose and
52
+ * Paste Link. Every choice composes into one `PasteSpecialOptions` request.
26
53
  */
27
54
  export const PasteSpecialDialog = memo(({ open, onOpenChange, onApply }) => {
28
55
  const [paste, setPaste] = useState("all");
29
56
  const [operation, setOperation] = useState("none");
30
57
  const [skipBlanks, setSkipBlanks] = useState(false);
31
58
  const [transpose, setTranspose] = useState(false);
32
- // Excel greys Operation out under Paste → Formats (a formats paste never
33
- // changes destination values); the choice is kept but not applied.
34
- const operationDisabled = paste === "formats";
59
+ // Excel greys Operation out under Formats, Comments and Notes, Validation
60
+ // and Column widths (none of them changes destination values); the choice
61
+ // is kept but not applied.
62
+ const operationDisabled = NO_OPERATION_MODES.has(paste);
35
63
  const commit = useCallback(() => {
36
64
  onApply({
37
65
  paste,
@@ -49,15 +77,20 @@ export const PasteSpecialDialog = memo(({ open, onOpenChange, onApply }) => {
49
77
  skipBlanks,
50
78
  transpose,
51
79
  ]);
80
+ // Excel's Paste Link button: reference formulas to the copied cells, in
81
+ // their orientation when Transpose is ticked.
82
+ const commitLink = useCallback(() => {
83
+ onApply({ link: true, transpose });
84
+ onOpenChange(false);
85
+ }, [onApply, onOpenChange, transpose]);
52
86
  return (React.createElement(Dialog, { open: open, onOpenChange: onOpenChange, modal: true },
53
- React.createElement(DialogContent, { className: "w-[380px] max-w-[92vw] pointer-events-auto" },
87
+ React.createElement(DialogContent, { className: "w-[460px] max-w-[92vw] pointer-events-auto" },
54
88
  React.createElement(DialogTitle, null, "Paste Special"),
55
89
  React.createElement(DialogCloseButton, null),
56
90
  React.createElement(DialogBody, { className: "flex flex-col gap-4" },
57
- React.createElement("div", { className: "grid grid-cols-2 gap-4" },
58
- React.createElement(RadioGroup, { name: "paste-special-paste", legend: "Paste", value: paste, options: PASTE_MODES, onChange: setPaste }),
59
- React.createElement(RadioGroup, { name: "paste-special-operation", legend: "Operation", value: operation, options: OPERATIONS, onChange: setOperation, disabled: operationDisabled })),
60
- React.createElement("div", { className: "flex flex-col gap-1" },
91
+ React.createElement(RadioGroup, { name: "paste-special-paste", legend: "Paste", value: paste, columns: PASTE_MODE_COLUMNS, onChange: setPaste }),
92
+ React.createElement(RadioGroup, { name: "paste-special-operation", legend: "Operation", value: operation, columns: [OPERATIONS.slice(0, 3), OPERATIONS.slice(3)], onChange: setOperation, disabled: operationDisabled }),
93
+ React.createElement("div", { className: "grid grid-cols-2 gap-x-4" },
61
94
  React.createElement("label", { className: "flex items-center gap-2 text-xs py-0.5 cursor-pointer" },
62
95
  React.createElement("input", { type: "checkbox", checked: skipBlanks, onChange: (e) => setSkipBlanks(e.target.checked) }),
63
96
  "Skip blanks"),
@@ -65,9 +98,11 @@ export const PasteSpecialDialog = memo(({ open, onOpenChange, onApply }) => {
65
98
  React.createElement("input", { type: "checkbox", checked: transpose, onChange: (e) => setTranspose(e.target.checked) }),
66
99
  "Transpose")),
67
100
  React.createElement(Separator, null),
68
- React.createElement("div", { className: "flex justify-end gap-2" },
69
- React.createElement(Button, { variant: "outline", size: "sm", onClick: () => onOpenChange(false) }, "Cancel"),
70
- React.createElement(Button, { size: "sm", onClick: commit }, "OK"))))));
101
+ React.createElement("div", { className: "flex justify-between gap-2" },
102
+ React.createElement(Button, { variant: "outline", size: "sm", onClick: commitLink }, "Paste Link"),
103
+ React.createElement("div", { className: "flex gap-2" },
104
+ React.createElement(Button, { size: "sm", onClick: commit }, "OK"),
105
+ React.createElement(Button, { variant: "outline", size: "sm", onClick: () => onOpenChange(false) }, "Cancel")))))));
71
106
  });
72
107
  PasteSpecialDialog.displayName = "PasteSpecialDialog";
73
108
  /**
@@ -0,0 +1,57 @@
1
+ import type { GridRange } from "@rowsncolumns/grid";
2
+ import React from "react";
3
+ import type { AllowEditRange } from "../../types";
4
+ /**
5
+ * Review ▸ Allow Edit Ranges (support.microsoft.com "Lock or unlock specific
6
+ * areas of a protected worksheet"): the sheet's titled ranges that stay
7
+ * editable once it is protected, with New / Modify / Delete and the
8
+ * New Range form (Title, Refers to cells, Range password).
9
+ */
10
+ /** The Range form's submission. `password` absent = unchanged (Modify). */
11
+ export type AllowEditRangeFormValue = {
12
+ title: string;
13
+ ranges: GridRange[];
14
+ password?: string;
15
+ };
16
+ /** Excel's text when "Refers to cells" is not a reference. */
17
+ export declare const INVALID_REFERENCE_MESSAGE = "The reference you typed is not valid.";
18
+ /** Excel's text for an empty or duplicate title. */
19
+ export declare const EMPTY_TITLE_MESSAGE = "Enter a title for the range.";
20
+ export declare const DUPLICATE_TITLE_MESSAGE = "The title you entered already exists. Enter a unique title.";
21
+ /** `$A$1:$B$2` per rectangle, joined with commas, as Excel shows "Refers to cells". */
22
+ export declare const rangesToReference: (ranges: GridRange[]) => string;
23
+ /**
24
+ * Parse "Refers to cells": `=$A$1:$B$2,D4` (sheet prefixes and `$` ignored).
25
+ * `null` when any part is not a cell or range reference.
26
+ */
27
+ export declare const referenceToRanges: (text: string) => GridRange[] | null;
28
+ export type AllowEditRangesDialogProps = {
29
+ open: boolean;
30
+ onOpenChange(open: boolean): void;
31
+ /** The active sheet's ranges (rnc engine `allowEditRanges` filtered to it). */
32
+ ranges: AllowEditRange[];
33
+ /** Excel disables the list while the sheet is protected. */
34
+ sheetProtected: boolean;
35
+ /** The current selection, offered as a New range's cells. */
36
+ defaultRanges?: GridRange[];
37
+ /** rnc engine `onAddAllowEditRange(sheetId, value)`. */
38
+ onAdd(value: AllowEditRangeFormValue): void;
39
+ /** rnc engine `onUpdateAllowEditRange(sheetId, title, value)`. */
40
+ onUpdate(title: string, value: AllowEditRangeFormValue): void;
41
+ /** rnc engine `onDeleteAllowEditRange(sheetId, title)`. */
42
+ onDelete(title: string): void;
43
+ /** The dialog's "Protect Sheet…" button: opens the host's Protect Sheet dialog. */
44
+ onProtectSheet?(): void;
45
+ };
46
+ export declare const AllowEditRangesDialog: React.MemoExoticComponent<({ open, onOpenChange, ranges, sheetProtected, defaultRanges, onAdd, onUpdate, onDelete, onProtectSheet, }: AllowEditRangesDialogProps) => React.JSX.Element>;
47
+ export type UnlockRangeDialogProps = {
48
+ open: boolean;
49
+ onOpenChange(open: boolean): void;
50
+ /** The range the user tried to edit. */
51
+ range?: AllowEditRange | null;
52
+ /** rnc engine `onUnlockAllowEditRange(sheetId, range.title, password)`. */
53
+ onConfirm(password: string): void;
54
+ };
55
+ /** Excel's Unlock Range prompt for a password-protected Allow Edit Range. */
56
+ export declare const UnlockRangeDialog: React.MemoExoticComponent<({ open, onOpenChange, range, onConfirm }: UnlockRangeDialogProps) => React.JSX.Element>;
57
+ //# sourceMappingURL=allow-edit-ranges-dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allow-edit-ranges-dialog.d.ts","sourceRoot":"","sources":["../../../../components/protect-sheet-dialog/allow-edit-ranges-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAYpD,OAAO,KAAyB,MAAM,OAAO,CAAC;AAE9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD;;;;;GAKG;AAEH,2EAA2E;AAC3E,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,yBAAyB,0CAA0C,CAAC;AACjF,oDAAoD;AACpD,eAAO,MAAM,mBAAmB,iCAAiC,CAAC;AAClE,eAAO,MAAM,uBAAuB,gEAC2B,CAAC;AAEhE,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,GAAI,QAAQ,SAAS,EAAE,KAAG,MAexC,CAAC;AAEjB;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,SAAS,EAAE,GAAG,IAiB9D,CAAC;AA2HF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,+EAA+E;IAC/E,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,4DAA4D;IAC5D,cAAc,EAAE,OAAO,CAAC;IACxB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;IAC5B,wDAAwD;IACxD,KAAK,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC5C,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC9D,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mFAAmF;IACnF,cAAc,CAAC,IAAI,IAAI,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,qBAAqB,wIAW7B,0BAA0B,uBAsI9B,CAAC;AAIF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,wCAAwC;IACxC,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,2EAA2E;IAC3E,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,uEACe,sBAAsB,uBAoDlE,CAAC"}
@@ -0,0 +1,177 @@
1
+ import { Button, Dialog, DialogBody, DialogCloseButton, DialogContent, DialogTitle, Input, Separator, } from "@rowsncolumns/ui";
2
+ import { addressToSelection, cellToAddress } from "@rowsncolumns/utils";
3
+ import React, { memo, useState } from "react";
4
+ import { CONFIRM_PASSWORD_MISMATCH } from "./constants";
5
+ /** Excel's text when "Refers to cells" is not a reference. */
6
+ export const INVALID_REFERENCE_MESSAGE = "The reference you typed is not valid.";
7
+ /** Excel's text for an empty or duplicate title. */
8
+ export const EMPTY_TITLE_MESSAGE = "Enter a title for the range.";
9
+ export const DUPLICATE_TITLE_MESSAGE = "The title you entered already exists. Enter a unique title.";
10
+ /** `$A$1:$B$2` per rectangle, joined with commas, as Excel shows "Refers to cells". */
11
+ export const rangesToReference = (ranges) => `=${ranges
12
+ .map((r) => {
13
+ const from = cellToAddress({ rowIndex: r.startRowIndex, columnIndex: r.startColumnIndex }, true, true);
14
+ const to = cellToAddress({ rowIndex: r.endRowIndex, columnIndex: r.endColumnIndex }, true, true);
15
+ return from === to ? `${from}` : `${from}:${to}`;
16
+ })
17
+ .join(",")}`;
18
+ /**
19
+ * Parse "Refers to cells": `=$A$1:$B$2,D4` (sheet prefixes and `$` ignored).
20
+ * `null` when any part is not a cell or range reference.
21
+ */
22
+ export const referenceToRanges = (text) => {
23
+ const parts = text
24
+ .trim()
25
+ .replace(/^=/, "")
26
+ .split(/[,;]/)
27
+ .map((p) => p.trim())
28
+ .filter(Boolean);
29
+ if (parts.length === 0)
30
+ return null;
31
+ const out = [];
32
+ for (const part of parts) {
33
+ const bare = part.replace(/^.*!/, "").replace(/\$/g, "").toUpperCase();
34
+ if (!/^[A-Z]+\d+(:[A-Z]+\d+)?$/.test(bare))
35
+ return null;
36
+ const selection = addressToSelection(bare);
37
+ if (!selection)
38
+ return null;
39
+ out.push(selection.range);
40
+ }
41
+ return out;
42
+ };
43
+ const RangeForm = ({ heading, initial, defaultRanges, takenTitles, onCancel, onSubmit, }) => {
44
+ const [title, setTitle] = useState(initial?.title ?? `Range${takenTitles.length + 1}`);
45
+ const [reference, setReference] = useState(() => {
46
+ const ranges = initial?.ranges ?? defaultRanges;
47
+ return ranges?.length ? rangesToReference(ranges) : "";
48
+ });
49
+ const [password, setPassword] = useState("");
50
+ const [confirm, setConfirm] = useState("");
51
+ const [error, setError] = useState(null);
52
+ return (React.createElement("form", { "aria-label": heading, className: "flex flex-col gap-3", onSubmit: (e) => {
53
+ e.preventDefault();
54
+ const trimmed = title.trim();
55
+ if (!trimmed)
56
+ return setError(EMPTY_TITLE_MESSAGE);
57
+ if (takenTitles.includes(trimmed.toLowerCase())) {
58
+ return setError(DUPLICATE_TITLE_MESSAGE);
59
+ }
60
+ const ranges = referenceToRanges(reference);
61
+ if (!ranges)
62
+ return setError(INVALID_REFERENCE_MESSAGE);
63
+ if (password !== "" && password !== confirm) {
64
+ return setError(CONFIRM_PASSWORD_MISMATCH);
65
+ }
66
+ onSubmit({
67
+ title: trimmed,
68
+ ranges,
69
+ // New: empty = no password. Modify: empty = keep the current one.
70
+ ...(password !== "" || !initial ? { password } : {}),
71
+ });
72
+ } },
73
+ React.createElement("p", { className: "text-xs font-semibold" }, heading),
74
+ React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
75
+ "Title:",
76
+ React.createElement(Input, { value: title, onChange: (e) => {
77
+ setTitle(e.target.value);
78
+ setError(null);
79
+ }, "data-testid": "allow-edit-range-title" })),
80
+ React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
81
+ "Refers to cells:",
82
+ React.createElement(Input, { value: reference, onChange: (e) => {
83
+ setReference(e.target.value);
84
+ setError(null);
85
+ }, "data-testid": "allow-edit-range-reference" })),
86
+ React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
87
+ "Range password:",
88
+ React.createElement(Input, { type: "password", autoComplete: "new-password", value: password, placeholder: initial?.hasPassword ? "(unchanged)" : undefined, onChange: (e) => {
89
+ setPassword(e.target.value);
90
+ setError(null);
91
+ }, "data-testid": "allow-edit-range-password" })),
92
+ password !== "" && (React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
93
+ "Reenter password to proceed:",
94
+ React.createElement(Input, { type: "password", autoComplete: "new-password", value: confirm, onChange: (e) => {
95
+ setConfirm(e.target.value);
96
+ setError(null);
97
+ }, "data-testid": "allow-edit-range-password-confirm" }))),
98
+ error && (React.createElement("p", { role: "alert", className: "text-xs text-red-600" }, error)),
99
+ React.createElement("div", { className: "flex justify-end gap-2" },
100
+ React.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: onCancel }, "Cancel"),
101
+ React.createElement(Button, { type: "submit", size: "sm" }, "OK"))));
102
+ };
103
+ export const AllowEditRangesDialog = memo(({ open, onOpenChange, ranges, sheetProtected, defaultRanges, onAdd, onUpdate, onDelete, onProtectSheet, }) => {
104
+ const [selected, setSelected] = useState(null);
105
+ const [mode, setMode] = useState("list");
106
+ const current = ranges.find((r) => r.title === selected);
107
+ const titles = ranges.map((r) => r.title.toLowerCase());
108
+ const close = () => {
109
+ setMode("list");
110
+ onOpenChange(false);
111
+ };
112
+ return (React.createElement(Dialog, { open: open, onOpenChange: (o) => (o ? onOpenChange(o) : close()), modal: true },
113
+ React.createElement(DialogContent, { className: "w-[420px] max-w-[92vw] pointer-events-auto" },
114
+ React.createElement(DialogTitle, null, "Allow Users to Edit Ranges"),
115
+ React.createElement(DialogCloseButton, null),
116
+ React.createElement(DialogBody, null, mode === "list" ? (React.createElement("div", { className: "flex flex-col gap-3" },
117
+ React.createElement("p", { className: "text-xs", id: "allow-edit-ranges-caption" }, "Ranges unlocked by a password when sheet is protected:"),
118
+ sheetProtected && (React.createElement("p", { role: "status", className: "text-xs text-amber-700" }, "Unprotect the sheet to change its ranges.")),
119
+ React.createElement("div", { role: "listbox", "aria-labelledby": "allow-edit-ranges-caption", className: "flex max-h-48 min-h-24 flex-col overflow-y-auto rounded border text-xs" }, ranges.map((r) => (React.createElement("div", { key: r.title, role: "option", "aria-selected": r.title === selected, tabIndex: 0, "data-testid": `allow-edit-range-row-${r.title}`, className: `flex cursor-default justify-between gap-2 px-2 py-1 ${r.title === selected ? "bg-blue-100" : ""}`, onClick: () => setSelected(r.title), onKeyDown: (e) => {
120
+ if (e.key === "Enter" || e.key === " ")
121
+ setSelected(r.title);
122
+ } },
123
+ React.createElement("span", { className: "font-medium" }, r.title),
124
+ React.createElement("span", null, rangesToReference(r.ranges)),
125
+ r.hasPassword && React.createElement("span", { className: "text-gray-500" }, "(password)"))))),
126
+ React.createElement("div", { className: "flex gap-2" },
127
+ React.createElement(Button, { type: "button", size: "sm", variant: "outline", disabled: sheetProtected, onClick: () => setMode("new") }, "New\u2026"),
128
+ React.createElement(Button, { type: "button", size: "sm", variant: "outline", disabled: sheetProtected || !current, onClick: () => setMode("modify") }, "Modify\u2026"),
129
+ React.createElement(Button, { type: "button", size: "sm", variant: "outline", disabled: sheetProtected || !current, onClick: () => {
130
+ if (!current)
131
+ return;
132
+ onDelete(current.title);
133
+ setSelected(null);
134
+ } }, "Delete")),
135
+ React.createElement(Separator, null),
136
+ React.createElement("div", { className: "flex justify-end gap-2" },
137
+ onProtectSheet && !sheetProtected && (React.createElement(Button, { type: "button", size: "sm", variant: "outline", onClick: () => {
138
+ close();
139
+ onProtectSheet();
140
+ } }, "Protect Sheet\u2026")),
141
+ React.createElement(Button, { type: "button", size: "sm", onClick: close }, "OK")))) : mode === "new" ? (React.createElement(RangeForm, { heading: "New Range", defaultRanges: defaultRanges, takenTitles: titles, onCancel: () => setMode("list"), onSubmit: (value) => {
142
+ onAdd(value);
143
+ setSelected(value.title);
144
+ setMode("list");
145
+ } })) : current ? (React.createElement(RangeForm, { heading: "Modify Range", initial: current, takenTitles: titles.filter((t) => t !== current.title.toLowerCase()), onCancel: () => setMode("list"), onSubmit: (value) => {
146
+ onUpdate(current.title, value);
147
+ setSelected(value.title);
148
+ setMode("list");
149
+ } })) : null))));
150
+ });
151
+ AllowEditRangesDialog.displayName = "AllowEditRangesDialog";
152
+ /** Excel's Unlock Range prompt for a password-protected Allow Edit Range. */
153
+ export const UnlockRangeDialog = memo(({ open, onOpenChange, range, onConfirm }) => {
154
+ const [password, setPassword] = useState("");
155
+ return (React.createElement(Dialog, { open: open, onOpenChange: onOpenChange, modal: true },
156
+ React.createElement(DialogContent, { className: "w-[340px] max-w-[92vw] pointer-events-auto" },
157
+ React.createElement(DialogTitle, null, "Unlock Range"),
158
+ React.createElement(DialogCloseButton, null),
159
+ React.createElement(DialogBody, null,
160
+ React.createElement("form", { className: "flex flex-col gap-3", onSubmit: (e) => {
161
+ e.preventDefault();
162
+ onConfirm(password);
163
+ setPassword("");
164
+ onOpenChange(false);
165
+ } },
166
+ React.createElement("p", { className: "text-xs" },
167
+ "A cell you are trying to change is password protected.",
168
+ range?.title ? ` (${range.title})` : ""),
169
+ React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
170
+ "Enter password to change this cell:",
171
+ React.createElement(Input, { type: "password", autoComplete: "current-password", autoFocus: true, value: password, onChange: (e) => setPassword(e.target.value), "data-testid": "unlock-range-password" })),
172
+ React.createElement(Separator, null),
173
+ React.createElement("div", { className: "flex justify-end gap-2" },
174
+ React.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onOpenChange(false) }, "Cancel"),
175
+ React.createElement(Button, { type: "submit", size: "sm" }, "OK")))))));
176
+ });
177
+ UnlockRangeDialog.displayName = "UnlockRangeDialog";
@@ -0,0 +1,3 @@
1
+ /** Excel's text when the re-entered password differs. */
2
+ export declare const CONFIRM_PASSWORD_MISMATCH = "Confirmation password is not identical.";
3
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../components/protect-sheet-dialog/constants.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,eAAO,MAAM,yBAAyB,4CAA4C,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Excel's text when the re-entered password differs. */
2
+ export const CONFIRM_PASSWORD_MISMATCH = "Confirmation password is not identical.";
@@ -21,8 +21,8 @@ export declare const sheetProtectionToAllowState: (protection?: SheetProtection
21
21
  * schema default.
22
22
  */
23
23
  export declare const allowStateToSheetProtection: (state: SheetProtectionAllowState) => Omit<SheetProtection, "password" | "algorithmName" | "hashValue" | "saltValue" | "spinCount">;
24
- /** Excel's text when the re-entered password differs. */
25
- export declare const CONFIRM_PASSWORD_MISMATCH = "Confirmation password is not identical.";
24
+ export { CONFIRM_PASSWORD_MISMATCH } from "./constants";
25
+ export * from "./allow-edit-ranges-dialog";
26
26
  export type ProtectSheetDialogProps = {
27
27
  open: boolean;
28
28
  onOpenChange(open: boolean): void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/protect-sheet-dialog/index.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAyB,MAAM,OAAO,CAAC;AAE9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,iFAAiF;AACjF,MAAM,MAAM,wBAAwB,GAChC,mBAAmB,GACnB,qBAAqB,GACrB,aAAa,GACb,eAAe,GACf,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,kBAAkB,GAClB,eAAe,GACf,YAAY,GACZ,MAAM,GACN,YAAY,GACZ,aAAa,GACb,SAAS,GACT,WAAW,CAAC;AAEhB;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,EAAE,aAAa,CAAC;IACzD,IAAI,EAAE,wBAAwB,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB,CAgBA,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;AAElF,iFAAiF;AACjF,eAAO,MAAM,2BAA2B,GACtC,aAAa,eAAe,GAAG,IAAI,KAClC,yBAOF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GACtC,OAAO,yBAAyB,KAC/B,IAAI,CACL,eAAe,EACf,UAAU,GAAG,eAAe,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAOvE,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,yBAAyB,4CAA4C,CAAC;AA4DnF,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,gEAAgE;IAChE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,OAAO,EAAE;QACjB,eAAe,EAAE,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC;QAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;CACV,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,yEACgB,uBAAuB,uBAoErE,CAAC;AAIF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,uEAAuE;IACvE,SAAS,CAAC,OAAO,EAAE;QAAE,aAAa,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACzE,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,qBAAqB,gEACI,0BAA0B,uBAwD/D,CAAC;AAIF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,eAAe,uEACiB,oBAAoB,uBAmChE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/protect-sheet-dialog/index.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAyB,MAAM,OAAO,CAAC;AAE9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,iFAAiF;AACjF,MAAM,MAAM,wBAAwB,GAChC,mBAAmB,GACnB,qBAAqB,GACrB,aAAa,GACb,eAAe,GACf,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,kBAAkB,GAClB,eAAe,GACf,YAAY,GACZ,MAAM,GACN,YAAY,GACZ,aAAa,GACb,SAAS,GACT,WAAW,CAAC;AAEhB;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,EAAE,aAAa,CAAC;IACzD,IAAI,EAAE,wBAAwB,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB,CAgBA,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;AAElF,iFAAiF;AACjF,eAAO,MAAM,2BAA2B,GACtC,aAAa,eAAe,GAAG,IAAI,KAClC,yBAOF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,GACtC,OAAO,yBAAyB,KAC/B,IAAI,CACL,eAAe,EACf,UAAU,GAAG,eAAe,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAOvE,CAAC;AAEF,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,cAAc,4BAA4B,CAAC;AA4D3C,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,gEAAgE;IAChE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,OAAO,EAAE;QACjB,eAAe,EAAE,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC;QAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;CACV,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,yEACgB,uBAAuB,uBAoErE,CAAC;AAIF,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,uEAAuE;IACvE,SAAS,CAAC,OAAO,EAAE;QAAE,aAAa,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACzE,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,qBAAqB,gEACI,0BAA0B,uBAwD/D,CAAC;AAIF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,eAAe,uEACiB,oBAAoB,uBAmChE,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { Button, Dialog, DialogBody, DialogCloseButton, DialogContent, DialogTitle, Input, Separator, } from "@rowsncolumns/ui";
2
2
  import React, { memo, useState } from "react";
3
+ import { CONFIRM_PASSWORD_MISMATCH } from "./constants";
3
4
  /**
4
5
  * Excel's "Allow all users of this worksheet to:" list, in the dialog's order
5
6
  * (support.microsoft.com "Protect a worksheet"), with the dialog defaults:
@@ -43,8 +44,8 @@ export const allowStateToSheetProtection = (state) => {
43
44
  }
44
45
  return protection;
45
46
  };
46
- /** Excel's text when the re-entered password differs. */
47
- export const CONFIRM_PASSWORD_MISMATCH = "Confirmation password is not identical.";
47
+ export { CONFIRM_PASSWORD_MISMATCH } from "./constants";
48
+ export * from "./allow-edit-ranges-dialog";
48
49
  /** Password + "Reenter password to proceed", as Excel's Confirm Password step. */
49
50
  const PasswordFields = ({ label, password, confirm, mismatch, onPassword, onConfirm, }) => (React.createElement(React.Fragment, null,
50
51
  React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
@@ -0,0 +1,51 @@
1
+ import React from "react";
2
+ /** A Scenario Manager scenario — the `ScenarioDefinition` of `spreadsheet-state`. */
3
+ export type ScenarioManagerScenario = {
4
+ name: string;
5
+ cells: {
6
+ rowIndex: number;
7
+ columnIndex: number;
8
+ value: string;
9
+ }[];
10
+ comment?: string;
11
+ locked?: boolean;
12
+ hidden?: boolean;
13
+ };
14
+ /** Excel's cap on changing cells per scenario. */
15
+ export declare const MAX_SCENARIO_CHANGING_CELLS = 32;
16
+ type Refusal = string | undefined;
17
+ export type ScenarioManagerDialogProps = {
18
+ open: boolean;
19
+ onOpenChange(open: boolean): void;
20
+ /** The active sheet's scenarios. */
21
+ scenarios: ScenarioManagerScenario[];
22
+ /** The selection as A1 text (`B1:B2`) — Add's default changing cells. */
23
+ defaultChangingCells: string;
24
+ /** A cell's current value as typed — Add's default scenario values. */
25
+ getCellValue(rowIndex: number, columnIndex: number): string;
26
+ /** Each resolves to Excel's refusal message, or `undefined` once done. */
27
+ onAdd(scenario: ScenarioManagerScenario): Promise<Refusal> | Refusal;
28
+ onUpdate(name: string, scenario: ScenarioManagerScenario): Promise<Refusal> | Refusal;
29
+ onDelete(name: string): Promise<Refusal> | Refusal;
30
+ onShow(name: string): Promise<Refusal> | Refusal;
31
+ onSummary(resultCells: {
32
+ rowIndex: number;
33
+ columnIndex: number;
34
+ }[]): Promise<Refusal> | Refusal;
35
+ };
36
+ /**
37
+ * `B1:B3, D5` → its cells in order (deduplicated), or `null` when a part is not a
38
+ * cell or range reference.
39
+ */
40
+ export declare const parseCellList: (text: string) => {
41
+ rowIndex: number;
42
+ columnIndex: number;
43
+ }[] | null;
44
+ /**
45
+ * Excel's Scenario Manager: the sheet's scenarios with Show / Add / Delete /
46
+ * Edit / Summary. Add and Edit ask for the name, changing cells and comment,
47
+ * then a value for each changing cell (Scenario Values). Merge is not offered.
48
+ */
49
+ export declare const ScenarioManagerDialog: React.MemoExoticComponent<({ open, onOpenChange, scenarios, defaultChangingCells, getCellValue, onAdd, onUpdate, onDelete, onShow, onSummary, }: ScenarioManagerDialogProps) => React.JSX.Element>;
50
+ export {};
51
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/scenario-manager-dialog/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,qFAAqF;AACrF,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,KAAK,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAElC,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,oCAAoC;IACpC,SAAS,EAAE,uBAAuB,EAAE,CAAC;IACrC,yEAAyE;IACzE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5D,0EAA0E;IAC1E,KAAK,CAAC,QAAQ,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACtF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACnD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACjD,SAAS,CAAC,WAAW,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACjG,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,KACX;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,IA2BhD,CAAC;AAWF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,mJAY7B,0BAA0B,uBAqS9B,CAAC"}