@rowsncolumns/spreadsheet 10.3.0 → 10.4.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 (484) hide show
  1. package/dist/cjs/api/banded-ranges.d.ts.map +1 -1
  2. package/dist/cjs/api/banded-ranges.js +40 -14
  3. package/dist/cjs/api/calculated-column-fill.d.ts +43 -0
  4. package/dist/cjs/api/calculated-column-fill.d.ts.map +1 -0
  5. package/dist/cjs/api/calculated-column-fill.js +16 -0
  6. package/dist/cjs/api/chart-sheet.d.ts +8 -0
  7. package/dist/cjs/api/chart-sheet.d.ts.map +1 -0
  8. package/dist/cjs/api/chart-sheet.js +20 -0
  9. package/dist/cjs/api/chart-source-ranges.d.ts +64 -0
  10. package/dist/cjs/api/chart-source-ranges.d.ts.map +1 -0
  11. package/dist/cjs/api/chart-source-ranges.js +175 -0
  12. package/dist/cjs/api/selections.d.ts +3 -3
  13. package/dist/cjs/api/selections.d.ts.map +1 -1
  14. package/dist/cjs/api/selections.js +28 -2
  15. package/dist/cjs/api/spreadsheet-api.d.ts +16 -3
  16. package/dist/cjs/api/spreadsheet-api.d.ts.map +1 -1
  17. package/dist/cjs/api/spreadsheet-api.js +22 -2
  18. package/dist/cjs/api/table-auto-expansion.d.ts +37 -0
  19. package/dist/cjs/api/table-auto-expansion.d.ts.map +1 -0
  20. package/dist/cjs/api/table-auto-expansion.js +16 -0
  21. package/dist/cjs/api/table.d.ts +49 -1
  22. package/dist/cjs/api/table.d.ts.map +1 -1
  23. package/dist/cjs/api/table.js +145 -1
  24. package/dist/cjs/api/validation.d.ts +26 -1
  25. package/dist/cjs/api/validation.d.ts.map +1 -1
  26. package/dist/cjs/api/validation.js +127 -9
  27. package/dist/cjs/atoms/calculated-column-fill.atom.d.ts +15 -0
  28. package/dist/cjs/atoms/calculated-column-fill.atom.d.ts.map +1 -0
  29. package/dist/cjs/atoms/calculated-column-fill.atom.js +18 -0
  30. package/dist/cjs/atoms/chart-actions.atom.d.ts +40 -0
  31. package/dist/cjs/atoms/chart-actions.atom.d.ts.map +1 -0
  32. package/dist/cjs/atoms/chart-actions.atom.js +66 -0
  33. package/dist/cjs/atoms/index.d.ts +5 -0
  34. package/dist/cjs/atoms/index.d.ts.map +1 -1
  35. package/dist/cjs/atoms/index.js +5 -0
  36. package/dist/cjs/atoms/move-chart-dialog.atom.d.ts +28 -0
  37. package/dist/cjs/atoms/move-chart-dialog.atom.d.ts.map +1 -0
  38. package/dist/cjs/atoms/move-chart-dialog.atom.js +34 -0
  39. package/dist/cjs/atoms/selected-chart-embed.atom.d.ts +9 -1
  40. package/dist/cjs/atoms/selected-chart-embed.atom.d.ts.map +1 -1
  41. package/dist/cjs/atoms/selected-chart-embed.atom.js +18 -1
  42. package/dist/cjs/atoms/selected-chart-series.atom.d.ts +24 -0
  43. package/dist/cjs/atoms/selected-chart-series.atom.d.ts.map +1 -0
  44. package/dist/cjs/atoms/selected-chart-series.atom.js +11 -0
  45. package/dist/cjs/atoms/sheet-context.atom.d.ts +2 -0
  46. package/dist/cjs/atoms/sheet-context.atom.d.ts.map +1 -1
  47. package/dist/cjs/atoms/sheet-context.atom.js +5 -2
  48. package/dist/cjs/atoms/sparkline-dialog.atom.d.ts +34 -0
  49. package/dist/cjs/atoms/sparkline-dialog.atom.d.ts.map +1 -0
  50. package/dist/cjs/atoms/sparkline-dialog.atom.js +30 -0
  51. package/dist/cjs/atoms/table-auto-expansion.atom.d.ts +14 -0
  52. package/dist/cjs/atoms/table-auto-expansion.atom.d.ts.map +1 -0
  53. package/dist/cjs/atoms/table-auto-expansion.atom.js +17 -0
  54. package/dist/cjs/components/calculated-column-smart-tag/index.d.ts +25 -0
  55. package/dist/cjs/components/calculated-column-smart-tag/index.d.ts.map +1 -0
  56. package/dist/cjs/components/calculated-column-smart-tag/index.js +31 -0
  57. package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
  58. package/dist/cjs/components/canvas-grid/index.js +407 -77
  59. package/dist/cjs/components/canvas-grid/typings.d.ts +127 -14
  60. package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
  61. package/dist/cjs/components/cell/index.d.ts.map +1 -1
  62. package/dist/cjs/components/cell/index.js +3 -3
  63. package/dist/cjs/components/cell/typings.d.ts +13 -0
  64. package/dist/cjs/components/cell/typings.d.ts.map +1 -1
  65. package/dist/cjs/components/cell-filter/index.d.ts.map +1 -1
  66. package/dist/cjs/components/cell-filter/index.js +13 -2
  67. package/dist/cjs/components/cell-input/formula-bar-cell-input.d.ts.map +1 -1
  68. package/dist/cjs/components/cell-input/formula-bar-cell-input.js +4 -1
  69. package/dist/cjs/components/cell-structured/sparkline-math.d.ts +28 -5
  70. package/dist/cjs/components/cell-structured/sparkline-math.d.ts.map +1 -1
  71. package/dist/cjs/components/cell-structured/sparkline-math.js +93 -5
  72. package/dist/cjs/components/cell-structured/sparkline.d.ts +1 -1
  73. package/dist/cjs/components/cell-structured/sparkline.d.ts.map +1 -1
  74. package/dist/cjs/components/cell-structured/sparkline.js +3 -3
  75. package/dist/cjs/components/cell-structured/types.d.ts +1 -1
  76. package/dist/cjs/components/cell-structured/types.d.ts.map +1 -1
  77. package/dist/cjs/components/chart-sheet-view/index.d.ts +27 -0
  78. package/dist/cjs/components/chart-sheet-view/index.d.ts.map +1 -0
  79. package/dist/cjs/components/chart-sheet-view/index.js +35 -0
  80. package/dist/cjs/components/context-menu/embed-context-menu.d.ts +48 -0
  81. package/dist/cjs/components/context-menu/embed-context-menu.d.ts.map +1 -0
  82. package/dist/cjs/components/context-menu/embed-context-menu.js +123 -0
  83. package/dist/cjs/components/context-menu/index.d.ts +23 -2
  84. package/dist/cjs/components/context-menu/index.d.ts.map +1 -1
  85. package/dist/cjs/components/context-menu/index.js +217 -39
  86. package/dist/cjs/components/context-menu/total-row-function-menu.d.ts +33 -0
  87. package/dist/cjs/components/context-menu/total-row-function-menu.d.ts.map +1 -0
  88. package/dist/cjs/components/context-menu/total-row-function-menu.js +58 -0
  89. package/dist/cjs/components/context-menu/total-row-functions.d.ts +12 -12
  90. package/dist/cjs/components/context-menu/total-row-functions.d.ts.map +1 -1
  91. package/dist/cjs/components/context-menu/total-row-functions.js +39 -39
  92. package/dist/cjs/components/embeds/chart-component.d.ts +17 -0
  93. package/dist/cjs/components/embeds/chart-component.d.ts.map +1 -1
  94. package/dist/cjs/components/embeds/embed-draggable.d.ts +61 -4
  95. package/dist/cjs/components/embeds/embed-draggable.d.ts.map +1 -1
  96. package/dist/cjs/components/embeds/embed-draggable.js +218 -42
  97. package/dist/cjs/components/filter-box/date-tree.d.ts +28 -0
  98. package/dist/cjs/components/filter-box/date-tree.d.ts.map +1 -0
  99. package/dist/cjs/components/filter-box/date-tree.js +147 -0
  100. package/dist/cjs/components/filter-box/filter-by-condition.d.ts +14 -2
  101. package/dist/cjs/components/filter-box/filter-by-condition.d.ts.map +1 -1
  102. package/dist/cjs/components/filter-box/filter-by-condition.js +95 -19
  103. package/dist/cjs/components/filter-box/filter-by-value.d.ts.map +1 -1
  104. package/dist/cjs/components/filter-box/filter-by-value.js +126 -40
  105. package/dist/cjs/components/filter-box/index.d.ts +7 -1
  106. package/dist/cjs/components/filter-box/index.d.ts.map +1 -1
  107. package/dist/cjs/components/filter-box/index.js +102 -11
  108. package/dist/cjs/components/move-chart-dialog/index.d.ts +34 -0
  109. package/dist/cjs/components/move-chart-dialog/index.d.ts.map +1 -0
  110. package/dist/cjs/components/move-chart-dialog/index.js +96 -0
  111. package/dist/cjs/components/print-preview/page-block.d.ts +9 -1
  112. package/dist/cjs/components/print-preview/page-block.d.ts.map +1 -1
  113. package/dist/cjs/components/print-preview/page-block.js +28 -2
  114. package/dist/cjs/components/print-preview/print-preview-dialog.d.ts +8 -1
  115. package/dist/cjs/components/print-preview/print-preview-dialog.d.ts.map +1 -1
  116. package/dist/cjs/components/print-preview/print-preview-dialog.js +144 -3
  117. package/dist/cjs/components/print-preview/run-print.d.ts.map +1 -1
  118. package/dist/cjs/components/print-preview/run-print.js +19 -7
  119. package/dist/cjs/components/print-preview/use-page-layout.d.ts +47 -0
  120. package/dist/cjs/components/print-preview/use-page-layout.d.ts.map +1 -1
  121. package/dist/cjs/components/print-preview/use-page-layout.js +81 -7
  122. package/dist/cjs/components/resizer/index.d.ts.map +1 -1
  123. package/dist/cjs/components/resizer/index.js +10 -5
  124. package/dist/cjs/components/selection/index.d.ts +1 -1
  125. package/dist/cjs/components/selection/index.d.ts.map +1 -1
  126. package/dist/cjs/components/selection/index.js +6 -2
  127. package/dist/cjs/components/selection/types.d.ts +15 -0
  128. package/dist/cjs/components/selection/types.d.ts.map +1 -1
  129. package/dist/cjs/components/sheet-search/index.d.ts.map +1 -1
  130. package/dist/cjs/components/sheet-search/index.js +6 -2
  131. package/dist/cjs/components/sheet-tabs/index.d.ts.map +1 -1
  132. package/dist/cjs/components/sheet-tabs/index.js +2 -2
  133. package/dist/cjs/components/sheet-tabs/sheet-tab.d.ts +1 -1
  134. package/dist/cjs/components/sheet-tabs/sheet-tab.d.ts.map +1 -1
  135. package/dist/cjs/components/sheet-tabs/sheet-tab.js +3 -1
  136. package/dist/cjs/components/sparkline-dialog/index.d.ts +43 -0
  137. package/dist/cjs/components/sparkline-dialog/index.d.ts.map +1 -0
  138. package/dist/cjs/components/sparkline-dialog/index.js +127 -0
  139. package/dist/cjs/components/subtotal-dialog/index.d.ts.map +1 -1
  140. package/dist/cjs/components/subtotal-dialog/index.js +10 -1
  141. package/dist/cjs/components/table-auto-expansion-smart-tag/index.d.ts +24 -0
  142. package/dist/cjs/components/table-auto-expansion-smart-tag/index.d.ts.map +1 -0
  143. package/dist/cjs/components/table-auto-expansion-smart-tag/index.js +31 -0
  144. package/dist/cjs/components/toolbar/index.d.ts +1 -0
  145. package/dist/cjs/components/toolbar/index.d.ts.map +1 -1
  146. package/dist/cjs/components/toolbar/index.js +1 -0
  147. package/dist/cjs/components/toolbar/insert-menu.d.ts +2 -1
  148. package/dist/cjs/components/toolbar/insert-menu.d.ts.map +1 -1
  149. package/dist/cjs/components/toolbar/insert-menu.js +24 -1
  150. package/dist/cjs/components/toolbar/merge-cells-selector.d.ts +4 -1
  151. package/dist/cjs/components/toolbar/merge-cells-selector.d.ts.map +1 -1
  152. package/dist/cjs/components/toolbar/merge-cells-selector.js +11 -5
  153. package/dist/cjs/components/toolbar/sparkline-actions.d.ts +31 -0
  154. package/dist/cjs/components/toolbar/sparkline-actions.d.ts.map +1 -0
  155. package/dist/cjs/components/toolbar/sparkline-actions.js +273 -0
  156. package/dist/cjs/components/toolbar/table-actions.d.ts +9 -1
  157. package/dist/cjs/components/toolbar/table-actions.d.ts.map +1 -1
  158. package/dist/cjs/components/toolbar/table-actions.js +17 -7
  159. package/dist/cjs/components/toolbar/table-style-selector.d.ts +38 -2
  160. package/dist/cjs/components/toolbar/table-style-selector.d.ts.map +1 -1
  161. package/dist/cjs/components/toolbar/table-style-selector.js +241 -389
  162. package/dist/cjs/config.d.ts +2 -0
  163. package/dist/cjs/config.d.ts.map +1 -1
  164. package/dist/cjs/config.js +31 -1
  165. package/dist/cjs/helpers.d.ts +1 -1
  166. package/dist/cjs/helpers.d.ts.map +1 -1
  167. package/dist/cjs/helpers.js +13 -2
  168. package/dist/cjs/hooks/use-cell-renderer.d.ts +16 -1
  169. package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
  170. package/dist/cjs/hooks/use-cell-renderer.js +20 -8
  171. package/dist/cjs/hooks/use-chart-clipboard.d.ts +55 -0
  172. package/dist/cjs/hooks/use-chart-clipboard.d.ts.map +1 -0
  173. package/dist/cjs/hooks/use-chart-clipboard.js +231 -0
  174. package/dist/cjs/hooks/use-chart-source-ranges.d.ts +27 -0
  175. package/dist/cjs/hooks/use-chart-source-ranges.d.ts.map +1 -0
  176. package/dist/cjs/hooks/use-chart-source-ranges.js +211 -0
  177. package/dist/cjs/hooks/use-context-setter.d.ts.map +1 -1
  178. package/dist/cjs/hooks/use-context-setter.js +3 -1
  179. package/dist/cjs/hooks/use-copy-paste-cut.d.ts.map +1 -1
  180. package/dist/cjs/hooks/use-copy-paste-cut.js +6 -3
  181. package/dist/cjs/hooks/use-editable.d.ts +9 -1
  182. package/dist/cjs/hooks/use-editable.d.ts.map +1 -1
  183. package/dist/cjs/hooks/use-editable.js +25 -1
  184. package/dist/cjs/hooks/use-embeds-charts.d.ts +64 -4
  185. package/dist/cjs/hooks/use-embeds-charts.d.ts.map +1 -1
  186. package/dist/cjs/hooks/use-embeds-charts.js +412 -41
  187. package/dist/cjs/hooks/use-grid-children.d.ts +2 -2
  188. package/dist/cjs/hooks/use-grid-children.d.ts.map +1 -1
  189. package/dist/cjs/hooks/use-grid-children.js +12 -6
  190. package/dist/cjs/hooks/use-header-actions.d.ts.map +1 -1
  191. package/dist/cjs/hooks/use-header-actions.js +17 -10
  192. package/dist/cjs/hooks/use-isomorphic-layout-effect.d.ts +2 -2
  193. package/dist/cjs/hooks/use-isomorphic-layout-effect.d.ts.map +1 -1
  194. package/dist/cjs/hooks/use-keyboard-handler.d.ts +2 -1
  195. package/dist/cjs/hooks/use-keyboard-handler.d.ts.map +1 -1
  196. package/dist/cjs/hooks/use-keyboard-handler.js +8 -2
  197. package/dist/cjs/hooks/use-move-columns-rows.d.ts.map +1 -1
  198. package/dist/cjs/hooks/use-move-columns-rows.js +21 -15
  199. package/dist/cjs/hooks/use-reveal-chart-embed.d.ts +17 -0
  200. package/dist/cjs/hooks/use-reveal-chart-embed.d.ts.map +1 -0
  201. package/dist/cjs/hooks/use-reveal-chart-embed.js +40 -0
  202. package/dist/cjs/hooks/use-selection-move.d.ts.map +1 -1
  203. package/dist/cjs/hooks/use-selection-move.js +14 -6
  204. package/dist/cjs/hooks/use-selection-renderer.d.ts +13 -1
  205. package/dist/cjs/hooks/use-selection-renderer.d.ts.map +1 -1
  206. package/dist/cjs/hooks/use-selection-renderer.js +37 -7
  207. package/dist/cjs/hooks/use-selection-resize.d.ts.map +1 -1
  208. package/dist/cjs/hooks/use-selection-resize.js +13 -6
  209. package/dist/cjs/hooks/use-selection.d.ts +9 -1
  210. package/dist/cjs/hooks/use-selection.d.ts.map +1 -1
  211. package/dist/cjs/hooks/use-selection.js +177 -55
  212. package/dist/cjs/hooks/use-structured-reference-selection.d.ts +1 -1
  213. package/dist/cjs/hooks/use-structured-reference-selection.d.ts.map +1 -1
  214. package/dist/cjs/hooks/use-structured-reference-selection.js +10 -0
  215. package/dist/cjs/hooks/use-table-hit-zones.d.ts +61 -0
  216. package/dist/cjs/hooks/use-table-hit-zones.d.ts.map +1 -0
  217. package/dist/cjs/hooks/use-table-hit-zones.js +157 -0
  218. package/dist/cjs/hooks/use-table-resizer.d.ts +7 -0
  219. package/dist/cjs/hooks/use-table-resizer.d.ts.map +1 -1
  220. package/dist/cjs/hooks/use-table-resizer.js +38 -18
  221. package/dist/cjs/hooks/use-touch.d.ts.map +1 -1
  222. package/dist/cjs/hooks/use-touch.js +16 -8
  223. package/dist/cjs/index.d.ts +13 -0
  224. package/dist/cjs/index.d.ts.map +1 -1
  225. package/dist/cjs/index.js +17 -1
  226. package/dist/cjs/release-date.js +1 -1
  227. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  228. package/dist/cjs/types.d.ts +289 -4
  229. package/dist/cjs/types.d.ts.map +1 -1
  230. package/dist/cjs/utils/copy-as-picture.d.ts +13 -0
  231. package/dist/cjs/utils/copy-as-picture.d.ts.map +1 -0
  232. package/dist/cjs/utils/copy-as-picture.js +70 -0
  233. package/dist/cjs/utils/pivot-chart-field-buttons.d.ts +19 -0
  234. package/dist/cjs/utils/pivot-chart-field-buttons.d.ts.map +1 -0
  235. package/dist/cjs/utils/pivot-chart-field-buttons.js +25 -0
  236. package/dist/cjs/utils/z-order.d.ts +47 -0
  237. package/dist/cjs/utils/z-order.d.ts.map +1 -0
  238. package/dist/cjs/utils/z-order.js +124 -0
  239. package/dist/esm/api/banded-ranges.d.ts.map +1 -1
  240. package/dist/esm/api/banded-ranges.js +39 -12
  241. package/dist/esm/api/calculated-column-fill.d.ts +43 -0
  242. package/dist/esm/api/calculated-column-fill.d.ts.map +1 -0
  243. package/dist/esm/api/calculated-column-fill.js +10 -0
  244. package/dist/esm/api/chart-sheet.d.ts +8 -0
  245. package/dist/esm/api/chart-sheet.d.ts.map +1 -0
  246. package/dist/esm/api/chart-sheet.js +15 -0
  247. package/dist/esm/api/chart-source-ranges.d.ts +64 -0
  248. package/dist/esm/api/chart-source-ranges.d.ts.map +1 -0
  249. package/dist/esm/api/chart-source-ranges.js +168 -0
  250. package/dist/esm/api/selections.d.ts +3 -3
  251. package/dist/esm/api/selections.d.ts.map +1 -1
  252. package/dist/esm/api/selections.js +26 -2
  253. package/dist/esm/api/spreadsheet-api.d.ts +16 -3
  254. package/dist/esm/api/spreadsheet-api.d.ts.map +1 -1
  255. package/dist/esm/api/spreadsheet-api.js +18 -2
  256. package/dist/esm/api/table-auto-expansion.d.ts +37 -0
  257. package/dist/esm/api/table-auto-expansion.d.ts.map +1 -0
  258. package/dist/esm/api/table-auto-expansion.js +10 -0
  259. package/dist/esm/api/table.d.ts +49 -1
  260. package/dist/esm/api/table.d.ts.map +1 -1
  261. package/dist/esm/api/table.js +138 -1
  262. package/dist/esm/api/validation.d.ts +26 -1
  263. package/dist/esm/api/validation.d.ts.map +1 -1
  264. package/dist/esm/api/validation.js +119 -9
  265. package/dist/esm/atoms/calculated-column-fill.atom.d.ts +15 -0
  266. package/dist/esm/atoms/calculated-column-fill.atom.d.ts.map +1 -0
  267. package/dist/esm/atoms/calculated-column-fill.atom.js +12 -0
  268. package/dist/esm/atoms/chart-actions.atom.d.ts +40 -0
  269. package/dist/esm/atoms/chart-actions.atom.d.ts.map +1 -0
  270. package/dist/esm/atoms/chart-actions.atom.js +58 -0
  271. package/dist/esm/atoms/index.d.ts +5 -0
  272. package/dist/esm/atoms/index.d.ts.map +1 -1
  273. package/dist/esm/atoms/index.js +5 -0
  274. package/dist/esm/atoms/move-chart-dialog.atom.d.ts +28 -0
  275. package/dist/esm/atoms/move-chart-dialog.atom.d.ts.map +1 -0
  276. package/dist/esm/atoms/move-chart-dialog.atom.js +25 -0
  277. package/dist/esm/atoms/selected-chart-embed.atom.d.ts +9 -1
  278. package/dist/esm/atoms/selected-chart-embed.atom.d.ts.map +1 -1
  279. package/dist/esm/atoms/selected-chart-embed.atom.js +19 -2
  280. package/dist/esm/atoms/selected-chart-series.atom.d.ts +24 -0
  281. package/dist/esm/atoms/selected-chart-series.atom.d.ts.map +1 -0
  282. package/dist/esm/atoms/selected-chart-series.atom.js +4 -0
  283. package/dist/esm/atoms/sheet-context.atom.d.ts +2 -0
  284. package/dist/esm/atoms/sheet-context.atom.d.ts.map +1 -1
  285. package/dist/esm/atoms/sheet-context.atom.js +2 -0
  286. package/dist/esm/atoms/sparkline-dialog.atom.d.ts +34 -0
  287. package/dist/esm/atoms/sparkline-dialog.atom.d.ts.map +1 -0
  288. package/dist/esm/atoms/sparkline-dialog.atom.js +21 -0
  289. package/dist/esm/atoms/table-auto-expansion.atom.d.ts +14 -0
  290. package/dist/esm/atoms/table-auto-expansion.atom.d.ts.map +1 -0
  291. package/dist/esm/atoms/table-auto-expansion.atom.js +11 -0
  292. package/dist/esm/components/calculated-column-smart-tag/index.d.ts +25 -0
  293. package/dist/esm/components/calculated-column-smart-tag/index.d.ts.map +1 -0
  294. package/dist/esm/components/calculated-column-smart-tag/index.js +25 -0
  295. package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
  296. package/dist/esm/components/canvas-grid/index.js +346 -26
  297. package/dist/esm/components/canvas-grid/typings.d.ts +127 -14
  298. package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
  299. package/dist/esm/components/cell/index.d.ts.map +1 -1
  300. package/dist/esm/components/cell/index.js +3 -3
  301. package/dist/esm/components/cell/typings.d.ts +13 -0
  302. package/dist/esm/components/cell/typings.d.ts.map +1 -1
  303. package/dist/esm/components/cell-filter/index.d.ts.map +1 -1
  304. package/dist/esm/components/cell-filter/index.js +14 -3
  305. package/dist/esm/components/cell-input/formula-bar-cell-input.d.ts.map +1 -1
  306. package/dist/esm/components/cell-input/formula-bar-cell-input.js +4 -1
  307. package/dist/esm/components/cell-structured/sparkline-math.d.ts +28 -5
  308. package/dist/esm/components/cell-structured/sparkline-math.d.ts.map +1 -1
  309. package/dist/esm/components/cell-structured/sparkline-math.js +58 -4
  310. package/dist/esm/components/cell-structured/sparkline.d.ts +1 -1
  311. package/dist/esm/components/cell-structured/sparkline.d.ts.map +1 -1
  312. package/dist/esm/components/cell-structured/sparkline.js +3 -3
  313. package/dist/esm/components/cell-structured/types.d.ts +1 -1
  314. package/dist/esm/components/cell-structured/types.d.ts.map +1 -1
  315. package/dist/esm/components/chart-sheet-view/index.d.ts +27 -0
  316. package/dist/esm/components/chart-sheet-view/index.d.ts.map +1 -0
  317. package/dist/esm/components/chart-sheet-view/index.js +30 -0
  318. package/dist/esm/components/context-menu/embed-context-menu.d.ts +48 -0
  319. package/dist/esm/components/context-menu/embed-context-menu.d.ts.map +1 -0
  320. package/dist/esm/components/context-menu/embed-context-menu.js +112 -0
  321. package/dist/esm/components/context-menu/index.d.ts +23 -2
  322. package/dist/esm/components/context-menu/index.d.ts.map +1 -1
  323. package/dist/esm/components/context-menu/index.js +174 -38
  324. package/dist/esm/components/context-menu/total-row-function-menu.d.ts +33 -0
  325. package/dist/esm/components/context-menu/total-row-function-menu.d.ts.map +1 -0
  326. package/dist/esm/components/context-menu/total-row-function-menu.js +50 -0
  327. package/dist/esm/components/context-menu/total-row-functions.d.ts +12 -12
  328. package/dist/esm/components/context-menu/total-row-functions.d.ts.map +1 -1
  329. package/dist/esm/components/context-menu/total-row-functions.js +29 -31
  330. package/dist/esm/components/embeds/chart-component.d.ts +17 -0
  331. package/dist/esm/components/embeds/chart-component.d.ts.map +1 -1
  332. package/dist/esm/components/embeds/embed-draggable.d.ts +61 -4
  333. package/dist/esm/components/embeds/embed-draggable.d.ts.map +1 -1
  334. package/dist/esm/components/embeds/embed-draggable.js +207 -47
  335. package/dist/esm/components/filter-box/date-tree.d.ts +28 -0
  336. package/dist/esm/components/filter-box/date-tree.d.ts.map +1 -0
  337. package/dist/esm/components/filter-box/date-tree.js +107 -0
  338. package/dist/esm/components/filter-box/filter-by-condition.d.ts +14 -2
  339. package/dist/esm/components/filter-box/filter-by-condition.d.ts.map +1 -1
  340. package/dist/esm/components/filter-box/filter-by-condition.js +72 -16
  341. package/dist/esm/components/filter-box/filter-by-value.d.ts.map +1 -1
  342. package/dist/esm/components/filter-box/filter-by-value.js +110 -39
  343. package/dist/esm/components/filter-box/index.d.ts +7 -1
  344. package/dist/esm/components/filter-box/index.d.ts.map +1 -1
  345. package/dist/esm/components/filter-box/index.js +88 -2
  346. package/dist/esm/components/move-chart-dialog/index.d.ts +34 -0
  347. package/dist/esm/components/move-chart-dialog/index.d.ts.map +1 -0
  348. package/dist/esm/components/move-chart-dialog/index.js +88 -0
  349. package/dist/esm/components/print-preview/page-block.d.ts +9 -1
  350. package/dist/esm/components/print-preview/page-block.d.ts.map +1 -1
  351. package/dist/esm/components/print-preview/page-block.js +27 -2
  352. package/dist/esm/components/print-preview/print-preview-dialog.d.ts +8 -1
  353. package/dist/esm/components/print-preview/print-preview-dialog.d.ts.map +1 -1
  354. package/dist/esm/components/print-preview/print-preview-dialog.js +92 -4
  355. package/dist/esm/components/print-preview/run-print.d.ts.map +1 -1
  356. package/dist/esm/components/print-preview/run-print.js +17 -7
  357. package/dist/esm/components/print-preview/use-page-layout.d.ts +47 -0
  358. package/dist/esm/components/print-preview/use-page-layout.d.ts.map +1 -1
  359. package/dist/esm/components/print-preview/use-page-layout.js +55 -0
  360. package/dist/esm/components/resizer/index.d.ts.map +1 -1
  361. package/dist/esm/components/resizer/index.js +8 -4
  362. package/dist/esm/components/selection/index.d.ts +1 -1
  363. package/dist/esm/components/selection/index.d.ts.map +1 -1
  364. package/dist/esm/components/selection/index.js +6 -2
  365. package/dist/esm/components/selection/types.d.ts +15 -0
  366. package/dist/esm/components/selection/types.d.ts.map +1 -1
  367. package/dist/esm/components/sheet-search/index.d.ts.map +1 -1
  368. package/dist/esm/components/sheet-search/index.js +5 -2
  369. package/dist/esm/components/sheet-tabs/index.d.ts.map +1 -1
  370. package/dist/esm/components/sheet-tabs/index.js +2 -2
  371. package/dist/esm/components/sheet-tabs/sheet-tab.d.ts +1 -1
  372. package/dist/esm/components/sheet-tabs/sheet-tab.d.ts.map +1 -1
  373. package/dist/esm/components/sheet-tabs/sheet-tab.js +4 -2
  374. package/dist/esm/components/sparkline-dialog/index.d.ts +43 -0
  375. package/dist/esm/components/sparkline-dialog/index.d.ts.map +1 -0
  376. package/dist/esm/components/sparkline-dialog/index.js +123 -0
  377. package/dist/esm/components/subtotal-dialog/index.d.ts.map +1 -1
  378. package/dist/esm/components/subtotal-dialog/index.js +10 -1
  379. package/dist/esm/components/table-auto-expansion-smart-tag/index.d.ts +24 -0
  380. package/dist/esm/components/table-auto-expansion-smart-tag/index.d.ts.map +1 -0
  381. package/dist/esm/components/table-auto-expansion-smart-tag/index.js +25 -0
  382. package/dist/esm/components/toolbar/index.d.ts +1 -0
  383. package/dist/esm/components/toolbar/index.d.ts.map +1 -1
  384. package/dist/esm/components/toolbar/index.js +1 -0
  385. package/dist/esm/components/toolbar/insert-menu.d.ts +2 -1
  386. package/dist/esm/components/toolbar/insert-menu.d.ts.map +1 -1
  387. package/dist/esm/components/toolbar/insert-menu.js +24 -1
  388. package/dist/esm/components/toolbar/merge-cells-selector.d.ts +4 -1
  389. package/dist/esm/components/toolbar/merge-cells-selector.d.ts.map +1 -1
  390. package/dist/esm/components/toolbar/merge-cells-selector.js +10 -6
  391. package/dist/esm/components/toolbar/sparkline-actions.d.ts +31 -0
  392. package/dist/esm/components/toolbar/sparkline-actions.d.ts.map +1 -0
  393. package/dist/esm/components/toolbar/sparkline-actions.js +238 -0
  394. package/dist/esm/components/toolbar/table-actions.d.ts +9 -1
  395. package/dist/esm/components/toolbar/table-actions.d.ts.map +1 -1
  396. package/dist/esm/components/toolbar/table-actions.js +15 -7
  397. package/dist/esm/components/toolbar/table-style-selector.d.ts +38 -2
  398. package/dist/esm/components/toolbar/table-style-selector.d.ts.map +1 -1
  399. package/dist/esm/components/toolbar/table-style-selector.js +210 -399
  400. package/dist/esm/config.d.ts +2 -0
  401. package/dist/esm/config.d.ts.map +1 -1
  402. package/dist/esm/config.js +30 -0
  403. package/dist/esm/helpers.d.ts +1 -1
  404. package/dist/esm/helpers.d.ts.map +1 -1
  405. package/dist/esm/helpers.js +12 -1
  406. package/dist/esm/hooks/use-cell-renderer.d.ts +16 -1
  407. package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
  408. package/dist/esm/hooks/use-cell-renderer.js +14 -4
  409. package/dist/esm/hooks/use-chart-clipboard.d.ts +55 -0
  410. package/dist/esm/hooks/use-chart-clipboard.d.ts.map +1 -0
  411. package/dist/esm/hooks/use-chart-clipboard.js +213 -0
  412. package/dist/esm/hooks/use-chart-source-ranges.d.ts +27 -0
  413. package/dist/esm/hooks/use-chart-source-ranges.d.ts.map +1 -0
  414. package/dist/esm/hooks/use-chart-source-ranges.js +186 -0
  415. package/dist/esm/hooks/use-context-setter.d.ts.map +1 -1
  416. package/dist/esm/hooks/use-context-setter.js +3 -1
  417. package/dist/esm/hooks/use-copy-paste-cut.d.ts.map +1 -1
  418. package/dist/esm/hooks/use-copy-paste-cut.js +6 -4
  419. package/dist/esm/hooks/use-editable.d.ts +9 -1
  420. package/dist/esm/hooks/use-editable.d.ts.map +1 -1
  421. package/dist/esm/hooks/use-editable.js +25 -1
  422. package/dist/esm/hooks/use-embeds-charts.d.ts +64 -4
  423. package/dist/esm/hooks/use-embeds-charts.d.ts.map +1 -1
  424. package/dist/esm/hooks/use-embeds-charts.js +394 -39
  425. package/dist/esm/hooks/use-grid-children.d.ts +2 -2
  426. package/dist/esm/hooks/use-grid-children.d.ts.map +1 -1
  427. package/dist/esm/hooks/use-grid-children.js +8 -2
  428. package/dist/esm/hooks/use-header-actions.d.ts.map +1 -1
  429. package/dist/esm/hooks/use-header-actions.js +11 -4
  430. package/dist/esm/hooks/use-isomorphic-layout-effect.d.ts +2 -2
  431. package/dist/esm/hooks/use-isomorphic-layout-effect.d.ts.map +1 -1
  432. package/dist/esm/hooks/use-keyboard-handler.d.ts +2 -1
  433. package/dist/esm/hooks/use-keyboard-handler.d.ts.map +1 -1
  434. package/dist/esm/hooks/use-keyboard-handler.js +8 -2
  435. package/dist/esm/hooks/use-move-columns-rows.d.ts.map +1 -1
  436. package/dist/esm/hooks/use-move-columns-rows.js +12 -6
  437. package/dist/esm/hooks/use-reveal-chart-embed.d.ts +17 -0
  438. package/dist/esm/hooks/use-reveal-chart-embed.d.ts.map +1 -0
  439. package/dist/esm/hooks/use-reveal-chart-embed.js +35 -0
  440. package/dist/esm/hooks/use-selection-move.d.ts.map +1 -1
  441. package/dist/esm/hooks/use-selection-move.js +11 -4
  442. package/dist/esm/hooks/use-selection-renderer.d.ts +13 -1
  443. package/dist/esm/hooks/use-selection-renderer.d.ts.map +1 -1
  444. package/dist/esm/hooks/use-selection-renderer.js +35 -6
  445. package/dist/esm/hooks/use-selection-resize.d.ts.map +1 -1
  446. package/dist/esm/hooks/use-selection-resize.js +11 -5
  447. package/dist/esm/hooks/use-selection.d.ts +9 -1
  448. package/dist/esm/hooks/use-selection.d.ts.map +1 -1
  449. package/dist/esm/hooks/use-selection.js +172 -54
  450. package/dist/esm/hooks/use-structured-reference-selection.d.ts +1 -1
  451. package/dist/esm/hooks/use-structured-reference-selection.d.ts.map +1 -1
  452. package/dist/esm/hooks/use-structured-reference-selection.js +16 -0
  453. package/dist/esm/hooks/use-table-hit-zones.d.ts +61 -0
  454. package/dist/esm/hooks/use-table-hit-zones.d.ts.map +1 -0
  455. package/dist/esm/hooks/use-table-hit-zones.js +146 -0
  456. package/dist/esm/hooks/use-table-resizer.d.ts +7 -0
  457. package/dist/esm/hooks/use-table-resizer.d.ts.map +1 -1
  458. package/dist/esm/hooks/use-table-resizer.js +36 -19
  459. package/dist/esm/hooks/use-touch.d.ts.map +1 -1
  460. package/dist/esm/hooks/use-touch.js +15 -7
  461. package/dist/esm/index.d.ts +13 -0
  462. package/dist/esm/index.d.ts.map +1 -1
  463. package/dist/esm/index.js +13 -0
  464. package/dist/esm/release-date.js +1 -1
  465. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  466. package/dist/esm/types.d.ts +289 -4
  467. package/dist/esm/types.d.ts.map +1 -1
  468. package/dist/esm/utils/copy-as-picture.d.ts +13 -0
  469. package/dist/esm/utils/copy-as-picture.d.ts.map +1 -0
  470. package/dist/esm/utils/copy-as-picture.js +45 -0
  471. package/dist/esm/utils/pivot-chart-field-buttons.d.ts +19 -0
  472. package/dist/esm/utils/pivot-chart-field-buttons.d.ts.map +1 -0
  473. package/dist/esm/utils/pivot-chart-field-buttons.js +18 -0
  474. package/dist/esm/utils/z-order.d.ts +47 -0
  475. package/dist/esm/utils/z-order.d.ts.map +1 -0
  476. package/dist/esm/utils/z-order.js +111 -0
  477. package/dist/spreadsheet.min.css +1 -1
  478. package/package.json +8 -6
  479. package/dist/cjs/components/cell-editor/helpers.spec.d.ts +0 -2
  480. package/dist/cjs/components/cell-editor/helpers.spec.d.ts.map +0 -1
  481. package/dist/cjs/components/cell-editor/helpers.spec.js +0 -32
  482. package/dist/esm/components/cell-editor/helpers.spec.d.ts +0 -2
  483. package/dist/esm/components/cell-editor/helpers.spec.d.ts.map +0 -1
  484. package/dist/esm/components/cell-editor/helpers.spec.js +0 -30
@@ -1,9 +1,36 @@
1
- import { Input, Select, SelectContent, SelectItem, SelectPortal, SelectTrigger, SelectValue, Stack, } from "@rowsncolumns/ui";
1
+ import { Button, Input, Select, SelectContent, SelectItem, SelectPortal, SelectTrigger, SelectValue, Stack, } from "@rowsncolumns/ui";
2
2
  import React, { useState } from "react";
3
3
  import { CONDITION_LABELS, CONDITION_NONE } from "../../config";
4
4
  import { shouldShowFromValue, shouldShowToValue } from "../../helpers";
5
5
  import { useIsomorphicLayoutEffect } from "../../hooks/use-isomorphic-layout-effect";
6
- export const FilterByCondition = ({ conditionType, fromValue, toValue, onChangeToValue, onChangeFromValue, onChangeConditionType, }) => {
6
+ /** Excel's "Top 10…" AutoFilter: the four `NUMBER_TOP_*` / `NUMBER_BOTTOM_*` condition types. */
7
+ export const isTop10ConditionType = (type) => type === "NUMBER_TOP_N" ||
8
+ type === "NUMBER_BOTTOM_N" ||
9
+ type === "NUMBER_TOP_PERCENT" ||
10
+ type === "NUMBER_BOTTOM_PERCENT";
11
+ export const top10ConditionType = (direction, unit) => direction === "top"
12
+ ? unit === "items"
13
+ ? "NUMBER_TOP_N"
14
+ : "NUMBER_TOP_PERCENT"
15
+ : unit === "items"
16
+ ? "NUMBER_BOTTOM_N"
17
+ : "NUMBER_BOTTOM_PERCENT";
18
+ /**
19
+ * Conditions Excel's Custom AutoFilter offers for its second clause: the
20
+ * per-cell comparisons. Column-ranked filters (Top 10, above / below
21
+ * average) are whole-column criteria and can't be And/Or-ed with another.
22
+ */
23
+ const SECOND_CLAUSE_LABELS = CONDITION_LABELS.filter(({ condition }) => !isTop10ConditionType(condition) &&
24
+ condition !== "NUMBER_ABOVE_AVERAGE" &&
25
+ condition !== "NUMBER_BELOW_AVERAGE");
26
+ const ConditionSelect = ({ value, labels, onChange, ariaLabel, }) => (React.createElement(Select, { value: value ?? CONDITION_NONE, onValueChange: (next) => onChange(next === CONDITION_NONE ? undefined : next) },
27
+ React.createElement(SelectTrigger, { className: "mb-1", "aria-label": ariaLabel },
28
+ React.createElement(SelectValue, { placeholder: "None" })),
29
+ React.createElement(SelectPortal, null,
30
+ React.createElement(SelectContent, null,
31
+ React.createElement(SelectItem, { value: CONDITION_NONE }, "None"),
32
+ labels.map(({ condition, label }) => (React.createElement(SelectItem, { key: condition, value: condition }, label)))))));
33
+ const ValueInputs = ({ conditionType, fromValue, toValue, onChangeFromValue, onChangeToValue, namePrefix, }) => {
7
34
  const [showToValue, setShowToValue] = useState(() => shouldShowToValue(conditionType));
8
35
  const [showFromValue, setShowFromValue] = useState(() => shouldShowFromValue(conditionType));
9
36
  useIsomorphicLayoutEffect(() => {
@@ -15,20 +42,49 @@ export const FilterByCondition = ({ conditionType, fromValue, toValue, onChangeT
15
42
  onChangeToValue("");
16
43
  }
17
44
  }, [conditionType, onChangeToValue, onChangeFromValue]);
18
- return (React.createElement(React.Fragment, null,
19
- React.createElement("label", { className: "text-sm font-semibold pb-1 block" }, "Filter by condition"),
20
- React.createElement(Select, { value: conditionType ?? CONDITION_NONE, onValueChange: (value) => onChangeConditionType?.(value === CONDITION_NONE
21
- ? undefined
22
- : value) },
23
- React.createElement(SelectTrigger, { className: "mb-1" },
24
- React.createElement(SelectValue, { placeholder: "None" })),
45
+ return (React.createElement(Stack, { direction: "vertical", className: "gap-1" },
46
+ showFromValue ? (React.createElement(Input, { value: fromValue, type: "text", name: `${namePrefix}fromValue`, onChange: (e) => onChangeFromValue?.(e.target.value), className: "text-xs", placeholder: "Enter value" })) : null,
47
+ showToValue ? (React.createElement(Input, { value: toValue, type: "text", name: `${namePrefix}toValue`, onChange: (e) => onChangeToValue?.(e.target.value), className: "text-xs", placeholder: "" })) : null));
48
+ };
49
+ /** Excel's Top 10 AutoFilter dialog: [Top | Bottom] [N] [Items | Percent]. */
50
+ const Top10Fields = ({ conditionType, count, onChangeConditionType, onChangeCount, }) => {
51
+ const direction = conditionType === "NUMBER_TOP_N" || conditionType === "NUMBER_TOP_PERCENT"
52
+ ? "top"
53
+ : "bottom";
54
+ const unit = conditionType === "NUMBER_TOP_PERCENT" ||
55
+ conditionType === "NUMBER_BOTTOM_PERCENT"
56
+ ? "percent"
57
+ : "items";
58
+ return (React.createElement(Stack, { className: "gap-1 items-center" },
59
+ React.createElement(Select, { value: direction, onValueChange: (next) => onChangeConditionType(top10ConditionType(next === "bottom" ? "bottom" : "top", unit)) },
60
+ React.createElement(SelectTrigger, { className: "w-24", "aria-label": "Top or bottom" },
61
+ React.createElement(SelectValue, null)),
62
+ React.createElement(SelectPortal, null,
63
+ React.createElement(SelectContent, null,
64
+ React.createElement(SelectItem, { value: "top" }, "Top"),
65
+ React.createElement(SelectItem, { value: "bottom" }, "Bottom")))),
66
+ React.createElement(Input, { value: count, type: "number", min: 1, name: "top10Count", "aria-label": "Top 10 count", onChange: (e) => onChangeCount(e.target.value), className: "text-xs w-16" }),
67
+ React.createElement(Select, { value: unit, onValueChange: (next) => onChangeConditionType(top10ConditionType(direction, next === "percent" ? "percent" : "items")) },
68
+ React.createElement(SelectTrigger, { className: "w-24", "aria-label": "Items or percent" },
69
+ React.createElement(SelectValue, null)),
25
70
  React.createElement(SelectPortal, null,
26
71
  React.createElement(SelectContent, null,
27
- React.createElement(SelectItem, { value: CONDITION_NONE }, "None"),
28
- CONDITION_LABELS.map(({ condition, label }) => {
29
- return (React.createElement(SelectItem, { key: condition, value: condition }, label));
30
- })))),
31
- React.createElement(Stack, { direction: "vertical", className: "gap-1" },
32
- showFromValue ? (React.createElement(Input, { value: fromValue, type: "text", name: "fromValue", onChange: (e) => onChangeFromValue?.(e.target.value), className: "text-xs", placeholder: "Enter value" })) : null,
33
- showToValue ? (React.createElement(Input, { value: toValue, type: "text", name: "toValue", onChange: (e) => onChangeToValue?.(e.target.value), className: "text-xs", placeholder: "" })) : null)));
72
+ React.createElement(SelectItem, { value: "items" }, "Items"),
73
+ React.createElement(SelectItem, { value: "percent" }, "Percent"))))));
74
+ };
75
+ export const FilterByCondition = ({ conditionType, fromValue, toValue, onChangeToValue, onChangeFromValue, onChangeConditionType, condition2Type, condition2From, condition2To, conditionJoin, onChangeCondition2Type, onChangeCondition2From, onChangeCondition2To, onChangeConditionJoin, }) => {
76
+ // Excel's Custom AutoFilter shows the second clause row only on request;
77
+ // it stays open while a second clause is stored on the column.
78
+ const [showSecondClause, setShowSecondClause] = useState(() => condition2Type !== undefined);
79
+ const isTop10 = isTop10ConditionType(conditionType);
80
+ return (React.createElement(React.Fragment, null,
81
+ React.createElement("label", { className: "text-sm font-semibold pb-1 block" }, "Filter by condition"),
82
+ React.createElement(ConditionSelect, { value: conditionType, labels: CONDITION_LABELS, onChange: (type) => onChangeConditionType?.(type), ariaLabel: "Condition" }),
83
+ isTop10 && conditionType ? (React.createElement(Top10Fields, { conditionType: conditionType, count: fromValue, onChangeConditionType: (type) => onChangeConditionType?.(type), onChangeCount: onChangeFromValue })) : (React.createElement(ValueInputs, { conditionType: conditionType, fromValue: fromValue, toValue: toValue, onChangeFromValue: onChangeFromValue, onChangeToValue: onChangeToValue, namePrefix: "" })),
84
+ conditionType && !isTop10 ? (showSecondClause ? (React.createElement("div", { className: "mt-1 flex flex-col gap-1" },
85
+ React.createElement("div", { role: "radiogroup", "aria-label": "Combine conditions", className: "flex gap-3 text-xs px-1" }, ["AND", "OR"].map((join) => (React.createElement("label", { key: join, className: "flex items-center gap-1 cursor-pointer" },
86
+ React.createElement("input", { type: "radio", name: "conditionJoin", value: join, checked: conditionJoin === join, onChange: () => onChangeConditionJoin(join) }),
87
+ join === "AND" ? "And" : "Or")))),
88
+ React.createElement(ConditionSelect, { value: condition2Type, labels: SECOND_CLAUSE_LABELS, onChange: onChangeCondition2Type, ariaLabel: "Second condition" }),
89
+ React.createElement(ValueInputs, { conditionType: condition2Type, fromValue: condition2From, toValue: condition2To, onChangeFromValue: onChangeCondition2From, onChangeToValue: onChangeCondition2To, namePrefix: "second" }))) : (React.createElement(Button, { type: "button", variant: "link", className: "text-xs px-1 mt-1 self-start", onClick: () => setShowSecondClause(true) }, "Custom filter (And / Or)\u2026"))) : null));
34
90
  };
@@ -1 +1 @@
1
- {"version":3,"file":"filter-by-value.d.ts","sourceRoot":"","sources":["../../../../components/filter-box/filter-by-value.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAOvC,KAAK,kBAAkB,GAAG;IACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,qBAAqB,EAAE,KAAK,CAAC,QAAQ,CACnC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI,CAAC,CAClD,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,mDAI3B,kBAAkB,sBA8GpB,CAAC"}
1
+ {"version":3,"file":"filter-by-value.d.ts","sourceRoot":"","sources":["../../../../components/filter-box/filter-by-value.tsx"],"names":[],"mappings":"AASA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAKtE,KAAK,kBAAkB,GAAG;IACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,qBAAqB,EAAE,KAAK,CAAC,QAAQ,CACnC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,SAAS,GAAG,IAAI,CAAC,CAClD,CAAC;CACH,CAAC;AAcF,eAAO,MAAM,aAAa,GAAI,mDAI3B,kBAAkB,sBA+PpB,CAAC"}
@@ -1,67 +1,138 @@
1
- import { CheckIcon } from "@rowsncolumns/icons";
2
- import { Input } from "@rowsncolumns/ui";
3
- import { Button, Stack } from "@rowsncolumns/ui";
1
+ import { CheckIcon, ChevronDownIcon, ChevronRightIcon, DividerHorizontalIcon, } from "@rowsncolumns/icons";
2
+ import { Button, Input } from "@rowsncolumns/ui";
4
3
  import { escapeCharacters } from "@rowsncolumns/utils";
5
4
  import { useVirtualizer } from "@tanstack/react-virtual";
6
- import React, { useMemo } from "react";
7
- import { useCallback } from "react";
8
- import { useRef } from "react";
9
- import { useState } from "react";
10
- import { DEFAULT_ARRAY } from "../../config";
5
+ import React, { useCallback, useMemo, useRef, useState } from "react";
6
+ import { BLANK_LABEL, DEFAULT_ARRAY } from "../../config";
7
+ import { buildDateTree, triState } from "./date-tree";
8
+ /** Excel's checklist glyph: checked, unchecked, or the "some children" dash. */
9
+ const TriStateMark = ({ state }) => (React.createElement("span", { className: "min-w-[15px] h-[15px] block leading-none border border-gray-400 rounded-sm text-center shrink-0", "aria-hidden": true }, state === true ? React.createElement(CheckIcon, null) : state === "mixed" ? React.createElement(DividerHorizontalIcon, null) : null));
10
+ const rowClassName = "justify-start px-2 py-0 gap-1 text-sm text-left w-full h-6";
11
11
  export const FilterByValue = ({ visibleValues, values = DEFAULT_ARRAY, onChangeVisibleValues, }) => {
12
12
  const [query, setQuery] = useState("");
13
+ // Excel's "Add current selection to filter": while searching, checking the
14
+ // results ADDS them to the values already shown instead of replacing them.
15
+ const [addToSelection, setAddToSelection] = useState(false);
16
+ const [expanded, setExpanded] = useState(() => new Set());
13
17
  const parentRef = useRef(null);
14
18
  const filteredValues = useMemo(() => {
15
19
  const regex = new RegExp(escapeCharacters(query), "i");
16
- return values.filter((value) => {
17
- return regex.test(String(value));
18
- });
20
+ return values.filter((value) => regex.test(String(value)));
19
21
  }, [values, query]);
22
+ // A date column's checklist is a Year → Month → Day tree; a search flattens
23
+ // it to the matching values, as Excel does.
24
+ const dateTree = useMemo(() => (query ? undefined : buildDateTree(values, BLANK_LABEL)), [values, query]);
25
+ const hasBlank = values.includes(BLANK_LABEL);
26
+ const visibleSet = useMemo(() => (visibleValues ? new Set(visibleValues) : undefined), [visibleValues]);
27
+ const isVisible = useCallback((value) => !visibleSet || visibleSet.has(value), [visibleSet]);
28
+ // `undefined` visible values = everything shown; collapse back to it once
29
+ // every value is checked so a full checklist never becomes a whitelist.
30
+ const normalize = useCallback((next) => values.every((value) => next.has(value)) ? undefined : [...next], [values]);
31
+ const setChecked = useCallback((targets, checked) => {
32
+ onChangeVisibleValues((prev) => {
33
+ const next = new Set(prev ?? values);
34
+ for (const value of targets) {
35
+ if (checked)
36
+ next.add(value);
37
+ else
38
+ next.delete(value);
39
+ }
40
+ return normalize(next);
41
+ });
42
+ }, [onChangeVisibleValues, values, normalize]);
43
+ const selectAllState = triState(filteredValues, isVisible);
44
+ const onToggleSelectAll = useCallback(() => {
45
+ if (selectAllState === true) {
46
+ setChecked(filteredValues, false);
47
+ return;
48
+ }
49
+ if (query && !addToSelection) {
50
+ // Checking the search results shows ONLY them (Excel replaces the
51
+ // selection unless "Add current selection to filter" is on).
52
+ onChangeVisibleValues(normalize(new Set(filteredValues)));
53
+ return;
54
+ }
55
+ setChecked(filteredValues, true);
56
+ }, [
57
+ selectAllState,
58
+ setChecked,
59
+ filteredValues,
60
+ query,
61
+ addToSelection,
62
+ onChangeVisibleValues,
63
+ normalize,
64
+ ]);
20
65
  const rowVirtualizer = useVirtualizer({
21
66
  count: filteredValues.length,
22
67
  getScrollElement: () => parentRef.current,
23
68
  estimateSize: useCallback(() => 24, []),
24
69
  overscan: 5,
25
70
  });
26
- const onCheck = (value) => {
27
- onChangeVisibleValues((prev = []) => {
28
- const newVisibleValues = prev?.concat(value);
29
- if (newVisibleValues?.length === values.length) {
30
- return undefined;
31
- }
32
- return newVisibleValues;
33
- });
34
- };
35
- const onUnCheck = (value) => {
36
- onChangeVisibleValues((prev = values) => prev?.filter((cur) => cur !== value));
71
+ const toggleExpanded = (key) => setExpanded((prev) => {
72
+ const next = new Set(prev);
73
+ if (next.has(key))
74
+ next.delete(key);
75
+ else
76
+ next.add(key);
77
+ return next;
78
+ });
79
+ const renderTreeNode = (node, depth) => {
80
+ const state = triState(node.values, isVisible);
81
+ const isExpanded = expanded.has(node.key);
82
+ return (React.createElement(React.Fragment, { key: node.key },
83
+ React.createElement("div", { className: "flex items-center", style: { paddingLeft: depth * 14 } },
84
+ node.children ? (React.createElement("button", { type: "button", "aria-expanded": isExpanded, "aria-label": `${isExpanded ? "Collapse" : "Expand"} ${node.label}`, className: "w-4 h-4 flex items-center justify-center shrink-0", onClick: (e) => {
85
+ e.stopPropagation();
86
+ toggleExpanded(node.key);
87
+ } }, isExpanded ? React.createElement(ChevronDownIcon, null) : React.createElement(ChevronRightIcon, null))) : (React.createElement("span", { className: "w-4 shrink-0" })),
88
+ React.createElement(Button, { type: "button", role: "checkbox", "aria-checked": state, onMouseDown: (e) => e.stopPropagation(), onClick: (e) => {
89
+ e.preventDefault();
90
+ e.stopPropagation();
91
+ setChecked(node.values, state !== true);
92
+ }, className: rowClassName, title: node.label },
93
+ React.createElement(TriStateMark, { state: state }),
94
+ React.createElement("span", { className: "whitespace-nowrap overflow-hidden text-ellipsis" }, node.label))),
95
+ isExpanded
96
+ ? node.children?.map((child) => renderTreeNode(child, depth + 1))
97
+ : null));
37
98
  };
38
99
  return (React.createElement(React.Fragment, null,
39
100
  React.createElement("label", { className: "text-sm font-semibold pb-1 block" }, "Filter by value"),
40
- React.createElement(Stack, { className: "pb-2 gap-2" },
41
- React.createElement(Button, { variant: "link", onClick: () => onChangeVisibleValues(undefined) }, "Select all"),
42
- React.createElement(Button, { variant: "link", onClick: () => onChangeVisibleValues([]) }, "Clear")),
43
- React.createElement(Input, { type: "text", value: query, onChange: (e) => setQuery(e.target.value), className: "text-xs" }),
44
- React.createElement("div", { className: "overflow-auto mt-1", style: { maxHeight: 160 }, ref: parentRef },
101
+ React.createElement(Input, { type: "text", value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search", "aria-label": "Search values", className: "text-xs" }),
102
+ React.createElement(Button, { type: "button", role: "checkbox", "aria-checked": selectAllState, onMouseDown: (e) => e.stopPropagation(), onClick: (e) => {
103
+ e.preventDefault();
104
+ e.stopPropagation();
105
+ onToggleSelectAll();
106
+ }, className: `${rowClassName} mt-1 font-medium` },
107
+ React.createElement(TriStateMark, { state: selectAllState }),
108
+ React.createElement("span", null, query ? "(Select All Search Results)" : "(Select All)")),
109
+ query ? (React.createElement("label", { className: "flex items-center gap-2 text-xs px-2 py-0.5 select-none cursor-pointer" },
110
+ React.createElement("input", { type: "checkbox", checked: addToSelection, onChange: (e) => setAddToSelection(e.target.checked) }),
111
+ "Add current selection to filter")) : null,
112
+ dateTree ? (React.createElement("div", { className: "overflow-auto mt-1 flex flex-col", style: { maxHeight: 160 } },
113
+ dateTree.map((node) => renderTreeNode(node, 0)),
114
+ hasBlank ? (React.createElement("div", { className: "flex items-center" },
115
+ React.createElement("span", { className: "w-4 shrink-0" }),
116
+ React.createElement(Button, { type: "button", role: "checkbox", "aria-checked": isVisible(BLANK_LABEL), onMouseDown: (e) => e.stopPropagation(), onClick: (e) => {
117
+ e.preventDefault();
118
+ e.stopPropagation();
119
+ setChecked([BLANK_LABEL], !isVisible(BLANK_LABEL));
120
+ }, className: rowClassName, title: BLANK_LABEL },
121
+ React.createElement(TriStateMark, { state: isVisible(BLANK_LABEL) }),
122
+ React.createElement("span", null, BLANK_LABEL)))) : null)) : (React.createElement("div", { className: "overflow-auto mt-1", style: { maxHeight: 160 }, ref: parentRef },
45
123
  React.createElement("div", { style: {
46
124
  height: `${rowVirtualizer.getTotalSize()}px`,
47
125
  width: "100%",
48
126
  position: "relative",
49
127
  } }, rowVirtualizer.getVirtualItems().map((virtualItem) => {
50
128
  const value = filteredValues[virtualItem.index];
51
- const isVisible = visibleValues
52
- ? visibleValues.indexOf(value) !== -1
53
- : true;
54
- return (React.createElement(Button, { key: virtualItem.key, type: "button", onMouseDown: (e) => {
129
+ const checked = isVisible(value);
130
+ return (React.createElement(Button, { key: virtualItem.key, type: "button", role: "checkbox", "aria-checked": checked, onMouseDown: (e) => {
55
131
  e.stopPropagation();
56
132
  }, onClick: (e) => {
57
133
  e.preventDefault();
58
134
  e.stopPropagation();
59
- if (isVisible) {
60
- onUnCheck(value);
61
- }
62
- else {
63
- onCheck(value);
64
- }
135
+ setChecked([value], !checked);
65
136
  }, className: "justify-start px-2 py-0 gap-1 text-sm text-left", title: value, style: {
66
137
  position: "absolute",
67
138
  top: 0,
@@ -70,7 +141,7 @@ export const FilterByValue = ({ visibleValues, values = DEFAULT_ARRAY, onChangeV
70
141
  height: `${virtualItem.size}px`,
71
142
  transform: `translateY(${virtualItem.start}px)`,
72
143
  } },
73
- React.createElement("span", { className: "min-w-[15px] block leading-none" }, isVisible ? React.createElement(CheckIcon, null) : null),
144
+ React.createElement(TriStateMark, { state: checked }),
74
145
  React.createElement("div", { className: "whitespace-nowrap overflow-hidden text-ellipsis" }, String(value))));
75
- })))));
146
+ }))))));
76
147
  };
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import type { UseFilterProps } from "../../hooks/use-filter";
3
- import type { FilterView, TableView } from "../../types";
3
+ import type { FilterCriteria, FilterView, TableView } from "../../types";
4
4
  import type { AvailableIcon } from "./filter-by-color";
5
5
  export type { AvailableIcon } from "./filter-by-color";
6
6
  export type FilterBoxBaseProps = {
@@ -32,6 +32,12 @@ export type FilterBoxBaseProps = {
32
32
  customLists?: string[][];
33
33
  };
34
34
  export declare const isTableView: (filter: FilterView | TableView) => filter is TableView;
35
+ /**
36
+ * Whether a column's stored criteria still filter anything — what enables
37
+ * Excel's "Clear Filter From <column>" item. Same test as the state layer's
38
+ * `isFilterCriteriaActive`.
39
+ */
40
+ export declare const hasActiveFilterCriteria: (criteria: FilterCriteria | undefined) => boolean;
35
41
  export declare const FilterBoxWrapper: React.MemoExoticComponent<({ dimensionIndex, onOpenChange, onSort, onFilter, onDeleteTableColumn, onInsertTableColumn, sheetId, filter, values, availableCellColors, availableFontColors, availableIcons, customLists, }: FilterBoxProps) => React.JSX.Element>;
36
42
  export type FilterBoxProps = FilterBoxBaseProps & {
37
43
  sheetId: number;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/filter-box/index.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAI3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAIV,UAAU,EAGV,SAAS,EACV,MAAM,aAAa,CAAC;AAIrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAKvD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,MAAM,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;IACtC,QAAQ,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;IAC1C,mBAAmB,EAAE,cAAc,CAAC,qBAAqB,CAAC,CAAC;IAC3D,mBAAmB,EAAE,cAAc,CAAC,qBAAqB,CAAC,CAAC;IAC3D,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,sEAAsE;IACtE,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;CAC1B,CAAC;AAGF,eAAO,MAAM,WAAW,GACtB,QAAQ,UAAU,GAAG,SAAS,KAC7B,MAAM,IAAI,SAEZ,CAAC;AA0BF,eAAO,MAAM,gBAAgB,4NAexB,cAAc,uBAkalB,CAAC;AAIF,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,SAAS;YAAW,cAAc;;CAuC9C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/filter-box/index.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAI3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAMV,cAAc,EACd,UAAU,EAGV,SAAS,EACV,MAAM,aAAa,CAAC;AAKrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAKvD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,MAAM,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;IACtC,QAAQ,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;IAC1C,mBAAmB,EAAE,cAAc,CAAC,qBAAqB,CAAC,CAAC;IAC3D,mBAAmB,EAAE,cAAc,CAAC,qBAAqB,CAAC,CAAC;IAC3D,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,sEAAsE;IACtE,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;CAC1B,CAAC;AAGF,eAAO,MAAM,WAAW,GACtB,QAAQ,UAAU,GAAG,SAAS,KAC7B,MAAM,IAAI,SAEZ,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAClC,UAAU,cAAc,GAAG,SAAS,KACnC,OAQA,CAAC;AA0BJ,eAAO,MAAM,gBAAgB,4NAexB,cAAc,uBA4kBlB,CAAC;AAIF,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,SAAS;YAAW,cAAc;;CAuC9C,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { Direction } from "@rowsncolumns/grid";
2
- import { ArrowLeftIcon, ArrowRightIcon, SortDownIcon, SortUpIcon, TrashIcon, } from "@rowsncolumns/icons";
2
+ import { ArrowLeftIcon, ArrowRightIcon, ChevronDownIcon, ChevronRightIcon, Cross2Icon, SortDownIcon, SortUpIcon, TrashIcon, } from "@rowsncolumns/icons";
3
3
  import { Button, cn, DropdownLeftSlot, DropdownMenuSeparator, Popover, PopoverContent, PopoverMenuItem, PopoverPortal, PopoverTrigger, Separator, } from "@rowsncolumns/ui";
4
4
  import { isNil, number2Alpha } from "@rowsncolumns/utils";
5
5
  import React, { useEffect, useRef, useState } from "react";
@@ -14,6 +14,17 @@ import { FilterByValue } from "./filter-by-value";
14
14
  export const isTableView = (filter) => {
15
15
  return "columns" in filter;
16
16
  };
17
+ /**
18
+ * Whether a column's stored criteria still filter anything — what enables
19
+ * Excel's "Clear Filter From <column>" item. Same test as the state layer's
20
+ * `isFilterCriteriaActive`.
21
+ */
22
+ export const hasActiveFilterCriteria = (criteria) => Boolean(criteria &&
23
+ (criteria.condition?.type ||
24
+ criteria.condition2?.type ||
25
+ criteria.visibleValues?.length ||
26
+ criteria.colorFilter ||
27
+ criteria.iconFilter));
17
28
  // Excel-style "Auto apply": changes in the filter box apply live without
18
29
  // pressing Apply. On by default like Excel; unchecking it survives across
19
30
  // filter boxes and sessions, matching Excel's sticky checkbox.
@@ -58,6 +69,13 @@ export const FilterBoxWrapper = memo(({ dimensionIndex, onOpenChange, onSort, on
58
69
  // existing criterion from the spec".
59
70
  const [colorFilter, onChangeColorFilter] = useState(undefined);
60
71
  const [iconFilter, onChangeIconFilter] = useState(undefined);
72
+ // Excel's Custom AutoFilter second clause + And / Or join.
73
+ const [condition2Type, onChangeCondition2Type] = useState(filterCriteria?.condition2?.type ?? undefined);
74
+ const [condition2From, onChangeCondition2From] = useState(filterCriteria?.condition2?.values?.[0]?.userEnteredValue ?? "");
75
+ const [condition2To, onChangeCondition2To] = useState(filterCriteria?.condition2?.values?.[1]?.userEnteredValue ?? "");
76
+ const [conditionJoin, onChangeConditionJoin] = useState(filterCriteria?.conditionJoin ?? "AND");
77
+ // "Sort by Color" is a collapsed sub-menu of the dropdown, like Excel's.
78
+ const [showSortByColor, setShowSortByColor] = useState(false);
61
79
  // Auto apply (Excel parity). `pendingAutoApplyTick` counts user edits made
62
80
  // while auto apply is on; the debounced effect below applies the newest
63
81
  // state once per burst.
@@ -161,9 +179,22 @@ export const FilterBoxWrapper = memo(({ dimensionIndex, onOpenChange, onSort, on
161
179
  }
162
180
  return undefined;
163
181
  })();
182
+ const condition2Values = [];
183
+ if (condition2From) {
184
+ condition2Values.push({ userEnteredValue: condition2From });
185
+ }
186
+ if (condition2To) {
187
+ condition2Values.push({ userEnteredValue: condition2To });
188
+ }
189
+ // A second clause without a first is applied as the only clause.
190
+ const condition2 = condition2Type
191
+ ? { type: condition2Type, values: condition2Values }
192
+ : null;
164
193
  onFilter?.(sheetId, filter, dimensionIndex, conditionType, conditionValues, normalizedVisibleValues, {
165
194
  colorFilter,
166
195
  iconFilter,
196
+ condition2,
197
+ conditionJoin: condition2 ? conditionJoin : null,
167
198
  });
168
199
  }, [
169
200
  sheetId,
@@ -173,11 +204,40 @@ export const FilterBoxWrapper = memo(({ dimensionIndex, onOpenChange, onSort, on
173
204
  fromValue,
174
205
  toValue,
175
206
  conditionType,
207
+ condition2Type,
208
+ condition2From,
209
+ condition2To,
210
+ conditionJoin,
176
211
  visibleValues,
177
212
  values,
178
213
  colorFilter,
179
214
  iconFilter,
180
215
  ]);
216
+ // Excel's "Clear Filter From <column>": drop every criterion on this
217
+ // column only — the filter (and the other columns' criteria) stay.
218
+ const columnLabel = isTable
219
+ ? filter.columns?.[dimensionIndex]?.name
220
+ : undefined;
221
+ const clearLabel = `Clear Filter From "${columnLabel ??
222
+ `Column ${number2Alpha(filter.range.startColumnIndex + dimensionIndex)}`}"`;
223
+ const canClearColumn = hasActiveFilterCriteria(filterCriteria);
224
+ const onClearColumnFilter = useCallback(() => {
225
+ onFilter?.(sheetId, filter, dimensionIndex, undefined, undefined, undefined, {
226
+ colorFilter: null,
227
+ iconFilter: null,
228
+ condition2: null,
229
+ });
230
+ onClose();
231
+ }, [onFilter, sheetId, filter, dimensionIndex, onClose]);
232
+ // Excel's "Sort by Color": surface the picked fill / font colour or CF icon
233
+ // to the top of the column (one level, ascending).
234
+ const onSortByColor = useCallback((options) => {
235
+ onSort?.(sheetId, filter, dimensionIndex, "ASCENDING", options);
236
+ onClose();
237
+ }, [onSort, sheetId, filter, dimensionIndex, onClose]);
238
+ const hasSortColors = Boolean(availableCellColors?.length ||
239
+ availableFontColors?.length ||
240
+ availableIcons?.length);
181
241
  // Debounced auto-apply. `appliedTickRef` keeps applyFilter identity
182
242
  // changes that carry no user edit (e.g. the async values re-sync above)
183
243
  // from re-applying an already-flushed tick.
@@ -231,6 +291,10 @@ export const FilterBoxWrapper = memo(({ dimensionIndex, onOpenChange, onSort, on
231
291
  const onUserChangeColorFilter = useMemo(() => wrapWithAutoApply(onChangeColorFilter), [wrapWithAutoApply]);
232
292
  const onUserChangeIconFilter = useMemo(() => wrapWithAutoApply(onChangeIconFilter), [wrapWithAutoApply]);
233
293
  const onUserChangeVisibleValues = useMemo(() => wrapWithAutoApply(onChangeVisibleValues), [wrapWithAutoApply]);
294
+ const onUserChangeCondition2Type = useMemo(() => wrapWithAutoApply(onChangeCondition2Type), [wrapWithAutoApply]);
295
+ const onUserChangeCondition2From = useMemo(() => wrapWithAutoApply(onChangeCondition2From), [wrapWithAutoApply]);
296
+ const onUserChangeCondition2To = useMemo(() => wrapWithAutoApply(onChangeCondition2To), [wrapWithAutoApply]);
297
+ const onUserChangeConditionJoin = useMemo(() => wrapWithAutoApply(onChangeConditionJoin), [wrapWithAutoApply]);
234
298
  // Apply
235
299
  const onSubmit = useCallback((event) => {
236
300
  event.preventDefault();
@@ -290,8 +354,30 @@ export const FilterBoxWrapper = memo(({ dimensionIndex, onOpenChange, onSort, on
290
354
  React.createElement(DropdownLeftSlot, { className: "text-base leading-4" },
291
355
  React.createElement(SortDownIcon, null)),
292
356
  "Custom sort\u2026"),
357
+ React.createElement(PopoverMenuItem, { type: "button", disabled: !hasSortColors, "aria-expanded": showSortByColor, onClick: () => setShowSortByColor((open) => !open) },
358
+ React.createElement(DropdownLeftSlot, { className: "text-base leading-4" }, showSortByColor ? React.createElement(ChevronDownIcon, null) : React.createElement(ChevronRightIcon, null)),
359
+ "Sort by Color"),
360
+ showSortByColor && hasSortColors ? (React.createElement("div", { className: "flex flex-col pl-6 pb-1", role: "group", "aria-label": "Sort by Color" },
361
+ availableCellColors?.map((color) => (React.createElement(Button, { key: `cell-${color}`, type: "button", "aria-label": `Sort by cell color ${color}`, title: `Sort by cell color ${color}`, onClick: () => onSortByColor({ sortBy: "cellColor", sortColor: color }), className: "justify-start px-2 py-0 gap-2 text-sm text-left w-full h-6" },
362
+ React.createElement("span", { className: "inline-block h-4 w-4 rounded border border-gray-300 shrink-0", style: { backgroundColor: color } }),
363
+ "Cell color ",
364
+ color))),
365
+ availableFontColors?.map((color) => (React.createElement(Button, { key: `font-${color}`, type: "button", "aria-label": `Sort by font color ${color}`, title: `Sort by font color ${color}`, onClick: () => onSortByColor({ sortBy: "fontColor", sortColor: color }), className: "justify-start px-2 py-0 gap-2 text-sm text-left w-full h-6" },
366
+ React.createElement("span", { className: "inline-block h-4 w-4 rounded border border-gray-300 shrink-0", style: { backgroundColor: color } }),
367
+ "Font color ",
368
+ color))),
369
+ availableIcons?.map((icon) => (React.createElement(Button, { key: `icon-${icon.iconSet}-${icon.iconId}`, type: "button", "aria-label": `Sort by ${icon.iconSet} icon ${icon.iconId}`, title: `Sort by ${icon.iconSet} icon ${icon.iconId}`, onClick: () => onSortByColor({
370
+ sortBy: "icon",
371
+ sortIcon: { iconSet: icon.iconSet, iconId: icon.iconId },
372
+ }), className: "justify-start px-2 py-0 gap-2 text-sm text-left w-full h-6" },
373
+ React.createElement("span", { className: "inline-block h-4 w-4 leading-none text-center text-sm shrink-0", style: icon.color ? { color: icon.color } : undefined }, icon.glyph),
374
+ "Icon"))))) : null,
375
+ React.createElement(PopoverMenuItem, { type: "button", disabled: !canClearColumn, onClick: onClearColumnFilter },
376
+ React.createElement(DropdownLeftSlot, { className: "text-base leading-4" },
377
+ React.createElement(Cross2Icon, null)),
378
+ clearLabel),
293
379
  React.createElement("div", { className: "py-2 px-2" },
294
- React.createElement(FilterByCondition, { conditionType: conditionType, fromValue: fromValue, toValue: toValue, onChangeConditionType: onUserChangeConditionType, onChangeFromValue: onUserChangeFromValue, onChangeToValue: onUserChangeToValue }),
380
+ React.createElement(FilterByCondition, { conditionType: conditionType, fromValue: fromValue, toValue: toValue, onChangeConditionType: onUserChangeConditionType, onChangeFromValue: onUserChangeFromValue, onChangeToValue: onUserChangeToValue, condition2Type: condition2Type, condition2From: condition2From, condition2To: condition2To, conditionJoin: conditionJoin, onChangeCondition2Type: onUserChangeCondition2Type, onChangeCondition2From: onUserChangeCondition2From, onChangeCondition2To: onUserChangeCondition2To, onChangeConditionJoin: onUserChangeConditionJoin }),
295
381
  React.createElement(Separator, { className: "mt-2 mb-2" }),
296
382
  React.createElement(FilterByColor, { colorFilter: colorFilter === undefined
297
383
  ? filterCriteria?.colorFilter
@@ -0,0 +1,34 @@
1
+ import React from "react";
2
+ import type { EmbeddedChart, MoveChartTarget, Sheet } from "../../types";
3
+ export type MoveChartDialogProps = {
4
+ /** Controls visibility. */
5
+ open: boolean;
6
+ onOpenChange(open: boolean): void;
7
+ /** The chart being moved; its `position.sheetId` is the source sheet. */
8
+ chart: EmbeddedChart;
9
+ /** Every sheet of the workbook (chartsheets are not offered as "Object in" targets). */
10
+ sheets: Sheet[];
11
+ onSubmit(target: MoveChartTarget): void;
12
+ };
13
+ /**
14
+ * Excel's "Move Chart…" dialog: "New sheet: [Chart1]" creates a chartsheet
15
+ * (a tab that is the chart, no cells) or "Object in: [Sheet]" moves the chart
16
+ * onto another worksheet. UI-only — the host turns the target into the move.
17
+ */
18
+ export declare const MoveChartDialog: React.MemoExoticComponent<({ open, onOpenChange, chart, sheets, onSubmit }: MoveChartDialogProps) => React.JSX.Element>;
19
+ export type MoveChartDialogHostProps = {
20
+ sheets: Sheet[];
21
+ /** `useCharts().onMoveChartToSheet` / the engine hook's `onMoveChartToSheet`. */
22
+ onMoveChartToSheet(chart: EmbeddedChart, target: MoveChartTarget): unknown;
23
+ };
24
+ /**
25
+ * Host-mounted, atom-driven wrapper around {@link MoveChartDialog}. Mount it
26
+ * once alongside the other editor dialogs; the chart context menu and the
27
+ * chart editor open it. Remounted per request so each opening starts from the
28
+ * chart's current sheet.
29
+ */
30
+ export declare const MoveChartDialogHost: {
31
+ ({ sheets, onMoveChartToSheet, }: MoveChartDialogHostProps): React.JSX.Element | null;
32
+ displayName: string;
33
+ };
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/move-chart-dialog/index.tsx"],"names":[],"mappings":"AASA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAO3D,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG;IACjC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,yEAAyE;IACzE,KAAK,EAAE,aAAa,CAAC;IACrB,wFAAwF;IACxF,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;CACzC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,8EACwB,oBAAoB,uBAgIvE,CAAC;AAIF,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,iFAAiF;IACjF,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC;CAC5E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;sCAG7B,wBAAwB;;CAiB1B,CAAC"}
@@ -0,0 +1,88 @@
1
+ import { Button, Dialog, DialogBody, DialogCloseButton, DialogContent, DialogTitle, Separator, } from "@rowsncolumns/ui";
2
+ import React, { memo, useCallback, useState } from "react";
3
+ import { getNextChartSheetTitle } from "../../api/chart-sheet";
4
+ import { useMoveChartDialogState, useRegisterMoveChartDialogHost, } from "../../atoms/move-chart-dialog.atom";
5
+ /**
6
+ * Excel's "Move Chart…" dialog: "New sheet: [Chart1]" creates a chartsheet
7
+ * (a tab that is the chart, no cells) or "Object in: [Sheet]" moves the chart
8
+ * onto another worksheet. UI-only — the host turns the target into the move.
9
+ */
10
+ export const MoveChartDialog = memo(({ open, onOpenChange, chart, sheets, onSubmit }) => {
11
+ const sourceSheetId = chart.position.sheetId;
12
+ const sourceSheet = sheets.find((sheet) => sheet.sheetId === sourceSheetId);
13
+ const sourceIsChartSheet = sourceSheet?.type === "chartsheet";
14
+ const worksheets = sheets.filter((sheet) => sheet.type !== "chartsheet" && !sheet.hidden);
15
+ // Excel pre-selects where the chart currently is: "New sheet" (with the
16
+ // chartsheet's own name) for a chartsheet chart, "Object in" otherwise.
17
+ const [mode, setMode] = useState(sourceIsChartSheet ? "newSheet" : "sheet");
18
+ const [title, setTitle] = useState(sourceIsChartSheet && sourceSheet
19
+ ? sourceSheet.title
20
+ : getNextChartSheetTitle(sheets));
21
+ const [targetSheetId, setTargetSheetId] = useState(worksheets.some((sheet) => sheet.sheetId === sourceSheetId)
22
+ ? sourceSheetId
23
+ : worksheets[0]?.sheetId);
24
+ const commit = useCallback(() => {
25
+ if (mode === "newSheet") {
26
+ const trimmed = title.trim();
27
+ // Keeping a chartsheet's own name is not a move.
28
+ if (!(sourceIsChartSheet && trimmed === sourceSheet?.title)) {
29
+ onSubmit({ kind: "newSheet", title: trimmed || undefined });
30
+ }
31
+ }
32
+ else if (targetSheetId !== undefined && targetSheetId !== sourceSheetId) {
33
+ onSubmit({ kind: "sheet", sheetId: targetSheetId });
34
+ }
35
+ onOpenChange(false);
36
+ }, [
37
+ mode,
38
+ title,
39
+ targetSheetId,
40
+ sourceSheetId,
41
+ sourceIsChartSheet,
42
+ sourceSheet,
43
+ onSubmit,
44
+ onOpenChange,
45
+ ]);
46
+ return (React.createElement(Dialog, { open: open, onOpenChange: onOpenChange, modal: true },
47
+ React.createElement(DialogContent, { className: "w-[360px] max-w-[92vw] pointer-events-auto" },
48
+ React.createElement(DialogTitle, null, "Move Chart"),
49
+ React.createElement(DialogCloseButton, null),
50
+ React.createElement(DialogBody, { className: "flex flex-col gap-4" },
51
+ React.createElement("form", { className: "flex flex-col gap-4", onSubmit: (e) => {
52
+ e.preventDefault();
53
+ commit();
54
+ } },
55
+ React.createElement("fieldset", { className: "flex flex-col gap-2 min-w-0 border-0 p-0 m-0" },
56
+ React.createElement("legend", { className: "text-xs font-medium mb-1" }, "Choose where you want the chart to be placed:"),
57
+ React.createElement("label", { className: "flex items-center gap-2 text-xs py-0.5 cursor-pointer" },
58
+ React.createElement("input", { type: "radio", name: "move-chart-target", value: "newSheet", checked: mode === "newSheet", onChange: () => setMode("newSheet") }),
59
+ React.createElement("span", { className: "w-20 shrink-0" }, "New sheet:"),
60
+ React.createElement("input", { type: "text", "aria-label": "New sheet name", className: "flex-1 min-w-0 rounded border border-rnc-border bg-transparent px-2 py-1 text-xs", value: title, disabled: mode !== "newSheet", onChange: (e) => setTitle(e.target.value), onFocus: () => setMode("newSheet") })),
61
+ React.createElement("label", { className: "flex items-center gap-2 text-xs py-0.5 cursor-pointer" },
62
+ React.createElement("input", { type: "radio", name: "move-chart-target", value: "sheet", checked: mode === "sheet", disabled: worksheets.length === 0, onChange: () => setMode("sheet") }),
63
+ React.createElement("span", { className: "w-20 shrink-0" }, "Object in:"),
64
+ React.createElement("select", { "aria-label": "Object in sheet", className: "flex-1 min-w-0 rounded border border-rnc-border bg-transparent px-2 py-1 text-xs", value: targetSheetId ?? "", disabled: mode !== "sheet" || worksheets.length === 0, onChange: (e) => setTargetSheetId(Number(e.target.value)) }, worksheets.map((sheet) => (React.createElement("option", { key: sheet.sheetId, value: sheet.sheetId }, sheet.title)))))),
65
+ React.createElement(Separator, null),
66
+ React.createElement("div", { className: "flex justify-end gap-2" },
67
+ React.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onOpenChange(false) }, "Cancel"),
68
+ React.createElement(Button, { type: "submit", size: "sm", autoFocus: true }, "OK")))))));
69
+ });
70
+ MoveChartDialog.displayName = "MoveChartDialog";
71
+ /**
72
+ * Host-mounted, atom-driven wrapper around {@link MoveChartDialog}. Mount it
73
+ * once alongside the other editor dialogs; the chart context menu and the
74
+ * chart editor open it. Remounted per request so each opening starts from the
75
+ * chart's current sheet.
76
+ */
77
+ export const MoveChartDialogHost = ({ sheets, onMoveChartToSheet, }) => {
78
+ useRegisterMoveChartDialogHost();
79
+ const [request, setRequest] = useMoveChartDialogState();
80
+ const close = useCallback(() => setRequest(null), [setRequest]);
81
+ if (!request)
82
+ return null;
83
+ return (React.createElement(MoveChartDialog, { key: String(request.chart.chartId), open: true, onOpenChange: (open) => {
84
+ if (!open)
85
+ close();
86
+ }, chart: request.chart, sheets: sheets, onSubmit: (target) => onMoveChartToSheet(request.chart, target) }));
87
+ };
88
+ MoveChartDialogHost.displayName = "MoveChartDialogHost";