@carto/ps-react-ui 4.7.1 → 4.9.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 (580) 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/{styles-BYTyKQFP.js → option-builders-F-c9ELi1.js} +25 -45
  16. package/dist/option-builders-F-c9ELi1.js.map +1 -0
  17. package/dist/png-item-CS4z1iSH.js +45 -0
  18. package/dist/png-item-CS4z1iSH.js.map +1 -0
  19. package/dist/range-l4fNHLEg.js +213 -0
  20. package/dist/range-l4fNHLEg.js.map +1 -0
  21. package/dist/resolve-theme-color-BdojIw0K.js +47 -0
  22. package/dist/resolve-theme-color-BdojIw0K.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-CQCAnDLb.js +388 -0
  30. package/dist/table-CQCAnDLb.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 +46 -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 +53 -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 +43 -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 +51 -0
  143. package/dist/types/widgets-v2/index.d.ts +108 -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 +57 -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 +27 -0
  166. package/dist/types/widgets-v2/range/range.d.ts +24 -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 +54 -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 +40 -0
  216. package/dist/types/widgets-v2/table/table-ui.d.ts +44 -0
  217. package/dist/types/widgets-v2/table/table.d.ts +50 -0
  218. package/dist/types/widgets-v2/table/types.d.ts +48 -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 +60 -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/types.d.ts +25 -0
  231. package/dist/types/widgets-v2/utils/data-zoom-layout.d.ts +11 -0
  232. package/dist/types/widgets-v2/utils/index.d.ts +3 -0
  233. package/dist/types/widgets-v2/utils/merge-options.d.ts +12 -0
  234. package/dist/types/widgets-v2/utils/merge-options.test.d.ts +1 -0
  235. package/dist/types/widgets-v2/utils/resolve-theme-color.d.ts +18 -0
  236. package/dist/types/widgets-v2/utils/resolve-theme-color.test.d.ts +1 -0
  237. package/dist/types/widgets-v2/wrapper/index.d.ts +4 -0
  238. package/dist/types/widgets-v2/wrapper/labels.d.ts +6 -0
  239. package/dist/types/widgets-v2/wrapper/style.d.ts +111 -0
  240. package/dist/types/widgets-v2/wrapper/widget-actions.d.ts +22 -0
  241. package/dist/types/widgets-v2/wrapper/widget-content.d.ts +12 -0
  242. package/dist/types/widgets-v2/wrapper/widget-wrapper.d.ts +51 -0
  243. package/dist/use-transform-DXPN3nY7.js +110 -0
  244. package/dist/use-transform-DXPN3nY7.js.map +1 -0
  245. package/dist/widget-context-DTGO0Yta.js +13 -0
  246. package/dist/widget-context-DTGO0Yta.js.map +1 -0
  247. package/dist/widget-store-registry-_W4Z4xp-.js +178 -0
  248. package/dist/widget-store-registry-_W4Z4xp-.js.map +1 -0
  249. package/dist/widgets/bar.js +14 -13
  250. package/dist/widgets/bar.js.map +1 -1
  251. package/dist/widgets/histogram.js +8 -7
  252. package/dist/widgets/histogram.js.map +1 -1
  253. package/dist/widgets/pie.js +19 -18
  254. package/dist/widgets/pie.js.map +1 -1
  255. package/dist/widgets/scatterplot.js +8 -7
  256. package/dist/widgets/scatterplot.js.map +1 -1
  257. package/dist/widgets/timeseries.js +11 -10
  258. package/dist/widgets/timeseries.js.map +1 -1
  259. package/dist/widgets/utils.js +8 -7
  260. package/dist/widgets/utils.js.map +1 -1
  261. package/dist/widgets-v2/actions.js +43 -0
  262. package/dist/widgets-v2/actions.js.map +1 -0
  263. package/dist/widgets-v2/bar.js +330 -0
  264. package/dist/widgets-v2/bar.js.map +1 -0
  265. package/dist/widgets-v2/category.js +104 -0
  266. package/dist/widgets-v2/category.js.map +1 -0
  267. package/dist/widgets-v2/echart.js +57 -0
  268. package/dist/widgets-v2/echart.js.map +1 -0
  269. package/dist/widgets-v2/formula.js +74 -0
  270. package/dist/widgets-v2/formula.js.map +1 -0
  271. package/dist/widgets-v2/histogram.js +353 -0
  272. package/dist/widgets-v2/histogram.js.map +1 -0
  273. package/dist/widgets-v2/markdown.js +68 -0
  274. package/dist/widgets-v2/markdown.js.map +1 -0
  275. package/dist/widgets-v2/pie.js +387 -0
  276. package/dist/widgets-v2/pie.js.map +1 -0
  277. package/dist/widgets-v2/range.js +52 -0
  278. package/dist/widgets-v2/range.js.map +1 -0
  279. package/dist/widgets-v2/scatterplot.js +411 -0
  280. package/dist/widgets-v2/scatterplot.js.map +1 -0
  281. package/dist/widgets-v2/spread.js +72 -0
  282. package/dist/widgets-v2/spread.js.map +1 -0
  283. package/dist/widgets-v2/stores.js +42 -0
  284. package/dist/widgets-v2/stores.js.map +1 -0
  285. package/dist/widgets-v2/table.js +78 -0
  286. package/dist/widgets-v2/table.js.map +1 -0
  287. package/dist/widgets-v2/timeseries.js +358 -0
  288. package/dist/widgets-v2/timeseries.js.map +1 -0
  289. package/dist/widgets-v2/utils.js +8 -0
  290. package/dist/widgets-v2/utils.js.map +1 -0
  291. package/dist/widgets-v2.js +953 -0
  292. package/dist/widgets-v2.js.map +1 -0
  293. package/package.json +71 -3
  294. package/src/components/lasso-tool/chip.test.tsx +176 -0
  295. package/src/components/lasso-tool/lasso-tool-inline.test.tsx +171 -0
  296. package/src/components/lasso-tool/lasso-tool.test.tsx +198 -0
  297. package/src/components/list-data/list-data.test.tsx +73 -0
  298. package/src/components/no-data-alert/no-data-alert.test.tsx +38 -0
  299. package/src/components/responsive-drawer/responsive-drawer.test.tsx +68 -0
  300. package/src/widgets/actions/brush-toggle/brush-overlay.test.tsx +465 -0
  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/range/components/range-item.test.tsx +243 -0
  309. package/src/widgets/stores/widget-store-branches.test.ts +275 -0
  310. package/src/widgets/table/config.test.ts +65 -0
  311. package/src/widgets/utils/chart-config/option-builders.test.ts +188 -0
  312. package/src/widgets-v2/PERFORMANCE.md +189 -0
  313. package/src/widgets-v2/actions/brush-toggle/brush-toggle.test.tsx +180 -0
  314. package/src/widgets-v2/actions/brush-toggle/brush-toggle.tsx +154 -0
  315. package/src/widgets-v2/actions/brush-toggle/index.ts +3 -0
  316. package/src/widgets-v2/actions/brush-toggle/labels.ts +9 -0
  317. package/src/widgets-v2/actions/brush-toggle/style.ts +11 -0
  318. package/src/widgets-v2/actions/brush-toggle/transforms.test.ts +47 -0
  319. package/src/widgets-v2/actions/brush-toggle/transforms.ts +31 -0
  320. package/src/widgets-v2/actions/change-column/change-column-icon.tsx +14 -0
  321. package/src/widgets-v2/actions/change-column/change-column.test.tsx +59 -0
  322. package/src/widgets-v2/actions/change-column/change-column.tsx +180 -0
  323. package/src/widgets-v2/actions/change-column/index.ts +7 -0
  324. package/src/widgets-v2/actions/change-column/labels.ts +9 -0
  325. package/src/widgets-v2/actions/change-column/sortable-column-item.tsx +56 -0
  326. package/src/widgets-v2/actions/change-column/style.ts +32 -0
  327. package/src/widgets-v2/actions/change-column/types.ts +11 -0
  328. package/src/widgets-v2/actions/download/download.test.tsx +327 -0
  329. package/src/widgets-v2/actions/download/download.tsx +144 -0
  330. package/src/widgets-v2/actions/download/exports.test.tsx +198 -0
  331. package/src/widgets-v2/actions/download/exports.ts +115 -0
  332. package/src/widgets-v2/actions/download/icons.tsx +26 -0
  333. package/src/widgets-v2/actions/download/index.ts +13 -0
  334. package/src/widgets-v2/actions/download/labels.ts +16 -0
  335. package/src/widgets-v2/actions/download/png-item.test.tsx +72 -0
  336. package/src/widgets-v2/actions/download/png-item.tsx +52 -0
  337. package/src/widgets-v2/actions/download/style.ts +3 -0
  338. package/src/widgets-v2/actions/download/types.ts +32 -0
  339. package/src/widgets-v2/actions/fullscreen/fullscreen.test.tsx +150 -0
  340. package/src/widgets-v2/actions/fullscreen/fullscreen.tsx +230 -0
  341. package/src/widgets-v2/actions/fullscreen/index.ts +7 -0
  342. package/src/widgets-v2/actions/fullscreen/labels.ts +9 -0
  343. package/src/widgets-v2/actions/fullscreen/style.ts +59 -0
  344. package/src/widgets-v2/actions/fullscreen/types.ts +15 -0
  345. package/src/widgets-v2/actions/index.ts +82 -0
  346. package/src/widgets-v2/actions/lock-selection/index.ts +10 -0
  347. package/src/widgets-v2/actions/lock-selection/labels.ts +11 -0
  348. package/src/widgets-v2/actions/lock-selection/lock-selection.test.tsx +187 -0
  349. package/src/widgets-v2/actions/lock-selection/lock-selection.tsx +130 -0
  350. package/src/widgets-v2/actions/lock-selection/style.ts +11 -0
  351. package/src/widgets-v2/actions/lock-selection/transforms.ts +27 -0
  352. package/src/widgets-v2/actions/relative-data/index.ts +3 -0
  353. package/src/widgets-v2/actions/relative-data/labels.ts +9 -0
  354. package/src/widgets-v2/actions/relative-data/relative-data.test.tsx +71 -0
  355. package/src/widgets-v2/actions/relative-data/relative-data.tsx +107 -0
  356. package/src/widgets-v2/actions/relative-data/style.ts +11 -0
  357. package/src/widgets-v2/actions/relative-data/transforms.test.ts +151 -0
  358. package/src/widgets-v2/actions/relative-data/transforms.ts +70 -0
  359. package/src/widgets-v2/actions/searcher/filter.ts +28 -0
  360. package/src/widgets-v2/actions/searcher/index.ts +8 -0
  361. package/src/widgets-v2/actions/searcher/labels.ts +13 -0
  362. package/src/widgets-v2/actions/searcher/searcher-toggle.tsx +91 -0
  363. package/src/widgets-v2/actions/searcher/searcher.test.tsx +92 -0
  364. package/src/widgets-v2/actions/searcher/searcher.tsx +112 -0
  365. package/src/widgets-v2/actions/searcher/style.ts +15 -0
  366. package/src/widgets-v2/actions/stack-toggle/index.ts +3 -0
  367. package/src/widgets-v2/actions/stack-toggle/labels.ts +9 -0
  368. package/src/widgets-v2/actions/stack-toggle/stack-toggle.test.tsx +61 -0
  369. package/src/widgets-v2/actions/stack-toggle/stack-toggle.tsx +54 -0
  370. package/src/widgets-v2/actions/stack-toggle/style.ts +11 -0
  371. package/src/widgets-v2/actions/stack-toggle/transforms.test.ts +43 -0
  372. package/src/widgets-v2/actions/stack-toggle/transforms.ts +25 -0
  373. package/src/widgets-v2/actions/zoom-toggle/index.ts +9 -0
  374. package/src/widgets-v2/actions/zoom-toggle/labels.ts +9 -0
  375. package/src/widgets-v2/actions/zoom-toggle/style.ts +11 -0
  376. package/src/widgets-v2/actions/zoom-toggle/transforms.test.ts +148 -0
  377. package/src/widgets-v2/actions/zoom-toggle/transforms.ts +171 -0
  378. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.test.tsx +107 -0
  379. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.tsx +106 -0
  380. package/src/widgets-v2/bar/download.test.tsx +91 -0
  381. package/src/widgets-v2/bar/download.tsx +66 -0
  382. package/src/widgets-v2/bar/index.ts +10 -0
  383. package/src/widgets-v2/bar/options.test.ts +334 -0
  384. package/src/widgets-v2/bar/options.ts +332 -0
  385. package/src/widgets-v2/bar/skeleton.test.tsx +19 -0
  386. package/src/widgets-v2/bar/skeleton.tsx +69 -0
  387. package/src/widgets-v2/bar/types.ts +51 -0
  388. package/src/widgets-v2/category/category-ui.test.tsx +746 -0
  389. package/src/widgets-v2/category/category-ui.tsx +389 -0
  390. package/src/widgets-v2/category/category.relative-data.test.tsx +107 -0
  391. package/src/widgets-v2/category/category.stack-toggle.test.tsx +85 -0
  392. package/src/widgets-v2/category/category.test.tsx +305 -0
  393. package/src/widgets-v2/category/category.tsx +121 -0
  394. package/src/widgets-v2/category/components/category-bar-stacked.test.tsx +121 -0
  395. package/src/widgets-v2/category/components/category-bar-stacked.tsx +73 -0
  396. package/src/widgets-v2/category/components/category-bar.test.tsx +64 -0
  397. package/src/widgets-v2/category/components/category-bar.tsx +49 -0
  398. package/src/widgets-v2/category/components/category-legend.test.tsx +51 -0
  399. package/src/widgets-v2/category/components/category-legend.tsx +39 -0
  400. package/src/widgets-v2/category/components/category-row-multi.tsx +86 -0
  401. package/src/widgets-v2/category/components/category-row-other.test.tsx +28 -0
  402. package/src/widgets-v2/category/components/category-row-other.tsx +33 -0
  403. package/src/widgets-v2/category/components/category-row-single.tsx +76 -0
  404. package/src/widgets-v2/category/components/category-row-stacked.test.tsx +244 -0
  405. package/src/widgets-v2/category/components/category-row-stacked.tsx +99 -0
  406. package/src/widgets-v2/category/download.test.ts +71 -0
  407. package/src/widgets-v2/category/download.ts +54 -0
  408. package/src/widgets-v2/category/index.ts +32 -0
  409. package/src/widgets-v2/category/skeleton.test.tsx +26 -0
  410. package/src/widgets-v2/category/skeleton.tsx +74 -0
  411. package/src/widgets-v2/category/style.ts +290 -0
  412. package/src/widgets-v2/category/types.ts +59 -0
  413. package/src/widgets-v2/echart/echart-ui.test.tsx +232 -0
  414. package/src/widgets-v2/echart/echart-ui.tsx +184 -0
  415. package/src/widgets-v2/echart/echart.test.tsx +229 -0
  416. package/src/widgets-v2/echart/echart.tsx +199 -0
  417. package/src/widgets-v2/echart/index.ts +22 -0
  418. package/src/widgets-v2/echart/shared-resize-observer.test.ts +91 -0
  419. package/src/widgets-v2/echart/shared-resize-observer.ts +56 -0
  420. package/src/widgets-v2/echart/style.ts +8 -0
  421. package/src/widgets-v2/echart/use-chart-selection.test.tsx +118 -0
  422. package/src/widgets-v2/echart/use-chart-selection.ts +115 -0
  423. package/src/widgets-v2/formula/delta.tsx +61 -0
  424. package/src/widgets-v2/formula/download.test.tsx +65 -0
  425. package/src/widgets-v2/formula/download.tsx +69 -0
  426. package/src/widgets-v2/formula/formula-ui.test.tsx +91 -0
  427. package/src/widgets-v2/formula/formula-ui.tsx +66 -0
  428. package/src/widgets-v2/formula/formula.test.tsx +50 -0
  429. package/src/widgets-v2/formula/formula.tsx +34 -0
  430. package/src/widgets-v2/formula/index.ts +17 -0
  431. package/src/widgets-v2/formula/note.tsx +25 -0
  432. package/src/widgets-v2/formula/prefix.tsx +25 -0
  433. package/src/widgets-v2/formula/series.tsx +67 -0
  434. package/src/widgets-v2/formula/skeleton.test.tsx +21 -0
  435. package/src/widgets-v2/formula/skeleton.tsx +27 -0
  436. package/src/widgets-v2/formula/style.ts +31 -0
  437. package/src/widgets-v2/formula/subcomponents.test.tsx +107 -0
  438. package/src/widgets-v2/formula/suffix.tsx +25 -0
  439. package/src/widgets-v2/formula/types.ts +48 -0
  440. package/src/widgets-v2/formula/value.tsx +31 -0
  441. package/src/widgets-v2/histogram/download.test.ts +94 -0
  442. package/src/widgets-v2/histogram/download.ts +60 -0
  443. package/src/widgets-v2/histogram/index.ts +10 -0
  444. package/src/widgets-v2/histogram/options.test.ts +318 -0
  445. package/src/widgets-v2/histogram/options.ts +338 -0
  446. package/src/widgets-v2/histogram/skeleton.test.tsx +16 -0
  447. package/src/widgets-v2/histogram/skeleton.tsx +70 -0
  448. package/src/widgets-v2/histogram/transforms.test.ts +46 -0
  449. package/src/widgets-v2/histogram/transforms.ts +30 -0
  450. package/src/widgets-v2/histogram/types.ts +55 -0
  451. package/src/widgets-v2/index.ts +204 -0
  452. package/src/widgets-v2/markdown/download.test.ts +66 -0
  453. package/src/widgets-v2/markdown/download.ts +53 -0
  454. package/src/widgets-v2/markdown/index.ts +6 -0
  455. package/src/widgets-v2/markdown/markdown-content.test.tsx +155 -0
  456. package/src/widgets-v2/markdown/markdown-content.tsx +72 -0
  457. package/src/widgets-v2/markdown/markdown-ui.test.tsx +75 -0
  458. package/src/widgets-v2/markdown/markdown-ui.tsx +55 -0
  459. package/src/widgets-v2/markdown/markdown.test.tsx +39 -0
  460. package/src/widgets-v2/markdown/markdown.tsx +17 -0
  461. package/src/widgets-v2/markdown/skeleton.test.tsx +15 -0
  462. package/src/widgets-v2/markdown/skeleton.tsx +32 -0
  463. package/src/widgets-v2/markdown/style.ts +53 -0
  464. package/src/widgets-v2/markdown/types.ts +4 -0
  465. package/src/widgets-v2/note/labels.ts +9 -0
  466. package/src/widgets-v2/note/style.ts +26 -0
  467. package/src/widgets-v2/note/widget-note.test.tsx +158 -0
  468. package/src/widgets-v2/note/widget-note.tsx +172 -0
  469. package/src/widgets-v2/pie/download.test.ts +78 -0
  470. package/src/widgets-v2/pie/download.ts +55 -0
  471. package/src/widgets-v2/pie/index.ts +10 -0
  472. package/src/widgets-v2/pie/options.test.ts +601 -0
  473. package/src/widgets-v2/pie/options.ts +513 -0
  474. package/src/widgets-v2/pie/skeleton.test.tsx +17 -0
  475. package/src/widgets-v2/pie/skeleton.tsx +32 -0
  476. package/src/widgets-v2/pie/types.ts +62 -0
  477. package/src/widgets-v2/provider/widget-provider.test.tsx +119 -0
  478. package/src/widgets-v2/provider/widget-provider.tsx +111 -0
  479. package/src/widgets-v2/range/index.ts +4 -0
  480. package/src/widgets-v2/range/range-ui.test.tsx +136 -0
  481. package/src/widgets-v2/range/range-ui.tsx +278 -0
  482. package/src/widgets-v2/range/range.test.tsx +68 -0
  483. package/src/widgets-v2/range/range.tsx +52 -0
  484. package/src/widgets-v2/range/skeleton.test.tsx +17 -0
  485. package/src/widgets-v2/range/skeleton.tsx +47 -0
  486. package/src/widgets-v2/range/style.ts +41 -0
  487. package/src/widgets-v2/range/types.ts +37 -0
  488. package/src/widgets-v2/scatterplot/download.test.ts +71 -0
  489. package/src/widgets-v2/scatterplot/download.ts +54 -0
  490. package/src/widgets-v2/scatterplot/index.ts +11 -0
  491. package/src/widgets-v2/scatterplot/options.test.ts +411 -0
  492. package/src/widgets-v2/scatterplot/options.ts +425 -0
  493. package/src/widgets-v2/scatterplot/skeleton.test.tsx +17 -0
  494. package/src/widgets-v2/scatterplot/skeleton.tsx +84 -0
  495. package/src/widgets-v2/scatterplot/transforms.test.ts +97 -0
  496. package/src/widgets-v2/scatterplot/transforms.ts +38 -0
  497. package/src/widgets-v2/scatterplot/types.ts +59 -0
  498. package/src/widgets-v2/selection-summary/labels.ts +11 -0
  499. package/src/widgets-v2/selection-summary/selection-summary.test.tsx +53 -0
  500. package/src/widgets-v2/selection-summary/selection-summary.tsx +62 -0
  501. package/src/widgets-v2/selection-summary/style.ts +23 -0
  502. package/src/widgets-v2/spread/download.test.ts +64 -0
  503. package/src/widgets-v2/spread/download.ts +59 -0
  504. package/src/widgets-v2/spread/index.ts +6 -0
  505. package/src/widgets-v2/spread/separator.tsx +11 -0
  506. package/src/widgets-v2/spread/skeleton.test.tsx +17 -0
  507. package/src/widgets-v2/spread/skeleton.tsx +38 -0
  508. package/src/widgets-v2/spread/spread-ui.test.tsx +108 -0
  509. package/src/widgets-v2/spread/spread-ui.tsx +52 -0
  510. package/src/widgets-v2/spread/spread.test.tsx +50 -0
  511. package/src/widgets-v2/spread/spread.tsx +31 -0
  512. package/src/widgets-v2/spread/types.ts +27 -0
  513. package/src/widgets-v2/state/labels.test.ts +33 -0
  514. package/src/widgets-v2/state/labels.ts +20 -0
  515. package/src/widgets-v2/state/style.ts +25 -0
  516. package/src/widgets-v2/state/widget-state.test.tsx +294 -0
  517. package/src/widgets-v2/state/widget-state.tsx +184 -0
  518. package/src/widgets-v2/stores/index.ts +49 -0
  519. package/src/widgets-v2/stores/pipeline-middleware.test.ts +187 -0
  520. package/src/widgets-v2/stores/pipeline-middleware.ts +91 -0
  521. package/src/widgets-v2/stores/transforms.test.ts +162 -0
  522. package/src/widgets-v2/stores/transforms.ts +70 -0
  523. package/src/widgets-v2/stores/types.ts +64 -0
  524. package/src/widgets-v2/stores/use-echart-instance.test.tsx +91 -0
  525. package/src/widgets-v2/stores/use-echart-instance.ts +29 -0
  526. package/src/widgets-v2/stores/use-transform-enabled.test.tsx +127 -0
  527. package/src/widgets-v2/stores/use-transform-enabled.ts +25 -0
  528. package/src/widgets-v2/stores/use-transform.test.tsx +262 -0
  529. package/src/widgets-v2/stores/use-transform.ts +158 -0
  530. package/src/widgets-v2/stores/widget-context.test.tsx +58 -0
  531. package/src/widgets-v2/stores/widget-context.ts +15 -0
  532. package/src/widgets-v2/stores/widget-store-registry.test.ts +292 -0
  533. package/src/widgets-v2/stores/widget-store-registry.ts +248 -0
  534. package/src/widgets-v2/subheader/style.ts +12 -0
  535. package/src/widgets-v2/subheader/subheader.test.tsx +30 -0
  536. package/src/widgets-v2/subheader/subheader.tsx +16 -0
  537. package/src/widgets-v2/table/download.test.ts +75 -0
  538. package/src/widgets-v2/table/download.ts +47 -0
  539. package/src/widgets-v2/table/helpers.test.ts +214 -0
  540. package/src/widgets-v2/table/helpers.ts +136 -0
  541. package/src/widgets-v2/table/index.ts +23 -0
  542. package/src/widgets-v2/table/labels.tsx +41 -0
  543. package/src/widgets-v2/table/skeleton.test.tsx +26 -0
  544. package/src/widgets-v2/table/skeleton.tsx +65 -0
  545. package/src/widgets-v2/table/style.ts +43 -0
  546. package/src/widgets-v2/table/table-ui.test.tsx +200 -0
  547. package/src/widgets-v2/table/table-ui.tsx +364 -0
  548. package/src/widgets-v2/table/table.test.tsx +119 -0
  549. package/src/widgets-v2/table/table.tsx +179 -0
  550. package/src/widgets-v2/table/types.ts +55 -0
  551. package/src/widgets-v2/test-utils.ts +107 -0
  552. package/src/widgets-v2/timeseries/download.test.ts +95 -0
  553. package/src/widgets-v2/timeseries/download.ts +86 -0
  554. package/src/widgets-v2/timeseries/index.ts +10 -0
  555. package/src/widgets-v2/timeseries/options.test.ts +394 -0
  556. package/src/widgets-v2/timeseries/options.ts +348 -0
  557. package/src/widgets-v2/timeseries/skeleton.test.tsx +13 -0
  558. package/src/widgets-v2/timeseries/skeleton.tsx +76 -0
  559. package/src/widgets-v2/timeseries/types.ts +65 -0
  560. package/src/widgets-v2/toolbox/labels.ts +9 -0
  561. package/src/widgets-v2/toolbox/style.ts +33 -0
  562. package/src/widgets-v2/toolbox/toolbox.test.tsx +200 -0
  563. package/src/widgets-v2/toolbox/toolbox.tsx +309 -0
  564. package/src/widgets-v2/types.ts +25 -0
  565. package/src/widgets-v2/utils/data-zoom-layout.ts +26 -0
  566. package/src/widgets-v2/utils/index.ts +3 -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/utils/resolve-theme-color.test.ts +43 -0
  570. package/src/widgets-v2/utils/resolve-theme-color.ts +34 -0
  571. package/src/widgets-v2/wrapper/index.ts +14 -0
  572. package/src/widgets-v2/wrapper/labels.ts +11 -0
  573. package/src/widgets-v2/wrapper/style.ts +134 -0
  574. package/src/widgets-v2/wrapper/widget-actions.test.tsx +52 -0
  575. package/src/widgets-v2/wrapper/widget-actions.tsx +43 -0
  576. package/src/widgets-v2/wrapper/widget-content.test.tsx +27 -0
  577. package/src/widgets-v2/wrapper/widget-content.tsx +29 -0
  578. package/src/widgets-v2/wrapper/widget-wrapper.test.tsx +159 -0
  579. package/src/widgets-v2/wrapper/widget-wrapper.tsx +178 -0
  580. package/dist/styles-BYTyKQFP.js.map +0 -1
@@ -0,0 +1,130 @@
1
+ import { useCallback, useEffect, useMemo, type ComponentType } from 'react'
2
+ import { IconButton, type SvgIconProps } from '@mui/material'
3
+ import LockIcon from '@mui/icons-material/Lock'
4
+ import LockOpenIcon from '@mui/icons-material/LockOpen'
5
+ import { Tooltip } from '../../../components'
6
+ import { useTransform, useWidgetId } from '../../stores'
7
+ import type { TransformPair } from '../../stores'
8
+ import { filterByLockedItems } from './transforms'
9
+ import {
10
+ DEFAULT_LOCK_SELECTION_LABELS,
11
+ type LockSelectionLabels,
12
+ } from './labels'
13
+ import { styles } from './style'
14
+
15
+ const LOCK_SELECTION_DESCRIPTOR = {
16
+ id: 'lock-selection',
17
+ type: 'data' as const,
18
+ order: 30,
19
+ }
20
+
21
+ export type LockSelectionKey = string | number
22
+
23
+ export interface LockSelectionProps {
24
+ /**
25
+ * Currently-selected items (destination-owned). On lock, this set is
26
+ * snapshotted into `lockedItems` via `onLockChange`.
27
+ */
28
+ selection: readonly LockSelectionKey[]
29
+ /**
30
+ * Currently-locked items (destination-owned). When non-empty, the widget's
31
+ * data is filtered to these items via the registered transform.
32
+ */
33
+ lockedItems: readonly LockSelectionKey[]
34
+ /**
35
+ * Fires when the user toggles the lock. The destination is responsible for
36
+ * persisting the new locked set (and re-feeding it via `lockedItems`).
37
+ */
38
+ onLockChange: (next: readonly LockSelectionKey[]) => void
39
+ labels?: Partial<LockSelectionLabels>
40
+ /** Lock icon (default: `LockIcon`). */
41
+ lockIcon?: ComponentType<SvgIconProps>
42
+ /** Unlock icon (default: `LockOpenIcon`). */
43
+ unlockIcon?: ComponentType<SvgIconProps>
44
+ iconProps?: SvgIconProps
45
+ }
46
+
47
+ /**
48
+ * Action that pins the current selection so the widget's data filters down
49
+ * to those items even as the user changes selections. Selection and lock
50
+ * state are destination-owned; this component is a controlled UI + a data
51
+ * transform registered against the widget's pipeline.
52
+ *
53
+ * The trigger is disabled when there is nothing to lock and nothing locked.
54
+ */
55
+ export function LockSelection({
56
+ selection,
57
+ lockedItems,
58
+ onLockChange,
59
+ labels,
60
+ lockIcon: LockSvg = LockIcon,
61
+ unlockIcon: UnlockSvg = LockOpenIcon,
62
+ iconProps,
63
+ }: LockSelectionProps) {
64
+ const id = useWidgetId()
65
+ const _labels = { ...DEFAULT_LOCK_SELECTION_LABELS, ...labels }
66
+ const isLocked = lockedItems.length > 0
67
+ const canToggle = isLocked || selection.length > 0
68
+
69
+ // Pair memoized on lockedItems identity — useTransform re-registers the fn
70
+ // (which closes over the current locked set) whenever the destination feeds
71
+ // a new array. setEnabled drives the middleware-level `enabled` flag.
72
+ const pairs = useMemoPair(lockedItems)
73
+ const { enabled, setEnabled } = useTransform(id, pairs, {
74
+ initialEnabled: isLocked,
75
+ })
76
+
77
+ // Keep middleware `enabled` in sync with destination-owned `isLocked`. The
78
+ // pipeline only short-circuits the transform when enabled === false, so
79
+ // toggling here is what makes lock/unlock actually take effect.
80
+ useEffect(() => {
81
+ if (enabled !== isLocked) setEnabled(isLocked)
82
+ }, [enabled, isLocked, setEnabled])
83
+
84
+ const handleToggle = useCallback(() => {
85
+ if (isLocked) {
86
+ onLockChange([])
87
+ } else {
88
+ onLockChange([...selection])
89
+ }
90
+ }, [isLocked, onLockChange, selection])
91
+
92
+ const tooltip = !canToggle
93
+ ? _labels.disabled
94
+ : isLocked
95
+ ? _labels.unlock
96
+ : _labels.lock
97
+ const Icon = isLocked ? UnlockSvg : LockSvg
98
+
99
+ return (
100
+ <Tooltip title={tooltip}>
101
+ <span>
102
+ <IconButton
103
+ size='small'
104
+ aria-label={tooltip}
105
+ aria-pressed={isLocked}
106
+ disabled={!canToggle}
107
+ onClick={handleToggle}
108
+ sx={{ ...styles.toggle, ...(isLocked && styles.toggleActive) }}
109
+ >
110
+ <Icon fontSize='small' {...iconProps} />
111
+ </IconButton>
112
+ </span>
113
+ </Tooltip>
114
+ )
115
+ }
116
+
117
+ /**
118
+ * Builds a stable `[{ descriptor, fn }]` pair where `fn` closes over the
119
+ * latest `lockedItems`. Re-memoized whenever the array identity changes so
120
+ * `useTransform` re-registers the closure with the freshest data.
121
+ */
122
+ function useMemoPair(
123
+ lockedItems: readonly LockSelectionKey[],
124
+ ): readonly TransformPair[] {
125
+ const fn = useCallback(
126
+ (data: unknown) => filterByLockedItems(data, lockedItems),
127
+ [lockedItems],
128
+ )
129
+ return useMemo(() => [{ descriptor: LOCK_SELECTION_DESCRIPTOR, fn }], [fn])
130
+ }
@@ -0,0 +1,11 @@
1
+ import type { SxProps, Theme } from '@mui/material'
2
+
3
+ export const styles = {
4
+ toggle: {
5
+ p: 0.5,
6
+ '& .MuiSvgIcon-root': { fontSize: 20 },
7
+ },
8
+ toggleActive: {
9
+ background: (theme: Theme) => theme.palette.primary.relatedLight,
10
+ },
11
+ } satisfies Record<string, SxProps<Theme>>
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Filters a 2D series of `{name, ...}` records, keeping only items whose
3
+ * `name` is in the locked set. Multi-series shape is preserved (one inner
4
+ * array per series). Used by the LockSelection action's data transform.
5
+ */
6
+ export function filterByLockedItems(
7
+ input: unknown,
8
+ lockedItems: readonly (string | number)[],
9
+ ): unknown {
10
+ if (lockedItems.length === 0) return input
11
+ if (!Array.isArray(input)) return input
12
+ const set = new Set<string | number>(lockedItems)
13
+ return input.map((series: unknown): unknown => {
14
+ if (!Array.isArray(series)) return series
15
+ return series.filter((item: unknown) => {
16
+ if (item == null) return false
17
+ if (typeof item === 'object' && 'name' in item) {
18
+ const name = (item as { name: unknown }).name
19
+ if (typeof name === 'string' || typeof name === 'number') {
20
+ return set.has(name)
21
+ }
22
+ return false
23
+ }
24
+ return false
25
+ })
26
+ })
27
+ }
@@ -0,0 +1,3 @@
1
+ export { RelativeData, type RelativeDataProps } from './relative-data'
2
+ export { toRelativeData, createPercentFormatter } from './transforms'
3
+ export { DEFAULT_RELATIVE_DATA_LABELS, type RelativeDataLabels } from './labels'
@@ -0,0 +1,9 @@
1
+ export interface RelativeDataLabels {
2
+ on: string
3
+ off: string
4
+ }
5
+
6
+ export const DEFAULT_RELATIVE_DATA_LABELS: RelativeDataLabels = {
7
+ on: 'Show absolute values',
8
+ off: 'Show relative values',
9
+ }
@@ -0,0 +1,71 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest'
2
+ import { render } from '@testing-library/react'
3
+ import { Provider } from '../../provider/widget-provider'
4
+ import { clearAllWidgetStores, getWidgetStore } from '../../stores'
5
+ import { RelativeData } from './relative-data'
6
+
7
+ beforeEach(() => clearAllWidgetStores())
8
+ afterEach(() => clearAllWidgetStores())
9
+
10
+ const fmtA = (n: number) => `A${n}`
11
+ const fmtB = (n: number) => `B${n}`
12
+
13
+ describe('<RelativeData> — rawFormatter-driven restoration', () => {
14
+ it('Provider mirrors the formatter prop into both rawFormatter and formatter', () => {
15
+ render(
16
+ <Provider id='rd1' data={[]} formatter={fmtA}>
17
+ <RelativeData initialEnabled={false} />
18
+ </Provider>,
19
+ )
20
+ const s = getWidgetStore('rd1').getState()
21
+ expect(s.rawFormatter).toBe(fmtA)
22
+ expect(s.formatter).toBe(fmtA)
23
+ })
24
+
25
+ it('initialEnabled=true installs the percent formatter and leaves rawFormatter untouched', () => {
26
+ render(
27
+ <Provider id='rd2' data={[]} formatter={fmtA}>
28
+ <RelativeData initialEnabled={true} />
29
+ </Provider>,
30
+ )
31
+ const s = getWidgetStore('rd2').getState()
32
+ expect(s.rawFormatter).toBe(fmtA)
33
+ expect(typeof s.formatter).toBe('function')
34
+ expect(s.formatter).not.toBe(fmtA)
35
+ // Sanity: the override is the percent formatter (50 → "50%" via Intl).
36
+ expect(s.formatter?.(50)).toMatch(/%$/)
37
+ })
38
+
39
+ it('consumer prop change while enabled updates rawFormatter; effect re-applies percent', () => {
40
+ const { rerender } = render(
41
+ <Provider id='rd3' data={[]} formatter={fmtA}>
42
+ <RelativeData initialEnabled={true} />
43
+ </Provider>,
44
+ )
45
+ const store = getWidgetStore('rd3')
46
+ expect(store.getState().rawFormatter).toBe(fmtA)
47
+ const beforePercent = store.getState().formatter
48
+
49
+ rerender(
50
+ <Provider id='rd3' data={[]} formatter={fmtB}>
51
+ <RelativeData initialEnabled={true} />
52
+ </Provider>,
53
+ )
54
+ const after = store.getState()
55
+ expect(after.rawFormatter).toBe(fmtB)
56
+ // Formatter is still the percent formatter (re-applied via the effect).
57
+ expect(after.formatter).not.toBe(fmtB)
58
+ expect(after.formatter).toBe(beforePercent)
59
+ })
60
+
61
+ it('initialEnabled=false leaves formatter equal to rawFormatter', () => {
62
+ render(
63
+ <Provider id='rd4' data={[]} formatter={fmtA}>
64
+ <RelativeData initialEnabled={false} />
65
+ </Provider>,
66
+ )
67
+ const s = getWidgetStore('rd4').getState()
68
+ expect(s.formatter).toBe(s.rawFormatter)
69
+ expect(s.formatter).toBe(fmtA)
70
+ })
71
+ })
@@ -0,0 +1,107 @@
1
+ import { useEffect, useMemo, type ComponentType } from 'react'
2
+ import { IconButton, type SvgIconProps } from '@mui/material'
3
+ import PercentIcon from '@mui/icons-material/Percent'
4
+ import { Tooltip } from '../../../components'
5
+ import {
6
+ getWidgetStore,
7
+ useSingleTransform,
8
+ useWidget,
9
+ useWidgetId,
10
+ } from '../../stores'
11
+ import { createPercentFormatter, toRelativeData } from './transforms'
12
+ import { DEFAULT_RELATIVE_DATA_LABELS, type RelativeDataLabels } from './labels'
13
+ import { styles } from './style'
14
+
15
+ const DATA_DESCRIPTOR = {
16
+ id: 'relative-data',
17
+ type: 'data' as const,
18
+ order: 15,
19
+ }
20
+
21
+ export interface RelativeDataProps {
22
+ initialEnabled?: boolean
23
+ /**
24
+ * BCP-47 locale tag forwarded to `Intl.NumberFormat`. Defaults to the
25
+ * runtime locale.
26
+ */
27
+ locale?: string
28
+ labels?: Partial<RelativeDataLabels>
29
+ icon?: ComponentType<SvgIconProps>
30
+ iconProps?: SvgIconProps
31
+ /**
32
+ * Data-side transform that rewrites the widget's series into their
33
+ * relative (0–100) form. Defaults to {@link toRelativeData}, which
34
+ * handles the canonical `{ name, value }[]` shape (bar / pie /
35
+ * timeseries / category). Widgets with a different data shape pass
36
+ * their own — `toRelativeHistogramData` for histogram's `number[]`,
37
+ * `toRelativeScatterplotData` for scatter's `[x, y][]`.
38
+ *
39
+ * Should be a stable top-level reference; inline `(data) => ...`
40
+ * literals re-register the transform every render.
41
+ */
42
+ transform?: (data: unknown) => unknown
43
+ }
44
+
45
+ /**
46
+ * Toggle between absolute and relative (percentage) values.
47
+ *
48
+ * - **Data side**: a single data transform ({@link toRelativeData}) registered
49
+ * through `useSingleTransform`. When disabled, the pipeline skips it and the
50
+ * derived `data` reverts to `rawData` automatically.
51
+ * - **Formatter side**: an effect writes directly to `state.formatter`. When
52
+ * enabled it installs the Intl-based percent formatter; when disabled it
53
+ * reads `state.rawFormatter` (the consumer-supplied original, always live)
54
+ * and writes it back to `formatter`. No "original" snapshot is captured —
55
+ * `rawFormatter` is the original.
56
+ */
57
+ export function RelativeData({
58
+ initialEnabled = false,
59
+ locale,
60
+ labels,
61
+ icon: Icon = PercentIcon,
62
+ iconProps,
63
+ transform,
64
+ }: RelativeDataProps) {
65
+ const id = useWidgetId()
66
+ const _labels = { ...DEFAULT_RELATIVE_DATA_LABELS, ...labels }
67
+
68
+ const { enabled, toggle } = useSingleTransform(
69
+ id,
70
+ DATA_DESCRIPTOR,
71
+ transform ?? toRelativeData,
72
+ { initialEnabled },
73
+ )
74
+
75
+ const percentFormatter = useMemo(
76
+ () => createPercentFormatter(locale),
77
+ [locale],
78
+ )
79
+
80
+ // Subscribe to rawFormatter so the effect re-runs and re-applies after the
81
+ // consumer's formatter prop changes (Provider syncs the new prop to both
82
+ // rawFormatter and formatter — re-applying restores the percent override
83
+ // when relative is on, and tracks the new rawFormatter when off).
84
+ const rawFormatter = useWidget(id, (s) => s.rawFormatter)
85
+
86
+ useEffect(() => {
87
+ getWidgetStore(id).setState({
88
+ formatter: enabled ? percentFormatter : rawFormatter,
89
+ })
90
+ }, [id, enabled, percentFormatter, rawFormatter])
91
+
92
+ const tooltip = enabled ? _labels.on : _labels.off
93
+
94
+ return (
95
+ <Tooltip title={tooltip}>
96
+ <IconButton
97
+ size='small'
98
+ aria-label={tooltip}
99
+ aria-pressed={enabled}
100
+ onClick={toggle}
101
+ sx={{ ...styles.toggle, ...(enabled && styles.toggleActive) }}
102
+ >
103
+ <Icon fontSize='small' {...iconProps} />
104
+ </IconButton>
105
+ </Tooltip>
106
+ )
107
+ }
@@ -0,0 +1,11 @@
1
+ import type { SxProps, Theme } from '@mui/material'
2
+
3
+ export const styles = {
4
+ toggle: {
5
+ p: 0.5,
6
+ '& .MuiSvgIcon-root': { fontSize: 20 },
7
+ },
8
+ toggleActive: {
9
+ background: (theme: Theme) => theme.palette.primary.relatedLight,
10
+ },
11
+ } satisfies Record<string, SxProps<Theme>>
@@ -0,0 +1,151 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { createPercentFormatter, toRelativeData } from './transforms'
3
+
4
+ describe('toRelativeData (default — named-value shape)', () => {
5
+ it('rewrites each datum value as its share of the series total in 0-100', () => {
6
+ const input = [
7
+ [
8
+ { name: 'a', value: 25 },
9
+ { name: 'b', value: 75 },
10
+ ],
11
+ ]
12
+ expect(toRelativeData(input)).toEqual([
13
+ [
14
+ { name: 'a', value: 25 },
15
+ { name: 'b', value: 75 },
16
+ ],
17
+ ])
18
+ })
19
+
20
+ it('handles non-100 totals (50/200 = 25%)', () => {
21
+ const input = [
22
+ [
23
+ { name: 'a', value: 50 },
24
+ { name: 'b', value: 150 },
25
+ ],
26
+ ]
27
+ expect(toRelativeData(input)).toEqual([
28
+ [
29
+ { name: 'a', value: 25 },
30
+ { name: 'b', value: 75 },
31
+ ],
32
+ ])
33
+ })
34
+
35
+ it('handles multiple series independently', () => {
36
+ const input = [
37
+ [{ name: 'x', value: 10 }],
38
+ [
39
+ { name: 'x', value: 50 },
40
+ { name: 'y', value: 50 },
41
+ ],
42
+ ]
43
+ const out = toRelativeData(input) as { value: number }[][]
44
+ expect(out[0]?.[0]?.value).toBe(100)
45
+ expect(out[1]?.[0]?.value).toBe(50)
46
+ expect(out[1]?.[1]?.value).toBe(50)
47
+ })
48
+
49
+ it('preserves extra fields on each datum', () => {
50
+ const input = [[{ name: 'a', value: 10, color: '#fff' }]]
51
+ expect(toRelativeData(input)).toEqual([
52
+ [{ name: 'a', value: 100, color: '#fff' }],
53
+ ])
54
+ })
55
+
56
+ it('returns the series unchanged when total is zero', () => {
57
+ const input = [
58
+ [
59
+ { name: 'a', value: 0 },
60
+ { name: 'b', value: 0 },
61
+ ],
62
+ ]
63
+ expect(toRelativeData(input)).toEqual(input)
64
+ })
65
+
66
+ it('produces signed share-of-magnitude percentages for mixed-sign series', () => {
67
+ const input = [
68
+ [
69
+ { name: 'a', value: 1000 },
70
+ { name: 'b', value: -990 },
71
+ ],
72
+ ]
73
+ const out = toRelativeData(input) as { value: number }[][]
74
+ // Denominator is 1000 + 990 = 1990, so 1000 / 1990 ≈ 50.25%
75
+ expect(out[0]?.[0]?.value).toBeCloseTo(50.25126, 4)
76
+ expect(out[0]?.[1]?.value).toBeCloseTo(-49.74874, 4)
77
+ })
78
+
79
+ it('works for all-negative series (signed shares sum to -100)', () => {
80
+ const input = [
81
+ [
82
+ { name: 'a', value: -100 },
83
+ { name: 'b', value: -200 },
84
+ ],
85
+ ]
86
+ const out = toRelativeData(input) as { value: number }[][]
87
+ expect(out[0]?.[0]?.value).toBeCloseTo(-33.333, 2)
88
+ expect(out[0]?.[1]?.value).toBeCloseTo(-66.667, 2)
89
+ })
90
+
91
+ it('returns the input unchanged when shape does not match named-value', () => {
92
+ expect(toRelativeData(null)).toBe(null)
93
+ expect(toRelativeData('not an array')).toBe('not an array')
94
+ // A top-level array whose entries are neither arrays-of-named-value
95
+ // nor matching the predicate falls through. Each series that isn't
96
+ // a named-value array is returned as-is — that's how widgets with
97
+ // a different shape (and their own transform) avoid double-running
98
+ // through this one.
99
+ expect(toRelativeData([42])).toEqual([42])
100
+ expect(toRelativeData([[1, 2, 3]])).toEqual([[1, 2, 3]])
101
+ expect(
102
+ toRelativeData([
103
+ [
104
+ [1, 10],
105
+ [2, 20],
106
+ ],
107
+ ]),
108
+ ).toEqual([
109
+ [
110
+ [1, 10],
111
+ [2, 20],
112
+ ],
113
+ ])
114
+ })
115
+ })
116
+
117
+ describe('createPercentFormatter', () => {
118
+ it('formats 0-100 input as percentages via Intl.NumberFormat', () => {
119
+ const fmt = createPercentFormatter('en-US')
120
+ // minimumFractionDigits: 0, maximumFractionDigits: 2 — integers render
121
+ // without decimals, fractions get up to two decimal places.
122
+ expect(fmt(50)).toBe('50%')
123
+ expect(fmt(2.5)).toBe('2.5%')
124
+ expect(fmt(100)).toBe('100%')
125
+ expect(fmt(12.345)).toBe('12.35%')
126
+ })
127
+
128
+ it('respects the provided locale (en-US uses dot, es-ES uses comma)', () => {
129
+ const en = createPercentFormatter('en-US')
130
+ const es = createPercentFormatter('es-ES')
131
+ expect(en(12.3)).toContain('12.3')
132
+ // Spanish locale uses comma as decimal separator. Format strings vary by
133
+ // ICU version (some emit narrow no-break space before "%"); assert on the
134
+ // decimal separator and the digits rather than the entire output.
135
+ const esOut = es(12.3)
136
+ expect(esOut).toContain('12,3')
137
+ expect(esOut).toContain('%')
138
+ })
139
+
140
+ it('passes through non-finite values as their string form', () => {
141
+ const fmt = createPercentFormatter('en-US')
142
+ expect(fmt(NaN)).toBe('NaN')
143
+ expect(fmt(Infinity)).toBe('Infinity')
144
+ })
145
+
146
+ it('falls back to runtime default locale when none is provided', () => {
147
+ const fmt = createPercentFormatter()
148
+ // Whatever locale the runtime uses, 50 should produce a string ending in '%'
149
+ expect(fmt(50)).toMatch(/%$/)
150
+ })
151
+ })
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Default data-side transform for `RelativeData`: rewrite each
3
+ * `{ name, value }` datum's `value` to its share of the series total
4
+ * expressed as 0–100 (matches v1's range). The companion percent
5
+ * formatter divides by 100 so it can call `Intl.NumberFormat` with
6
+ * `style: 'percent'`.
7
+ *
8
+ * Used by widgets whose series are arrays of `{ name, value }`
9
+ * objects — bar, pie, timeseries, category. Widgets with a different
10
+ * data shape pass their own transform via
11
+ * `<RelativeData transform={...} />`; see `widgets-v2/histogram` and
12
+ * `widgets-v2/scatterplot` for in-tree examples.
13
+ *
14
+ * The denominator is the sum of |value| across the series so mixed-sign
15
+ * series (e.g. cashflow with inflows + outflows) produce sane signed
16
+ * shares-of-magnitude. A series whose total magnitude is zero (all-zero
17
+ * or empty input) is returned unchanged so a stalled or empty data set
18
+ * doesn't show misleading 0% values. Series whose shape doesn't match
19
+ * the named-value pattern fall through untouched.
20
+ */
21
+
22
+ interface NamedValue {
23
+ name: unknown
24
+ value: number
25
+ [k: string]: unknown
26
+ }
27
+
28
+ function isNamedValueArray(v: unknown): v is NamedValue[] {
29
+ if (!Array.isArray(v)) return false
30
+ return v.every(
31
+ (item) =>
32
+ item != null &&
33
+ typeof item === 'object' &&
34
+ 'value' in item &&
35
+ typeof (item as { value: unknown }).value === 'number',
36
+ )
37
+ }
38
+
39
+ export const toRelativeData = (input: unknown): unknown => {
40
+ if (!Array.isArray(input)) return input
41
+ return input.map((series: unknown): unknown => {
42
+ if (!isNamedValueArray(series)) return series
43
+ const total = series.reduce((acc, d) => acc + Math.abs(d.value), 0)
44
+ if (total <= 0) return series
45
+ return series.map((d) => ({ ...d, value: (d.value / total) * 100 }))
46
+ })
47
+ }
48
+
49
+ /**
50
+ * Build a percent formatter using `Intl.NumberFormat`. The returned function
51
+ * expects values in the 0–100 range (output of {@link toRelativeData}) and
52
+ * divides by 100 internally before calling `style: 'percent'`.
53
+ *
54
+ * Locale: passed straight to `Intl.NumberFormat`. Falls back to the runtime
55
+ * default when omitted.
56
+ */
57
+ export function createPercentFormatter(
58
+ locale?: string,
59
+ ): (value: number) => string {
60
+ const fmt = new Intl.NumberFormat(locale, {
61
+ style: 'percent',
62
+ minimumFractionDigits: 0,
63
+ maximumFractionDigits: 2,
64
+ })
65
+ return (value: number) => {
66
+ if (typeof value !== 'number' || !Number.isFinite(value))
67
+ return String(value)
68
+ return fmt.format(value / 100)
69
+ }
70
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Filters a 2D series of `{name, ...}` records by case-insensitive substring on
3
+ * the `name` field. Keeps the dataset shape (one inner array per series).
4
+ * Used by the Searcher action's data transform.
5
+ */
6
+ export function filterBySearchText(input: unknown, search: string): unknown {
7
+ if (!search) return input
8
+ const needle = search.toLowerCase()
9
+ if (!Array.isArray(input)) return input
10
+ return input.map((series: unknown): unknown => {
11
+ if (!Array.isArray(series)) return series
12
+ return series.filter((item: unknown) => {
13
+ if (item == null) return false
14
+ if (typeof item === 'object' && 'name' in item) {
15
+ const rawName = (item as { name: unknown }).name
16
+ const name = rawName == null ? '' : stringifyPrimitive(rawName)
17
+ return name.toLowerCase().includes(needle)
18
+ }
19
+ return stringifyPrimitive(item).toLowerCase().includes(needle)
20
+ })
21
+ })
22
+ }
23
+
24
+ function stringifyPrimitive(v: unknown): string {
25
+ if (typeof v === 'string') return v
26
+ if (typeof v === 'number' || typeof v === 'boolean') return String(v)
27
+ return ''
28
+ }
@@ -0,0 +1,8 @@
1
+ export { Searcher, type SearcherProps } from './searcher'
2
+ export {
3
+ SearcherToggle,
4
+ setSearcherText,
5
+ type SearcherToggleProps,
6
+ } from './searcher-toggle'
7
+ export { filterBySearchText } from './filter'
8
+ export { DEFAULT_SEARCHER_LABELS, type SearcherLabels } from './labels'
@@ -0,0 +1,13 @@
1
+ export interface SearcherLabels {
2
+ toggle: string
3
+ placeholder: string
4
+ clearAriaLabel: string
5
+ noResults: string
6
+ }
7
+
8
+ export const DEFAULT_SEARCHER_LABELS: SearcherLabels = {
9
+ toggle: 'Search',
10
+ placeholder: 'Search…',
11
+ clearAriaLabel: 'Clear search',
12
+ noResults: 'No matches.',
13
+ }