@carto/ps-react-ui 4.7.0 → 4.8.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 (578) hide show
  1. package/dist/category-DwaeYjpX.js +656 -0
  2. package/dist/category-DwaeYjpX.js.map +1 -0
  3. package/dist/change-column-Cidl_M-4.js +1110 -0
  4. package/dist/change-column-Cidl_M-4.js.map +1 -0
  5. package/dist/data-zoom-layout-BH0LPwSy.js +28 -0
  6. package/dist/data-zoom-layout-BH0LPwSy.js.map +1 -0
  7. package/dist/echart-CU0KmClP.js +176 -0
  8. package/dist/echart-CU0KmClP.js.map +1 -0
  9. package/dist/exports-Cx-f6m6U.js +63 -0
  10. package/dist/exports-Cx-f6m6U.js.map +1 -0
  11. package/dist/formula-DuC0NQLH.js +79 -0
  12. package/dist/formula-DuC0NQLH.js.map +1 -0
  13. package/dist/markdown-BD1jcknS.js +8326 -0
  14. package/dist/markdown-BD1jcknS.js.map +1 -0
  15. package/dist/merge-options-DCkkHZIf.js +34 -0
  16. package/dist/merge-options-DCkkHZIf.js.map +1 -0
  17. package/dist/{styles-BYTyKQFP.js → option-builders-F-c9ELi1.js} +25 -45
  18. package/dist/option-builders-F-c9ELi1.js.map +1 -0
  19. package/dist/png-item-CS4z1iSH.js +45 -0
  20. package/dist/png-item-CS4z1iSH.js.map +1 -0
  21. package/dist/range-DsqTjSpg.js +186 -0
  22. package/dist/range-DsqTjSpg.js.map +1 -0
  23. package/dist/spread-CTuIXZSM.js +67 -0
  24. package/dist/spread-CTuIXZSM.js.map +1 -0
  25. package/dist/style-DVnT6HC1.js +131 -0
  26. package/dist/style-DVnT6HC1.js.map +1 -0
  27. package/dist/styles-cohnxh9F.js +23 -0
  28. package/dist/styles-cohnxh9F.js.map +1 -0
  29. package/dist/table-HIpXuq4G.js +390 -0
  30. package/dist/table-HIpXuq4G.js.map +1 -0
  31. package/dist/transforms-Cdx4fkU5.js +106 -0
  32. package/dist/transforms-Cdx4fkU5.js.map +1 -0
  33. package/dist/types/widgets/echart/utils.test.d.ts +1 -0
  34. package/dist/types/widgets/formula/config.test.d.ts +1 -0
  35. package/dist/types/widgets/stores/widget-store-branches.test.d.ts +1 -0
  36. package/dist/types/widgets/table/config.test.d.ts +1 -0
  37. package/dist/types/widgets-v2/actions/brush-toggle/brush-toggle.d.ts +56 -0
  38. package/dist/types/widgets-v2/actions/brush-toggle/index.d.ts +3 -0
  39. package/dist/types/widgets-v2/actions/brush-toggle/labels.d.ts +5 -0
  40. package/dist/types/widgets-v2/actions/brush-toggle/style.d.ts +12 -0
  41. package/dist/types/widgets-v2/actions/brush-toggle/transforms.d.ts +11 -0
  42. package/dist/types/widgets-v2/actions/brush-toggle/transforms.test.d.ts +1 -0
  43. package/dist/types/widgets-v2/actions/change-column/change-column-icon.d.ts +2 -0
  44. package/dist/types/widgets-v2/actions/change-column/change-column.d.ts +29 -0
  45. package/dist/types/widgets-v2/actions/change-column/index.d.ts +3 -0
  46. package/dist/types/widgets-v2/actions/change-column/labels.d.ts +5 -0
  47. package/dist/types/widgets-v2/actions/change-column/sortable-column-item.d.ts +14 -0
  48. package/dist/types/widgets-v2/actions/change-column/style.d.ts +33 -0
  49. package/dist/types/widgets-v2/actions/change-column/types.d.ts +10 -0
  50. package/dist/types/widgets-v2/actions/download/download.d.ts +18 -0
  51. package/dist/types/widgets-v2/actions/download/exports.d.ts +37 -0
  52. package/dist/types/widgets-v2/actions/download/icons.d.ts +12 -0
  53. package/dist/types/widgets-v2/actions/download/index.d.ts +6 -0
  54. package/dist/types/widgets-v2/actions/download/labels.d.ts +11 -0
  55. package/dist/types/widgets-v2/actions/download/png-item.d.ts +24 -0
  56. package/dist/types/widgets-v2/actions/download/style.d.ts +1 -0
  57. package/dist/types/widgets-v2/actions/download/types.d.ts +35 -0
  58. package/dist/types/widgets-v2/actions/fullscreen/fullscreen.d.ts +59 -0
  59. package/dist/types/widgets-v2/actions/fullscreen/index.d.ts +3 -0
  60. package/dist/types/widgets-v2/actions/fullscreen/labels.d.ts +5 -0
  61. package/dist/types/widgets-v2/actions/fullscreen/style.d.ts +48 -0
  62. package/dist/types/widgets-v2/actions/fullscreen/types.d.ts +14 -0
  63. package/dist/types/widgets-v2/actions/index.d.ts +9 -0
  64. package/dist/types/widgets-v2/actions/lock-selection/index.d.ts +3 -0
  65. package/dist/types/widgets-v2/actions/lock-selection/labels.d.ts +6 -0
  66. package/dist/types/widgets-v2/actions/lock-selection/lock-selection.d.ts +36 -0
  67. package/dist/types/widgets-v2/actions/lock-selection/style.d.ts +12 -0
  68. package/dist/types/widgets-v2/actions/lock-selection/transforms.d.ts +6 -0
  69. package/dist/types/widgets-v2/actions/relative-data/index.d.ts +3 -0
  70. package/dist/types/widgets-v2/actions/relative-data/labels.d.ts +5 -0
  71. package/dist/types/widgets-v2/actions/relative-data/relative-data.d.ts +39 -0
  72. package/dist/types/widgets-v2/actions/relative-data/style.d.ts +12 -0
  73. package/dist/types/widgets-v2/actions/relative-data/transforms.d.ts +30 -0
  74. package/dist/types/widgets-v2/actions/relative-data/transforms.test.d.ts +1 -0
  75. package/dist/types/widgets-v2/actions/searcher/filter.d.ts +6 -0
  76. package/dist/types/widgets-v2/actions/searcher/index.d.ts +4 -0
  77. package/dist/types/widgets-v2/actions/searcher/labels.d.ts +7 -0
  78. package/dist/types/widgets-v2/actions/searcher/searcher-toggle.d.ts +23 -0
  79. package/dist/types/widgets-v2/actions/searcher/searcher.d.ts +11 -0
  80. package/dist/types/widgets-v2/actions/searcher/style.d.ts +16 -0
  81. package/dist/types/widgets-v2/actions/stack-toggle/index.d.ts +3 -0
  82. package/dist/types/widgets-v2/actions/stack-toggle/labels.d.ts +5 -0
  83. package/dist/types/widgets-v2/actions/stack-toggle/stack-toggle.d.ts +10 -0
  84. package/dist/types/widgets-v2/actions/stack-toggle/style.d.ts +12 -0
  85. package/dist/types/widgets-v2/actions/stack-toggle/transforms.d.ts +13 -0
  86. package/dist/types/widgets-v2/actions/stack-toggle/transforms.test.d.ts +1 -0
  87. package/dist/types/widgets-v2/actions/zoom-toggle/index.d.ts +3 -0
  88. package/dist/types/widgets-v2/actions/zoom-toggle/labels.d.ts +5 -0
  89. package/dist/types/widgets-v2/actions/zoom-toggle/style.d.ts +12 -0
  90. package/dist/types/widgets-v2/actions/zoom-toggle/transforms.d.ts +51 -0
  91. package/dist/types/widgets-v2/actions/zoom-toggle/transforms.test.d.ts +1 -0
  92. package/dist/types/widgets-v2/actions/zoom-toggle/zoom-toggle.d.ts +35 -0
  93. package/dist/types/widgets-v2/bar/download.d.ts +24 -0
  94. package/dist/types/widgets-v2/bar/index.d.ts +4 -0
  95. package/dist/types/widgets-v2/bar/options.d.ts +43 -0
  96. package/dist/types/widgets-v2/bar/options.test.d.ts +1 -0
  97. package/dist/types/widgets-v2/bar/skeleton.d.ts +6 -0
  98. package/dist/types/widgets-v2/bar/types.d.ts +41 -0
  99. package/dist/types/widgets-v2/category/category-ui.d.ts +81 -0
  100. package/dist/types/widgets-v2/category/category.d.ts +48 -0
  101. package/dist/types/widgets-v2/category/components/category-bar-stacked.d.ts +28 -0
  102. package/dist/types/widgets-v2/category/components/category-bar.d.ts +23 -0
  103. package/dist/types/widgets-v2/category/components/category-legend.d.ts +18 -0
  104. package/dist/types/widgets-v2/category/components/category-row-multi.d.ts +31 -0
  105. package/dist/types/widgets-v2/category/components/category-row-other.d.ts +13 -0
  106. package/dist/types/widgets-v2/category/components/category-row-single.d.ts +28 -0
  107. package/dist/types/widgets-v2/category/components/category-row-stacked.d.ts +38 -0
  108. package/dist/types/widgets-v2/category/download.d.ts +16 -0
  109. package/dist/types/widgets-v2/category/download.test.d.ts +1 -0
  110. package/dist/types/widgets-v2/category/index.d.ts +10 -0
  111. package/dist/types/widgets-v2/category/skeleton.d.ts +11 -0
  112. package/dist/types/widgets-v2/category/style.d.ts +166 -0
  113. package/dist/types/widgets-v2/category/types.d.ts +49 -0
  114. package/dist/types/widgets-v2/echart/echart-ui.d.ts +44 -0
  115. package/dist/types/widgets-v2/echart/echart.d.ts +75 -0
  116. package/dist/types/widgets-v2/echart/index.d.ts +4 -0
  117. package/dist/types/widgets-v2/echart/shared-resize-observer.d.ts +5 -0
  118. package/dist/types/widgets-v2/echart/shared-resize-observer.test.d.ts +1 -0
  119. package/dist/types/widgets-v2/echart/style.d.ts +6 -0
  120. package/dist/types/widgets-v2/echart/use-chart-selection.d.ts +51 -0
  121. package/dist/types/widgets-v2/formula/delta.d.ts +22 -0
  122. package/dist/types/widgets-v2/formula/download.d.ts +20 -0
  123. package/dist/types/widgets-v2/formula/formula-ui.d.ts +20 -0
  124. package/dist/types/widgets-v2/formula/formula.d.ts +8 -0
  125. package/dist/types/widgets-v2/formula/index.d.ts +11 -0
  126. package/dist/types/widgets-v2/formula/note.d.ts +11 -0
  127. package/dist/types/widgets-v2/formula/prefix.d.ts +12 -0
  128. package/dist/types/widgets-v2/formula/series.d.ts +16 -0
  129. package/dist/types/widgets-v2/formula/skeleton.d.ts +4 -0
  130. package/dist/types/widgets-v2/formula/style.d.ts +29 -0
  131. package/dist/types/widgets-v2/formula/suffix.d.ts +12 -0
  132. package/dist/types/widgets-v2/formula/types.d.ts +40 -0
  133. package/dist/types/widgets-v2/formula/value.d.ts +14 -0
  134. package/dist/types/widgets-v2/histogram/download.d.ts +17 -0
  135. package/dist/types/widgets-v2/histogram/download.test.d.ts +1 -0
  136. package/dist/types/widgets-v2/histogram/index.d.ts +5 -0
  137. package/dist/types/widgets-v2/histogram/options.d.ts +42 -0
  138. package/dist/types/widgets-v2/histogram/options.test.d.ts +1 -0
  139. package/dist/types/widgets-v2/histogram/skeleton.d.ts +9 -0
  140. package/dist/types/widgets-v2/histogram/transforms.d.ts +17 -0
  141. package/dist/types/widgets-v2/histogram/transforms.test.d.ts +1 -0
  142. package/dist/types/widgets-v2/histogram/types.d.ts +47 -0
  143. package/dist/types/widgets-v2/index.d.ts +107 -0
  144. package/dist/types/widgets-v2/markdown/download.d.ts +16 -0
  145. package/dist/types/widgets-v2/markdown/download.test.d.ts +1 -0
  146. package/dist/types/widgets-v2/markdown/index.d.ts +6 -0
  147. package/dist/types/widgets-v2/markdown/markdown-content.d.ts +34 -0
  148. package/dist/types/widgets-v2/markdown/markdown-ui.d.ts +12 -0
  149. package/dist/types/widgets-v2/markdown/markdown.d.ts +6 -0
  150. package/dist/types/widgets-v2/markdown/skeleton.d.ts +4 -0
  151. package/dist/types/widgets-v2/markdown/style.d.ts +61 -0
  152. package/dist/types/widgets-v2/markdown/types.d.ts +4 -0
  153. package/dist/types/widgets-v2/note/labels.d.ts +5 -0
  154. package/dist/types/widgets-v2/note/style.d.ts +26 -0
  155. package/dist/types/widgets-v2/note/widget-note.d.ts +46 -0
  156. package/dist/types/widgets-v2/pie/download.d.ts +17 -0
  157. package/dist/types/widgets-v2/pie/download.test.d.ts +1 -0
  158. package/dist/types/widgets-v2/pie/index.d.ts +4 -0
  159. package/dist/types/widgets-v2/pie/options.d.ts +35 -0
  160. package/dist/types/widgets-v2/pie/options.test.d.ts +1 -0
  161. package/dist/types/widgets-v2/pie/skeleton.d.ts +4 -0
  162. package/dist/types/widgets-v2/pie/types.d.ts +50 -0
  163. package/dist/types/widgets-v2/provider/widget-provider.d.ts +32 -0
  164. package/dist/types/widgets-v2/range/index.d.ts +4 -0
  165. package/dist/types/widgets-v2/range/range-ui.d.ts +19 -0
  166. package/dist/types/widgets-v2/range/range.d.ts +19 -0
  167. package/dist/types/widgets-v2/range/skeleton.d.ts +9 -0
  168. package/dist/types/widgets-v2/range/style.d.ts +40 -0
  169. package/dist/types/widgets-v2/range/types.d.ts +37 -0
  170. package/dist/types/widgets-v2/scatterplot/download.d.ts +16 -0
  171. package/dist/types/widgets-v2/scatterplot/download.test.d.ts +1 -0
  172. package/dist/types/widgets-v2/scatterplot/index.d.ts +5 -0
  173. package/dist/types/widgets-v2/scatterplot/options.d.ts +42 -0
  174. package/dist/types/widgets-v2/scatterplot/options.test.d.ts +1 -0
  175. package/dist/types/widgets-v2/scatterplot/skeleton.d.ts +12 -0
  176. package/dist/types/widgets-v2/scatterplot/transforms.d.ts +17 -0
  177. package/dist/types/widgets-v2/scatterplot/transforms.test.d.ts +1 -0
  178. package/dist/types/widgets-v2/scatterplot/types.d.ts +50 -0
  179. package/dist/types/widgets-v2/selection-summary/labels.d.ts +6 -0
  180. package/dist/types/widgets-v2/selection-summary/selection-summary.d.ts +22 -0
  181. package/dist/types/widgets-v2/selection-summary/style.d.ts +23 -0
  182. package/dist/types/widgets-v2/spread/download.d.ts +15 -0
  183. package/dist/types/widgets-v2/spread/download.test.d.ts +1 -0
  184. package/dist/types/widgets-v2/spread/index.d.ts +6 -0
  185. package/dist/types/widgets-v2/spread/separator.d.ts +7 -0
  186. package/dist/types/widgets-v2/spread/skeleton.d.ts +9 -0
  187. package/dist/types/widgets-v2/spread/spread-ui.d.ts +18 -0
  188. package/dist/types/widgets-v2/spread/spread.d.ts +5 -0
  189. package/dist/types/widgets-v2/spread/types.d.ts +25 -0
  190. package/dist/types/widgets-v2/state/labels.d.ts +7 -0
  191. package/dist/types/widgets-v2/state/labels.test.d.ts +1 -0
  192. package/dist/types/widgets-v2/state/style.d.ts +19 -0
  193. package/dist/types/widgets-v2/state/widget-state.d.ts +19 -0
  194. package/dist/types/widgets-v2/stores/index.d.ts +8 -0
  195. package/dist/types/widgets-v2/stores/pipeline-middleware.d.ts +5 -0
  196. package/dist/types/widgets-v2/stores/pipeline-middleware.test.d.ts +1 -0
  197. package/dist/types/widgets-v2/stores/transforms.d.ts +4 -0
  198. package/dist/types/widgets-v2/stores/transforms.test.d.ts +1 -0
  199. package/dist/types/widgets-v2/stores/types.d.ts +55 -0
  200. package/dist/types/widgets-v2/stores/use-echart-instance.d.ts +15 -0
  201. package/dist/types/widgets-v2/stores/use-transform-enabled.d.ts +17 -0
  202. package/dist/types/widgets-v2/stores/use-transform.d.ts +12 -0
  203. package/dist/types/widgets-v2/stores/widget-context.d.ts +2 -0
  204. package/dist/types/widgets-v2/stores/widget-store-registry.d.ts +74 -0
  205. package/dist/types/widgets-v2/stores/widget-store-registry.test.d.ts +1 -0
  206. package/dist/types/widgets-v2/subheader/style.d.ts +10 -0
  207. package/dist/types/widgets-v2/subheader/subheader.d.ts +11 -0
  208. package/dist/types/widgets-v2/table/download.d.ts +18 -0
  209. package/dist/types/widgets-v2/table/download.test.d.ts +1 -0
  210. package/dist/types/widgets-v2/table/helpers.d.ts +32 -0
  211. package/dist/types/widgets-v2/table/helpers.test.d.ts +1 -0
  212. package/dist/types/widgets-v2/table/index.d.ts +7 -0
  213. package/dist/types/widgets-v2/table/labels.d.ts +22 -0
  214. package/dist/types/widgets-v2/table/skeleton.d.ts +22 -0
  215. package/dist/types/widgets-v2/table/style.d.ts +44 -0
  216. package/dist/types/widgets-v2/table/table-ui.d.ts +38 -0
  217. package/dist/types/widgets-v2/table/table.d.ts +50 -0
  218. package/dist/types/widgets-v2/table/types.d.ts +37 -0
  219. package/dist/types/widgets-v2/test-utils.d.ts +52 -0
  220. package/dist/types/widgets-v2/timeseries/download.d.ts +17 -0
  221. package/dist/types/widgets-v2/timeseries/download.test.d.ts +1 -0
  222. package/dist/types/widgets-v2/timeseries/index.d.ts +4 -0
  223. package/dist/types/widgets-v2/timeseries/options.d.ts +39 -0
  224. package/dist/types/widgets-v2/timeseries/options.test.d.ts +1 -0
  225. package/dist/types/widgets-v2/timeseries/skeleton.d.ts +8 -0
  226. package/dist/types/widgets-v2/timeseries/types.d.ts +56 -0
  227. package/dist/types/widgets-v2/toolbox/labels.d.ts +5 -0
  228. package/dist/types/widgets-v2/toolbox/style.d.ts +30 -0
  229. package/dist/types/widgets-v2/toolbox/toolbox.d.ts +49 -0
  230. package/dist/types/widgets-v2/utils/data-zoom-layout.d.ts +11 -0
  231. package/dist/types/widgets-v2/utils/index.d.ts +2 -0
  232. package/dist/types/widgets-v2/utils/merge-options.d.ts +12 -0
  233. package/dist/types/widgets-v2/utils/merge-options.test.d.ts +1 -0
  234. package/dist/types/widgets-v2/wrapper/index.d.ts +4 -0
  235. package/dist/types/widgets-v2/wrapper/labels.d.ts +6 -0
  236. package/dist/types/widgets-v2/wrapper/style.d.ts +111 -0
  237. package/dist/types/widgets-v2/wrapper/widget-actions.d.ts +22 -0
  238. package/dist/types/widgets-v2/wrapper/widget-content.d.ts +12 -0
  239. package/dist/types/widgets-v2/wrapper/widget-wrapper.d.ts +51 -0
  240. package/dist/use-transform-DXPN3nY7.js +110 -0
  241. package/dist/use-transform-DXPN3nY7.js.map +1 -0
  242. package/dist/widget-context-DTGO0Yta.js +13 -0
  243. package/dist/widget-context-DTGO0Yta.js.map +1 -0
  244. package/dist/widget-store-registry-_W4Z4xp-.js +178 -0
  245. package/dist/widget-store-registry-_W4Z4xp-.js.map +1 -0
  246. package/dist/widgets/actions.js +688 -668
  247. package/dist/widgets/actions.js.map +1 -1
  248. package/dist/widgets/bar.js +14 -13
  249. package/dist/widgets/bar.js.map +1 -1
  250. package/dist/widgets/histogram.js +38 -37
  251. package/dist/widgets/histogram.js.map +1 -1
  252. package/dist/widgets/pie.js +19 -18
  253. package/dist/widgets/pie.js.map +1 -1
  254. package/dist/widgets/scatterplot.js +8 -7
  255. package/dist/widgets/scatterplot.js.map +1 -1
  256. package/dist/widgets/timeseries.js +11 -10
  257. package/dist/widgets/timeseries.js.map +1 -1
  258. package/dist/widgets/utils.js +8 -7
  259. package/dist/widgets/utils.js.map +1 -1
  260. package/dist/widgets-v2/actions.js +43 -0
  261. package/dist/widgets-v2/actions.js.map +1 -0
  262. package/dist/widgets-v2/bar.js +327 -0
  263. package/dist/widgets-v2/bar.js.map +1 -0
  264. package/dist/widgets-v2/category.js +104 -0
  265. package/dist/widgets-v2/category.js.map +1 -0
  266. package/dist/widgets-v2/echart.js +57 -0
  267. package/dist/widgets-v2/echart.js.map +1 -0
  268. package/dist/widgets-v2/formula.js +74 -0
  269. package/dist/widgets-v2/formula.js.map +1 -0
  270. package/dist/widgets-v2/histogram.js +350 -0
  271. package/dist/widgets-v2/histogram.js.map +1 -0
  272. package/dist/widgets-v2/markdown.js +68 -0
  273. package/dist/widgets-v2/markdown.js.map +1 -0
  274. package/dist/widgets-v2/pie.js +381 -0
  275. package/dist/widgets-v2/pie.js.map +1 -0
  276. package/dist/widgets-v2/range.js +52 -0
  277. package/dist/widgets-v2/range.js.map +1 -0
  278. package/dist/widgets-v2/scatterplot.js +405 -0
  279. package/dist/widgets-v2/scatterplot.js.map +1 -0
  280. package/dist/widgets-v2/spread.js +72 -0
  281. package/dist/widgets-v2/spread.js.map +1 -0
  282. package/dist/widgets-v2/stores.js +42 -0
  283. package/dist/widgets-v2/stores.js.map +1 -0
  284. package/dist/widgets-v2/table.js +78 -0
  285. package/dist/widgets-v2/table.js.map +1 -0
  286. package/dist/widgets-v2/timeseries.js +352 -0
  287. package/dist/widgets-v2/timeseries.js.map +1 -0
  288. package/dist/widgets-v2/utils.js +7 -0
  289. package/dist/widgets-v2/utils.js.map +1 -0
  290. package/dist/widgets-v2.js +953 -0
  291. package/dist/widgets-v2.js.map +1 -0
  292. package/package.json +73 -5
  293. package/src/components/lasso-tool/chip.test.tsx +176 -0
  294. package/src/components/lasso-tool/lasso-tool-inline.test.tsx +171 -0
  295. package/src/components/lasso-tool/lasso-tool.test.tsx +198 -0
  296. package/src/components/list-data/list-data.test.tsx +73 -0
  297. package/src/components/no-data-alert/no-data-alert.test.tsx +38 -0
  298. package/src/components/responsive-drawer/responsive-drawer.test.tsx +68 -0
  299. package/src/widgets/actions/brush-toggle/brush-overlay.test.tsx +465 -0
  300. package/src/widgets/actions/brush-toggle/brush-overlay.tsx +24 -2
  301. package/src/widgets/actions/brush-toggle/brush-toggle.test.tsx +208 -0
  302. package/src/widgets/actions/change-column/change-column-dnd.test.tsx +193 -0
  303. package/src/widgets/actions/change-column/sortable-column-item.test.tsx +124 -0
  304. package/src/widgets/actions/zoom-toggle/zoom-toggle.test.tsx +322 -0
  305. package/src/widgets/category/components/category-rows.test.tsx +213 -0
  306. package/src/widgets/echart/utils.test.ts +277 -0
  307. package/src/widgets/formula/config.test.ts +37 -0
  308. package/src/widgets/histogram/config.ts +1 -3
  309. package/src/widgets/range/components/range-item.test.tsx +243 -0
  310. package/src/widgets/stores/widget-store-branches.test.ts +275 -0
  311. package/src/widgets/table/config.test.ts +65 -0
  312. package/src/widgets/utils/chart-config/option-builders.test.ts +188 -0
  313. package/src/widgets-v2/PERFORMANCE.md +189 -0
  314. package/src/widgets-v2/actions/brush-toggle/brush-toggle.test.tsx +180 -0
  315. package/src/widgets-v2/actions/brush-toggle/brush-toggle.tsx +154 -0
  316. package/src/widgets-v2/actions/brush-toggle/index.ts +3 -0
  317. package/src/widgets-v2/actions/brush-toggle/labels.ts +9 -0
  318. package/src/widgets-v2/actions/brush-toggle/style.ts +11 -0
  319. package/src/widgets-v2/actions/brush-toggle/transforms.test.ts +47 -0
  320. package/src/widgets-v2/actions/brush-toggle/transforms.ts +31 -0
  321. package/src/widgets-v2/actions/change-column/change-column-icon.tsx +14 -0
  322. package/src/widgets-v2/actions/change-column/change-column.test.tsx +59 -0
  323. package/src/widgets-v2/actions/change-column/change-column.tsx +180 -0
  324. package/src/widgets-v2/actions/change-column/index.ts +7 -0
  325. package/src/widgets-v2/actions/change-column/labels.ts +9 -0
  326. package/src/widgets-v2/actions/change-column/sortable-column-item.tsx +56 -0
  327. package/src/widgets-v2/actions/change-column/style.ts +32 -0
  328. package/src/widgets-v2/actions/change-column/types.ts +11 -0
  329. package/src/widgets-v2/actions/download/download.test.tsx +327 -0
  330. package/src/widgets-v2/actions/download/download.tsx +144 -0
  331. package/src/widgets-v2/actions/download/exports.test.tsx +198 -0
  332. package/src/widgets-v2/actions/download/exports.ts +115 -0
  333. package/src/widgets-v2/actions/download/icons.tsx +26 -0
  334. package/src/widgets-v2/actions/download/index.ts +13 -0
  335. package/src/widgets-v2/actions/download/labels.ts +16 -0
  336. package/src/widgets-v2/actions/download/png-item.test.tsx +72 -0
  337. package/src/widgets-v2/actions/download/png-item.tsx +52 -0
  338. package/src/widgets-v2/actions/download/style.ts +3 -0
  339. package/src/widgets-v2/actions/download/types.ts +32 -0
  340. package/src/widgets-v2/actions/fullscreen/fullscreen.test.tsx +150 -0
  341. package/src/widgets-v2/actions/fullscreen/fullscreen.tsx +230 -0
  342. package/src/widgets-v2/actions/fullscreen/index.ts +7 -0
  343. package/src/widgets-v2/actions/fullscreen/labels.ts +9 -0
  344. package/src/widgets-v2/actions/fullscreen/style.ts +59 -0
  345. package/src/widgets-v2/actions/fullscreen/types.ts +15 -0
  346. package/src/widgets-v2/actions/index.ts +82 -0
  347. package/src/widgets-v2/actions/lock-selection/index.ts +10 -0
  348. package/src/widgets-v2/actions/lock-selection/labels.ts +11 -0
  349. package/src/widgets-v2/actions/lock-selection/lock-selection.test.tsx +187 -0
  350. package/src/widgets-v2/actions/lock-selection/lock-selection.tsx +130 -0
  351. package/src/widgets-v2/actions/lock-selection/style.ts +11 -0
  352. package/src/widgets-v2/actions/lock-selection/transforms.ts +27 -0
  353. package/src/widgets-v2/actions/relative-data/index.ts +3 -0
  354. package/src/widgets-v2/actions/relative-data/labels.ts +9 -0
  355. package/src/widgets-v2/actions/relative-data/relative-data.test.tsx +71 -0
  356. package/src/widgets-v2/actions/relative-data/relative-data.tsx +107 -0
  357. package/src/widgets-v2/actions/relative-data/style.ts +11 -0
  358. package/src/widgets-v2/actions/relative-data/transforms.test.ts +151 -0
  359. package/src/widgets-v2/actions/relative-data/transforms.ts +70 -0
  360. package/src/widgets-v2/actions/searcher/filter.ts +28 -0
  361. package/src/widgets-v2/actions/searcher/index.ts +8 -0
  362. package/src/widgets-v2/actions/searcher/labels.ts +13 -0
  363. package/src/widgets-v2/actions/searcher/searcher-toggle.tsx +91 -0
  364. package/src/widgets-v2/actions/searcher/searcher.test.tsx +92 -0
  365. package/src/widgets-v2/actions/searcher/searcher.tsx +112 -0
  366. package/src/widgets-v2/actions/searcher/style.ts +15 -0
  367. package/src/widgets-v2/actions/stack-toggle/index.ts +3 -0
  368. package/src/widgets-v2/actions/stack-toggle/labels.ts +9 -0
  369. package/src/widgets-v2/actions/stack-toggle/stack-toggle.test.tsx +61 -0
  370. package/src/widgets-v2/actions/stack-toggle/stack-toggle.tsx +54 -0
  371. package/src/widgets-v2/actions/stack-toggle/style.ts +11 -0
  372. package/src/widgets-v2/actions/stack-toggle/transforms.test.ts +43 -0
  373. package/src/widgets-v2/actions/stack-toggle/transforms.ts +25 -0
  374. package/src/widgets-v2/actions/zoom-toggle/index.ts +9 -0
  375. package/src/widgets-v2/actions/zoom-toggle/labels.ts +9 -0
  376. package/src/widgets-v2/actions/zoom-toggle/style.ts +11 -0
  377. package/src/widgets-v2/actions/zoom-toggle/transforms.test.ts +148 -0
  378. package/src/widgets-v2/actions/zoom-toggle/transforms.ts +171 -0
  379. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.test.tsx +107 -0
  380. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.tsx +106 -0
  381. package/src/widgets-v2/bar/download.test.tsx +91 -0
  382. package/src/widgets-v2/bar/download.tsx +66 -0
  383. package/src/widgets-v2/bar/index.ts +10 -0
  384. package/src/widgets-v2/bar/options.test.ts +317 -0
  385. package/src/widgets-v2/bar/options.ts +326 -0
  386. package/src/widgets-v2/bar/skeleton.test.tsx +19 -0
  387. package/src/widgets-v2/bar/skeleton.tsx +69 -0
  388. package/src/widgets-v2/bar/types.ts +46 -0
  389. package/src/widgets-v2/category/category-ui.test.tsx +746 -0
  390. package/src/widgets-v2/category/category-ui.tsx +389 -0
  391. package/src/widgets-v2/category/category.relative-data.test.tsx +107 -0
  392. package/src/widgets-v2/category/category.stack-toggle.test.tsx +85 -0
  393. package/src/widgets-v2/category/category.test.tsx +305 -0
  394. package/src/widgets-v2/category/category.tsx +121 -0
  395. package/src/widgets-v2/category/components/category-bar-stacked.test.tsx +121 -0
  396. package/src/widgets-v2/category/components/category-bar-stacked.tsx +73 -0
  397. package/src/widgets-v2/category/components/category-bar.test.tsx +64 -0
  398. package/src/widgets-v2/category/components/category-bar.tsx +49 -0
  399. package/src/widgets-v2/category/components/category-legend.test.tsx +51 -0
  400. package/src/widgets-v2/category/components/category-legend.tsx +39 -0
  401. package/src/widgets-v2/category/components/category-row-multi.tsx +86 -0
  402. package/src/widgets-v2/category/components/category-row-other.test.tsx +28 -0
  403. package/src/widgets-v2/category/components/category-row-other.tsx +33 -0
  404. package/src/widgets-v2/category/components/category-row-single.tsx +76 -0
  405. package/src/widgets-v2/category/components/category-row-stacked.test.tsx +244 -0
  406. package/src/widgets-v2/category/components/category-row-stacked.tsx +99 -0
  407. package/src/widgets-v2/category/download.test.ts +71 -0
  408. package/src/widgets-v2/category/download.ts +54 -0
  409. package/src/widgets-v2/category/index.ts +32 -0
  410. package/src/widgets-v2/category/skeleton.test.tsx +26 -0
  411. package/src/widgets-v2/category/skeleton.tsx +74 -0
  412. package/src/widgets-v2/category/style.ts +290 -0
  413. package/src/widgets-v2/category/types.ts +54 -0
  414. package/src/widgets-v2/echart/echart-ui.test.tsx +232 -0
  415. package/src/widgets-v2/echart/echart-ui.tsx +184 -0
  416. package/src/widgets-v2/echart/echart.test.tsx +229 -0
  417. package/src/widgets-v2/echart/echart.tsx +199 -0
  418. package/src/widgets-v2/echart/index.ts +22 -0
  419. package/src/widgets-v2/echart/shared-resize-observer.test.ts +91 -0
  420. package/src/widgets-v2/echart/shared-resize-observer.ts +56 -0
  421. package/src/widgets-v2/echart/style.ts +8 -0
  422. package/src/widgets-v2/echart/use-chart-selection.test.tsx +118 -0
  423. package/src/widgets-v2/echart/use-chart-selection.ts +115 -0
  424. package/src/widgets-v2/formula/delta.tsx +61 -0
  425. package/src/widgets-v2/formula/download.test.tsx +65 -0
  426. package/src/widgets-v2/formula/download.tsx +69 -0
  427. package/src/widgets-v2/formula/formula-ui.test.tsx +91 -0
  428. package/src/widgets-v2/formula/formula-ui.tsx +66 -0
  429. package/src/widgets-v2/formula/formula.test.tsx +50 -0
  430. package/src/widgets-v2/formula/formula.tsx +34 -0
  431. package/src/widgets-v2/formula/index.ts +17 -0
  432. package/src/widgets-v2/formula/note.tsx +25 -0
  433. package/src/widgets-v2/formula/prefix.tsx +25 -0
  434. package/src/widgets-v2/formula/series.tsx +67 -0
  435. package/src/widgets-v2/formula/skeleton.test.tsx +21 -0
  436. package/src/widgets-v2/formula/skeleton.tsx +27 -0
  437. package/src/widgets-v2/formula/style.ts +31 -0
  438. package/src/widgets-v2/formula/subcomponents.test.tsx +107 -0
  439. package/src/widgets-v2/formula/suffix.tsx +25 -0
  440. package/src/widgets-v2/formula/types.ts +44 -0
  441. package/src/widgets-v2/formula/value.tsx +31 -0
  442. package/src/widgets-v2/histogram/download.test.ts +94 -0
  443. package/src/widgets-v2/histogram/download.ts +60 -0
  444. package/src/widgets-v2/histogram/index.ts +10 -0
  445. package/src/widgets-v2/histogram/options.test.ts +304 -0
  446. package/src/widgets-v2/histogram/options.ts +337 -0
  447. package/src/widgets-v2/histogram/skeleton.test.tsx +16 -0
  448. package/src/widgets-v2/histogram/skeleton.tsx +70 -0
  449. package/src/widgets-v2/histogram/transforms.test.ts +46 -0
  450. package/src/widgets-v2/histogram/transforms.ts +30 -0
  451. package/src/widgets-v2/histogram/types.ts +51 -0
  452. package/src/widgets-v2/index.ts +201 -0
  453. package/src/widgets-v2/markdown/download.test.ts +66 -0
  454. package/src/widgets-v2/markdown/download.ts +53 -0
  455. package/src/widgets-v2/markdown/index.ts +6 -0
  456. package/src/widgets-v2/markdown/markdown-content.test.tsx +155 -0
  457. package/src/widgets-v2/markdown/markdown-content.tsx +72 -0
  458. package/src/widgets-v2/markdown/markdown-ui.test.tsx +75 -0
  459. package/src/widgets-v2/markdown/markdown-ui.tsx +55 -0
  460. package/src/widgets-v2/markdown/markdown.test.tsx +39 -0
  461. package/src/widgets-v2/markdown/markdown.tsx +17 -0
  462. package/src/widgets-v2/markdown/skeleton.test.tsx +15 -0
  463. package/src/widgets-v2/markdown/skeleton.tsx +32 -0
  464. package/src/widgets-v2/markdown/style.ts +53 -0
  465. package/src/widgets-v2/markdown/types.ts +4 -0
  466. package/src/widgets-v2/note/labels.ts +9 -0
  467. package/src/widgets-v2/note/style.ts +26 -0
  468. package/src/widgets-v2/note/widget-note.test.tsx +158 -0
  469. package/src/widgets-v2/note/widget-note.tsx +172 -0
  470. package/src/widgets-v2/pie/download.test.ts +78 -0
  471. package/src/widgets-v2/pie/download.ts +55 -0
  472. package/src/widgets-v2/pie/index.ts +10 -0
  473. package/src/widgets-v2/pie/options.test.ts +585 -0
  474. package/src/widgets-v2/pie/options.ts +509 -0
  475. package/src/widgets-v2/pie/skeleton.test.tsx +17 -0
  476. package/src/widgets-v2/pie/skeleton.tsx +32 -0
  477. package/src/widgets-v2/pie/types.ts +55 -0
  478. package/src/widgets-v2/provider/widget-provider.test.tsx +119 -0
  479. package/src/widgets-v2/provider/widget-provider.tsx +111 -0
  480. package/src/widgets-v2/range/index.ts +4 -0
  481. package/src/widgets-v2/range/range-ui.test.tsx +130 -0
  482. package/src/widgets-v2/range/range-ui.tsx +211 -0
  483. package/src/widgets-v2/range/range.test.tsx +68 -0
  484. package/src/widgets-v2/range/range.tsx +46 -0
  485. package/src/widgets-v2/range/skeleton.test.tsx +17 -0
  486. package/src/widgets-v2/range/skeleton.tsx +47 -0
  487. package/src/widgets-v2/range/style.ts +41 -0
  488. package/src/widgets-v2/range/types.ts +37 -0
  489. package/src/widgets-v2/scatterplot/download.test.ts +71 -0
  490. package/src/widgets-v2/scatterplot/download.ts +54 -0
  491. package/src/widgets-v2/scatterplot/index.ts +11 -0
  492. package/src/widgets-v2/scatterplot/options.test.ts +399 -0
  493. package/src/widgets-v2/scatterplot/options.ts +421 -0
  494. package/src/widgets-v2/scatterplot/skeleton.test.tsx +17 -0
  495. package/src/widgets-v2/scatterplot/skeleton.tsx +84 -0
  496. package/src/widgets-v2/scatterplot/transforms.test.ts +97 -0
  497. package/src/widgets-v2/scatterplot/transforms.ts +38 -0
  498. package/src/widgets-v2/scatterplot/types.ts +55 -0
  499. package/src/widgets-v2/selection-summary/labels.ts +11 -0
  500. package/src/widgets-v2/selection-summary/selection-summary.test.tsx +53 -0
  501. package/src/widgets-v2/selection-summary/selection-summary.tsx +62 -0
  502. package/src/widgets-v2/selection-summary/style.ts +23 -0
  503. package/src/widgets-v2/spread/download.test.ts +64 -0
  504. package/src/widgets-v2/spread/download.ts +59 -0
  505. package/src/widgets-v2/spread/index.ts +6 -0
  506. package/src/widgets-v2/spread/separator.tsx +11 -0
  507. package/src/widgets-v2/spread/skeleton.test.tsx +17 -0
  508. package/src/widgets-v2/spread/skeleton.tsx +38 -0
  509. package/src/widgets-v2/spread/spread-ui.test.tsx +108 -0
  510. package/src/widgets-v2/spread/spread-ui.tsx +52 -0
  511. package/src/widgets-v2/spread/spread.test.tsx +50 -0
  512. package/src/widgets-v2/spread/spread.tsx +31 -0
  513. package/src/widgets-v2/spread/types.ts +27 -0
  514. package/src/widgets-v2/state/labels.test.ts +33 -0
  515. package/src/widgets-v2/state/labels.ts +20 -0
  516. package/src/widgets-v2/state/style.ts +25 -0
  517. package/src/widgets-v2/state/widget-state.test.tsx +294 -0
  518. package/src/widgets-v2/state/widget-state.tsx +184 -0
  519. package/src/widgets-v2/stores/index.ts +49 -0
  520. package/src/widgets-v2/stores/pipeline-middleware.test.ts +187 -0
  521. package/src/widgets-v2/stores/pipeline-middleware.ts +91 -0
  522. package/src/widgets-v2/stores/transforms.test.ts +162 -0
  523. package/src/widgets-v2/stores/transforms.ts +70 -0
  524. package/src/widgets-v2/stores/types.ts +64 -0
  525. package/src/widgets-v2/stores/use-echart-instance.test.tsx +91 -0
  526. package/src/widgets-v2/stores/use-echart-instance.ts +29 -0
  527. package/src/widgets-v2/stores/use-transform-enabled.test.tsx +127 -0
  528. package/src/widgets-v2/stores/use-transform-enabled.ts +25 -0
  529. package/src/widgets-v2/stores/use-transform.test.tsx +262 -0
  530. package/src/widgets-v2/stores/use-transform.ts +158 -0
  531. package/src/widgets-v2/stores/widget-context.test.tsx +58 -0
  532. package/src/widgets-v2/stores/widget-context.ts +15 -0
  533. package/src/widgets-v2/stores/widget-store-registry.test.ts +292 -0
  534. package/src/widgets-v2/stores/widget-store-registry.ts +248 -0
  535. package/src/widgets-v2/subheader/style.ts +12 -0
  536. package/src/widgets-v2/subheader/subheader.test.tsx +30 -0
  537. package/src/widgets-v2/subheader/subheader.tsx +16 -0
  538. package/src/widgets-v2/table/download.test.ts +75 -0
  539. package/src/widgets-v2/table/download.ts +47 -0
  540. package/src/widgets-v2/table/helpers.test.ts +214 -0
  541. package/src/widgets-v2/table/helpers.ts +136 -0
  542. package/src/widgets-v2/table/index.ts +23 -0
  543. package/src/widgets-v2/table/labels.tsx +41 -0
  544. package/src/widgets-v2/table/skeleton.test.tsx +26 -0
  545. package/src/widgets-v2/table/skeleton.tsx +65 -0
  546. package/src/widgets-v2/table/style.ts +46 -0
  547. package/src/widgets-v2/table/table-ui.test.tsx +200 -0
  548. package/src/widgets-v2/table/table-ui.tsx +331 -0
  549. package/src/widgets-v2/table/table.test.tsx +119 -0
  550. package/src/widgets-v2/table/table.tsx +174 -0
  551. package/src/widgets-v2/table/types.ts +44 -0
  552. package/src/widgets-v2/test-utils.ts +107 -0
  553. package/src/widgets-v2/timeseries/download.test.ts +95 -0
  554. package/src/widgets-v2/timeseries/download.ts +86 -0
  555. package/src/widgets-v2/timeseries/index.ts +10 -0
  556. package/src/widgets-v2/timeseries/options.test.ts +379 -0
  557. package/src/widgets-v2/timeseries/options.ts +341 -0
  558. package/src/widgets-v2/timeseries/skeleton.test.tsx +13 -0
  559. package/src/widgets-v2/timeseries/skeleton.tsx +76 -0
  560. package/src/widgets-v2/timeseries/types.ts +61 -0
  561. package/src/widgets-v2/toolbox/labels.ts +9 -0
  562. package/src/widgets-v2/toolbox/style.ts +33 -0
  563. package/src/widgets-v2/toolbox/toolbox.test.tsx +200 -0
  564. package/src/widgets-v2/toolbox/toolbox.tsx +309 -0
  565. package/src/widgets-v2/utils/data-zoom-layout.ts +26 -0
  566. package/src/widgets-v2/utils/index.ts +2 -0
  567. package/src/widgets-v2/utils/merge-options.test.ts +52 -0
  568. package/src/widgets-v2/utils/merge-options.ts +50 -0
  569. package/src/widgets-v2/wrapper/index.ts +14 -0
  570. package/src/widgets-v2/wrapper/labels.ts +11 -0
  571. package/src/widgets-v2/wrapper/style.ts +134 -0
  572. package/src/widgets-v2/wrapper/widget-actions.test.tsx +52 -0
  573. package/src/widgets-v2/wrapper/widget-actions.tsx +43 -0
  574. package/src/widgets-v2/wrapper/widget-content.test.tsx +27 -0
  575. package/src/widgets-v2/wrapper/widget-content.tsx +29 -0
  576. package/src/widgets-v2/wrapper/widget-wrapper.test.tsx +159 -0
  577. package/src/widgets-v2/wrapper/widget-wrapper.tsx +178 -0
  578. package/dist/styles-BYTyKQFP.js.map +0 -1
@@ -0,0 +1,389 @@
1
+ import { useCallback, useMemo, useRef, useState } from 'react'
2
+ import { Box, useTheme } from '@mui/material'
3
+ import { CategoryRowSingle } from './components/category-row-single'
4
+ import { CategoryRowMulti } from './components/category-row-multi'
5
+ import { CategoryRowStacked } from './components/category-row-stacked'
6
+ import { CategoryRowOther } from './components/category-row-other'
7
+ import { CategoryLegend } from './components/category-legend'
8
+ import type {
9
+ CategoryKey,
10
+ CategoryLabels,
11
+ CategorySeriesConfig,
12
+ CategorySize,
13
+ CategoryWidgetData,
14
+ } from './types'
15
+ import { styles } from './style'
16
+
17
+ const DEFAULT_MAX_ITEMS = 20
18
+
19
+ // Fallback viewport height used in scroll mode ONLY when no natural
20
+ // measurement is available yet — i.e., the consumer mounts directly into
21
+ // `maxItems === 0` (e.g., SearcherToggle pre-enabled), so the list has
22
+ // never rendered in capped form for us to measure.
23
+ //
24
+ // small: label(~20) + gap(4) + bar(4) + list-gap(8) ≈ 36
25
+ // medium: label(~20) + gap(4) + bar(12) + list-gap(8) ≈ 44
26
+ const ROW_HEIGHT_PX: Record<CategorySize, number> = { small: 36, medium: 44 }
27
+ const SCROLL_VIEWPORT_FALLBACK_ROWS = 8
28
+
29
+ export interface CategoryUIProps {
30
+ data: CategoryWidgetData
31
+ /** Currently-selected category names (destination-owned). */
32
+ selection?: readonly CategoryKey[]
33
+ /** Fires with the next selection set when a row is clicked. */
34
+ onSelectionChange?: (next: readonly CategoryKey[]) => void
35
+ /** Number formatter applied to each row's value. */
36
+ formatter?: (value: number) => string
37
+ /**
38
+ * Display-only transform for category names. Selection callbacks always
39
+ * receive the raw `item.name` regardless of this formatter.
40
+ */
41
+ labelFormatter?: (value: string | number) => string | number
42
+ /**
43
+ * Per-series metadata. Enables the legend (for multi-series) and
44
+ * overrides palette colors per series index. Length need not match
45
+ * `data.length`; mismatches degrade gracefully (extras ignored, gaps
46
+ * fall back to palette).
47
+ */
48
+ series?: readonly CategorySeriesConfig[]
49
+ /**
50
+ * Caps the number of visible category rows.
51
+ *
52
+ * - `undefined` (omitted) — caps at {@link DEFAULT_MAX_ITEMS} (20).
53
+ * Surplus rows fold into a single italic "Other (X more)" footer.
54
+ * `undefined` cannot mean "no cap" because it's consumed by the
55
+ * default-parameter syntax — pass `null` instead.
56
+ * - positive finite N — same as the default but with a custom cap.
57
+ * - `0` — **no cap WITH scroll**: every row renders inside a
58
+ * fixed-height viewport that scrolls internally. The viewport's
59
+ * max-height is the list's natural `clientHeight` measured on the
60
+ * first render where the list was NOT in scroll mode (i.e., the
61
+ * capped view) — frozen for the component's lifetime. If the
62
+ * consumer mounts directly into scroll mode and we never see a
63
+ * capped render, the viewport falls back to `8 × ROW_HEIGHT_PX`.
64
+ * Composers flip into this mode while the user is searching
65
+ * (`maxItems = searcherOpen ? 0 : userMaxItems`) so the widget
66
+ * card height stays stable.
67
+ * - `null` / `Infinity` / negative — **no cap, no scroll**: render
68
+ * every row; the list grows with content. Matches v1's "undefined"
69
+ * behavior. Use `null` as the canonical explicit form.
70
+ */
71
+ maxItems?: number | null
72
+ /** Labels for the "Other" overflow row. `{count}` placeholder is replaced. */
73
+ labels?: CategoryLabels
74
+ /** Manual override for the bar-width denominator. */
75
+ maxOverride?: number
76
+ /**
77
+ * Visual density of the bar primitive. `'small'` (default) keeps the
78
+ * historical 4px-tall pill; `'medium'` switches to a 12px-tall track
79
+ * with a 2px corner radius. Only the bar track + fill change.
80
+ */
81
+ size?: CategorySize
82
+ /**
83
+ * Multi-series stacked mode. When `true` and `data.length > 1`, each
84
+ * category renders as a single segmented bar (one segment per series)
85
+ * with a `formatter(sum)` total in the header and a per-series
86
+ * breakdown line below. Composers typically thread this from
87
+ * `useTransformEnabled(id, 'stack-toggle')`.
88
+ *
89
+ * No-op for single-series data — same convention as the legend.
90
+ */
91
+ stacked?: boolean
92
+ }
93
+
94
+ interface GroupedRow {
95
+ name: CategoryKey
96
+ values: number[]
97
+ /** Per-series per-row color override (first non-undefined wins). */
98
+ rowColors: (string | undefined)[]
99
+ }
100
+
101
+ /**
102
+ * Group items by `name` across series so each unique name produces one
103
+ * row containing N values (zero-filled where a series has no entry for
104
+ * that name). First-seen order across series is preserved.
105
+ *
106
+ * Ported from v1
107
+ * (`packages/react-ui/src/widgets/category/category-ui.tsx:137-166`)
108
+ * with readonly typing + per-row color capture.
109
+ */
110
+ function generateGroupedData(data: CategoryWidgetData): GroupedRow[] {
111
+ if (!data || data.length === 0) return []
112
+ const seriesCount = Math.max(data.length, 1)
113
+ const grouped = new Map<CategoryKey, GroupedRow>()
114
+ const order: CategoryKey[] = []
115
+ for (let s = 0; s < data.length; s++) {
116
+ const series = data[s] ?? []
117
+ for (const item of series) {
118
+ let row = grouped.get(item.name)
119
+ if (!row) {
120
+ row = {
121
+ name: item.name,
122
+ values: new Array<number>(seriesCount).fill(0),
123
+ rowColors: new Array<string | undefined>(seriesCount).fill(undefined),
124
+ }
125
+ grouped.set(item.name, row)
126
+ order.push(item.name)
127
+ }
128
+ row.values[s] = item.value
129
+ row.rowColors[s] = item.color
130
+ }
131
+ }
132
+ return order.map((k) => grouped.get(k)!)
133
+ }
134
+
135
+ /**
136
+ * Pure presentational component for the Category widget. Renders
137
+ * single-series rows (`data.length === 1`) as a compact grid or
138
+ * multi-series rows (`data.length > 1`) as stacked-bar groups, capped at
139
+ * `maxItems` with an overflow summary, and an optional sticky color
140
+ * legend when `series` metadata is supplied.
141
+ *
142
+ * Selection is destination-owned: clicking a row fires
143
+ * `onSelectionChange(next)` with the toggled set; the consumer keeps the
144
+ * list in their own store. `aria-pressed` + Enter/Space keyboard
145
+ * activation give full a11y parity with the mouse path.
146
+ *
147
+ * Returns `null` when there's nothing to render — `Widget.State` is the
148
+ * empty-state authority in the canonical compositor.
149
+ */
150
+ export function CategoryUI({
151
+ data,
152
+ selection,
153
+ onSelectionChange,
154
+ formatter,
155
+ labelFormatter,
156
+ series,
157
+ maxItems = DEFAULT_MAX_ITEMS,
158
+ labels,
159
+ maxOverride,
160
+ size = 'small',
161
+ stacked = false,
162
+ }: CategoryUIProps) {
163
+ const theme = useTheme()
164
+ const fmt = formatter ?? ((n: number) => String(n))
165
+
166
+ const hasSelection = !!selection && selection.length > 0
167
+ const selectionSet = useMemo(
168
+ () => new Set<CategoryKey>(selection ?? []),
169
+ [selection],
170
+ )
171
+
172
+ const toggle = useCallback(
173
+ (name: CategoryKey) => {
174
+ if (!onSelectionChange) return
175
+ const cur = selection ?? []
176
+ const next = cur.includes(name)
177
+ ? cur.filter((n) => n !== name)
178
+ : [...cur, name]
179
+ onSelectionChange(next)
180
+ },
181
+ [onSelectionChange, selection],
182
+ )
183
+
184
+ // Palette: same convention as Bar/Pie/Histogram/Scatterplot/Timeseries v2.
185
+ const paletteColors = useMemo<readonly string[]>(
186
+ () => [
187
+ theme.palette.secondary.main,
188
+ ...Object.values(
189
+ (theme.palette as { qualitative?: { bold?: Record<string, string> } })
190
+ .qualitative?.bold ?? {},
191
+ ),
192
+ ],
193
+ [theme],
194
+ )
195
+
196
+ const colorAt = useCallback(
197
+ (seriesIndex: number, rowColor?: string): string => {
198
+ if (rowColor) return rowColor
199
+ const seriesColor = series?.[seriesIndex]?.color
200
+ if (seriesColor) return seriesColor
201
+ return (
202
+ paletteColors[seriesIndex % paletteColors.length] ??
203
+ theme.palette.secondary.main
204
+ )
205
+ },
206
+ [series, paletteColors, theme],
207
+ )
208
+
209
+ // Dim color for non-selected rows when a selection exists. Swapped in
210
+ // at the bar-fill level only — text + track stay at their real colors.
211
+ // Theme-driven so it survives palette swaps.
212
+ const dimColor = theme.palette.action.disabled
213
+
214
+ const grouped = useMemo(() => generateGroupedData(data), [data])
215
+
216
+ const maxValue = useMemo(() => {
217
+ if (typeof maxOverride === 'number' && maxOverride > 0) return maxOverride
218
+ let m = 0
219
+ for (const row of grouped) {
220
+ for (const v of row.values) if (v > m) m = v
221
+ }
222
+ return m
223
+ }, [grouped, maxOverride])
224
+
225
+ // Three modes:
226
+ // * positive finite N (default `DEFAULT_MAX_ITEMS = 20` when prop
227
+ // omitted): cap at N rows; surplus folds into "Other (X more)".
228
+ // * `0`: no cap WITH scroll — every row renders, the list locks to a
229
+ // fixed viewport and scrolls internally. Composers use this to
230
+ // bypass pagination while the user is searching:
231
+ // `maxItems = searcherOpen ? 0 : userMaxItems`
232
+ // * `null` / `Infinity` / negative: no cap, no scroll — every row
233
+ // renders and the list grows with content. `null` is the canonical
234
+ // explicit form (`undefined` is consumed by the default param above).
235
+ const scrollMode = maxItems === 0
236
+
237
+ // Natural-height measurement. In scroll mode (`maxItems === 0`,
238
+ // set by the composer when the SearcherToggle is open) every row
239
+ // renders inside a scrollable viewport. The viewport's max-height
240
+ // must match the pre-overflow content area — i.e., whatever the
241
+ // list was rendering BEFORE the composer dropped the cap.
242
+ //
243
+ // We measure the list's `clientHeight` exactly once, the first time
244
+ // it attaches while NOT in scroll mode (otherwise we'd capture the
245
+ // wrong layout). Once set, `naturalHeight` is the lock anchor
246
+ // forever — matches v1's frozen-at-mount semantics, just with a
247
+ // real DOM measurement instead of a hard-coded constant.
248
+ //
249
+ // Implemented via a callback ref instead of `useLayoutEffect` so
250
+ // setState fires during commit, not inside an effect — satisfies
251
+ // the `react-hooks/set-state-in-effect` rule. React invokes
252
+ // callback refs on attach (and re-invokes them when the callback
253
+ // identity changes, which it does when `scrollMode` flips), so
254
+ // toggling the searcher off after a scroll-mode mount triggers the
255
+ // first measurement at that point.
256
+ //
257
+ // Fallback: if the consumer never lands a non-scroll render
258
+ // (e.g., searcher pre-enabled and never closed), `naturalHeight`
259
+ // stays `null` → viewport falls back to `8 × ROW_HEIGHT_PX`.
260
+ const measuredRef = useRef(false)
261
+ const [naturalHeight, setNaturalHeight] = useState<number | null>(null)
262
+ const listRefCallback = useCallback(
263
+ (node: HTMLDivElement | null) => {
264
+ if (!node) return
265
+ if (measuredRef.current) return
266
+ if (scrollMode) return
267
+ const h = node.clientHeight
268
+ if (h > 0) {
269
+ measuredRef.current = true
270
+ setNaturalHeight(h)
271
+ }
272
+ },
273
+ [scrollMode],
274
+ )
275
+
276
+ if (grouped.length === 0) return null
277
+
278
+ const hasCap =
279
+ typeof maxItems === 'number' && Number.isFinite(maxItems) && maxItems > 0
280
+ const visible = hasCap ? grouped.slice(0, maxItems) : grouped
281
+ const hiddenCount = hasCap ? grouped.length - visible.length : 0
282
+
283
+ const isMulti = data.length > 1
284
+ const hasLegend = isMulti && !!series && series.length > 0
285
+
286
+ // Fallback viewport height matches the documented "8 × ROW_HEIGHT_PX"
287
+ // (see the constants at the top of the file). Earlier code multiplied
288
+ // this by `seriesCount`, making a 3-series widget render 3× the
289
+ // intended viewport on the first frame before `naturalHeight` was
290
+ // measured — a visible layout jump.
291
+ const scrollMaxHeight = scrollMode
292
+ ? (naturalHeight ?? ROW_HEIGHT_PX[size] * SCROLL_VIEWPORT_FALLBACK_ROWS)
293
+ : undefined
294
+
295
+ return (
296
+ <Box sx={styles.root}>
297
+ <Box
298
+ ref={listRefCallback}
299
+ sx={styles.list}
300
+ style={
301
+ scrollMaxHeight !== undefined
302
+ ? { maxHeight: scrollMaxHeight, overflowY: 'auto' }
303
+ : undefined
304
+ }
305
+ >
306
+ {visible.map((row) => {
307
+ const selected = selectionSet.has(row.name)
308
+ const dimmed = hasSelection && !selected
309
+ const displayName = labelFormatter
310
+ ? labelFormatter(row.name)
311
+ : undefined
312
+ // When the row is dimmed, every series' bar fill is replaced
313
+ // with `dimColor`. Text + track are untouched. This is the
314
+ // ONLY visual difference between selected and non-selected
315
+ // rows — no row-level opacity, no `rowSelected` bg tint.
316
+ const fill = (i: number): string =>
317
+ dimmed ? dimColor : colorAt(i, row.rowColors[i])
318
+ if (isMulti) {
319
+ if (stacked) {
320
+ // Stacked-mode branch: one segmented bar per row. Toggling
321
+ // `stacked` after the natural-height measurement does NOT
322
+ // re-trigger measurement (see the `naturalHeight` comment
323
+ // above) — accepted trade-off: stacked rows have a slightly
324
+ // different height, so the scroll viewport may show extra
325
+ // whitespace after the toggle. Visual only, not functional.
326
+ // Stacked rows are per-row normalized — they don't take
327
+ // the global `maxValue`. Each row's bar fills 100% of the
328
+ // track and the segments split it by `value_i / sum`. The
329
+ // numeric total in the header preserves the per-row
330
+ // magnitude information.
331
+ return (
332
+ <CategoryRowStacked
333
+ key={String(row.name)}
334
+ name={row.name}
335
+ displayName={displayName}
336
+ values={row.values}
337
+ colors={row.values.map((_, i) => fill(i))}
338
+ seriesNames={series?.map((s) => s.name) ?? []}
339
+ formatter={fmt}
340
+ selected={selected}
341
+ onToggle={toggle}
342
+ size={size}
343
+ />
344
+ )
345
+ }
346
+ return (
347
+ <CategoryRowMulti
348
+ key={String(row.name)}
349
+ name={row.name}
350
+ displayName={displayName}
351
+ values={row.values}
352
+ colors={row.values.map((_, i) => fill(i))}
353
+ maxValue={maxValue}
354
+ formatter={fmt}
355
+ selected={selected}
356
+ onToggle={toggle}
357
+ size={size}
358
+ />
359
+ )
360
+ }
361
+ return (
362
+ <CategoryRowSingle
363
+ key={String(row.name)}
364
+ name={row.name}
365
+ displayName={displayName}
366
+ value={row.values[0] ?? 0}
367
+ maxValue={maxValue}
368
+ color={fill(0)}
369
+ formatter={fmt}
370
+ selected={selected}
371
+ onToggle={toggle}
372
+ size={size}
373
+ />
374
+ )
375
+ })}
376
+ {hiddenCount > 0 && (
377
+ <CategoryRowOther
378
+ hiddenCount={hiddenCount}
379
+ otherLabel={labels?.other}
380
+ otherCountLabel={labels?.otherCount}
381
+ />
382
+ )}
383
+ </Box>
384
+ {hasLegend && series && (
385
+ <CategoryLegend series={series} colorAt={(i) => colorAt(i)} />
386
+ )}
387
+ </Box>
388
+ )
389
+ }
@@ -0,0 +1,107 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest'
2
+ import { fireEvent, render, screen } from '@testing-library/react'
3
+ import { Provider } from '../provider/widget-provider'
4
+ import {
5
+ clearAllWidgetStores,
6
+ useTransformEnabled,
7
+ useWidgetId,
8
+ } from '../stores'
9
+ import { Category } from './category'
10
+ import { RelativeData } from '../actions/relative-data/relative-data'
11
+ import type { CategoryWidgetData } from './types'
12
+
13
+ beforeEach(() => clearAllWidgetStores())
14
+ afterEach(() => clearAllWidgetStores())
15
+
16
+ // Replicates `CategoryActionWiring` from the storybook composer
17
+ // (apps/storybook/stories/modules/widgets/category/category.tsx). The
18
+ // composer-level wiring isn't testable in `apps/storybook` (no vitest
19
+ // infra), so we re-implement just the relative-data branch here and
20
+ // assert the bar-width math end-to-end through Provider → action →
21
+ // bridge → UI.
22
+ function Wired({ maxOverride }: { maxOverride?: number }) {
23
+ const id = useWidgetId()
24
+ const relativeDataActive = useTransformEnabled(id, 'relative-data')
25
+ const effectiveMaxOverride = relativeDataActive ? 100 : maxOverride
26
+ return <Category maxOverride={effectiveMaxOverride} />
27
+ }
28
+
29
+ // Single-series dataset where the max value is 1000 so percent values
30
+ // map to round numbers we can match exactly against bar widths.
31
+ const DATA: CategoryWidgetData = [
32
+ [
33
+ { name: 'A', value: 1000 },
34
+ { name: 'B', value: 500 },
35
+ { name: 'C', value: 250 },
36
+ ],
37
+ ]
38
+
39
+ function getBarFills(): HTMLElement[] {
40
+ return Array.from(
41
+ document.querySelectorAll<HTMLElement>('[data-bar-fill="true"]'),
42
+ )
43
+ }
44
+
45
+ describe('Category + RelativeData composer wiring', () => {
46
+ it('default (RelativeData off) → bars scale to data max', () => {
47
+ render(
48
+ <Provider id='cat-rd-off' data={DATA}>
49
+ <RelativeData />
50
+ <Wired />
51
+ </Provider>,
52
+ )
53
+ const fills = getBarFills()
54
+ expect(fills).toHaveLength(3)
55
+ // 1000/1000, 500/1000, 250/1000
56
+ expect(fills[0]!.style.width).toBe('100%')
57
+ expect(fills[1]!.style.width).toBe('50%')
58
+ expect(fills[2]!.style.width).toBe('25%')
59
+ })
60
+
61
+ it('clicking the % action flips bars to a 100-denominator', () => {
62
+ render(
63
+ <Provider id='cat-rd-toggle' data={DATA}>
64
+ <RelativeData />
65
+ <Wired />
66
+ </Provider>,
67
+ )
68
+ // Toggle ON. RelativeData rewrites data values into percentages
69
+ // (A=1000/1750 ≈ 57.14, B=500/1750 ≈ 28.57, C=250/1750 ≈ 14.29) AND
70
+ // the composer wiring forces maxOverride=100 so the bar widths
71
+ // match those percent values directly.
72
+ fireEvent.click(screen.getByRole('button', { name: /relative|percent/i }))
73
+ const fills = getBarFills()
74
+ expect(fills).toHaveLength(3)
75
+ // Allow a small rounding tolerance — the percent transform produces
76
+ // floats, the bar math multiplies by 100 again.
77
+ const a = parseFloat(fills[0]!.style.width)
78
+ const b = parseFloat(fills[1]!.style.width)
79
+ const c = parseFloat(fills[2]!.style.width)
80
+ expect(a).toBeGreaterThan(55)
81
+ expect(a).toBeLessThan(60)
82
+ expect(b).toBeGreaterThan(27)
83
+ expect(b).toBeLessThan(30)
84
+ expect(c).toBeGreaterThan(13)
85
+ expect(c).toBeLessThan(16)
86
+ // The largest bar must be NOT 100% — that's the whole point of the
87
+ // fix. Without the wiring, A would have been 100% (largest of the
88
+ // percent series).
89
+ expect(a).toBeLessThan(100)
90
+ })
91
+
92
+ it('toggling off again restores data-max scaling', () => {
93
+ render(
94
+ <Provider id='cat-rd-restore' data={DATA}>
95
+ <RelativeData />
96
+ <Wired />
97
+ </Provider>,
98
+ )
99
+ const button = screen.getByRole('button', { name: /relative|percent/i })
100
+ fireEvent.click(button) // on
101
+ fireEvent.click(button) // off
102
+ const fills = getBarFills()
103
+ expect(fills[0]!.style.width).toBe('100%')
104
+ expect(fills[1]!.style.width).toBe('50%')
105
+ expect(fills[2]!.style.width).toBe('25%')
106
+ })
107
+ })
@@ -0,0 +1,85 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest'
2
+ import { fireEvent, render, screen } from '@testing-library/react'
3
+ import { Provider } from '../provider/widget-provider'
4
+ import {
5
+ clearAllWidgetStores,
6
+ useTransformEnabled,
7
+ useWidgetId,
8
+ } from '../stores'
9
+ import { Category } from './category'
10
+ import { StackToggle } from '../actions/stack-toggle/stack-toggle'
11
+ import type { CategoryWidgetData } from './types'
12
+
13
+ beforeEach(() => clearAllWidgetStores())
14
+ afterEach(() => clearAllWidgetStores())
15
+
16
+ // Replicates the stack-toggle branch of `CategoryActionWiring` from the
17
+ // storybook composer. The composer-level wiring isn't testable in
18
+ // `apps/storybook` (no vitest infra), so we re-implement just the
19
+ // stack-toggle branch here and assert the action → bridge → UI path
20
+ // end-to-end through Provider → action → bridge → UI.
21
+ function Wired() {
22
+ const id = useWidgetId()
23
+ const stacked = useTransformEnabled(id, 'stack-toggle')
24
+ return (
25
+ <Category series={[{ name: 'Women' }, { name: 'Men' }]} stacked={stacked} />
26
+ )
27
+ }
28
+
29
+ const DATA: CategoryWidgetData = [
30
+ [
31
+ { name: 'A', value: 45 },
32
+ { name: 'B', value: 30 },
33
+ ],
34
+ [
35
+ { name: 'A', value: 32 },
36
+ { name: 'B', value: 18 },
37
+ ],
38
+ ]
39
+
40
+ describe('Category + StackToggle composer wiring', () => {
41
+ it('default (StackToggle off) → multi-series renders one bar per series per row', () => {
42
+ const { container } = render(
43
+ <Provider id='cat-stack-off' data={DATA}>
44
+ <StackToggle />
45
+ <Wired />
46
+ </Provider>,
47
+ )
48
+ // CategoryRowMulti renders one track per series per row → 2 rows × 2 = 4.
49
+ expect(container.querySelectorAll('[data-size]').length).toBe(4)
50
+ // No breakdown text from the stacked row.
51
+ expect(screen.queryByText(/Women: 45/)).toBeNull()
52
+ })
53
+
54
+ it('clicking the stack action flips multi-series rendering to stacked rows', () => {
55
+ const { container } = render(
56
+ <Provider id='cat-stack-on' data={DATA}>
57
+ <StackToggle />
58
+ <Wired />
59
+ </Provider>,
60
+ )
61
+ fireEvent.click(screen.getByRole('button', { name: /stack|unstack/i }))
62
+ // Stacked rendering: one track per row → 2 tracks total.
63
+ expect(container.querySelectorAll('[data-size]').length).toBe(2)
64
+ // Breakdown text appears.
65
+ expect(screen.getByText('Women: 45')).toBeTruthy()
66
+ expect(screen.getByText('Men: 32')).toBeTruthy()
67
+ // Totals show in the header.
68
+ expect(screen.getByText('77')).toBeTruthy() // A: 45 + 32
69
+ expect(screen.getByText('48')).toBeTruthy() // B: 30 + 18
70
+ })
71
+
72
+ it('toggling off again restores CategoryRowMulti rendering', () => {
73
+ const { container } = render(
74
+ <Provider id='cat-stack-restore' data={DATA}>
75
+ <StackToggle />
76
+ <Wired />
77
+ </Provider>,
78
+ )
79
+ const button = screen.getByRole('button', { name: /stack|unstack/i })
80
+ fireEvent.click(button) // on
81
+ fireEvent.click(button) // off
82
+ expect(container.querySelectorAll('[data-size]').length).toBe(4)
83
+ expect(screen.queryByText(/Women: 45/)).toBeNull()
84
+ })
85
+ })