@rowsncolumns/spreadsheet 10.2.74 → 10.2.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/dist/cjs/api/excel-validation-kinds.d.ts +71 -0
  2. package/dist/cjs/api/excel-validation-kinds.d.ts.map +1 -0
  3. package/dist/cjs/api/excel-validation-kinds.js +304 -0
  4. package/dist/cjs/api/fill-series.d.ts +38 -0
  5. package/dist/cjs/api/fill-series.d.ts.map +1 -0
  6. package/dist/cjs/api/fill-series.js +89 -0
  7. package/dist/cjs/api/go-to-special.d.ts +32 -0
  8. package/dist/cjs/api/go-to-special.d.ts.map +1 -0
  9. package/dist/cjs/api/go-to-special.js +111 -0
  10. package/dist/cjs/api/spreadsheet-api.d.ts +6 -2
  11. package/dist/cjs/api/spreadsheet-api.d.ts.map +1 -1
  12. package/dist/cjs/api/spreadsheet-api.js +9 -3
  13. package/dist/cjs/api/validation-tooltip.d.ts +17 -0
  14. package/dist/cjs/api/validation-tooltip.d.ts.map +1 -0
  15. package/dist/cjs/api/validation-tooltip.js +42 -0
  16. package/dist/cjs/atoms/advanced-filter-dialog.atom.d.ts +28 -0
  17. package/dist/cjs/atoms/advanced-filter-dialog.atom.d.ts.map +1 -0
  18. package/dist/cjs/atoms/advanced-filter-dialog.atom.js +32 -0
  19. package/dist/cjs/atoms/fill-options.atom.d.ts +36 -0
  20. package/dist/cjs/atoms/fill-options.atom.d.ts.map +1 -0
  21. package/dist/cjs/atoms/fill-options.atom.js +11 -0
  22. package/dist/cjs/atoms/fill-series-dialog.atom.d.ts +26 -0
  23. package/dist/cjs/atoms/fill-series-dialog.atom.d.ts.map +1 -0
  24. package/dist/cjs/atoms/fill-series-dialog.atom.js +14 -0
  25. package/dist/cjs/atoms/go-to-dialog.atom.d.ts +11 -1
  26. package/dist/cjs/atoms/go-to-dialog.atom.d.ts.map +1 -1
  27. package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts +29 -0
  28. package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts.map +1 -0
  29. package/dist/cjs/atoms/goal-seek-dialog.atom.js +30 -0
  30. package/dist/cjs/atoms/index.d.ts +3 -0
  31. package/dist/cjs/atoms/index.d.ts.map +1 -1
  32. package/dist/cjs/atoms/index.js +3 -0
  33. package/dist/cjs/atoms/subtotal-dialog.atom.d.ts +39 -0
  34. package/dist/cjs/atoms/subtotal-dialog.atom.d.ts.map +1 -0
  35. package/dist/cjs/atoms/subtotal-dialog.atom.js +30 -0
  36. package/dist/cjs/atoms/text-to-columns-dialog.atom.d.ts +34 -0
  37. package/dist/cjs/atoms/text-to-columns-dialog.atom.d.ts.map +1 -0
  38. package/dist/cjs/atoms/text-to-columns-dialog.atom.js +36 -0
  39. package/dist/cjs/atoms/watch-window.atom.d.ts +37 -0
  40. package/dist/cjs/atoms/watch-window.atom.d.ts.map +1 -0
  41. package/dist/cjs/atoms/watch-window.atom.js +61 -0
  42. package/dist/cjs/components/advanced-filter-dialog/index.d.ts +28 -0
  43. package/dist/cjs/components/advanced-filter-dialog/index.d.ts.map +1 -0
  44. package/dist/cjs/components/advanced-filter-dialog/index.js +134 -0
  45. package/dist/cjs/components/calculation-options-dialog/index.d.ts +33 -0
  46. package/dist/cjs/components/calculation-options-dialog/index.d.ts.map +1 -0
  47. package/dist/cjs/components/calculation-options-dialog/index.js +69 -0
  48. package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
  49. package/dist/cjs/components/canvas-grid/index.js +328 -71
  50. package/dist/cjs/components/canvas-grid/typings.d.ts +31 -5
  51. package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
  52. package/dist/cjs/components/cell/alignment.d.ts +30 -0
  53. package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
  54. package/dist/cjs/components/cell/alignment.js +56 -1
  55. package/dist/cjs/components/cell/index.d.ts.map +1 -1
  56. package/dist/cjs/components/cell/index.js +15 -7
  57. package/dist/cjs/components/cell-diff/index.d.ts +3 -2
  58. package/dist/cjs/components/cell-diff/index.d.ts.map +1 -1
  59. package/dist/cjs/components/cell-editor/helpers.d.ts +9 -0
  60. package/dist/cjs/components/cell-editor/helpers.d.ts.map +1 -1
  61. package/dist/cjs/components/cell-editor/helpers.js +8 -1
  62. package/dist/cjs/components/cell-editor/helpers.spec.js +14 -0
  63. package/dist/cjs/components/cell-editor/index.d.ts.map +1 -1
  64. package/dist/cjs/components/cell-editor/index.js +7 -3
  65. package/dist/cjs/components/context-menu/index.d.ts +6 -1
  66. package/dist/cjs/components/context-menu/index.d.ts.map +1 -1
  67. package/dist/cjs/components/context-menu/index.js +146 -3
  68. package/dist/cjs/components/embeds/embed-component.d.ts.map +1 -1
  69. package/dist/cjs/components/embeds/embed-component.js +16 -1
  70. package/dist/cjs/components/fill-series-dialog/index.d.ts +29 -0
  71. package/dist/cjs/components/fill-series-dialog/index.d.ts.map +1 -0
  72. package/dist/cjs/components/fill-series-dialog/index.js +156 -0
  73. package/dist/cjs/components/go-to-dialog/index.d.ts +11 -1
  74. package/dist/cjs/components/go-to-dialog/index.d.ts.map +1 -1
  75. package/dist/cjs/components/go-to-dialog/index.js +67 -24
  76. package/dist/cjs/components/goal-seek-dialog/index.d.ts +32 -0
  77. package/dist/cjs/components/goal-seek-dialog/index.d.ts.map +1 -0
  78. package/dist/cjs/components/goal-seek-dialog/index.js +149 -0
  79. package/dist/cjs/components/selection/fill-options-menu.d.ts +32 -0
  80. package/dist/cjs/components/selection/fill-options-menu.d.ts.map +1 -0
  81. package/dist/cjs/components/selection/fill-options-menu.js +65 -0
  82. package/dist/cjs/components/selection/index.d.ts +1 -1
  83. package/dist/cjs/components/selection/index.d.ts.map +1 -1
  84. package/dist/cjs/components/selection/index.js +4 -2
  85. package/dist/cjs/components/selection/types.d.ts +11 -1
  86. package/dist/cjs/components/selection/types.d.ts.map +1 -1
  87. package/dist/cjs/components/subtotal-dialog/index.d.ts +30 -0
  88. package/dist/cjs/components/subtotal-dialog/index.d.ts.map +1 -0
  89. package/dist/cjs/components/subtotal-dialog/index.js +126 -0
  90. package/dist/cjs/components/text-to-columns-dialog/index.d.ts +37 -0
  91. package/dist/cjs/components/text-to-columns-dialog/index.d.ts.map +1 -0
  92. package/dist/cjs/components/text-to-columns-dialog/index.js +166 -0
  93. package/dist/cjs/components/toolbar/background-color-selector.d.ts +13 -1
  94. package/dist/cjs/components/toolbar/background-color-selector.d.ts.map +1 -1
  95. package/dist/cjs/components/toolbar/background-color-selector.js +57 -11
  96. package/dist/cjs/components/toolbar/cell-style-selector.d.ts +15 -2
  97. package/dist/cjs/components/toolbar/cell-style-selector.d.ts.map +1 -1
  98. package/dist/cjs/components/toolbar/cell-style-selector.js +56 -3
  99. package/dist/cjs/components/toolbar/fill-selectors.d.ts +49 -0
  100. package/dist/cjs/components/toolbar/fill-selectors.d.ts.map +1 -0
  101. package/dist/cjs/components/toolbar/fill-selectors.js +196 -0
  102. package/dist/cjs/components/toolbar/index.d.ts +1 -0
  103. package/dist/cjs/components/toolbar/index.d.ts.map +1 -1
  104. package/dist/cjs/components/toolbar/index.js +1 -0
  105. package/dist/cjs/components/toolbar/text-format-selector.d.ts +9 -0
  106. package/dist/cjs/components/toolbar/text-format-selector.d.ts.map +1 -1
  107. package/dist/cjs/components/toolbar/text-format-selector.js +15 -3
  108. package/dist/cjs/components/toolbar/text-horizontal-align-selector.d.ts +8 -0
  109. package/dist/cjs/components/toolbar/text-horizontal-align-selector.d.ts.map +1 -1
  110. package/dist/cjs/components/toolbar/text-horizontal-align-selector.js +23 -4
  111. package/dist/cjs/components/watch-window/index.d.ts +25 -0
  112. package/dist/cjs/components/watch-window/index.d.ts.map +1 -0
  113. package/dist/cjs/components/watch-window/index.js +63 -0
  114. package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
  115. package/dist/cjs/hooks/use-cell-renderer.js +17 -6
  116. package/dist/cjs/hooks/use-editable.d.ts +11 -2
  117. package/dist/cjs/hooks/use-editable.d.ts.map +1 -1
  118. package/dist/cjs/hooks/use-editable.js +8 -0
  119. package/dist/cjs/hooks/use-editor-submit.d.ts +32 -3
  120. package/dist/cjs/hooks/use-editor-submit.d.ts.map +1 -1
  121. package/dist/cjs/hooks/use-editor-submit.js +111 -2
  122. package/dist/cjs/hooks/use-get-tooltip.d.ts.map +1 -1
  123. package/dist/cjs/hooks/use-get-tooltip.js +7 -2
  124. package/dist/cjs/hooks/use-keyboard-handler.d.ts.map +1 -1
  125. package/dist/cjs/hooks/use-keyboard-handler.js +27 -14
  126. package/dist/cjs/hooks/use-selection-renderer.d.ts +13 -2
  127. package/dist/cjs/hooks/use-selection-renderer.d.ts.map +1 -1
  128. package/dist/cjs/hooks/use-selection-renderer.js +21 -4
  129. package/dist/cjs/hooks/use-selection.d.ts +54 -4
  130. package/dist/cjs/hooks/use-selection.d.ts.map +1 -1
  131. package/dist/cjs/hooks/use-selection.js +232 -37
  132. package/dist/cjs/index.d.ts +12 -0
  133. package/dist/cjs/index.d.ts.map +1 -1
  134. package/dist/cjs/index.js +11 -0
  135. package/dist/cjs/release-date.js +1 -1
  136. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  137. package/dist/cjs/types.d.ts +156 -5
  138. package/dist/cjs/types.d.ts.map +1 -1
  139. package/dist/cjs/types.js +19 -1
  140. package/dist/esm/api/excel-validation-kinds.d.ts +71 -0
  141. package/dist/esm/api/excel-validation-kinds.d.ts.map +1 -0
  142. package/dist/esm/api/excel-validation-kinds.js +287 -0
  143. package/dist/esm/api/fill-series.d.ts +38 -0
  144. package/dist/esm/api/fill-series.d.ts.map +1 -0
  145. package/dist/esm/api/fill-series.js +78 -0
  146. package/dist/esm/api/go-to-special.d.ts +32 -0
  147. package/dist/esm/api/go-to-special.d.ts.map +1 -0
  148. package/dist/esm/api/go-to-special.js +96 -0
  149. package/dist/esm/api/spreadsheet-api.d.ts +6 -2
  150. package/dist/esm/api/spreadsheet-api.d.ts.map +1 -1
  151. package/dist/esm/api/spreadsheet-api.js +8 -3
  152. package/dist/esm/api/validation-tooltip.d.ts +17 -0
  153. package/dist/esm/api/validation-tooltip.d.ts.map +1 -0
  154. package/dist/esm/api/validation-tooltip.js +34 -0
  155. package/dist/esm/atoms/advanced-filter-dialog.atom.d.ts +28 -0
  156. package/dist/esm/atoms/advanced-filter-dialog.atom.d.ts.map +1 -0
  157. package/dist/esm/atoms/advanced-filter-dialog.atom.js +21 -0
  158. package/dist/esm/atoms/fill-options.atom.d.ts +36 -0
  159. package/dist/esm/atoms/fill-options.atom.d.ts.map +1 -0
  160. package/dist/esm/atoms/fill-options.atom.js +5 -0
  161. package/dist/esm/atoms/fill-series-dialog.atom.d.ts +26 -0
  162. package/dist/esm/atoms/fill-series-dialog.atom.d.ts.map +1 -0
  163. package/dist/esm/atoms/fill-series-dialog.atom.js +9 -0
  164. package/dist/esm/atoms/go-to-dialog.atom.d.ts +11 -1
  165. package/dist/esm/atoms/go-to-dialog.atom.d.ts.map +1 -1
  166. package/dist/esm/atoms/goal-seek-dialog.atom.d.ts +29 -0
  167. package/dist/esm/atoms/goal-seek-dialog.atom.d.ts.map +1 -0
  168. package/dist/esm/atoms/goal-seek-dialog.atom.js +21 -0
  169. package/dist/esm/atoms/index.d.ts +3 -0
  170. package/dist/esm/atoms/index.d.ts.map +1 -1
  171. package/dist/esm/atoms/index.js +3 -0
  172. package/dist/esm/atoms/subtotal-dialog.atom.d.ts +39 -0
  173. package/dist/esm/atoms/subtotal-dialog.atom.d.ts.map +1 -0
  174. package/dist/esm/atoms/subtotal-dialog.atom.js +21 -0
  175. package/dist/esm/atoms/text-to-columns-dialog.atom.d.ts +34 -0
  176. package/dist/esm/atoms/text-to-columns-dialog.atom.d.ts.map +1 -0
  177. package/dist/esm/atoms/text-to-columns-dialog.atom.js +25 -0
  178. package/dist/esm/atoms/watch-window.atom.d.ts +37 -0
  179. package/dist/esm/atoms/watch-window.atom.d.ts.map +1 -0
  180. package/dist/esm/atoms/watch-window.atom.js +37 -0
  181. package/dist/esm/components/advanced-filter-dialog/index.d.ts +28 -0
  182. package/dist/esm/components/advanced-filter-dialog/index.d.ts.map +1 -0
  183. package/dist/esm/components/advanced-filter-dialog/index.js +125 -0
  184. package/dist/esm/components/calculation-options-dialog/index.d.ts +33 -0
  185. package/dist/esm/components/calculation-options-dialog/index.d.ts.map +1 -0
  186. package/dist/esm/components/calculation-options-dialog/index.js +61 -0
  187. package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
  188. package/dist/esm/components/canvas-grid/index.js +266 -26
  189. package/dist/esm/components/canvas-grid/typings.d.ts +31 -5
  190. package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
  191. package/dist/esm/components/cell/alignment.d.ts +30 -0
  192. package/dist/esm/components/cell/alignment.d.ts.map +1 -1
  193. package/dist/esm/components/cell/alignment.js +51 -0
  194. package/dist/esm/components/cell/index.d.ts.map +1 -1
  195. package/dist/esm/components/cell/index.js +16 -8
  196. package/dist/esm/components/cell-diff/index.d.ts +3 -2
  197. package/dist/esm/components/cell-diff/index.d.ts.map +1 -1
  198. package/dist/esm/components/cell-editor/helpers.d.ts +9 -0
  199. package/dist/esm/components/cell-editor/helpers.d.ts.map +1 -1
  200. package/dist/esm/components/cell-editor/helpers.js +6 -0
  201. package/dist/esm/components/cell-editor/helpers.spec.js +15 -1
  202. package/dist/esm/components/cell-editor/index.d.ts.map +1 -1
  203. package/dist/esm/components/cell-editor/index.js +8 -4
  204. package/dist/esm/components/context-menu/index.d.ts +6 -1
  205. package/dist/esm/components/context-menu/index.d.ts.map +1 -1
  206. package/dist/esm/components/context-menu/index.js +139 -4
  207. package/dist/esm/components/embeds/embed-component.d.ts.map +1 -1
  208. package/dist/esm/components/embeds/embed-component.js +17 -1
  209. package/dist/esm/components/fill-series-dialog/index.d.ts +29 -0
  210. package/dist/esm/components/fill-series-dialog/index.d.ts.map +1 -0
  211. package/dist/esm/components/fill-series-dialog/index.js +151 -0
  212. package/dist/esm/components/go-to-dialog/index.d.ts +11 -1
  213. package/dist/esm/components/go-to-dialog/index.d.ts.map +1 -1
  214. package/dist/esm/components/go-to-dialog/index.js +63 -23
  215. package/dist/esm/components/goal-seek-dialog/index.d.ts +32 -0
  216. package/dist/esm/components/goal-seek-dialog/index.d.ts.map +1 -0
  217. package/dist/esm/components/goal-seek-dialog/index.js +125 -0
  218. package/dist/esm/components/selection/fill-options-menu.d.ts +32 -0
  219. package/dist/esm/components/selection/fill-options-menu.d.ts.map +1 -0
  220. package/dist/esm/components/selection/fill-options-menu.js +63 -0
  221. package/dist/esm/components/selection/index.d.ts +1 -1
  222. package/dist/esm/components/selection/index.d.ts.map +1 -1
  223. package/dist/esm/components/selection/index.js +4 -2
  224. package/dist/esm/components/selection/types.d.ts +11 -1
  225. package/dist/esm/components/selection/types.d.ts.map +1 -1
  226. package/dist/esm/components/subtotal-dialog/index.d.ts +30 -0
  227. package/dist/esm/components/subtotal-dialog/index.d.ts.map +1 -0
  228. package/dist/esm/components/subtotal-dialog/index.js +115 -0
  229. package/dist/esm/components/text-to-columns-dialog/index.d.ts +37 -0
  230. package/dist/esm/components/text-to-columns-dialog/index.d.ts.map +1 -0
  231. package/dist/esm/components/text-to-columns-dialog/index.js +147 -0
  232. package/dist/esm/components/toolbar/background-color-selector.d.ts +13 -1
  233. package/dist/esm/components/toolbar/background-color-selector.d.ts.map +1 -1
  234. package/dist/esm/components/toolbar/background-color-selector.js +61 -11
  235. package/dist/esm/components/toolbar/cell-style-selector.d.ts +15 -2
  236. package/dist/esm/components/toolbar/cell-style-selector.d.ts.map +1 -1
  237. package/dist/esm/components/toolbar/cell-style-selector.js +46 -2
  238. package/dist/esm/components/toolbar/fill-selectors.d.ts +49 -0
  239. package/dist/esm/components/toolbar/fill-selectors.d.ts.map +1 -0
  240. package/dist/esm/components/toolbar/fill-selectors.js +162 -0
  241. package/dist/esm/components/toolbar/index.d.ts +1 -0
  242. package/dist/esm/components/toolbar/index.d.ts.map +1 -1
  243. package/dist/esm/components/toolbar/index.js +1 -0
  244. package/dist/esm/components/toolbar/text-format-selector.d.ts +9 -0
  245. package/dist/esm/components/toolbar/text-format-selector.d.ts.map +1 -1
  246. package/dist/esm/components/toolbar/text-format-selector.js +14 -2
  247. package/dist/esm/components/toolbar/text-horizontal-align-selector.d.ts +8 -0
  248. package/dist/esm/components/toolbar/text-horizontal-align-selector.d.ts.map +1 -1
  249. package/dist/esm/components/toolbar/text-horizontal-align-selector.js +21 -5
  250. package/dist/esm/components/watch-window/index.d.ts +25 -0
  251. package/dist/esm/components/watch-window/index.d.ts.map +1 -0
  252. package/dist/esm/components/watch-window/index.js +54 -0
  253. package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
  254. package/dist/esm/hooks/use-cell-renderer.js +17 -6
  255. package/dist/esm/hooks/use-editable.d.ts +11 -2
  256. package/dist/esm/hooks/use-editable.d.ts.map +1 -1
  257. package/dist/esm/hooks/use-editable.js +8 -0
  258. package/dist/esm/hooks/use-editor-submit.d.ts +32 -3
  259. package/dist/esm/hooks/use-editor-submit.d.ts.map +1 -1
  260. package/dist/esm/hooks/use-editor-submit.js +82 -3
  261. package/dist/esm/hooks/use-get-tooltip.d.ts.map +1 -1
  262. package/dist/esm/hooks/use-get-tooltip.js +7 -2
  263. package/dist/esm/hooks/use-keyboard-handler.d.ts.map +1 -1
  264. package/dist/esm/hooks/use-keyboard-handler.js +27 -14
  265. package/dist/esm/hooks/use-selection-renderer.d.ts +13 -2
  266. package/dist/esm/hooks/use-selection-renderer.d.ts.map +1 -1
  267. package/dist/esm/hooks/use-selection-renderer.js +22 -5
  268. package/dist/esm/hooks/use-selection.d.ts +54 -4
  269. package/dist/esm/hooks/use-selection.d.ts.map +1 -1
  270. package/dist/esm/hooks/use-selection.js +220 -36
  271. package/dist/esm/index.d.ts +12 -0
  272. package/dist/esm/index.d.ts.map +1 -1
  273. package/dist/esm/index.js +11 -0
  274. package/dist/esm/release-date.js +1 -1
  275. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  276. package/dist/esm/types.d.ts +156 -5
  277. package/dist/esm/types.d.ts.map +1 -1
  278. package/dist/esm/types.js +18 -0
  279. package/dist/spreadsheet.min.css +1 -1
  280. package/package.json +7 -7
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubtotalDialogHost = exports.SubtotalDialog = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var icons_1 = require("@rowsncolumns/icons");
6
+ var ui_1 = require("@rowsncolumns/ui");
7
+ var react_1 = tslib_1.__importStar(require("react"));
8
+ var subtotal_dialog_atom_1 = require("../../atoms/subtotal-dialog.atom");
9
+ var types_1 = require("../../types");
10
+ /**
11
+ * Excel's "Use function" labels. Excel's "Count" is COUNTA (non-empty cells,
12
+ * `SUBTOTAL(3,…)`) and "Count Numbers" is COUNT (`SUBTOTAL(2,…)`).
13
+ */
14
+ var FUNCTION_LABELS = {
15
+ SUM: "Sum",
16
+ COUNTA: "Count",
17
+ AVERAGE: "Average",
18
+ MAX: "Max",
19
+ MIN: "Min",
20
+ PRODUCT: "Product",
21
+ COUNT: "Count Numbers",
22
+ STDEV: "StdDev",
23
+ STDEVP: "StdDevp",
24
+ VAR: "Var",
25
+ VARP: "Varp",
26
+ };
27
+ /**
28
+ * Excel's Subtotal dialog: "At each change in" (group column), "Use
29
+ * function", "Add subtotal to" (aggregate columns), "Replace current
30
+ * subtotals". Summary rows are always placed below the data.
31
+ */
32
+ exports.SubtotalDialog = (0, react_1.memo)(function (_a) {
33
+ var _b;
34
+ var open = _a.open, onOpenChange = _a.onOpenChange, columns = _a.columns, _c = _a.initialHasHeader, initialHasHeader = _c === void 0 ? true : _c, onApply = _a.onApply;
35
+ var _d = tslib_1.__read((0, react_1.useState)(initialHasHeader), 2), hasHeader = _d[0], setHasHeader = _d[1];
36
+ var _e = tslib_1.__read((0, react_1.useState)((_b = columns[0]) === null || _b === void 0 ? void 0 : _b.columnIndex), 2), groupBy = _e[0], setGroupBy = _e[1];
37
+ var _f = tslib_1.__read((0, react_1.useState)("SUM"), 2), fn = _f[0], setFn = _f[1];
38
+ var _g = tslib_1.__read((0, react_1.useState)(function () { return new Set(columns.length ? [columns[columns.length - 1].columnIndex] : []); }), 2), aggregates = _g[0], setAggregates = _g[1];
39
+ var _h = tslib_1.__read((0, react_1.useState)(true), 2), replaceCurrent = _h[0], setReplaceCurrent = _h[1];
40
+ // Re-seed when reopened for a different range.
41
+ (0, react_1.useEffect)(function () {
42
+ var _a;
43
+ if (open) {
44
+ setHasHeader(initialHasHeader);
45
+ setGroupBy((_a = columns[0]) === null || _a === void 0 ? void 0 : _a.columnIndex);
46
+ setFn("SUM");
47
+ setAggregates(new Set(columns.length ? [columns[columns.length - 1].columnIndex] : []));
48
+ setReplaceCurrent(true);
49
+ }
50
+ // Only reset on open transitions.
51
+ // eslint-disable-next-line react-hooks/exhaustive-deps
52
+ }, [open]);
53
+ var labelOf = (0, react_1.useCallback)(function (column) {
54
+ return hasHeader && column.header ? column.header : column.label;
55
+ }, [hasHeader]);
56
+ var toggleAggregate = (0, react_1.useCallback)(function (columnIndex) {
57
+ setAggregates(function (prev) {
58
+ var next = new Set(prev);
59
+ if (next.has(columnIndex))
60
+ next.delete(columnIndex);
61
+ else
62
+ next.add(columnIndex);
63
+ return next;
64
+ });
65
+ }, []);
66
+ var canApply = groupBy !== undefined && aggregates.size > 0;
67
+ var orderedAggregates = (0, react_1.useMemo)(function () { return columns.map(function (c) { return c.columnIndex; }).filter(function (c) { return aggregates.has(c); }); }, [columns, aggregates]);
68
+ var commit = (0, react_1.useCallback)(function () {
69
+ if (groupBy === undefined)
70
+ return;
71
+ onApply({
72
+ groupByColumnIndex: groupBy,
73
+ aggregateColumnIndices: orderedAggregates,
74
+ fn: fn,
75
+ hasHeader: hasHeader,
76
+ replaceCurrent: replaceCurrent,
77
+ });
78
+ onOpenChange(false);
79
+ }, [groupBy, orderedAggregates, fn, hasHeader, replaceCurrent, onApply, onOpenChange]);
80
+ return (react_1.default.createElement(ui_1.Dialog, { open: open, onOpenChange: onOpenChange },
81
+ react_1.default.createElement(ui_1.DialogContent, { className: "w-[420px] max-w-[92vw] pointer-events-auto" },
82
+ react_1.default.createElement(ui_1.DialogTitle, null, "Subtotal"),
83
+ react_1.default.createElement(ui_1.DialogDescription, null, "Insert a total row after every change in a column, plus a grand total, and outline the groups."),
84
+ react_1.default.createElement(ui_1.DialogCloseButton, { onClick: function () { return onOpenChange(false); } },
85
+ react_1.default.createElement(icons_1.Cross1Icon, null)),
86
+ react_1.default.createElement(ui_1.DialogBody, { className: "flex flex-col gap-3 font-system text-sm" },
87
+ react_1.default.createElement("label", { className: "flex items-center gap-1" },
88
+ react_1.default.createElement("input", { type: "checkbox", name: "hasHeader", checked: hasHeader, onChange: function (e) { return setHasHeader(e.target.checked); } }),
89
+ "My data has headers"),
90
+ react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
91
+ "At each change in:",
92
+ react_1.default.createElement("select", { className: "h-8 rounded border border-rnc-border bg-transparent px-2 text-sm", "aria-label": "At each change in", value: groupBy !== null && groupBy !== void 0 ? groupBy : "", onChange: function (e) { return setGroupBy(Number(e.target.value)); } }, columns.map(function (column) { return (react_1.default.createElement("option", { key: column.columnIndex, value: column.columnIndex }, labelOf(column))); }))),
93
+ react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
94
+ "Use function:",
95
+ react_1.default.createElement("select", { className: "h-8 rounded border border-rnc-border bg-transparent px-2 text-sm", "aria-label": "Use function", value: fn, onChange: function (e) { return setFn(e.target.value); } }, types_1.SUBTOTAL_FUNCTIONS.map(function (name) { return (react_1.default.createElement("option", { key: name, value: name }, FUNCTION_LABELS[name])); }))),
96
+ react_1.default.createElement("div", { className: "flex flex-col gap-1" },
97
+ react_1.default.createElement("span", { className: "text-xs font-medium" }, "Add subtotal to:"),
98
+ react_1.default.createElement("div", { className: "flex flex-col gap-1 max-h-[180px] overflow-y-auto border border-rnc-border rounded p-2", role: "group", "aria-label": "Add subtotal to" }, columns.map(function (column) { return (react_1.default.createElement("label", { key: column.columnIndex, className: "flex items-center gap-1" },
99
+ react_1.default.createElement("input", { type: "checkbox", name: "subtotal-column-".concat(column.columnIndex), checked: aggregates.has(column.columnIndex), onChange: function () { return toggleAggregate(column.columnIndex); } }),
100
+ react_1.default.createElement("span", { className: "truncate", title: labelOf(column) }, labelOf(column)))); }))),
101
+ react_1.default.createElement("label", { className: "flex items-center gap-1" },
102
+ react_1.default.createElement("input", { type: "checkbox", name: "replaceCurrent", checked: replaceCurrent, onChange: function (e) { return setReplaceCurrent(e.target.checked); } }),
103
+ "Replace current subtotals"),
104
+ react_1.default.createElement(ui_1.Separator, null),
105
+ react_1.default.createElement("div", { className: "flex justify-end gap-2" },
106
+ react_1.default.createElement(ui_1.Button, { variant: "outline", size: "sm", type: "button", onClick: function () { return onOpenChange(false); } }, "Cancel"),
107
+ react_1.default.createElement(ui_1.Button, { size: "sm", type: "button", onClick: commit, disabled: !canApply }, "OK"))))));
108
+ });
109
+ exports.SubtotalDialog.displayName = "SubtotalDialog";
110
+ /**
111
+ * Host-mounted, atom-driven wrapper around {@link SubtotalDialog}. Mount
112
+ * once in the host; the context menu opens it via `useOpenSubtotalDialog`
113
+ * and only offers the item while a host is mounted.
114
+ */
115
+ var SubtotalDialogHost = function () {
116
+ var _a;
117
+ (0, subtotal_dialog_atom_1.useRegisterSubtotalDialogHost)();
118
+ var _b = tslib_1.__read((0, subtotal_dialog_atom_1.useSubtotalDialogState)(), 2), request = _b[0], setRequest = _b[1];
119
+ var close = (0, react_1.useCallback)(function () { return setRequest(null); }, [setRequest]);
120
+ return (react_1.default.createElement(exports.SubtotalDialog, { open: request != null, onOpenChange: function (open) {
121
+ if (!open)
122
+ close();
123
+ }, columns: (_a = request === null || request === void 0 ? void 0 : request.columns) !== null && _a !== void 0 ? _a : [], initialHasHeader: request === null || request === void 0 ? void 0 : request.hasHeader, onApply: function (choices) { return request === null || request === void 0 ? void 0 : request.onApply(choices); } }));
124
+ };
125
+ exports.SubtotalDialogHost = SubtotalDialogHost;
126
+ exports.SubtotalDialogHost.displayName = "SubtotalDialogHost";
@@ -0,0 +1,37 @@
1
+ import React from "react";
2
+ import type { SplitTextOptions } from "../../types";
3
+ export type TextToColumnsMode = "delimited" | "fixed";
4
+ export type TextToColumnsDialogProps = {
5
+ /** Controls visibility. */
6
+ open: boolean;
7
+ onOpenChange(open: boolean): void;
8
+ /** Texts of the first cells of the selected column — the preview / ruler. */
9
+ preview: string[];
10
+ /** Initial wizard step-1 choice (default Delimited). */
11
+ initialMode?: TextToColumnsMode;
12
+ /**
13
+ * Emits the chosen delimiter (Delimited) or column breaks (Fixed width).
14
+ * The host routes it to `onSplitTextToColumns`.
15
+ */
16
+ onApply(options: {
17
+ delimiter: string;
18
+ } & SplitTextOptions): void;
19
+ };
20
+ /**
21
+ * Excel's Convert Text to Columns wizard, condensed: choose Delimited (pick
22
+ * a delimiter or type another) or Fixed width (click the ruler to add or
23
+ * remove break lines, or type the positions), with a live preview of the
24
+ * first rows.
25
+ */
26
+ export declare const TextToColumnsDialog: React.MemoExoticComponent<({ open, onOpenChange, preview, initialMode, onApply, }: TextToColumnsDialogProps) => React.JSX.Element>;
27
+ /**
28
+ * Host-mounted, atom-driven wrapper around {@link TextToColumnsDialog}.
29
+ * Mount once in the host (alongside the other editor dialogs); the context
30
+ * menu opens it via `useOpenTextToColumnsDialog`. Without a host the menu
31
+ * keeps its one-click delimiter items only.
32
+ */
33
+ export declare const TextToColumnsDialogHost: {
34
+ (): React.JSX.Element;
35
+ displayName: string;
36
+ };
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/text-to-columns-dialog/index.tsx"],"names":[],"mappings":"AAYA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAM/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,OAAO,CAAC;AAEtD,MAAM,MAAM,wBAAwB,GAAG;IACrC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wDAAwD;IACxD,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,gBAAgB,GAAG,IAAI,CAAC;CAClE,CAAC;AAiCF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,qFAO3B,wBAAwB,uBAgO5B,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB;;;CAenC,CAAC"}
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TextToColumnsDialogHost = exports.TextToColumnsDialog = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var icons_1 = require("@rowsncolumns/icons");
6
+ var ui_1 = require("@rowsncolumns/ui");
7
+ var react_1 = tslib_1.__importStar(require("react"));
8
+ var text_to_columns_dialog_atom_1 = require("../../atoms/text-to-columns-dialog.atom");
9
+ var DELIMITERS = [
10
+ { label: "Comma", value: "," },
11
+ { label: "Semicolon", value: ";" },
12
+ { label: "Tab", value: "\t" },
13
+ { label: "Space", value: " " },
14
+ { label: "Period", value: "." },
15
+ { label: "Pipe", value: "|" },
16
+ ];
17
+ /** Cuts `text` at ascending character positions (the dialog's own preview). */
18
+ var cutAt = function (text, breaks) {
19
+ var e_1, _a;
20
+ var parts = [];
21
+ var start = 0;
22
+ try {
23
+ for (var breaks_1 = tslib_1.__values(breaks), breaks_1_1 = breaks_1.next(); !breaks_1_1.done; breaks_1_1 = breaks_1.next()) {
24
+ var position = breaks_1_1.value;
25
+ parts.push(text.slice(start, position));
26
+ start = position;
27
+ }
28
+ }
29
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
30
+ finally {
31
+ try {
32
+ if (breaks_1_1 && !breaks_1_1.done && (_a = breaks_1.return)) _a.call(breaks_1);
33
+ }
34
+ finally { if (e_1) throw e_1.error; }
35
+ }
36
+ parts.push(text.slice(start));
37
+ return parts;
38
+ };
39
+ var parseBreaks = function (text) {
40
+ return tslib_1.__spreadArray([], tslib_1.__read(new Set(text
41
+ .split(/[\s,;]+/)
42
+ .map(function (part) { return Number.parseInt(part, 10); })
43
+ .filter(function (n) { return Number.isInteger(n) && n > 0; }))), false).sort(function (a, b) { return a - b; });
44
+ };
45
+ /**
46
+ * Excel's Convert Text to Columns wizard, condensed: choose Delimited (pick
47
+ * a delimiter or type another) or Fixed width (click the ruler to add or
48
+ * remove break lines, or type the positions), with a live preview of the
49
+ * first rows.
50
+ */
51
+ exports.TextToColumnsDialog = (0, react_1.memo)(function (_a) {
52
+ var open = _a.open, onOpenChange = _a.onOpenChange, preview = _a.preview, _b = _a.initialMode, initialMode = _b === void 0 ? "delimited" : _b, onApply = _a.onApply;
53
+ var _c = tslib_1.__read((0, react_1.useState)(initialMode), 2), mode = _c[0], setMode = _c[1];
54
+ var _d = tslib_1.__read((0, react_1.useState)(","), 2), delimiter = _d[0], setDelimiter = _d[1];
55
+ var _e = tslib_1.__read((0, react_1.useState)(""), 2), customDelimiter = _e[0], setCustomDelimiter = _e[1];
56
+ var _f = tslib_1.__read((0, react_1.useState)([]), 2), breaks = _f[0], setBreaks = _f[1];
57
+ var _g = tslib_1.__read((0, react_1.useState)(""), 2), breaksText = _g[0], setBreaksText = _g[1];
58
+ (0, react_1.useEffect)(function () {
59
+ if (open) {
60
+ setMode(initialMode);
61
+ setDelimiter(",");
62
+ setCustomDelimiter("");
63
+ setBreaks([]);
64
+ setBreaksText("");
65
+ }
66
+ // Only reset on open transitions.
67
+ // eslint-disable-next-line react-hooks/exhaustive-deps
68
+ }, [open]);
69
+ var sample = (0, react_1.useMemo)(function () { return preview.slice(0, 6); }, [preview]);
70
+ var rulerLength = (0, react_1.useMemo)(function () { return Math.min(120, Math.max.apply(Math, tslib_1.__spreadArray([10], tslib_1.__read(sample.map(function (text) { return text.length; })), false))); }, [sample]);
71
+ var toggleBreak = (0, react_1.useCallback)(function (position) {
72
+ setBreaks(function (prev) {
73
+ var next = prev.includes(position)
74
+ ? prev.filter(function (p) { return p !== position; })
75
+ : tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(prev), false), [position], false).sort(function (a, b) { return a - b; });
76
+ setBreaksText(next.join(", "));
77
+ return next;
78
+ });
79
+ }, []);
80
+ var effectiveDelimiter = delimiter === "custom" ? customDelimiter : delimiter;
81
+ var canApply = mode === "delimited" ? effectiveDelimiter.length > 0 : breaks.length > 0;
82
+ var commit = (0, react_1.useCallback)(function () {
83
+ if (mode === "fixed") {
84
+ onApply({ delimiter: ",", columnBreaks: breaks });
85
+ }
86
+ else {
87
+ onApply({ delimiter: effectiveDelimiter });
88
+ }
89
+ onOpenChange(false);
90
+ }, [mode, breaks, effectiveDelimiter, onApply, onOpenChange]);
91
+ return (react_1.default.createElement(ui_1.Dialog, { open: open, onOpenChange: onOpenChange },
92
+ react_1.default.createElement(ui_1.DialogContent, { className: "w-[520px] max-w-[92vw] pointer-events-auto" },
93
+ react_1.default.createElement(ui_1.DialogTitle, null, "Text to columns"),
94
+ react_1.default.createElement(ui_1.DialogDescription, null, "Split the selected column into several columns."),
95
+ react_1.default.createElement(ui_1.DialogCloseButton, { onClick: function () { return onOpenChange(false); } },
96
+ react_1.default.createElement(icons_1.Cross1Icon, null)),
97
+ react_1.default.createElement(ui_1.DialogBody, { className: "flex flex-col gap-3 font-system text-sm" },
98
+ react_1.default.createElement("div", { className: "flex gap-4", role: "radiogroup", "aria-label": "Original data type" },
99
+ react_1.default.createElement("label", { className: "flex items-center gap-1" },
100
+ react_1.default.createElement("input", { type: "radio", name: "text-to-columns-mode", value: "delimited", checked: mode === "delimited", onChange: function () { return setMode("delimited"); } }),
101
+ "Delimited"),
102
+ react_1.default.createElement("label", { className: "flex items-center gap-1" },
103
+ react_1.default.createElement("input", { type: "radio", name: "text-to-columns-mode", value: "fixed", checked: mode === "fixed", onChange: function () { return setMode("fixed"); } }),
104
+ "Fixed width")),
105
+ mode === "delimited" ? (react_1.default.createElement("div", { className: "flex flex-col gap-2" },
106
+ react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
107
+ "Delimiter",
108
+ react_1.default.createElement("select", { className: "h-8 rounded border border-rnc-border bg-transparent px-2 text-sm", value: delimiter, onChange: function (e) { return setDelimiter(e.target.value); }, "aria-label": "Delimiter" },
109
+ DELIMITERS.map(function (option) { return (react_1.default.createElement("option", { key: option.value, value: option.value }, option.label)); }),
110
+ react_1.default.createElement("option", { value: "custom" }, "Other\u2026"))),
111
+ delimiter === "custom" ? (react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
112
+ "Other delimiter",
113
+ react_1.default.createElement(ui_1.Input, { value: customDelimiter, maxLength: 5, "aria-label": "Other delimiter", onChange: function (e) { return setCustomDelimiter(e.target.value); } }))) : null)) : (react_1.default.createElement("div", { className: "flex flex-col gap-2" },
114
+ react_1.default.createElement("div", { className: "text-xs text-rnc-foreground/70" }, "Click the ruler to create a break line; click it again to remove it."),
115
+ react_1.default.createElement("div", { className: "overflow-x-auto rounded border border-rnc-border p-2 font-mono text-xs leading-5", "data-testid": "fixed-width-ruler" },
116
+ react_1.default.createElement("div", { className: "flex select-none" }, Array.from({ length: rulerLength }, function (_, index) {
117
+ var position = index + 1;
118
+ var active = breaks.includes(position);
119
+ return (react_1.default.createElement("button", { key: position, type: "button", "aria-label": "Break after character ".concat(position), "aria-pressed": active, className: "w-[1ch] shrink-0 border-r ".concat(active ? "border-rnc-primary bg-rnc-primary/20" : "border-transparent", " hover:bg-rnc-accent"), onClick: function () { return toggleBreak(position); } }, position % 10 === 0 ? String(position / 10) : "·"));
120
+ })),
121
+ sample.map(function (text, rowIndex) { return (react_1.default.createElement("div", { key: rowIndex, className: "flex whitespace-pre" }, Array.from({ length: rulerLength }, function (_, index) {
122
+ var _a;
123
+ var position = index + 1;
124
+ var active = breaks.includes(position);
125
+ return (react_1.default.createElement("span", { key: position, className: "w-[1ch] shrink-0 border-r ".concat(active ? "border-rnc-primary" : "border-transparent") }, (_a = text[index]) !== null && _a !== void 0 ? _a : " "));
126
+ }))); })),
127
+ react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
128
+ "Break positions (characters before each break)",
129
+ react_1.default.createElement(ui_1.Input, { value: breaksText, placeholder: "e.g. 4, 10", "aria-label": "Break positions", onChange: function (e) {
130
+ setBreaksText(e.target.value);
131
+ setBreaks(parseBreaks(e.target.value));
132
+ } })))),
133
+ react_1.default.createElement("div", { className: "flex flex-col gap-1" },
134
+ react_1.default.createElement("span", { className: "text-xs font-medium" }, "Data preview"),
135
+ react_1.default.createElement("div", { className: "max-h-[120px] overflow-auto rounded border border-rnc-border p-2 font-mono text-xs", "data-testid": "text-to-columns-preview" }, sample.map(function (text, rowIndex) {
136
+ var parts = mode === "fixed"
137
+ ? cutAt(text, breaks)
138
+ : effectiveDelimiter
139
+ ? text.split(effectiveDelimiter)
140
+ : [text];
141
+ return (react_1.default.createElement("div", { key: rowIndex, className: "flex gap-1 whitespace-pre" }, parts.map(function (part, partIndex) { return (react_1.default.createElement("span", { key: partIndex, className: "border-r border-rnc-border pr-1 last:border-r-0" }, part.trim() || " ")); })));
142
+ }))),
143
+ react_1.default.createElement(ui_1.Separator, null),
144
+ react_1.default.createElement("div", { className: "flex justify-end gap-2" },
145
+ react_1.default.createElement(ui_1.Button, { variant: "outline", size: "sm", type: "button", onClick: function () { return onOpenChange(false); } }, "Cancel"),
146
+ react_1.default.createElement(ui_1.Button, { size: "sm", type: "button", onClick: commit, disabled: !canApply }, "Finish"))))));
147
+ });
148
+ exports.TextToColumnsDialog.displayName = "TextToColumnsDialog";
149
+ /**
150
+ * Host-mounted, atom-driven wrapper around {@link TextToColumnsDialog}.
151
+ * Mount once in the host (alongside the other editor dialogs); the context
152
+ * menu opens it via `useOpenTextToColumnsDialog`. Without a host the menu
153
+ * keeps its one-click delimiter items only.
154
+ */
155
+ var TextToColumnsDialogHost = function () {
156
+ var _a;
157
+ (0, text_to_columns_dialog_atom_1.useRegisterTextToColumnsDialogHost)();
158
+ var _b = tslib_1.__read((0, text_to_columns_dialog_atom_1.useTextToColumnsDialogState)(), 2), request = _b[0], setRequest = _b[1];
159
+ var close = (0, react_1.useCallback)(function () { return setRequest(null); }, [setRequest]);
160
+ return (react_1.default.createElement(exports.TextToColumnsDialog, { open: request != null, onOpenChange: function (open) {
161
+ if (!open)
162
+ close();
163
+ }, preview: (_a = request === null || request === void 0 ? void 0 : request.preview) !== null && _a !== void 0 ? _a : [], initialMode: "fixed", onApply: function (options) { return request === null || request === void 0 ? void 0 : request.onApply(options); } }));
164
+ };
165
+ exports.TextToColumnsDialogHost = TextToColumnsDialogHost;
166
+ exports.TextToColumnsDialogHost.displayName = "TextToColumnsDialogHost";
@@ -4,16 +4,28 @@ import type { Color } from "../../types";
4
4
  import type { SpreadsheetTheme } from "../canvas-grid/typings";
5
5
  import type { ColorSelectorProps } from "./color-selector";
6
6
  import { ColorSelector } from "./color-selector";
7
+ import { type CellFill } from "./fill-selectors";
7
8
  type BackgroundColorSelectorProps = {
8
9
  disabled?: boolean;
9
10
  color?: Color | null;
10
11
  theme?: SpreadsheetTheme;
11
12
  onChange?(color: Color | undefined): void;
13
+ /**
14
+ * The active cell's fill (pattern / gradient fields) — enables the
15
+ * Pattern and Gradient tabs together with `onChangeFill`. Without
16
+ * `onChangeFill` the popover is the solid colour picker only.
17
+ */
18
+ fill?: CellFill | null;
19
+ /**
20
+ * Apply a pattern or gradient fill (Excel: Format Cells → Fill → Pattern /
21
+ * Fill Effects). Receives the full fill slice so cleared fields reset.
22
+ */
23
+ onChangeFill?(fill: CellFill): void;
12
24
  /**
13
25
  * Custom color selector component
14
26
  */
15
27
  ColorSelector?: ComponentType<ColorSelectorProps>;
16
28
  } & Pick<ComponentProps<typeof ColorSelector>, "userDefinedColors" | "onAddUserDefinedColor">;
17
- export declare const BackgroundColorSelector: ({ color, theme, onChange, onAddUserDefinedColor, userDefinedColors, disabled, ColorSelector: ColorSelectorComponent, }: BackgroundColorSelectorProps) => React.JSX.Element;
29
+ export declare const BackgroundColorSelector: ({ color, theme, onChange, fill, onChangeFill, onAddUserDefinedColor, userDefinedColors, disabled, ColorSelector: ColorSelectorComponent, }: BackgroundColorSelectorProps) => React.JSX.Element;
18
30
  export {};
19
31
  //# sourceMappingURL=background-color-selector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"background-color-selector.d.ts","sourceRoot":"","sources":["../../../../components/toolbar/background-color-selector.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,KAAK,4BAA4B,GAAG;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1C;;OAEG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACnD,GAAG,IAAI,CACN,cAAc,CAAC,OAAO,aAAa,CAAC,EACpC,mBAAmB,GAAG,uBAAuB,CAC9C,CAAC;AACF,eAAO,MAAM,uBAAuB,GAAI,wHAQrC,4BAA4B,sBAqC9B,CAAC"}
1
+ {"version":3,"file":"background-color-selector.d.ts","sourceRoot":"","sources":["../../../../components/toolbar/background-color-selector.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACL,KAAK,QAAQ,EAId,MAAM,kBAAkB,CAAC;AAE1B,KAAK,4BAA4B,GAAG;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1C;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACpC;;OAEG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACnD,GAAG,IAAI,CACN,cAAc,CAAC,OAAO,aAAa,CAAC,EACpC,mBAAmB,GAAG,uBAAuB,CAC9C,CAAC;AACF,eAAO,MAAM,uBAAuB,GAAI,4IAUrC,4BAA4B,sBA+G9B,CAAC"}
@@ -11,24 +11,70 @@ var atoms_1 = require("../../atoms");
11
11
  var config_1 = require("../../config");
12
12
  var themes_1 = require("../../themes");
13
13
  var color_selector_1 = require("./color-selector");
14
+ var fill_selectors_1 = require("./fill-selectors");
14
15
  var BackgroundColorSelector = function (_a) {
15
- var _b = _a.color, color = _b === void 0 ? "transparent" : _b, _c = _a.theme, theme = _c === void 0 ? config_1.defaultSpreadsheetTheme : _c, onChange = _a.onChange, onAddUserDefinedColor = _a.onAddUserDefinedColor, userDefinedColors = _a.userDefinedColors, disabled = _a.disabled, _d = _a.ColorSelector, ColorSelectorComponent = _d === void 0 ? color_selector_1.ColorSelector : _d;
16
- var _e = tslib_1.__read((0, react_2.useState)(false), 2), isOpen = _e[0], setIsOpen = _e[1];
16
+ var _b, _c;
17
+ var _d = _a.color, color = _d === void 0 ? "transparent" : _d, _e = _a.theme, theme = _e === void 0 ? config_1.defaultSpreadsheetTheme : _e, onChange = _a.onChange, fill = _a.fill, onChangeFill = _a.onChangeFill, onAddUserDefinedColor = _a.onAddUserDefinedColor, userDefinedColors = _a.userDefinedColors, disabled = _a.disabled, _f = _a.ColorSelector, ColorSelectorComponent = _f === void 0 ? color_selector_1.ColorSelector : _f;
18
+ var _g = tslib_1.__read((0, react_2.useState)(false), 2), isOpen = _g[0], setIsOpen = _g[1];
17
19
  var close = function () { return setIsOpen(false); };
18
20
  var open = function () { return setIsOpen(true); };
19
21
  var colorString = (0, themes_1.getStringifiedColor)(color, theme);
20
22
  var focusSheet = (0, atoms_1.useFocusSheet)();
23
+ // The trigger underline previews the effective fill: gradient, then the
24
+ // pattern colour, then the solid colour.
25
+ var swatchStyle = (fill === null || fill === void 0 ? void 0 : fill.gradient)
26
+ ? {
27
+ borderBottom: "4px solid transparent",
28
+ borderImage: "".concat((0, fill_selectors_1.gradientToCss)(fill.gradient), " 1"),
29
+ }
30
+ : {
31
+ borderBottom: "4px ".concat((fill === null || fill === void 0 ? void 0 : fill.fillPattern) &&
32
+ fill.fillPattern !== "none" &&
33
+ fill.foregroundColor
34
+ ? (0, themes_1.getStringifiedColor)(fill.foregroundColor, theme)
35
+ : colorString, " solid"),
36
+ };
37
+ var solidPicker = (react_1.default.createElement(ColorSelectorComponent, { color: color, onChange: function (color) {
38
+ var _a, _b;
39
+ // A solid pick replaces a gradient (Excel keeps them exclusive) and,
40
+ // with "No fill", clears the pattern too.
41
+ if (onChangeFill && ((fill === null || fill === void 0 ? void 0 : fill.gradient) || (!color && (fill === null || fill === void 0 ? void 0 : fill.fillPattern)))) {
42
+ onChangeFill({
43
+ backgroundColor: color,
44
+ fillPattern: color ? (_a = fill === null || fill === void 0 ? void 0 : fill.fillPattern) !== null && _a !== void 0 ? _a : undefined : undefined,
45
+ foregroundColor: color
46
+ ? (_b = fill === null || fill === void 0 ? void 0 : fill.foregroundColor) !== null && _b !== void 0 ? _b : undefined
47
+ : undefined,
48
+ gradient: undefined,
49
+ });
50
+ }
51
+ else {
52
+ onChange === null || onChange === void 0 ? void 0 : onChange(color);
53
+ }
54
+ focusSheet === null || focusSheet === void 0 ? void 0 : focusSheet();
55
+ close();
56
+ }, theme: theme, resetButtonTitle: "No fill", userDefinedColors: userDefinedColors, onAddUserDefinedColor: onAddUserDefinedColor }));
57
+ var applyFill = function (next) {
58
+ onChangeFill === null || onChangeFill === void 0 ? void 0 : onChangeFill(next);
59
+ focusSheet === null || focusSheet === void 0 ? void 0 : focusSheet();
60
+ };
21
61
  return (react_1.default.createElement(ui_1.Popover, { modal: false, open: isOpen, onOpenChange: setIsOpen },
22
62
  react_1.default.createElement(ui_1.PopoverTrigger, { asChild: true },
23
- react_1.default.createElement(ui_2.IconButton, { className: "text-base flex-row", style: {
24
- borderBottom: "4px ".concat(colorString, " solid"),
25
- }, tooltip: "Fill color", onClick: open, disabled: disabled },
63
+ react_1.default.createElement(ui_2.IconButton, { className: "text-base flex-row", style: swatchStyle, tooltip: "Fill color", "aria-label": "Fill color", onClick: open, disabled: disabled },
26
64
  react_1.default.createElement(icons_1.IoMdColorFill, null))),
27
- react_1.default.createElement(ui_1.PopoverContent, { align: "start" },
28
- react_1.default.createElement(ColorSelectorComponent, { color: color, onChange: function (color) {
29
- onChange === null || onChange === void 0 ? void 0 : onChange(color);
30
- focusSheet === null || focusSheet === void 0 ? void 0 : focusSheet();
31
- close();
32
- }, theme: theme, resetButtonTitle: "No fill", userDefinedColors: userDefinedColors, onAddUserDefinedColor: onAddUserDefinedColor }))));
65
+ react_1.default.createElement(ui_1.PopoverContent, { align: "start" }, onChangeFill ? (react_1.default.createElement(ui_2.Tabs, { defaultValue: (fill === null || fill === void 0 ? void 0 : fill.gradient)
66
+ ? "gradient"
67
+ : (fill === null || fill === void 0 ? void 0 : fill.fillPattern) && fill.fillPattern !== "none"
68
+ ? "pattern"
69
+ : "solid" },
70
+ react_1.default.createElement(ui_2.TabsList, { className: "grid-cols-3 mb-2" },
71
+ react_1.default.createElement(ui_2.TabsTrigger, { value: "solid" }, "Solid"),
72
+ react_1.default.createElement(ui_2.TabsTrigger, { value: "pattern" }, "Pattern"),
73
+ react_1.default.createElement(ui_2.TabsTrigger, { value: "gradient" }, "Gradient")),
74
+ react_1.default.createElement(ui_2.TabsContent, { value: "solid" }, solidPicker),
75
+ react_1.default.createElement(ui_2.TabsContent, { value: "pattern" },
76
+ react_1.default.createElement(fill_selectors_1.PatternFillPicker, { fill: tslib_1.__assign(tslib_1.__assign({}, fill), { backgroundColor: (_b = fill === null || fill === void 0 ? void 0 : fill.backgroundColor) !== null && _b !== void 0 ? _b : color }), theme: theme, onChangeFill: applyFill })),
77
+ react_1.default.createElement(ui_2.TabsContent, { value: "gradient" },
78
+ react_1.default.createElement(fill_selectors_1.GradientFillPicker, { fill: tslib_1.__assign(tslib_1.__assign({}, fill), { backgroundColor: (_c = fill === null || fill === void 0 ? void 0 : fill.backgroundColor) !== null && _c !== void 0 ? _c : color }), theme: theme, onChangeFill: applyFill })))) : (solidPicker))));
33
79
  };
34
80
  exports.BackgroundColorSelector = BackgroundColorSelector;
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import type { CellFormat } from "../../types";
2
+ import type { CellFormat, NamedCellStyle } from "../../types";
3
3
  import type { SpreadsheetTheme } from "../canvas-grid/typings";
4
4
  type WithCellFormat = (value: CellFormat) => void;
5
5
  type WithTypeValue<T extends keyof CellFormat> = (type: T, value: CellFormat[T]) => void;
@@ -8,6 +8,13 @@ export type CellStyleSelectorProps = {
8
8
  locale?: string;
9
9
  theme: SpreadsheetTheme;
10
10
  userDefinedStyles?: [string, CellFormat][];
11
+ /**
12
+ * Workbook named cell styles imported from `<cellStyles>` ("Heading 1",
13
+ * "Good", "Accent 1", …). Shown as a "Workbook styles" section ahead of
14
+ * the built-in gallery; hidden entries and the "Normal" base style are
15
+ * skipped, as is any entry whose xf resolved to no formatting.
16
+ */
17
+ namedCellStyles?: NamedCellStyle[] | null;
11
18
  selectedFormat?: CellFormat | null;
12
19
  onAddUserDefinedStyle?(name: string): void;
13
20
  onChangeFormatting: (...args: Parameters<WithCellFormat | WithTypeValue<keyof CellFormat>>) => void;
@@ -19,7 +26,13 @@ type StyleList = [
19
26
  format: CellFormat,
20
27
  style?: React.CSSProperties
21
28
  ];
29
+ /** Named styles worth showing in the gallery (see `namedCellStyles` prop). */
30
+ export declare const getGalleryNamedCellStyles: (namedCellStyles: NamedCellStyle[] | null | undefined) => Array<NamedCellStyle & {
31
+ format: CellFormat;
32
+ }>;
33
+ /** CSS preview of a named style's format for the gallery swatch. */
34
+ export declare const getNamedCellStylePreview: (format: CellFormat | undefined, theme: SpreadsheetTheme) => React.CSSProperties;
22
35
  export declare const getCellStyles: (theme: SpreadsheetTheme, currencySymbol?: string) => Map<string, StyleList[]>;
23
- export declare const CellStyleSelector: React.MemoExoticComponent<({ currency, locale, theme, selectedFormat, canAddCustomStyle, onChangeFormatting, onClearFormatting, }: CellStyleSelectorProps) => React.JSX.Element>;
36
+ export declare const CellStyleSelector: React.MemoExoticComponent<({ currency, locale, theme, selectedFormat, namedCellStyles, canAddCustomStyle, onChangeFormatting, onClearFormatting, }: CellStyleSelectorProps) => React.JSX.Element>;
24
37
  export {};
25
38
  //# sourceMappingURL=cell-style-selector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cell-style-selector.d.ts","sourceRoot":"","sources":["../../../../components/toolbar/cell-style-selector.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAMrD,OAAO,KAAK,EAAE,UAAU,EAAuB,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,KAAK,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAClD,KAAK,aAAa,CAAC,CAAC,SAAS,MAAM,UAAU,IAAI,CAC/C,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KACjB,IAAI,CAAC;AAEV,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,gBAAgB,CAAC;IACxB,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;IAC3C,cAAc,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACnC,qBAAqB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,kBAAkB,EAAE,CAClB,GAAG,IAAI,EAAE,UAAU,CAAC,cAAc,GAAG,aAAa,CAAC,MAAM,UAAU,CAAC,CAAC,KAClE,IAAI,CAAC;IACV,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,QAAQ,EAAE,MAAM;IAChB,MAAM,EAAE,UAAU;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa;CAC5B,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,OAAO,gBAAgB,EACvB,iBAAiB,MAAM,6BAgYxB,CAAC;AAEF,eAAO,MAAM,iBAAiB,qIASzB,sBAAsB,uBAwM1B,CAAC"}
1
+ {"version":3,"file":"cell-style-selector.d.ts","sourceRoot":"","sources":["../../../../components/toolbar/cell-style-selector.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAMrD,OAAO,KAAK,EACV,UAAU,EAEV,cAAc,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,KAAK,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAClD,KAAK,aAAa,CAAC,CAAC,SAAS,MAAM,UAAU,IAAI,CAC/C,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KACjB,IAAI,CAAC;AAEV,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,gBAAgB,CAAC;IACxB,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;IAC3C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAC1C,cAAc,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACnC,qBAAqB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,kBAAkB,EAAE,CAClB,GAAG,IAAI,EAAE,UAAU,CAAC,cAAc,GAAG,aAAa,CAAC,MAAM,UAAU,CAAC,CAAC,KAClE,IAAI,CAAC;IACV,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,QAAQ,EAAE,MAAM;IAChB,MAAM,EAAE,UAAU;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa;CAC5B,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,yBAAyB,GACpC,iBAAiB,cAAc,EAAE,GAAG,IAAI,GAAG,SAAS,KACnD,KAAK,CAAC,cAAc,GAAG;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAQ7C,CAAC;AAcJ,oEAAoE;AACpE,eAAO,MAAM,wBAAwB,GACnC,QAAQ,UAAU,GAAG,SAAS,EAC9B,OAAO,gBAAgB,KACtB,KAAK,CAAC,aAqBR,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,OAAO,gBAAgB,EACvB,iBAAiB,MAAM,6BAgYxB,CAAC;AAEF,eAAO,MAAM,iBAAiB,sJAUzB,sBAAsB,uBAsO1B,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CellStyleSelector = exports.getCellStyles = void 0;
3
+ exports.CellStyleSelector = exports.getCellStyles = exports.getNamedCellStylePreview = exports.getGalleryNamedCellStyles = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var icons_1 = require("@rowsncolumns/icons");
6
6
  var icons_2 = require("@rowsncolumns/icons");
@@ -12,6 +12,54 @@ var react_1 = tslib_1.__importStar(require("react"));
12
12
  var atoms_1 = require("../../atoms");
13
13
  var helpers_1 = require("../../helpers");
14
14
  var themes_1 = require("../../themes");
15
+ /** Named styles worth showing in the gallery (see `namedCellStyles` prop). */
16
+ var getGalleryNamedCellStyles = function (namedCellStyles) {
17
+ return (namedCellStyles !== null && namedCellStyles !== void 0 ? namedCellStyles : []).filter(function (style) {
18
+ return !style.hidden &&
19
+ style.builtinId !== 0 &&
20
+ style.name !== "Normal" &&
21
+ !!style.format &&
22
+ Object.keys(style.format).length > 0;
23
+ });
24
+ };
25
+ exports.getGalleryNamedCellStyles = getGalleryNamedCellStyles;
26
+ var previewBorder = function (border, theme) {
27
+ var _a;
28
+ return border
29
+ ? "".concat((_a = border.width) !== null && _a !== void 0 ? _a : 1, "px ").concat(border.style === "double" ? "double" : "solid", " ").concat((0, themes_1.getStringifiedColor)(border.color, theme))
30
+ : undefined;
31
+ };
32
+ /** CSS preview of a named style's format for the gallery swatch. */
33
+ var getNamedCellStylePreview = function (format, theme) {
34
+ if (!format)
35
+ return {};
36
+ var style = {};
37
+ if (format.backgroundColor) {
38
+ style.backgroundColor = (0, themes_1.getStringifiedColor)(format.backgroundColor, theme);
39
+ }
40
+ var text = format.textFormat;
41
+ if (text === null || text === void 0 ? void 0 : text.color)
42
+ style.color = (0, themes_1.getStringifiedColor)(text.color, theme);
43
+ if (text === null || text === void 0 ? void 0 : text.bold)
44
+ style.fontWeight = "bold";
45
+ if (text === null || text === void 0 ? void 0 : text.italic)
46
+ style.fontStyle = "italic";
47
+ if (text === null || text === void 0 ? void 0 : text.underline)
48
+ style.textDecoration = "underline";
49
+ if (text === null || text === void 0 ? void 0 : text.fontSize)
50
+ style.fontSize = text.fontSize;
51
+ if (text === null || text === void 0 ? void 0 : text.fontFamily)
52
+ style.fontFamily = text.fontFamily;
53
+ var borders = format.borders;
54
+ if (borders) {
55
+ style.borderTop = previewBorder(borders.top, theme);
56
+ style.borderBottom = previewBorder(borders.bottom, theme);
57
+ style.borderLeft = previewBorder(borders.left, theme);
58
+ style.borderRight = previewBorder(borders.right, theme);
59
+ }
60
+ return style;
61
+ };
62
+ exports.getNamedCellStylePreview = getNamedCellStylePreview;
15
63
  var getCellStyles = function (theme, currencySymbol) {
16
64
  return new Map([
17
65
  [
@@ -389,13 +437,14 @@ var getCellStyles = function (theme, currencySymbol) {
389
437
  };
390
438
  exports.getCellStyles = getCellStyles;
391
439
  exports.CellStyleSelector = (0, react_1.memo)(function (_a) {
392
- var currency = _a.currency, locale = _a.locale, theme = _a.theme, selectedFormat = _a.selectedFormat, _b = _a.canAddCustomStyle, canAddCustomStyle = _b === void 0 ? false : _b, onChangeFormatting = _a.onChangeFormatting, onClearFormatting = _a.onClearFormatting;
440
+ var currency = _a.currency, locale = _a.locale, theme = _a.theme, selectedFormat = _a.selectedFormat, namedCellStyles = _a.namedCellStyles, _b = _a.canAddCustomStyle, canAddCustomStyle = _b === void 0 ? false : _b, onChangeFormatting = _a.onChangeFormatting, onClearFormatting = _a.onClearFormatting;
393
441
  var colorIndexes = [4, 5, 6, 7, 8, 9];
394
442
  var colorTints = [0.8, 0.6, 0.4, 0];
395
443
  var currencySymbol = (0, helpers_1.getCurrencySymbol)(locale, currency);
396
444
  var shouldFocusSheetRef = (0, react_1.useRef)(true);
397
445
  var focusSheet = (0, atoms_1.useFocusSheet)();
398
446
  var cellStyles = (0, react_1.useMemo)(function () { return tslib_1.__spreadArray([], tslib_1.__read((0, exports.getCellStyles)(theme, currencySymbol).entries()), false); }, [theme, currencySymbol]);
447
+ var workbookStyles = (0, react_1.useMemo)(function () { return (0, exports.getGalleryNamedCellStyles)(namedCellStyles); }, [namedCellStyles]);
399
448
  // Number formats
400
449
  var numberFormats = [
401
450
  [
@@ -440,7 +489,7 @@ exports.CellStyleSelector = (0, react_1.memo)(function (_a) {
440
489
  var gridClass = "grid grid-cols-3 md:grid-cols-6 gap-1 pb-1";
441
490
  return (react_1.default.createElement(ui_2.DropdownMenu, { modal: false },
442
491
  react_1.default.createElement(ui_2.DropdownMenuTrigger, { asChild: true },
443
- react_1.default.createElement(ui_2.IconButton, { size: "xl", tooltip: "Cell styles", className: "gap-1" },
492
+ react_1.default.createElement(ui_2.IconButton, { size: "xl", tooltip: "Cell styles", "aria-label": "Cell styles", className: "gap-1" },
444
493
  react_1.default.createElement(icons_2.MdBrush, null),
445
494
  react_1.default.createElement("div", { className: "text-xs" }, "Cell styles"),
446
495
  react_1.default.createElement(icons_1.MdOutlineArrowDropDown, null))),
@@ -454,6 +503,10 @@ exports.CellStyleSelector = (0, react_1.memo)(function (_a) {
454
503
  shouldFocusSheetRef.current = false;
455
504
  } },
456
505
  react_1.default.createElement("div", { className: "max-w-dropdown md:min-w-[400px] p-2 pt-0" },
506
+ workbookStyles.length ? (react_1.default.createElement("div", null,
507
+ react_1.default.createElement("div", { className: headingClass }, "Workbook styles"),
508
+ react_1.default.createElement(ui_1.Separator, { className: "mb-2" }),
509
+ react_1.default.createElement("div", { className: gridClass }, workbookStyles.map(function (namedStyle) { return (react_1.default.createElement(ui_1.DropdownMenuItem, { onClick: function () { return onChangeFormatting(namedStyle.format); }, className: hoverClass, key: "".concat(namedStyle.name, "-").concat(namedStyle.xfId), style: (0, exports.getNamedCellStylePreview)(namedStyle.format, theme) }, namedStyle.name)); })))) : null,
457
510
  cellStyles.map(function (_a) {
458
511
  var _b = tslib_1.__read(_a, 2), category = _b[0], cellStyleList = _b[1];
459
512
  return (react_1.default.createElement("div", { key: category },