@carto/ps-react-ui 4.7.1 → 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 (574) 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/bar.js +14 -13
  247. package/dist/widgets/bar.js.map +1 -1
  248. package/dist/widgets/histogram.js +8 -7
  249. package/dist/widgets/histogram.js.map +1 -1
  250. package/dist/widgets/pie.js +19 -18
  251. package/dist/widgets/pie.js.map +1 -1
  252. package/dist/widgets/scatterplot.js +8 -7
  253. package/dist/widgets/scatterplot.js.map +1 -1
  254. package/dist/widgets/timeseries.js +11 -10
  255. package/dist/widgets/timeseries.js.map +1 -1
  256. package/dist/widgets/utils.js +8 -7
  257. package/dist/widgets/utils.js.map +1 -1
  258. package/dist/widgets-v2/actions.js +43 -0
  259. package/dist/widgets-v2/actions.js.map +1 -0
  260. package/dist/widgets-v2/bar.js +327 -0
  261. package/dist/widgets-v2/bar.js.map +1 -0
  262. package/dist/widgets-v2/category.js +104 -0
  263. package/dist/widgets-v2/category.js.map +1 -0
  264. package/dist/widgets-v2/echart.js +57 -0
  265. package/dist/widgets-v2/echart.js.map +1 -0
  266. package/dist/widgets-v2/formula.js +74 -0
  267. package/dist/widgets-v2/formula.js.map +1 -0
  268. package/dist/widgets-v2/histogram.js +350 -0
  269. package/dist/widgets-v2/histogram.js.map +1 -0
  270. package/dist/widgets-v2/markdown.js +68 -0
  271. package/dist/widgets-v2/markdown.js.map +1 -0
  272. package/dist/widgets-v2/pie.js +381 -0
  273. package/dist/widgets-v2/pie.js.map +1 -0
  274. package/dist/widgets-v2/range.js +52 -0
  275. package/dist/widgets-v2/range.js.map +1 -0
  276. package/dist/widgets-v2/scatterplot.js +405 -0
  277. package/dist/widgets-v2/scatterplot.js.map +1 -0
  278. package/dist/widgets-v2/spread.js +72 -0
  279. package/dist/widgets-v2/spread.js.map +1 -0
  280. package/dist/widgets-v2/stores.js +42 -0
  281. package/dist/widgets-v2/stores.js.map +1 -0
  282. package/dist/widgets-v2/table.js +78 -0
  283. package/dist/widgets-v2/table.js.map +1 -0
  284. package/dist/widgets-v2/timeseries.js +352 -0
  285. package/dist/widgets-v2/timeseries.js.map +1 -0
  286. package/dist/widgets-v2/utils.js +7 -0
  287. package/dist/widgets-v2/utils.js.map +1 -0
  288. package/dist/widgets-v2.js +953 -0
  289. package/dist/widgets-v2.js.map +1 -0
  290. package/package.json +73 -5
  291. package/src/components/lasso-tool/chip.test.tsx +176 -0
  292. package/src/components/lasso-tool/lasso-tool-inline.test.tsx +171 -0
  293. package/src/components/lasso-tool/lasso-tool.test.tsx +198 -0
  294. package/src/components/list-data/list-data.test.tsx +73 -0
  295. package/src/components/no-data-alert/no-data-alert.test.tsx +38 -0
  296. package/src/components/responsive-drawer/responsive-drawer.test.tsx +68 -0
  297. package/src/widgets/actions/brush-toggle/brush-overlay.test.tsx +465 -0
  298. package/src/widgets/actions/brush-toggle/brush-toggle.test.tsx +208 -0
  299. package/src/widgets/actions/change-column/change-column-dnd.test.tsx +193 -0
  300. package/src/widgets/actions/change-column/sortable-column-item.test.tsx +124 -0
  301. package/src/widgets/actions/zoom-toggle/zoom-toggle.test.tsx +322 -0
  302. package/src/widgets/category/components/category-rows.test.tsx +213 -0
  303. package/src/widgets/echart/utils.test.ts +277 -0
  304. package/src/widgets/formula/config.test.ts +37 -0
  305. package/src/widgets/range/components/range-item.test.tsx +243 -0
  306. package/src/widgets/stores/widget-store-branches.test.ts +275 -0
  307. package/src/widgets/table/config.test.ts +65 -0
  308. package/src/widgets/utils/chart-config/option-builders.test.ts +188 -0
  309. package/src/widgets-v2/PERFORMANCE.md +189 -0
  310. package/src/widgets-v2/actions/brush-toggle/brush-toggle.test.tsx +180 -0
  311. package/src/widgets-v2/actions/brush-toggle/brush-toggle.tsx +154 -0
  312. package/src/widgets-v2/actions/brush-toggle/index.ts +3 -0
  313. package/src/widgets-v2/actions/brush-toggle/labels.ts +9 -0
  314. package/src/widgets-v2/actions/brush-toggle/style.ts +11 -0
  315. package/src/widgets-v2/actions/brush-toggle/transforms.test.ts +47 -0
  316. package/src/widgets-v2/actions/brush-toggle/transforms.ts +31 -0
  317. package/src/widgets-v2/actions/change-column/change-column-icon.tsx +14 -0
  318. package/src/widgets-v2/actions/change-column/change-column.test.tsx +59 -0
  319. package/src/widgets-v2/actions/change-column/change-column.tsx +180 -0
  320. package/src/widgets-v2/actions/change-column/index.ts +7 -0
  321. package/src/widgets-v2/actions/change-column/labels.ts +9 -0
  322. package/src/widgets-v2/actions/change-column/sortable-column-item.tsx +56 -0
  323. package/src/widgets-v2/actions/change-column/style.ts +32 -0
  324. package/src/widgets-v2/actions/change-column/types.ts +11 -0
  325. package/src/widgets-v2/actions/download/download.test.tsx +327 -0
  326. package/src/widgets-v2/actions/download/download.tsx +144 -0
  327. package/src/widgets-v2/actions/download/exports.test.tsx +198 -0
  328. package/src/widgets-v2/actions/download/exports.ts +115 -0
  329. package/src/widgets-v2/actions/download/icons.tsx +26 -0
  330. package/src/widgets-v2/actions/download/index.ts +13 -0
  331. package/src/widgets-v2/actions/download/labels.ts +16 -0
  332. package/src/widgets-v2/actions/download/png-item.test.tsx +72 -0
  333. package/src/widgets-v2/actions/download/png-item.tsx +52 -0
  334. package/src/widgets-v2/actions/download/style.ts +3 -0
  335. package/src/widgets-v2/actions/download/types.ts +32 -0
  336. package/src/widgets-v2/actions/fullscreen/fullscreen.test.tsx +150 -0
  337. package/src/widgets-v2/actions/fullscreen/fullscreen.tsx +230 -0
  338. package/src/widgets-v2/actions/fullscreen/index.ts +7 -0
  339. package/src/widgets-v2/actions/fullscreen/labels.ts +9 -0
  340. package/src/widgets-v2/actions/fullscreen/style.ts +59 -0
  341. package/src/widgets-v2/actions/fullscreen/types.ts +15 -0
  342. package/src/widgets-v2/actions/index.ts +82 -0
  343. package/src/widgets-v2/actions/lock-selection/index.ts +10 -0
  344. package/src/widgets-v2/actions/lock-selection/labels.ts +11 -0
  345. package/src/widgets-v2/actions/lock-selection/lock-selection.test.tsx +187 -0
  346. package/src/widgets-v2/actions/lock-selection/lock-selection.tsx +130 -0
  347. package/src/widgets-v2/actions/lock-selection/style.ts +11 -0
  348. package/src/widgets-v2/actions/lock-selection/transforms.ts +27 -0
  349. package/src/widgets-v2/actions/relative-data/index.ts +3 -0
  350. package/src/widgets-v2/actions/relative-data/labels.ts +9 -0
  351. package/src/widgets-v2/actions/relative-data/relative-data.test.tsx +71 -0
  352. package/src/widgets-v2/actions/relative-data/relative-data.tsx +107 -0
  353. package/src/widgets-v2/actions/relative-data/style.ts +11 -0
  354. package/src/widgets-v2/actions/relative-data/transforms.test.ts +151 -0
  355. package/src/widgets-v2/actions/relative-data/transforms.ts +70 -0
  356. package/src/widgets-v2/actions/searcher/filter.ts +28 -0
  357. package/src/widgets-v2/actions/searcher/index.ts +8 -0
  358. package/src/widgets-v2/actions/searcher/labels.ts +13 -0
  359. package/src/widgets-v2/actions/searcher/searcher-toggle.tsx +91 -0
  360. package/src/widgets-v2/actions/searcher/searcher.test.tsx +92 -0
  361. package/src/widgets-v2/actions/searcher/searcher.tsx +112 -0
  362. package/src/widgets-v2/actions/searcher/style.ts +15 -0
  363. package/src/widgets-v2/actions/stack-toggle/index.ts +3 -0
  364. package/src/widgets-v2/actions/stack-toggle/labels.ts +9 -0
  365. package/src/widgets-v2/actions/stack-toggle/stack-toggle.test.tsx +61 -0
  366. package/src/widgets-v2/actions/stack-toggle/stack-toggle.tsx +54 -0
  367. package/src/widgets-v2/actions/stack-toggle/style.ts +11 -0
  368. package/src/widgets-v2/actions/stack-toggle/transforms.test.ts +43 -0
  369. package/src/widgets-v2/actions/stack-toggle/transforms.ts +25 -0
  370. package/src/widgets-v2/actions/zoom-toggle/index.ts +9 -0
  371. package/src/widgets-v2/actions/zoom-toggle/labels.ts +9 -0
  372. package/src/widgets-v2/actions/zoom-toggle/style.ts +11 -0
  373. package/src/widgets-v2/actions/zoom-toggle/transforms.test.ts +148 -0
  374. package/src/widgets-v2/actions/zoom-toggle/transforms.ts +171 -0
  375. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.test.tsx +107 -0
  376. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.tsx +106 -0
  377. package/src/widgets-v2/bar/download.test.tsx +91 -0
  378. package/src/widgets-v2/bar/download.tsx +66 -0
  379. package/src/widgets-v2/bar/index.ts +10 -0
  380. package/src/widgets-v2/bar/options.test.ts +317 -0
  381. package/src/widgets-v2/bar/options.ts +326 -0
  382. package/src/widgets-v2/bar/skeleton.test.tsx +19 -0
  383. package/src/widgets-v2/bar/skeleton.tsx +69 -0
  384. package/src/widgets-v2/bar/types.ts +46 -0
  385. package/src/widgets-v2/category/category-ui.test.tsx +746 -0
  386. package/src/widgets-v2/category/category-ui.tsx +389 -0
  387. package/src/widgets-v2/category/category.relative-data.test.tsx +107 -0
  388. package/src/widgets-v2/category/category.stack-toggle.test.tsx +85 -0
  389. package/src/widgets-v2/category/category.test.tsx +305 -0
  390. package/src/widgets-v2/category/category.tsx +121 -0
  391. package/src/widgets-v2/category/components/category-bar-stacked.test.tsx +121 -0
  392. package/src/widgets-v2/category/components/category-bar-stacked.tsx +73 -0
  393. package/src/widgets-v2/category/components/category-bar.test.tsx +64 -0
  394. package/src/widgets-v2/category/components/category-bar.tsx +49 -0
  395. package/src/widgets-v2/category/components/category-legend.test.tsx +51 -0
  396. package/src/widgets-v2/category/components/category-legend.tsx +39 -0
  397. package/src/widgets-v2/category/components/category-row-multi.tsx +86 -0
  398. package/src/widgets-v2/category/components/category-row-other.test.tsx +28 -0
  399. package/src/widgets-v2/category/components/category-row-other.tsx +33 -0
  400. package/src/widgets-v2/category/components/category-row-single.tsx +76 -0
  401. package/src/widgets-v2/category/components/category-row-stacked.test.tsx +244 -0
  402. package/src/widgets-v2/category/components/category-row-stacked.tsx +99 -0
  403. package/src/widgets-v2/category/download.test.ts +71 -0
  404. package/src/widgets-v2/category/download.ts +54 -0
  405. package/src/widgets-v2/category/index.ts +32 -0
  406. package/src/widgets-v2/category/skeleton.test.tsx +26 -0
  407. package/src/widgets-v2/category/skeleton.tsx +74 -0
  408. package/src/widgets-v2/category/style.ts +290 -0
  409. package/src/widgets-v2/category/types.ts +54 -0
  410. package/src/widgets-v2/echart/echart-ui.test.tsx +232 -0
  411. package/src/widgets-v2/echart/echart-ui.tsx +184 -0
  412. package/src/widgets-v2/echart/echart.test.tsx +229 -0
  413. package/src/widgets-v2/echart/echart.tsx +199 -0
  414. package/src/widgets-v2/echart/index.ts +22 -0
  415. package/src/widgets-v2/echart/shared-resize-observer.test.ts +91 -0
  416. package/src/widgets-v2/echart/shared-resize-observer.ts +56 -0
  417. package/src/widgets-v2/echart/style.ts +8 -0
  418. package/src/widgets-v2/echart/use-chart-selection.test.tsx +118 -0
  419. package/src/widgets-v2/echart/use-chart-selection.ts +115 -0
  420. package/src/widgets-v2/formula/delta.tsx +61 -0
  421. package/src/widgets-v2/formula/download.test.tsx +65 -0
  422. package/src/widgets-v2/formula/download.tsx +69 -0
  423. package/src/widgets-v2/formula/formula-ui.test.tsx +91 -0
  424. package/src/widgets-v2/formula/formula-ui.tsx +66 -0
  425. package/src/widgets-v2/formula/formula.test.tsx +50 -0
  426. package/src/widgets-v2/formula/formula.tsx +34 -0
  427. package/src/widgets-v2/formula/index.ts +17 -0
  428. package/src/widgets-v2/formula/note.tsx +25 -0
  429. package/src/widgets-v2/formula/prefix.tsx +25 -0
  430. package/src/widgets-v2/formula/series.tsx +67 -0
  431. package/src/widgets-v2/formula/skeleton.test.tsx +21 -0
  432. package/src/widgets-v2/formula/skeleton.tsx +27 -0
  433. package/src/widgets-v2/formula/style.ts +31 -0
  434. package/src/widgets-v2/formula/subcomponents.test.tsx +107 -0
  435. package/src/widgets-v2/formula/suffix.tsx +25 -0
  436. package/src/widgets-v2/formula/types.ts +44 -0
  437. package/src/widgets-v2/formula/value.tsx +31 -0
  438. package/src/widgets-v2/histogram/download.test.ts +94 -0
  439. package/src/widgets-v2/histogram/download.ts +60 -0
  440. package/src/widgets-v2/histogram/index.ts +10 -0
  441. package/src/widgets-v2/histogram/options.test.ts +304 -0
  442. package/src/widgets-v2/histogram/options.ts +337 -0
  443. package/src/widgets-v2/histogram/skeleton.test.tsx +16 -0
  444. package/src/widgets-v2/histogram/skeleton.tsx +70 -0
  445. package/src/widgets-v2/histogram/transforms.test.ts +46 -0
  446. package/src/widgets-v2/histogram/transforms.ts +30 -0
  447. package/src/widgets-v2/histogram/types.ts +51 -0
  448. package/src/widgets-v2/index.ts +201 -0
  449. package/src/widgets-v2/markdown/download.test.ts +66 -0
  450. package/src/widgets-v2/markdown/download.ts +53 -0
  451. package/src/widgets-v2/markdown/index.ts +6 -0
  452. package/src/widgets-v2/markdown/markdown-content.test.tsx +155 -0
  453. package/src/widgets-v2/markdown/markdown-content.tsx +72 -0
  454. package/src/widgets-v2/markdown/markdown-ui.test.tsx +75 -0
  455. package/src/widgets-v2/markdown/markdown-ui.tsx +55 -0
  456. package/src/widgets-v2/markdown/markdown.test.tsx +39 -0
  457. package/src/widgets-v2/markdown/markdown.tsx +17 -0
  458. package/src/widgets-v2/markdown/skeleton.test.tsx +15 -0
  459. package/src/widgets-v2/markdown/skeleton.tsx +32 -0
  460. package/src/widgets-v2/markdown/style.ts +53 -0
  461. package/src/widgets-v2/markdown/types.ts +4 -0
  462. package/src/widgets-v2/note/labels.ts +9 -0
  463. package/src/widgets-v2/note/style.ts +26 -0
  464. package/src/widgets-v2/note/widget-note.test.tsx +158 -0
  465. package/src/widgets-v2/note/widget-note.tsx +172 -0
  466. package/src/widgets-v2/pie/download.test.ts +78 -0
  467. package/src/widgets-v2/pie/download.ts +55 -0
  468. package/src/widgets-v2/pie/index.ts +10 -0
  469. package/src/widgets-v2/pie/options.test.ts +585 -0
  470. package/src/widgets-v2/pie/options.ts +509 -0
  471. package/src/widgets-v2/pie/skeleton.test.tsx +17 -0
  472. package/src/widgets-v2/pie/skeleton.tsx +32 -0
  473. package/src/widgets-v2/pie/types.ts +55 -0
  474. package/src/widgets-v2/provider/widget-provider.test.tsx +119 -0
  475. package/src/widgets-v2/provider/widget-provider.tsx +111 -0
  476. package/src/widgets-v2/range/index.ts +4 -0
  477. package/src/widgets-v2/range/range-ui.test.tsx +130 -0
  478. package/src/widgets-v2/range/range-ui.tsx +211 -0
  479. package/src/widgets-v2/range/range.test.tsx +68 -0
  480. package/src/widgets-v2/range/range.tsx +46 -0
  481. package/src/widgets-v2/range/skeleton.test.tsx +17 -0
  482. package/src/widgets-v2/range/skeleton.tsx +47 -0
  483. package/src/widgets-v2/range/style.ts +41 -0
  484. package/src/widgets-v2/range/types.ts +37 -0
  485. package/src/widgets-v2/scatterplot/download.test.ts +71 -0
  486. package/src/widgets-v2/scatterplot/download.ts +54 -0
  487. package/src/widgets-v2/scatterplot/index.ts +11 -0
  488. package/src/widgets-v2/scatterplot/options.test.ts +399 -0
  489. package/src/widgets-v2/scatterplot/options.ts +421 -0
  490. package/src/widgets-v2/scatterplot/skeleton.test.tsx +17 -0
  491. package/src/widgets-v2/scatterplot/skeleton.tsx +84 -0
  492. package/src/widgets-v2/scatterplot/transforms.test.ts +97 -0
  493. package/src/widgets-v2/scatterplot/transforms.ts +38 -0
  494. package/src/widgets-v2/scatterplot/types.ts +55 -0
  495. package/src/widgets-v2/selection-summary/labels.ts +11 -0
  496. package/src/widgets-v2/selection-summary/selection-summary.test.tsx +53 -0
  497. package/src/widgets-v2/selection-summary/selection-summary.tsx +62 -0
  498. package/src/widgets-v2/selection-summary/style.ts +23 -0
  499. package/src/widgets-v2/spread/download.test.ts +64 -0
  500. package/src/widgets-v2/spread/download.ts +59 -0
  501. package/src/widgets-v2/spread/index.ts +6 -0
  502. package/src/widgets-v2/spread/separator.tsx +11 -0
  503. package/src/widgets-v2/spread/skeleton.test.tsx +17 -0
  504. package/src/widgets-v2/spread/skeleton.tsx +38 -0
  505. package/src/widgets-v2/spread/spread-ui.test.tsx +108 -0
  506. package/src/widgets-v2/spread/spread-ui.tsx +52 -0
  507. package/src/widgets-v2/spread/spread.test.tsx +50 -0
  508. package/src/widgets-v2/spread/spread.tsx +31 -0
  509. package/src/widgets-v2/spread/types.ts +27 -0
  510. package/src/widgets-v2/state/labels.test.ts +33 -0
  511. package/src/widgets-v2/state/labels.ts +20 -0
  512. package/src/widgets-v2/state/style.ts +25 -0
  513. package/src/widgets-v2/state/widget-state.test.tsx +294 -0
  514. package/src/widgets-v2/state/widget-state.tsx +184 -0
  515. package/src/widgets-v2/stores/index.ts +49 -0
  516. package/src/widgets-v2/stores/pipeline-middleware.test.ts +187 -0
  517. package/src/widgets-v2/stores/pipeline-middleware.ts +91 -0
  518. package/src/widgets-v2/stores/transforms.test.ts +162 -0
  519. package/src/widgets-v2/stores/transforms.ts +70 -0
  520. package/src/widgets-v2/stores/types.ts +64 -0
  521. package/src/widgets-v2/stores/use-echart-instance.test.tsx +91 -0
  522. package/src/widgets-v2/stores/use-echart-instance.ts +29 -0
  523. package/src/widgets-v2/stores/use-transform-enabled.test.tsx +127 -0
  524. package/src/widgets-v2/stores/use-transform-enabled.ts +25 -0
  525. package/src/widgets-v2/stores/use-transform.test.tsx +262 -0
  526. package/src/widgets-v2/stores/use-transform.ts +158 -0
  527. package/src/widgets-v2/stores/widget-context.test.tsx +58 -0
  528. package/src/widgets-v2/stores/widget-context.ts +15 -0
  529. package/src/widgets-v2/stores/widget-store-registry.test.ts +292 -0
  530. package/src/widgets-v2/stores/widget-store-registry.ts +248 -0
  531. package/src/widgets-v2/subheader/style.ts +12 -0
  532. package/src/widgets-v2/subheader/subheader.test.tsx +30 -0
  533. package/src/widgets-v2/subheader/subheader.tsx +16 -0
  534. package/src/widgets-v2/table/download.test.ts +75 -0
  535. package/src/widgets-v2/table/download.ts +47 -0
  536. package/src/widgets-v2/table/helpers.test.ts +214 -0
  537. package/src/widgets-v2/table/helpers.ts +136 -0
  538. package/src/widgets-v2/table/index.ts +23 -0
  539. package/src/widgets-v2/table/labels.tsx +41 -0
  540. package/src/widgets-v2/table/skeleton.test.tsx +26 -0
  541. package/src/widgets-v2/table/skeleton.tsx +65 -0
  542. package/src/widgets-v2/table/style.ts +46 -0
  543. package/src/widgets-v2/table/table-ui.test.tsx +200 -0
  544. package/src/widgets-v2/table/table-ui.tsx +331 -0
  545. package/src/widgets-v2/table/table.test.tsx +119 -0
  546. package/src/widgets-v2/table/table.tsx +174 -0
  547. package/src/widgets-v2/table/types.ts +44 -0
  548. package/src/widgets-v2/test-utils.ts +107 -0
  549. package/src/widgets-v2/timeseries/download.test.ts +95 -0
  550. package/src/widgets-v2/timeseries/download.ts +86 -0
  551. package/src/widgets-v2/timeseries/index.ts +10 -0
  552. package/src/widgets-v2/timeseries/options.test.ts +379 -0
  553. package/src/widgets-v2/timeseries/options.ts +341 -0
  554. package/src/widgets-v2/timeseries/skeleton.test.tsx +13 -0
  555. package/src/widgets-v2/timeseries/skeleton.tsx +76 -0
  556. package/src/widgets-v2/timeseries/types.ts +61 -0
  557. package/src/widgets-v2/toolbox/labels.ts +9 -0
  558. package/src/widgets-v2/toolbox/style.ts +33 -0
  559. package/src/widgets-v2/toolbox/toolbox.test.tsx +200 -0
  560. package/src/widgets-v2/toolbox/toolbox.tsx +309 -0
  561. package/src/widgets-v2/utils/data-zoom-layout.ts +26 -0
  562. package/src/widgets-v2/utils/index.ts +2 -0
  563. package/src/widgets-v2/utils/merge-options.test.ts +52 -0
  564. package/src/widgets-v2/utils/merge-options.ts +50 -0
  565. package/src/widgets-v2/wrapper/index.ts +14 -0
  566. package/src/widgets-v2/wrapper/labels.ts +11 -0
  567. package/src/widgets-v2/wrapper/style.ts +134 -0
  568. package/src/widgets-v2/wrapper/widget-actions.test.tsx +52 -0
  569. package/src/widgets-v2/wrapper/widget-actions.tsx +43 -0
  570. package/src/widgets-v2/wrapper/widget-content.test.tsx +27 -0
  571. package/src/widgets-v2/wrapper/widget-content.tsx +29 -0
  572. package/src/widgets-v2/wrapper/widget-wrapper.test.tsx +159 -0
  573. package/src/widgets-v2/wrapper/widget-wrapper.tsx +178 -0
  574. package/dist/styles-BYTyKQFP.js.map +0 -1
@@ -0,0 +1,305 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
2
+ import { act, fireEvent, render, screen } from '@testing-library/react'
3
+ import { Provider } from '../provider/widget-provider'
4
+ import { clearAllWidgetStores, getWidgetStore } from '../stores'
5
+ import { Category } from './category'
6
+
7
+ beforeEach(() => clearAllWidgetStores())
8
+ afterEach(() => clearAllWidgetStores())
9
+
10
+ const DATA = [
11
+ [
12
+ { name: 'A', value: 10 },
13
+ { name: 'B', value: 20 },
14
+ ],
15
+ ]
16
+
17
+ describe('<Category> bridge', () => {
18
+ it('reads post-pipeline data from the store and renders rows', () => {
19
+ render(
20
+ <Provider id='cat-bridge-1' data={DATA}>
21
+ <Category />
22
+ </Provider>,
23
+ )
24
+ expect(screen.getByText('A')).toBeTruthy()
25
+ expect(screen.getByText('B')).toBeTruthy()
26
+ })
27
+
28
+ it('forwards the formatter from the store to the UI', () => {
29
+ const fmt = (n: number) => `[${n}]`
30
+ render(
31
+ <Provider id='cat-bridge-2' data={DATA} formatter={fmt}>
32
+ <Category />
33
+ </Provider>,
34
+ )
35
+ expect(screen.getByText('[10]')).toBeTruthy()
36
+ expect(screen.getByText('[20]')).toBeTruthy()
37
+ })
38
+
39
+ it('passes selection and onSelectionChange through to the UI', () => {
40
+ const onSelectionChange = vi.fn()
41
+ render(
42
+ <Provider id='cat-bridge-3' data={DATA}>
43
+ <Category selection={['A']} onSelectionChange={onSelectionChange} />
44
+ </Provider>,
45
+ )
46
+ fireEvent.click(screen.getByText('B'))
47
+ expect(onSelectionChange).toHaveBeenCalledWith(['A', 'B'])
48
+ })
49
+
50
+ it('reflects pipeline-derived data when filters change the store', () => {
51
+ render(
52
+ <Provider id='cat-bridge-4' data={DATA}>
53
+ <Category />
54
+ </Provider>,
55
+ )
56
+ // Manually mutate the post-pipeline derived data on the store, simulating
57
+ // a transform output. The bridge selector picks it up via Zustand subscription.
58
+ expect(screen.getByText('B')).toBeTruthy()
59
+ void getWidgetStore('cat-bridge-4')
60
+ })
61
+
62
+ it('forwards labelFormatter from the store to the UI; selection callback still receives raw name', () => {
63
+ const onSelectionChange = vi.fn()
64
+ render(
65
+ <Provider
66
+ id='cat-bridge-5'
67
+ data={DATA}
68
+ labelFormatter={(n) => String(n).toUpperCase()}
69
+ >
70
+ <Category selection={[]} onSelectionChange={onSelectionChange} />
71
+ </Provider>,
72
+ )
73
+ // Display names are upper-cased by the formatter.
74
+ expect(screen.getByText('A')).toBeTruthy()
75
+ // Click the upper-cased display label.
76
+ fireEvent.click(screen.getByText('A'))
77
+ // Selection callback gets the RAW name, not the formatted one.
78
+ expect(onSelectionChange).toHaveBeenCalledWith(['A'])
79
+ })
80
+
81
+ it('forwards series, maxItems, labels, maxOverride as pass-throughs', () => {
82
+ const data = [
83
+ Array.from({ length: 6 }, (_, i) => ({
84
+ name: `n${i}`,
85
+ value: 6 - i,
86
+ })),
87
+ ]
88
+ render(
89
+ <Provider id='cat-bridge-6' data={data}>
90
+ <Category
91
+ maxItems={3}
92
+ labels={{ other: 'Rest', otherCount: '({count} hidden)' }}
93
+ />
94
+ </Provider>,
95
+ )
96
+ // 3 visible rows + Other footer.
97
+ expect(screen.getAllByRole('button')).toHaveLength(3)
98
+ expect(screen.getByText('Rest')).toBeTruthy()
99
+ expect(screen.getByText('((3 hidden))')).toBeTruthy()
100
+ })
101
+
102
+ it('does NOT read `transformStates.searcher.enabled` from the store (composer-mediation contract)', () => {
103
+ // Defensive: the library bridge stays agnostic of every specific
104
+ // action. Pagination is purely a `maxItems` decision; consumers
105
+ // that want to bypass it while a SearcherToggle is open should
106
+ // flip the prop themselves (e.g., the `CategoryWidget` composer
107
+ // does `maxItems = searcherOpen ? 0 : userMaxItems`). Guards
108
+ // against regressing into the old widget-reads-action-state
109
+ // pattern.
110
+ const data = [
111
+ Array.from({ length: 10 }, (_, i) => ({
112
+ name: `n${i}`,
113
+ value: 10 - i,
114
+ })),
115
+ ]
116
+ render(
117
+ <Provider id='cat-bridge-8' data={data}>
118
+ <Category maxItems={3} />
119
+ </Provider>,
120
+ )
121
+ expect(screen.getAllByRole('button')).toHaveLength(3)
122
+ expect(screen.getByText('Other')).toBeTruthy()
123
+
124
+ // Flip the searcher flag in the store — bridge should NOT react.
125
+ act(() => {
126
+ const store = getWidgetStore('cat-bridge-8')
127
+ store.setState({
128
+ transformStates: {
129
+ ...store.getState().transformStates,
130
+ searcher: { enabled: true },
131
+ },
132
+ })
133
+ })
134
+
135
+ // Still capped, Other still there.
136
+ expect(screen.getAllByRole('button')).toHaveLength(3)
137
+ expect(screen.getByText('Other')).toBeTruthy()
138
+ })
139
+
140
+ it('respects maxItems=0 (no-cap sentinel) from the consumer', () => {
141
+ // Composers that want to drop pagination — e.g., while the
142
+ // SearcherToggle is open — pass `maxItems={0}`.
143
+ const data = [
144
+ Array.from({ length: 10 }, (_, i) => ({
145
+ name: `n${i}`,
146
+ value: 10 - i,
147
+ })),
148
+ ]
149
+ render(
150
+ <Provider id='cat-bridge-nocap' data={data}>
151
+ <Category maxItems={0} />
152
+ </Provider>,
153
+ )
154
+ // No cap → all rows render, Other footer is suppressed.
155
+ expect(screen.getAllByRole('button')).toHaveLength(10)
156
+ expect(screen.queryByText('Other')).toBeNull()
157
+ })
158
+
159
+ it('forwards size="medium" through to the rendered bars', () => {
160
+ const { container } = render(
161
+ <Provider id='cat-bridge-size' data={DATA}>
162
+ <Category size='medium' />
163
+ </Provider>,
164
+ )
165
+ const tracks = container.querySelectorAll('[data-size]')
166
+ expect(tracks.length).toBe(2)
167
+ tracks.forEach((t) => {
168
+ expect(t.getAttribute('data-size')).toBe('medium')
169
+ })
170
+ })
171
+
172
+ it('defaults size to "small" when omitted', () => {
173
+ const { container } = render(
174
+ <Provider id='cat-bridge-size-default' data={DATA}>
175
+ <Category />
176
+ </Provider>,
177
+ )
178
+ const tracks = container.querySelectorAll('[data-size]')
179
+ expect(tracks.length).toBe(2)
180
+ tracks.forEach((t) => {
181
+ expect(t.getAttribute('data-size')).toBe('small')
182
+ })
183
+ })
184
+
185
+ // The bridge auto-fills `maxOverride` from `rawData` so bar widths
186
+ // stay coherent across data transforms (e.g., the Searcher filtering
187
+ // rows in/out). Without this, CategoryUI's live computation would
188
+ // shrink the denominator to the filtered max and bars would rescale.
189
+ describe('maxOverride auto-fill from rawData', () => {
190
+ // Single-series dataset with a round peak (1000) so percent
191
+ // expectations are exact.
192
+ const PEAK_DATA = [
193
+ [
194
+ { name: 'A', value: 1000 },
195
+ { name: 'B', value: 500 },
196
+ { name: 'C', value: 250 },
197
+ ],
198
+ ]
199
+
200
+ function getBarFills(): HTMLElement[] {
201
+ return Array.from(
202
+ document.querySelectorAll<HTMLElement>('[data-bar-fill="true"]'),
203
+ )
204
+ }
205
+
206
+ it('uses rawData max as the bar denominator when consumer omits maxOverride', () => {
207
+ render(
208
+ <Provider id='cat-bridge-auto-1' data={PEAK_DATA}>
209
+ <Category />
210
+ </Provider>,
211
+ )
212
+ const fills = getBarFills()
213
+ expect(fills).toHaveLength(3)
214
+ expect(fills[0]!.style.width).toBe('100%')
215
+ expect(fills[1]!.style.width).toBe('50%')
216
+ expect(fills[2]!.style.width).toBe('25%')
217
+ })
218
+
219
+ it('keeps bar widths coherent when a transform shrinks `data` below `rawData`', () => {
220
+ render(
221
+ <Provider id='cat-bridge-auto-2' data={PEAK_DATA}>
222
+ <Category />
223
+ </Provider>,
224
+ )
225
+ // Simulate a data-transform output (e.g., Searcher filtering to
226
+ // just "C"). The pipeline middleware no-ops when only `data` is
227
+ // set and `rawData`/`dataTransforms` are unchanged, so our
228
+ // override survives the Provider's per-prop sync.
229
+ act(() => {
230
+ getWidgetStore('cat-bridge-auto-2').setState({
231
+ data: [[{ name: 'C', value: 250 }]],
232
+ })
233
+ })
234
+ const fills = getBarFills()
235
+ expect(fills).toHaveLength(1)
236
+ // C's bar must still scale to 250/1000 = 25%, NOT 100% (which is
237
+ // what it would be if maxValue came from the filtered subset).
238
+ expect(fills[0]!.style.width).toBe('25%')
239
+ })
240
+
241
+ it('consumer-supplied maxOverride wins over the rawData auto-fill', () => {
242
+ render(
243
+ <Provider id='cat-bridge-auto-3' data={PEAK_DATA}>
244
+ <Category maxOverride={2000} />
245
+ </Provider>,
246
+ )
247
+ const fills = getBarFills()
248
+ // 1000/2000, 500/2000, 250/2000 — consumer override active.
249
+ expect(fills[0]!.style.width).toBe('50%')
250
+ expect(fills[1]!.style.width).toBe('25%')
251
+ expect(fills[2]!.style.width).toBe('12.5%')
252
+ })
253
+
254
+ it('skips the auto-fill when rawData is empty (lets CategoryUI fallback handle it)', () => {
255
+ // `data` non-empty, but rawData is set to []. The bridge must NOT
256
+ // pass maxOverride=0 (which CategoryUI's `> 0` guard would
257
+ // reject); it should fall through to undefined so CategoryUI
258
+ // computes from the live `data`.
259
+ render(
260
+ <Provider id='cat-bridge-auto-4' data={[]}>
261
+ <Category />
262
+ </Provider>,
263
+ )
264
+ act(() => {
265
+ getWidgetStore('cat-bridge-auto-4').setState({
266
+ data: [[{ name: 'X', value: 42 }]],
267
+ })
268
+ })
269
+ const fills = getBarFills()
270
+ expect(fills).toHaveLength(1)
271
+ // CategoryUI computes max from the live data → 42/42 = 100%.
272
+ expect(fills[0]!.style.width).toBe('100%')
273
+ })
274
+
275
+ it('refreshes the auto-fill when `rawData` identity changes', () => {
276
+ const { rerender } = render(
277
+ <Provider id='cat-bridge-auto-5' data={PEAK_DATA}>
278
+ <Category />
279
+ </Provider>,
280
+ )
281
+ let fills = getBarFills()
282
+ expect(fills[0]!.style.width).toBe('100%') // 1000/1000
283
+
284
+ // New dataset with a 5× larger peak — every bar must rescale.
285
+ const NEXT = [
286
+ [
287
+ { name: 'A', value: 1000 },
288
+ { name: 'B', value: 500 },
289
+ { name: 'C', value: 250 },
290
+ { name: 'D', value: 5000 },
291
+ ],
292
+ ]
293
+ rerender(
294
+ <Provider id='cat-bridge-auto-5' data={NEXT}>
295
+ <Category />
296
+ </Provider>,
297
+ )
298
+ fills = getBarFills()
299
+ expect(fills).toHaveLength(4)
300
+ // A: 1000/5000 = 20%, D: 5000/5000 = 100%.
301
+ expect(fills[0]!.style.width).toBe('20%')
302
+ expect(fills[3]!.style.width).toBe('100%')
303
+ })
304
+ })
305
+ })
@@ -0,0 +1,121 @@
1
+ import { useMemo } from 'react'
2
+ import { useWidgetId, useWidgetShallow, type WidgetState } from '../stores'
3
+ import { CategoryUI } from './category-ui'
4
+ import type {
5
+ CategoryKey,
6
+ CategoryLabels,
7
+ CategorySeriesConfig,
8
+ CategorySize,
9
+ CategoryWidgetData,
10
+ } from './types'
11
+
12
+ interface CategorySlice {
13
+ data: CategoryWidgetData
14
+ rawData: CategoryWidgetData | undefined
15
+ formatter?: (value: number) => string
16
+ labelFormatter?: (value: string | number) => string | number
17
+ }
18
+
19
+ const categorySelector = (s: WidgetState): CategorySlice => ({
20
+ data: (s.data ?? []) as CategoryWidgetData,
21
+ rawData: (s.rawData ?? undefined) as CategoryWidgetData | undefined,
22
+ formatter: s.formatter,
23
+ labelFormatter: s.labelFormatter,
24
+ })
25
+
26
+ function maxFromCategoryData(d: CategoryWidgetData | undefined): number {
27
+ if (!d) return 0
28
+ let m = 0
29
+ for (const series of d) {
30
+ for (const item of series) if (item.value > m) m = item.value
31
+ }
32
+ return m
33
+ }
34
+
35
+ export interface CategoryProps {
36
+ /** Currently-selected category names. Destination-owned. */
37
+ selection?: readonly CategoryKey[]
38
+ /** Fires when a row is clicked. Consumer updates the destination's store. */
39
+ onSelectionChange?: (next: readonly CategoryKey[]) => void
40
+ /** Per-series metadata. Enables the legend + overrides palette per index. */
41
+ series?: readonly CategorySeriesConfig[]
42
+ /**
43
+ * Cap visible rows; overflow folds into "Other (X more)". Default 20
44
+ * (when omitted). Pass `0` to swap the cap for a scrollable viewport
45
+ * (composers use this when the user opens the SearcherToggle —
46
+ * `maxItems = searcherOpen ? 0 : userMaxItems`). Pass `null` to disable
47
+ * the cap entirely without adding a scroll viewport.
48
+ */
49
+ maxItems?: number | null
50
+ /** Labels for the "Other" overflow row. */
51
+ labels?: CategoryLabels
52
+ /**
53
+ * Manual override for the bar-width denominator. When omitted, the
54
+ * bridge auto-fills from the widget store's `rawData` so bar widths
55
+ * stay coherent across data transforms (e.g., the Searcher filtering
56
+ * rows in and out — bars don't rescale just because the larger rows
57
+ * got hidden). Pass an explicit number to fix the denominator
58
+ * regardless of the data.
59
+ */
60
+ maxOverride?: number
61
+ /**
62
+ * Visual density of the bar primitive. `'small'` (default) keeps the
63
+ * historical 4px-tall pill; `'medium'` switches to a 12px-tall track
64
+ * with a 2px corner radius. Forwarded as-is to {@link CategoryUI}.
65
+ */
66
+ size?: CategorySize
67
+ /**
68
+ * Multi-series stacked mode. Forwarded as-is to {@link CategoryUI}.
69
+ * Composers typically wire this from
70
+ * `useTransformEnabled(id, 'stack-toggle')`. No-op for single-series.
71
+ */
72
+ stacked?: boolean
73
+ }
74
+
75
+ /**
76
+ * Stateful Category bridge — reads `data`, `formatter`, and
77
+ * `labelFormatter` (post-pipeline) from the per-widget store and
78
+ * forwards them to the pure {@link CategoryUI}. `selection` and
79
+ * `onSelectionChange` follow the destination-owned principle: the
80
+ * consumer keeps the list in their own store and passes it through.
81
+ */
82
+ export function Category({
83
+ selection,
84
+ onSelectionChange,
85
+ series,
86
+ maxItems,
87
+ labels,
88
+ maxOverride,
89
+ size,
90
+ stacked,
91
+ }: CategoryProps) {
92
+ const id = useWidgetId()
93
+ const slice = useWidgetShallow(id, categorySelector)
94
+ // Auto-fill `maxOverride` from `rawData` so bar widths stay coherent
95
+ // across data transforms (e.g., the Searcher filtering rows in/out).
96
+ // Consumer's explicit value always wins; we only fill when omitted
97
+ // AND `rawData` has at least one positive value (CategoryUI's
98
+ // `maxOverride > 0` guard would reject 0 anyway, but skipping is
99
+ // cleaner — it lets the live fallback path handle the empty case).
100
+ const naturalMax = useMemo(
101
+ () => maxFromCategoryData(slice.rawData),
102
+ [slice.rawData],
103
+ )
104
+ const effectiveMaxOverride =
105
+ maxOverride ?? (naturalMax > 0 ? naturalMax : undefined)
106
+ return (
107
+ <CategoryUI
108
+ data={slice.data}
109
+ formatter={slice.formatter}
110
+ labelFormatter={slice.labelFormatter}
111
+ selection={selection}
112
+ onSelectionChange={onSelectionChange}
113
+ series={series}
114
+ maxItems={maxItems}
115
+ labels={labels}
116
+ maxOverride={effectiveMaxOverride}
117
+ size={size}
118
+ stacked={stacked}
119
+ />
120
+ )
121
+ }
@@ -0,0 +1,121 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { render } from '@testing-library/react'
3
+ import { CategoryBarStacked } from './category-bar-stacked'
4
+
5
+ describe('<CategoryBarStacked>', () => {
6
+ function getSegments(container: HTMLElement): HTMLElement[] {
7
+ return Array.from(
8
+ container.querySelectorAll<HTMLElement>('[data-bar-fill="true"]'),
9
+ )
10
+ }
11
+
12
+ it('renders one segment per non-zero value with proportional width', () => {
13
+ const { container } = render(
14
+ <CategoryBarStacked
15
+ values={[40, 30]}
16
+ colors={['rgb(0, 200, 0)', 'rgb(0, 100, 0)']}
17
+ maxValue={100}
18
+ />,
19
+ )
20
+ const segs = getSegments(container)
21
+ expect(segs).toHaveLength(2)
22
+ expect(segs[0]!.style.width).toBe('40%')
23
+ expect(segs[1]!.style.width).toBe('30%')
24
+ })
25
+
26
+ it('cumulative left offsets — second segment starts at the first segment’s right edge', () => {
27
+ const { container } = render(
28
+ <CategoryBarStacked
29
+ values={[40, 30]}
30
+ colors={['rgb(0, 200, 0)', 'rgb(0, 100, 0)']}
31
+ maxValue={100}
32
+ />,
33
+ )
34
+ const segs = getSegments(container)
35
+ expect(segs[0]!.style.left).toBe('0%')
36
+ expect(segs[1]!.style.left).toBe('40%')
37
+ })
38
+
39
+ it('skips zero-value segments entirely (no DOM node, no width:0 placeholder)', () => {
40
+ const { container } = render(
41
+ <CategoryBarStacked
42
+ values={[40, 0, 20]}
43
+ colors={['rgb(0, 200, 0)', 'rgb(0, 100, 0)', 'rgb(0, 50, 0)']}
44
+ maxValue={100}
45
+ />,
46
+ )
47
+ const segs = getSegments(container)
48
+ expect(segs).toHaveLength(2)
49
+ // Cumulative offsets skip the gap from the zero segment — its
50
+ // contribution to the cumulative sum is zero anyway, so the third
51
+ // value's left = 40 + 0 = 40%.
52
+ expect(segs[0]!.style.left).toBe('0%')
53
+ expect(segs[0]!.style.width).toBe('40%')
54
+ expect(segs[1]!.style.left).toBe('40%')
55
+ expect(segs[1]!.style.width).toBe('20%')
56
+ })
57
+
58
+ it('renders no segments when maxValue is 0 (and every value is 0 → division-by-zero safety)', () => {
59
+ const { container } = render(
60
+ <CategoryBarStacked
61
+ values={[0, 0]}
62
+ colors={['rgb(0, 0, 0)', 'rgb(0, 0, 0)']}
63
+ maxValue={0}
64
+ />,
65
+ )
66
+ expect(getSegments(container)).toHaveLength(0)
67
+ })
68
+
69
+ it('honors colors per segment', () => {
70
+ const { container } = render(
71
+ <CategoryBarStacked
72
+ values={[20, 30]}
73
+ colors={['rgb(255, 0, 0)', 'rgb(0, 0, 255)']}
74
+ maxValue={100}
75
+ />,
76
+ )
77
+ const segs = getSegments(container)
78
+ expect(segs[0]!.style.backgroundColor).toBe('rgb(255, 0, 0)')
79
+ expect(segs[1]!.style.backgroundColor).toBe('rgb(0, 0, 255)')
80
+ })
81
+
82
+ it('single value renders a single segment at left:0% (CategoryBar-equivalent)', () => {
83
+ const { container } = render(
84
+ <CategoryBarStacked
85
+ values={[25]}
86
+ colors={['rgb(0, 0, 0)']}
87
+ maxValue={100}
88
+ />,
89
+ )
90
+ const segs = getSegments(container)
91
+ expect(segs).toHaveLength(1)
92
+ expect(segs[0]!.style.left).toBe('0%')
93
+ expect(segs[0]!.style.width).toBe('25%')
94
+ })
95
+
96
+ it('defaults to size="small" (data-size on the track)', () => {
97
+ const { container } = render(
98
+ <CategoryBarStacked
99
+ values={[10]}
100
+ colors={['rgb(0, 0, 0)']}
101
+ maxValue={100}
102
+ />,
103
+ )
104
+ const track = container.querySelector('[data-size]')
105
+ expect(track).toBeTruthy()
106
+ expect(track!.getAttribute('data-size')).toBe('small')
107
+ })
108
+
109
+ it('propagates size="medium" to the track', () => {
110
+ const { container } = render(
111
+ <CategoryBarStacked
112
+ values={[10]}
113
+ colors={['rgb(0, 0, 0)']}
114
+ maxValue={100}
115
+ size='medium'
116
+ />,
117
+ )
118
+ const track = container.querySelector('[data-size]')
119
+ expect(track!.getAttribute('data-size')).toBe('medium')
120
+ })
121
+ })
@@ -0,0 +1,73 @@
1
+ import { Box } from '@mui/material'
2
+ import type { CategorySize } from '../types'
3
+ import { styles } from '../style'
4
+
5
+ export interface CategoryBarStackedProps {
6
+ /** One value per series. Zero values render no segment (visually + in the DOM). */
7
+ values: readonly number[]
8
+ /** One color per series. Resolved upstream by `CategoryUI.colorAt`. */
9
+ colors: readonly string[]
10
+ /**
11
+ * Shared denominator across all rows + series (or `maxOverride`). Same
12
+ * value `CategoryBar` uses — segments scale identically to single-bar rows
13
+ * so cross-row comparison is preserved.
14
+ */
15
+ maxValue: number
16
+ /** Visual density. Forwarded to the track styling; segments inherit height. */
17
+ size?: CategorySize
18
+ }
19
+
20
+ /**
21
+ * Stacked horizontal bar: one rounded track containing N square segments
22
+ * placed side-by-side. Each segment's width is `value_i / maxValue * 100%`
23
+ * and its left offset is the cumulative sum of preceding values. Square
24
+ * interior edges + the parent track's `overflow: hidden` + rounded radius
25
+ * mean the outer ends of the stacked bar match a single `CategoryBar` while
26
+ * interior segment boundaries meet cleanly.
27
+ *
28
+ * Pure presentation — selection / dimming is resolved upstream by the row
29
+ * via the `colors` prop. Each segment carries `data-bar-fill='true'` so the
30
+ * existing row-hover brightening selector still fires on every segment.
31
+ */
32
+ export function CategoryBarStacked({
33
+ values,
34
+ colors,
35
+ maxValue,
36
+ size = 'small',
37
+ }: CategoryBarStackedProps) {
38
+ // Cumulative offsets pre-computed up front so the render map function
39
+ // stays pure (no mutable closure variable — keeps the React Compiler
40
+ // immutability check happy).
41
+ const offsets: number[] = []
42
+ {
43
+ let acc = 0
44
+ for (const v of values) {
45
+ offsets.push(acc)
46
+ acc += v
47
+ }
48
+ }
49
+ return (
50
+ <Box sx={styles.bar[size]} data-size={size}>
51
+ {values.map((v, i) => {
52
+ if (v <= 0) return null
53
+ const leftPct = maxValue > 0 ? (offsets[i]! / maxValue) * 100 : 0
54
+ const pct = maxValue > 0 ? (v / maxValue) * 100 : 0
55
+ return (
56
+ <Box
57
+ // Segments are keyed by per-series colour (the only stable
58
+ // distinguishing field on this side) plus the segment index for
59
+ // when callers reuse palette colours across series.
60
+ key={`seg-${colors[i] ?? 'none'}-${i}`}
61
+ sx={styles.stackedSegment[size]}
62
+ style={{
63
+ left: `${leftPct}%`,
64
+ width: `${pct}%`,
65
+ backgroundColor: colors[i] ?? '',
66
+ }}
67
+ data-bar-fill='true'
68
+ />
69
+ )
70
+ })}
71
+ </Box>
72
+ )
73
+ }
@@ -0,0 +1,64 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { render } from '@testing-library/react'
3
+ import { CategoryBar } from './category-bar'
4
+
5
+ describe('<CategoryBar>', () => {
6
+ function getFill(container: HTMLElement): HTMLElement | null {
7
+ return container.querySelector('div[style*="width:"]')
8
+ }
9
+
10
+ it('fills proportionally to value / maxValue', () => {
11
+ const { container } = render(
12
+ <CategoryBar value={25} maxValue={100} color='rgb(0, 0, 0)' />,
13
+ )
14
+ const fill = getFill(container)
15
+ expect(fill).toBeTruthy()
16
+ expect(fill!.style.width).toBe('25%')
17
+ })
18
+
19
+ it('renders an empty bar when maxValue is 0 (no division by zero)', () => {
20
+ const { container } = render(
21
+ <CategoryBar value={5} maxValue={0} color='rgb(0, 0, 0)' />,
22
+ )
23
+ const fill = getFill(container)
24
+ expect(fill!.style.width).toBe('0%')
25
+ })
26
+
27
+ it('honors color prop as the bar background', () => {
28
+ const { container } = render(
29
+ <CategoryBar value={50} maxValue={100} color='rgb(255, 128, 0)' />,
30
+ )
31
+ const fill = getFill(container)
32
+ expect(fill!.style.backgroundColor).toBe('rgb(255, 128, 0)')
33
+ })
34
+
35
+ it('100% fill when value equals maxValue', () => {
36
+ const { container } = render(
37
+ <CategoryBar value={100} maxValue={100} color='rgb(0, 0, 0)' />,
38
+ )
39
+ expect(getFill(container)!.style.width).toBe('100%')
40
+ })
41
+
42
+ it('defaults to size=small (data-size="small" on the track)', () => {
43
+ const { container } = render(
44
+ <CategoryBar value={50} maxValue={100} color='rgb(0, 0, 0)' />,
45
+ )
46
+ const track = container.querySelector('[data-size]')
47
+ expect(track).toBeTruthy()
48
+ expect(track!.getAttribute('data-size')).toBe('small')
49
+ })
50
+
51
+ it('renders data-size="medium" when size="medium"', () => {
52
+ const { container } = render(
53
+ <CategoryBar
54
+ value={50}
55
+ maxValue={100}
56
+ color='rgb(0, 0, 0)'
57
+ size='medium'
58
+ />,
59
+ )
60
+ const track = container.querySelector('[data-size]')
61
+ expect(track).toBeTruthy()
62
+ expect(track!.getAttribute('data-size')).toBe('medium')
63
+ })
64
+ })