@carto/ps-react-ui 4.7.0 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (578) hide show
  1. package/dist/category-DwaeYjpX.js +656 -0
  2. package/dist/category-DwaeYjpX.js.map +1 -0
  3. package/dist/change-column-Cidl_M-4.js +1110 -0
  4. package/dist/change-column-Cidl_M-4.js.map +1 -0
  5. package/dist/data-zoom-layout-BH0LPwSy.js +28 -0
  6. package/dist/data-zoom-layout-BH0LPwSy.js.map +1 -0
  7. package/dist/echart-CU0KmClP.js +176 -0
  8. package/dist/echart-CU0KmClP.js.map +1 -0
  9. package/dist/exports-Cx-f6m6U.js +63 -0
  10. package/dist/exports-Cx-f6m6U.js.map +1 -0
  11. package/dist/formula-DuC0NQLH.js +79 -0
  12. package/dist/formula-DuC0NQLH.js.map +1 -0
  13. package/dist/markdown-BD1jcknS.js +8326 -0
  14. package/dist/markdown-BD1jcknS.js.map +1 -0
  15. package/dist/merge-options-DCkkHZIf.js +34 -0
  16. package/dist/merge-options-DCkkHZIf.js.map +1 -0
  17. package/dist/{styles-BYTyKQFP.js → option-builders-F-c9ELi1.js} +25 -45
  18. package/dist/option-builders-F-c9ELi1.js.map +1 -0
  19. package/dist/png-item-CS4z1iSH.js +45 -0
  20. package/dist/png-item-CS4z1iSH.js.map +1 -0
  21. package/dist/range-DsqTjSpg.js +186 -0
  22. package/dist/range-DsqTjSpg.js.map +1 -0
  23. package/dist/spread-CTuIXZSM.js +67 -0
  24. package/dist/spread-CTuIXZSM.js.map +1 -0
  25. package/dist/style-DVnT6HC1.js +131 -0
  26. package/dist/style-DVnT6HC1.js.map +1 -0
  27. package/dist/styles-cohnxh9F.js +23 -0
  28. package/dist/styles-cohnxh9F.js.map +1 -0
  29. package/dist/table-HIpXuq4G.js +390 -0
  30. package/dist/table-HIpXuq4G.js.map +1 -0
  31. package/dist/transforms-Cdx4fkU5.js +106 -0
  32. package/dist/transforms-Cdx4fkU5.js.map +1 -0
  33. package/dist/types/widgets/echart/utils.test.d.ts +1 -0
  34. package/dist/types/widgets/formula/config.test.d.ts +1 -0
  35. package/dist/types/widgets/stores/widget-store-branches.test.d.ts +1 -0
  36. package/dist/types/widgets/table/config.test.d.ts +1 -0
  37. package/dist/types/widgets-v2/actions/brush-toggle/brush-toggle.d.ts +56 -0
  38. package/dist/types/widgets-v2/actions/brush-toggle/index.d.ts +3 -0
  39. package/dist/types/widgets-v2/actions/brush-toggle/labels.d.ts +5 -0
  40. package/dist/types/widgets-v2/actions/brush-toggle/style.d.ts +12 -0
  41. package/dist/types/widgets-v2/actions/brush-toggle/transforms.d.ts +11 -0
  42. package/dist/types/widgets-v2/actions/brush-toggle/transforms.test.d.ts +1 -0
  43. package/dist/types/widgets-v2/actions/change-column/change-column-icon.d.ts +2 -0
  44. package/dist/types/widgets-v2/actions/change-column/change-column.d.ts +29 -0
  45. package/dist/types/widgets-v2/actions/change-column/index.d.ts +3 -0
  46. package/dist/types/widgets-v2/actions/change-column/labels.d.ts +5 -0
  47. package/dist/types/widgets-v2/actions/change-column/sortable-column-item.d.ts +14 -0
  48. package/dist/types/widgets-v2/actions/change-column/style.d.ts +33 -0
  49. package/dist/types/widgets-v2/actions/change-column/types.d.ts +10 -0
  50. package/dist/types/widgets-v2/actions/download/download.d.ts +18 -0
  51. package/dist/types/widgets-v2/actions/download/exports.d.ts +37 -0
  52. package/dist/types/widgets-v2/actions/download/icons.d.ts +12 -0
  53. package/dist/types/widgets-v2/actions/download/index.d.ts +6 -0
  54. package/dist/types/widgets-v2/actions/download/labels.d.ts +11 -0
  55. package/dist/types/widgets-v2/actions/download/png-item.d.ts +24 -0
  56. package/dist/types/widgets-v2/actions/download/style.d.ts +1 -0
  57. package/dist/types/widgets-v2/actions/download/types.d.ts +35 -0
  58. package/dist/types/widgets-v2/actions/fullscreen/fullscreen.d.ts +59 -0
  59. package/dist/types/widgets-v2/actions/fullscreen/index.d.ts +3 -0
  60. package/dist/types/widgets-v2/actions/fullscreen/labels.d.ts +5 -0
  61. package/dist/types/widgets-v2/actions/fullscreen/style.d.ts +48 -0
  62. package/dist/types/widgets-v2/actions/fullscreen/types.d.ts +14 -0
  63. package/dist/types/widgets-v2/actions/index.d.ts +9 -0
  64. package/dist/types/widgets-v2/actions/lock-selection/index.d.ts +3 -0
  65. package/dist/types/widgets-v2/actions/lock-selection/labels.d.ts +6 -0
  66. package/dist/types/widgets-v2/actions/lock-selection/lock-selection.d.ts +36 -0
  67. package/dist/types/widgets-v2/actions/lock-selection/style.d.ts +12 -0
  68. package/dist/types/widgets-v2/actions/lock-selection/transforms.d.ts +6 -0
  69. package/dist/types/widgets-v2/actions/relative-data/index.d.ts +3 -0
  70. package/dist/types/widgets-v2/actions/relative-data/labels.d.ts +5 -0
  71. package/dist/types/widgets-v2/actions/relative-data/relative-data.d.ts +39 -0
  72. package/dist/types/widgets-v2/actions/relative-data/style.d.ts +12 -0
  73. package/dist/types/widgets-v2/actions/relative-data/transforms.d.ts +30 -0
  74. package/dist/types/widgets-v2/actions/relative-data/transforms.test.d.ts +1 -0
  75. package/dist/types/widgets-v2/actions/searcher/filter.d.ts +6 -0
  76. package/dist/types/widgets-v2/actions/searcher/index.d.ts +4 -0
  77. package/dist/types/widgets-v2/actions/searcher/labels.d.ts +7 -0
  78. package/dist/types/widgets-v2/actions/searcher/searcher-toggle.d.ts +23 -0
  79. package/dist/types/widgets-v2/actions/searcher/searcher.d.ts +11 -0
  80. package/dist/types/widgets-v2/actions/searcher/style.d.ts +16 -0
  81. package/dist/types/widgets-v2/actions/stack-toggle/index.d.ts +3 -0
  82. package/dist/types/widgets-v2/actions/stack-toggle/labels.d.ts +5 -0
  83. package/dist/types/widgets-v2/actions/stack-toggle/stack-toggle.d.ts +10 -0
  84. package/dist/types/widgets-v2/actions/stack-toggle/style.d.ts +12 -0
  85. package/dist/types/widgets-v2/actions/stack-toggle/transforms.d.ts +13 -0
  86. package/dist/types/widgets-v2/actions/stack-toggle/transforms.test.d.ts +1 -0
  87. package/dist/types/widgets-v2/actions/zoom-toggle/index.d.ts +3 -0
  88. package/dist/types/widgets-v2/actions/zoom-toggle/labels.d.ts +5 -0
  89. package/dist/types/widgets-v2/actions/zoom-toggle/style.d.ts +12 -0
  90. package/dist/types/widgets-v2/actions/zoom-toggle/transforms.d.ts +51 -0
  91. package/dist/types/widgets-v2/actions/zoom-toggle/transforms.test.d.ts +1 -0
  92. package/dist/types/widgets-v2/actions/zoom-toggle/zoom-toggle.d.ts +35 -0
  93. package/dist/types/widgets-v2/bar/download.d.ts +24 -0
  94. package/dist/types/widgets-v2/bar/index.d.ts +4 -0
  95. package/dist/types/widgets-v2/bar/options.d.ts +43 -0
  96. package/dist/types/widgets-v2/bar/options.test.d.ts +1 -0
  97. package/dist/types/widgets-v2/bar/skeleton.d.ts +6 -0
  98. package/dist/types/widgets-v2/bar/types.d.ts +41 -0
  99. package/dist/types/widgets-v2/category/category-ui.d.ts +81 -0
  100. package/dist/types/widgets-v2/category/category.d.ts +48 -0
  101. package/dist/types/widgets-v2/category/components/category-bar-stacked.d.ts +28 -0
  102. package/dist/types/widgets-v2/category/components/category-bar.d.ts +23 -0
  103. package/dist/types/widgets-v2/category/components/category-legend.d.ts +18 -0
  104. package/dist/types/widgets-v2/category/components/category-row-multi.d.ts +31 -0
  105. package/dist/types/widgets-v2/category/components/category-row-other.d.ts +13 -0
  106. package/dist/types/widgets-v2/category/components/category-row-single.d.ts +28 -0
  107. package/dist/types/widgets-v2/category/components/category-row-stacked.d.ts +38 -0
  108. package/dist/types/widgets-v2/category/download.d.ts +16 -0
  109. package/dist/types/widgets-v2/category/download.test.d.ts +1 -0
  110. package/dist/types/widgets-v2/category/index.d.ts +10 -0
  111. package/dist/types/widgets-v2/category/skeleton.d.ts +11 -0
  112. package/dist/types/widgets-v2/category/style.d.ts +166 -0
  113. package/dist/types/widgets-v2/category/types.d.ts +49 -0
  114. package/dist/types/widgets-v2/echart/echart-ui.d.ts +44 -0
  115. package/dist/types/widgets-v2/echart/echart.d.ts +75 -0
  116. package/dist/types/widgets-v2/echart/index.d.ts +4 -0
  117. package/dist/types/widgets-v2/echart/shared-resize-observer.d.ts +5 -0
  118. package/dist/types/widgets-v2/echart/shared-resize-observer.test.d.ts +1 -0
  119. package/dist/types/widgets-v2/echart/style.d.ts +6 -0
  120. package/dist/types/widgets-v2/echart/use-chart-selection.d.ts +51 -0
  121. package/dist/types/widgets-v2/formula/delta.d.ts +22 -0
  122. package/dist/types/widgets-v2/formula/download.d.ts +20 -0
  123. package/dist/types/widgets-v2/formula/formula-ui.d.ts +20 -0
  124. package/dist/types/widgets-v2/formula/formula.d.ts +8 -0
  125. package/dist/types/widgets-v2/formula/index.d.ts +11 -0
  126. package/dist/types/widgets-v2/formula/note.d.ts +11 -0
  127. package/dist/types/widgets-v2/formula/prefix.d.ts +12 -0
  128. package/dist/types/widgets-v2/formula/series.d.ts +16 -0
  129. package/dist/types/widgets-v2/formula/skeleton.d.ts +4 -0
  130. package/dist/types/widgets-v2/formula/style.d.ts +29 -0
  131. package/dist/types/widgets-v2/formula/suffix.d.ts +12 -0
  132. package/dist/types/widgets-v2/formula/types.d.ts +40 -0
  133. package/dist/types/widgets-v2/formula/value.d.ts +14 -0
  134. package/dist/types/widgets-v2/histogram/download.d.ts +17 -0
  135. package/dist/types/widgets-v2/histogram/download.test.d.ts +1 -0
  136. package/dist/types/widgets-v2/histogram/index.d.ts +5 -0
  137. package/dist/types/widgets-v2/histogram/options.d.ts +42 -0
  138. package/dist/types/widgets-v2/histogram/options.test.d.ts +1 -0
  139. package/dist/types/widgets-v2/histogram/skeleton.d.ts +9 -0
  140. package/dist/types/widgets-v2/histogram/transforms.d.ts +17 -0
  141. package/dist/types/widgets-v2/histogram/transforms.test.d.ts +1 -0
  142. package/dist/types/widgets-v2/histogram/types.d.ts +47 -0
  143. package/dist/types/widgets-v2/index.d.ts +107 -0
  144. package/dist/types/widgets-v2/markdown/download.d.ts +16 -0
  145. package/dist/types/widgets-v2/markdown/download.test.d.ts +1 -0
  146. package/dist/types/widgets-v2/markdown/index.d.ts +6 -0
  147. package/dist/types/widgets-v2/markdown/markdown-content.d.ts +34 -0
  148. package/dist/types/widgets-v2/markdown/markdown-ui.d.ts +12 -0
  149. package/dist/types/widgets-v2/markdown/markdown.d.ts +6 -0
  150. package/dist/types/widgets-v2/markdown/skeleton.d.ts +4 -0
  151. package/dist/types/widgets-v2/markdown/style.d.ts +61 -0
  152. package/dist/types/widgets-v2/markdown/types.d.ts +4 -0
  153. package/dist/types/widgets-v2/note/labels.d.ts +5 -0
  154. package/dist/types/widgets-v2/note/style.d.ts +26 -0
  155. package/dist/types/widgets-v2/note/widget-note.d.ts +46 -0
  156. package/dist/types/widgets-v2/pie/download.d.ts +17 -0
  157. package/dist/types/widgets-v2/pie/download.test.d.ts +1 -0
  158. package/dist/types/widgets-v2/pie/index.d.ts +4 -0
  159. package/dist/types/widgets-v2/pie/options.d.ts +35 -0
  160. package/dist/types/widgets-v2/pie/options.test.d.ts +1 -0
  161. package/dist/types/widgets-v2/pie/skeleton.d.ts +4 -0
  162. package/dist/types/widgets-v2/pie/types.d.ts +50 -0
  163. package/dist/types/widgets-v2/provider/widget-provider.d.ts +32 -0
  164. package/dist/types/widgets-v2/range/index.d.ts +4 -0
  165. package/dist/types/widgets-v2/range/range-ui.d.ts +19 -0
  166. package/dist/types/widgets-v2/range/range.d.ts +19 -0
  167. package/dist/types/widgets-v2/range/skeleton.d.ts +9 -0
  168. package/dist/types/widgets-v2/range/style.d.ts +40 -0
  169. package/dist/types/widgets-v2/range/types.d.ts +37 -0
  170. package/dist/types/widgets-v2/scatterplot/download.d.ts +16 -0
  171. package/dist/types/widgets-v2/scatterplot/download.test.d.ts +1 -0
  172. package/dist/types/widgets-v2/scatterplot/index.d.ts +5 -0
  173. package/dist/types/widgets-v2/scatterplot/options.d.ts +42 -0
  174. package/dist/types/widgets-v2/scatterplot/options.test.d.ts +1 -0
  175. package/dist/types/widgets-v2/scatterplot/skeleton.d.ts +12 -0
  176. package/dist/types/widgets-v2/scatterplot/transforms.d.ts +17 -0
  177. package/dist/types/widgets-v2/scatterplot/transforms.test.d.ts +1 -0
  178. package/dist/types/widgets-v2/scatterplot/types.d.ts +50 -0
  179. package/dist/types/widgets-v2/selection-summary/labels.d.ts +6 -0
  180. package/dist/types/widgets-v2/selection-summary/selection-summary.d.ts +22 -0
  181. package/dist/types/widgets-v2/selection-summary/style.d.ts +23 -0
  182. package/dist/types/widgets-v2/spread/download.d.ts +15 -0
  183. package/dist/types/widgets-v2/spread/download.test.d.ts +1 -0
  184. package/dist/types/widgets-v2/spread/index.d.ts +6 -0
  185. package/dist/types/widgets-v2/spread/separator.d.ts +7 -0
  186. package/dist/types/widgets-v2/spread/skeleton.d.ts +9 -0
  187. package/dist/types/widgets-v2/spread/spread-ui.d.ts +18 -0
  188. package/dist/types/widgets-v2/spread/spread.d.ts +5 -0
  189. package/dist/types/widgets-v2/spread/types.d.ts +25 -0
  190. package/dist/types/widgets-v2/state/labels.d.ts +7 -0
  191. package/dist/types/widgets-v2/state/labels.test.d.ts +1 -0
  192. package/dist/types/widgets-v2/state/style.d.ts +19 -0
  193. package/dist/types/widgets-v2/state/widget-state.d.ts +19 -0
  194. package/dist/types/widgets-v2/stores/index.d.ts +8 -0
  195. package/dist/types/widgets-v2/stores/pipeline-middleware.d.ts +5 -0
  196. package/dist/types/widgets-v2/stores/pipeline-middleware.test.d.ts +1 -0
  197. package/dist/types/widgets-v2/stores/transforms.d.ts +4 -0
  198. package/dist/types/widgets-v2/stores/transforms.test.d.ts +1 -0
  199. package/dist/types/widgets-v2/stores/types.d.ts +55 -0
  200. package/dist/types/widgets-v2/stores/use-echart-instance.d.ts +15 -0
  201. package/dist/types/widgets-v2/stores/use-transform-enabled.d.ts +17 -0
  202. package/dist/types/widgets-v2/stores/use-transform.d.ts +12 -0
  203. package/dist/types/widgets-v2/stores/widget-context.d.ts +2 -0
  204. package/dist/types/widgets-v2/stores/widget-store-registry.d.ts +74 -0
  205. package/dist/types/widgets-v2/stores/widget-store-registry.test.d.ts +1 -0
  206. package/dist/types/widgets-v2/subheader/style.d.ts +10 -0
  207. package/dist/types/widgets-v2/subheader/subheader.d.ts +11 -0
  208. package/dist/types/widgets-v2/table/download.d.ts +18 -0
  209. package/dist/types/widgets-v2/table/download.test.d.ts +1 -0
  210. package/dist/types/widgets-v2/table/helpers.d.ts +32 -0
  211. package/dist/types/widgets-v2/table/helpers.test.d.ts +1 -0
  212. package/dist/types/widgets-v2/table/index.d.ts +7 -0
  213. package/dist/types/widgets-v2/table/labels.d.ts +22 -0
  214. package/dist/types/widgets-v2/table/skeleton.d.ts +22 -0
  215. package/dist/types/widgets-v2/table/style.d.ts +44 -0
  216. package/dist/types/widgets-v2/table/table-ui.d.ts +38 -0
  217. package/dist/types/widgets-v2/table/table.d.ts +50 -0
  218. package/dist/types/widgets-v2/table/types.d.ts +37 -0
  219. package/dist/types/widgets-v2/test-utils.d.ts +52 -0
  220. package/dist/types/widgets-v2/timeseries/download.d.ts +17 -0
  221. package/dist/types/widgets-v2/timeseries/download.test.d.ts +1 -0
  222. package/dist/types/widgets-v2/timeseries/index.d.ts +4 -0
  223. package/dist/types/widgets-v2/timeseries/options.d.ts +39 -0
  224. package/dist/types/widgets-v2/timeseries/options.test.d.ts +1 -0
  225. package/dist/types/widgets-v2/timeseries/skeleton.d.ts +8 -0
  226. package/dist/types/widgets-v2/timeseries/types.d.ts +56 -0
  227. package/dist/types/widgets-v2/toolbox/labels.d.ts +5 -0
  228. package/dist/types/widgets-v2/toolbox/style.d.ts +30 -0
  229. package/dist/types/widgets-v2/toolbox/toolbox.d.ts +49 -0
  230. package/dist/types/widgets-v2/utils/data-zoom-layout.d.ts +11 -0
  231. package/dist/types/widgets-v2/utils/index.d.ts +2 -0
  232. package/dist/types/widgets-v2/utils/merge-options.d.ts +12 -0
  233. package/dist/types/widgets-v2/utils/merge-options.test.d.ts +1 -0
  234. package/dist/types/widgets-v2/wrapper/index.d.ts +4 -0
  235. package/dist/types/widgets-v2/wrapper/labels.d.ts +6 -0
  236. package/dist/types/widgets-v2/wrapper/style.d.ts +111 -0
  237. package/dist/types/widgets-v2/wrapper/widget-actions.d.ts +22 -0
  238. package/dist/types/widgets-v2/wrapper/widget-content.d.ts +12 -0
  239. package/dist/types/widgets-v2/wrapper/widget-wrapper.d.ts +51 -0
  240. package/dist/use-transform-DXPN3nY7.js +110 -0
  241. package/dist/use-transform-DXPN3nY7.js.map +1 -0
  242. package/dist/widget-context-DTGO0Yta.js +13 -0
  243. package/dist/widget-context-DTGO0Yta.js.map +1 -0
  244. package/dist/widget-store-registry-_W4Z4xp-.js +178 -0
  245. package/dist/widget-store-registry-_W4Z4xp-.js.map +1 -0
  246. package/dist/widgets/actions.js +688 -668
  247. package/dist/widgets/actions.js.map +1 -1
  248. package/dist/widgets/bar.js +14 -13
  249. package/dist/widgets/bar.js.map +1 -1
  250. package/dist/widgets/histogram.js +38 -37
  251. package/dist/widgets/histogram.js.map +1 -1
  252. package/dist/widgets/pie.js +19 -18
  253. package/dist/widgets/pie.js.map +1 -1
  254. package/dist/widgets/scatterplot.js +8 -7
  255. package/dist/widgets/scatterplot.js.map +1 -1
  256. package/dist/widgets/timeseries.js +11 -10
  257. package/dist/widgets/timeseries.js.map +1 -1
  258. package/dist/widgets/utils.js +8 -7
  259. package/dist/widgets/utils.js.map +1 -1
  260. package/dist/widgets-v2/actions.js +43 -0
  261. package/dist/widgets-v2/actions.js.map +1 -0
  262. package/dist/widgets-v2/bar.js +327 -0
  263. package/dist/widgets-v2/bar.js.map +1 -0
  264. package/dist/widgets-v2/category.js +104 -0
  265. package/dist/widgets-v2/category.js.map +1 -0
  266. package/dist/widgets-v2/echart.js +57 -0
  267. package/dist/widgets-v2/echart.js.map +1 -0
  268. package/dist/widgets-v2/formula.js +74 -0
  269. package/dist/widgets-v2/formula.js.map +1 -0
  270. package/dist/widgets-v2/histogram.js +350 -0
  271. package/dist/widgets-v2/histogram.js.map +1 -0
  272. package/dist/widgets-v2/markdown.js +68 -0
  273. package/dist/widgets-v2/markdown.js.map +1 -0
  274. package/dist/widgets-v2/pie.js +381 -0
  275. package/dist/widgets-v2/pie.js.map +1 -0
  276. package/dist/widgets-v2/range.js +52 -0
  277. package/dist/widgets-v2/range.js.map +1 -0
  278. package/dist/widgets-v2/scatterplot.js +405 -0
  279. package/dist/widgets-v2/scatterplot.js.map +1 -0
  280. package/dist/widgets-v2/spread.js +72 -0
  281. package/dist/widgets-v2/spread.js.map +1 -0
  282. package/dist/widgets-v2/stores.js +42 -0
  283. package/dist/widgets-v2/stores.js.map +1 -0
  284. package/dist/widgets-v2/table.js +78 -0
  285. package/dist/widgets-v2/table.js.map +1 -0
  286. package/dist/widgets-v2/timeseries.js +352 -0
  287. package/dist/widgets-v2/timeseries.js.map +1 -0
  288. package/dist/widgets-v2/utils.js +7 -0
  289. package/dist/widgets-v2/utils.js.map +1 -0
  290. package/dist/widgets-v2.js +953 -0
  291. package/dist/widgets-v2.js.map +1 -0
  292. package/package.json +73 -5
  293. package/src/components/lasso-tool/chip.test.tsx +176 -0
  294. package/src/components/lasso-tool/lasso-tool-inline.test.tsx +171 -0
  295. package/src/components/lasso-tool/lasso-tool.test.tsx +198 -0
  296. package/src/components/list-data/list-data.test.tsx +73 -0
  297. package/src/components/no-data-alert/no-data-alert.test.tsx +38 -0
  298. package/src/components/responsive-drawer/responsive-drawer.test.tsx +68 -0
  299. package/src/widgets/actions/brush-toggle/brush-overlay.test.tsx +465 -0
  300. package/src/widgets/actions/brush-toggle/brush-overlay.tsx +24 -2
  301. package/src/widgets/actions/brush-toggle/brush-toggle.test.tsx +208 -0
  302. package/src/widgets/actions/change-column/change-column-dnd.test.tsx +193 -0
  303. package/src/widgets/actions/change-column/sortable-column-item.test.tsx +124 -0
  304. package/src/widgets/actions/zoom-toggle/zoom-toggle.test.tsx +322 -0
  305. package/src/widgets/category/components/category-rows.test.tsx +213 -0
  306. package/src/widgets/echart/utils.test.ts +277 -0
  307. package/src/widgets/formula/config.test.ts +37 -0
  308. package/src/widgets/histogram/config.ts +1 -3
  309. package/src/widgets/range/components/range-item.test.tsx +243 -0
  310. package/src/widgets/stores/widget-store-branches.test.ts +275 -0
  311. package/src/widgets/table/config.test.ts +65 -0
  312. package/src/widgets/utils/chart-config/option-builders.test.ts +188 -0
  313. package/src/widgets-v2/PERFORMANCE.md +189 -0
  314. package/src/widgets-v2/actions/brush-toggle/brush-toggle.test.tsx +180 -0
  315. package/src/widgets-v2/actions/brush-toggle/brush-toggle.tsx +154 -0
  316. package/src/widgets-v2/actions/brush-toggle/index.ts +3 -0
  317. package/src/widgets-v2/actions/brush-toggle/labels.ts +9 -0
  318. package/src/widgets-v2/actions/brush-toggle/style.ts +11 -0
  319. package/src/widgets-v2/actions/brush-toggle/transforms.test.ts +47 -0
  320. package/src/widgets-v2/actions/brush-toggle/transforms.ts +31 -0
  321. package/src/widgets-v2/actions/change-column/change-column-icon.tsx +14 -0
  322. package/src/widgets-v2/actions/change-column/change-column.test.tsx +59 -0
  323. package/src/widgets-v2/actions/change-column/change-column.tsx +180 -0
  324. package/src/widgets-v2/actions/change-column/index.ts +7 -0
  325. package/src/widgets-v2/actions/change-column/labels.ts +9 -0
  326. package/src/widgets-v2/actions/change-column/sortable-column-item.tsx +56 -0
  327. package/src/widgets-v2/actions/change-column/style.ts +32 -0
  328. package/src/widgets-v2/actions/change-column/types.ts +11 -0
  329. package/src/widgets-v2/actions/download/download.test.tsx +327 -0
  330. package/src/widgets-v2/actions/download/download.tsx +144 -0
  331. package/src/widgets-v2/actions/download/exports.test.tsx +198 -0
  332. package/src/widgets-v2/actions/download/exports.ts +115 -0
  333. package/src/widgets-v2/actions/download/icons.tsx +26 -0
  334. package/src/widgets-v2/actions/download/index.ts +13 -0
  335. package/src/widgets-v2/actions/download/labels.ts +16 -0
  336. package/src/widgets-v2/actions/download/png-item.test.tsx +72 -0
  337. package/src/widgets-v2/actions/download/png-item.tsx +52 -0
  338. package/src/widgets-v2/actions/download/style.ts +3 -0
  339. package/src/widgets-v2/actions/download/types.ts +32 -0
  340. package/src/widgets-v2/actions/fullscreen/fullscreen.test.tsx +150 -0
  341. package/src/widgets-v2/actions/fullscreen/fullscreen.tsx +230 -0
  342. package/src/widgets-v2/actions/fullscreen/index.ts +7 -0
  343. package/src/widgets-v2/actions/fullscreen/labels.ts +9 -0
  344. package/src/widgets-v2/actions/fullscreen/style.ts +59 -0
  345. package/src/widgets-v2/actions/fullscreen/types.ts +15 -0
  346. package/src/widgets-v2/actions/index.ts +82 -0
  347. package/src/widgets-v2/actions/lock-selection/index.ts +10 -0
  348. package/src/widgets-v2/actions/lock-selection/labels.ts +11 -0
  349. package/src/widgets-v2/actions/lock-selection/lock-selection.test.tsx +187 -0
  350. package/src/widgets-v2/actions/lock-selection/lock-selection.tsx +130 -0
  351. package/src/widgets-v2/actions/lock-selection/style.ts +11 -0
  352. package/src/widgets-v2/actions/lock-selection/transforms.ts +27 -0
  353. package/src/widgets-v2/actions/relative-data/index.ts +3 -0
  354. package/src/widgets-v2/actions/relative-data/labels.ts +9 -0
  355. package/src/widgets-v2/actions/relative-data/relative-data.test.tsx +71 -0
  356. package/src/widgets-v2/actions/relative-data/relative-data.tsx +107 -0
  357. package/src/widgets-v2/actions/relative-data/style.ts +11 -0
  358. package/src/widgets-v2/actions/relative-data/transforms.test.ts +151 -0
  359. package/src/widgets-v2/actions/relative-data/transforms.ts +70 -0
  360. package/src/widgets-v2/actions/searcher/filter.ts +28 -0
  361. package/src/widgets-v2/actions/searcher/index.ts +8 -0
  362. package/src/widgets-v2/actions/searcher/labels.ts +13 -0
  363. package/src/widgets-v2/actions/searcher/searcher-toggle.tsx +91 -0
  364. package/src/widgets-v2/actions/searcher/searcher.test.tsx +92 -0
  365. package/src/widgets-v2/actions/searcher/searcher.tsx +112 -0
  366. package/src/widgets-v2/actions/searcher/style.ts +15 -0
  367. package/src/widgets-v2/actions/stack-toggle/index.ts +3 -0
  368. package/src/widgets-v2/actions/stack-toggle/labels.ts +9 -0
  369. package/src/widgets-v2/actions/stack-toggle/stack-toggle.test.tsx +61 -0
  370. package/src/widgets-v2/actions/stack-toggle/stack-toggle.tsx +54 -0
  371. package/src/widgets-v2/actions/stack-toggle/style.ts +11 -0
  372. package/src/widgets-v2/actions/stack-toggle/transforms.test.ts +43 -0
  373. package/src/widgets-v2/actions/stack-toggle/transforms.ts +25 -0
  374. package/src/widgets-v2/actions/zoom-toggle/index.ts +9 -0
  375. package/src/widgets-v2/actions/zoom-toggle/labels.ts +9 -0
  376. package/src/widgets-v2/actions/zoom-toggle/style.ts +11 -0
  377. package/src/widgets-v2/actions/zoom-toggle/transforms.test.ts +148 -0
  378. package/src/widgets-v2/actions/zoom-toggle/transforms.ts +171 -0
  379. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.test.tsx +107 -0
  380. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.tsx +106 -0
  381. package/src/widgets-v2/bar/download.test.tsx +91 -0
  382. package/src/widgets-v2/bar/download.tsx +66 -0
  383. package/src/widgets-v2/bar/index.ts +10 -0
  384. package/src/widgets-v2/bar/options.test.ts +317 -0
  385. package/src/widgets-v2/bar/options.ts +326 -0
  386. package/src/widgets-v2/bar/skeleton.test.tsx +19 -0
  387. package/src/widgets-v2/bar/skeleton.tsx +69 -0
  388. package/src/widgets-v2/bar/types.ts +46 -0
  389. package/src/widgets-v2/category/category-ui.test.tsx +746 -0
  390. package/src/widgets-v2/category/category-ui.tsx +389 -0
  391. package/src/widgets-v2/category/category.relative-data.test.tsx +107 -0
  392. package/src/widgets-v2/category/category.stack-toggle.test.tsx +85 -0
  393. package/src/widgets-v2/category/category.test.tsx +305 -0
  394. package/src/widgets-v2/category/category.tsx +121 -0
  395. package/src/widgets-v2/category/components/category-bar-stacked.test.tsx +121 -0
  396. package/src/widgets-v2/category/components/category-bar-stacked.tsx +73 -0
  397. package/src/widgets-v2/category/components/category-bar.test.tsx +64 -0
  398. package/src/widgets-v2/category/components/category-bar.tsx +49 -0
  399. package/src/widgets-v2/category/components/category-legend.test.tsx +51 -0
  400. package/src/widgets-v2/category/components/category-legend.tsx +39 -0
  401. package/src/widgets-v2/category/components/category-row-multi.tsx +86 -0
  402. package/src/widgets-v2/category/components/category-row-other.test.tsx +28 -0
  403. package/src/widgets-v2/category/components/category-row-other.tsx +33 -0
  404. package/src/widgets-v2/category/components/category-row-single.tsx +76 -0
  405. package/src/widgets-v2/category/components/category-row-stacked.test.tsx +244 -0
  406. package/src/widgets-v2/category/components/category-row-stacked.tsx +99 -0
  407. package/src/widgets-v2/category/download.test.ts +71 -0
  408. package/src/widgets-v2/category/download.ts +54 -0
  409. package/src/widgets-v2/category/index.ts +32 -0
  410. package/src/widgets-v2/category/skeleton.test.tsx +26 -0
  411. package/src/widgets-v2/category/skeleton.tsx +74 -0
  412. package/src/widgets-v2/category/style.ts +290 -0
  413. package/src/widgets-v2/category/types.ts +54 -0
  414. package/src/widgets-v2/echart/echart-ui.test.tsx +232 -0
  415. package/src/widgets-v2/echart/echart-ui.tsx +184 -0
  416. package/src/widgets-v2/echart/echart.test.tsx +229 -0
  417. package/src/widgets-v2/echart/echart.tsx +199 -0
  418. package/src/widgets-v2/echart/index.ts +22 -0
  419. package/src/widgets-v2/echart/shared-resize-observer.test.ts +91 -0
  420. package/src/widgets-v2/echart/shared-resize-observer.ts +56 -0
  421. package/src/widgets-v2/echart/style.ts +8 -0
  422. package/src/widgets-v2/echart/use-chart-selection.test.tsx +118 -0
  423. package/src/widgets-v2/echart/use-chart-selection.ts +115 -0
  424. package/src/widgets-v2/formula/delta.tsx +61 -0
  425. package/src/widgets-v2/formula/download.test.tsx +65 -0
  426. package/src/widgets-v2/formula/download.tsx +69 -0
  427. package/src/widgets-v2/formula/formula-ui.test.tsx +91 -0
  428. package/src/widgets-v2/formula/formula-ui.tsx +66 -0
  429. package/src/widgets-v2/formula/formula.test.tsx +50 -0
  430. package/src/widgets-v2/formula/formula.tsx +34 -0
  431. package/src/widgets-v2/formula/index.ts +17 -0
  432. package/src/widgets-v2/formula/note.tsx +25 -0
  433. package/src/widgets-v2/formula/prefix.tsx +25 -0
  434. package/src/widgets-v2/formula/series.tsx +67 -0
  435. package/src/widgets-v2/formula/skeleton.test.tsx +21 -0
  436. package/src/widgets-v2/formula/skeleton.tsx +27 -0
  437. package/src/widgets-v2/formula/style.ts +31 -0
  438. package/src/widgets-v2/formula/subcomponents.test.tsx +107 -0
  439. package/src/widgets-v2/formula/suffix.tsx +25 -0
  440. package/src/widgets-v2/formula/types.ts +44 -0
  441. package/src/widgets-v2/formula/value.tsx +31 -0
  442. package/src/widgets-v2/histogram/download.test.ts +94 -0
  443. package/src/widgets-v2/histogram/download.ts +60 -0
  444. package/src/widgets-v2/histogram/index.ts +10 -0
  445. package/src/widgets-v2/histogram/options.test.ts +304 -0
  446. package/src/widgets-v2/histogram/options.ts +337 -0
  447. package/src/widgets-v2/histogram/skeleton.test.tsx +16 -0
  448. package/src/widgets-v2/histogram/skeleton.tsx +70 -0
  449. package/src/widgets-v2/histogram/transforms.test.ts +46 -0
  450. package/src/widgets-v2/histogram/transforms.ts +30 -0
  451. package/src/widgets-v2/histogram/types.ts +51 -0
  452. package/src/widgets-v2/index.ts +201 -0
  453. package/src/widgets-v2/markdown/download.test.ts +66 -0
  454. package/src/widgets-v2/markdown/download.ts +53 -0
  455. package/src/widgets-v2/markdown/index.ts +6 -0
  456. package/src/widgets-v2/markdown/markdown-content.test.tsx +155 -0
  457. package/src/widgets-v2/markdown/markdown-content.tsx +72 -0
  458. package/src/widgets-v2/markdown/markdown-ui.test.tsx +75 -0
  459. package/src/widgets-v2/markdown/markdown-ui.tsx +55 -0
  460. package/src/widgets-v2/markdown/markdown.test.tsx +39 -0
  461. package/src/widgets-v2/markdown/markdown.tsx +17 -0
  462. package/src/widgets-v2/markdown/skeleton.test.tsx +15 -0
  463. package/src/widgets-v2/markdown/skeleton.tsx +32 -0
  464. package/src/widgets-v2/markdown/style.ts +53 -0
  465. package/src/widgets-v2/markdown/types.ts +4 -0
  466. package/src/widgets-v2/note/labels.ts +9 -0
  467. package/src/widgets-v2/note/style.ts +26 -0
  468. package/src/widgets-v2/note/widget-note.test.tsx +158 -0
  469. package/src/widgets-v2/note/widget-note.tsx +172 -0
  470. package/src/widgets-v2/pie/download.test.ts +78 -0
  471. package/src/widgets-v2/pie/download.ts +55 -0
  472. package/src/widgets-v2/pie/index.ts +10 -0
  473. package/src/widgets-v2/pie/options.test.ts +585 -0
  474. package/src/widgets-v2/pie/options.ts +509 -0
  475. package/src/widgets-v2/pie/skeleton.test.tsx +17 -0
  476. package/src/widgets-v2/pie/skeleton.tsx +32 -0
  477. package/src/widgets-v2/pie/types.ts +55 -0
  478. package/src/widgets-v2/provider/widget-provider.test.tsx +119 -0
  479. package/src/widgets-v2/provider/widget-provider.tsx +111 -0
  480. package/src/widgets-v2/range/index.ts +4 -0
  481. package/src/widgets-v2/range/range-ui.test.tsx +130 -0
  482. package/src/widgets-v2/range/range-ui.tsx +211 -0
  483. package/src/widgets-v2/range/range.test.tsx +68 -0
  484. package/src/widgets-v2/range/range.tsx +46 -0
  485. package/src/widgets-v2/range/skeleton.test.tsx +17 -0
  486. package/src/widgets-v2/range/skeleton.tsx +47 -0
  487. package/src/widgets-v2/range/style.ts +41 -0
  488. package/src/widgets-v2/range/types.ts +37 -0
  489. package/src/widgets-v2/scatterplot/download.test.ts +71 -0
  490. package/src/widgets-v2/scatterplot/download.ts +54 -0
  491. package/src/widgets-v2/scatterplot/index.ts +11 -0
  492. package/src/widgets-v2/scatterplot/options.test.ts +399 -0
  493. package/src/widgets-v2/scatterplot/options.ts +421 -0
  494. package/src/widgets-v2/scatterplot/skeleton.test.tsx +17 -0
  495. package/src/widgets-v2/scatterplot/skeleton.tsx +84 -0
  496. package/src/widgets-v2/scatterplot/transforms.test.ts +97 -0
  497. package/src/widgets-v2/scatterplot/transforms.ts +38 -0
  498. package/src/widgets-v2/scatterplot/types.ts +55 -0
  499. package/src/widgets-v2/selection-summary/labels.ts +11 -0
  500. package/src/widgets-v2/selection-summary/selection-summary.test.tsx +53 -0
  501. package/src/widgets-v2/selection-summary/selection-summary.tsx +62 -0
  502. package/src/widgets-v2/selection-summary/style.ts +23 -0
  503. package/src/widgets-v2/spread/download.test.ts +64 -0
  504. package/src/widgets-v2/spread/download.ts +59 -0
  505. package/src/widgets-v2/spread/index.ts +6 -0
  506. package/src/widgets-v2/spread/separator.tsx +11 -0
  507. package/src/widgets-v2/spread/skeleton.test.tsx +17 -0
  508. package/src/widgets-v2/spread/skeleton.tsx +38 -0
  509. package/src/widgets-v2/spread/spread-ui.test.tsx +108 -0
  510. package/src/widgets-v2/spread/spread-ui.tsx +52 -0
  511. package/src/widgets-v2/spread/spread.test.tsx +50 -0
  512. package/src/widgets-v2/spread/spread.tsx +31 -0
  513. package/src/widgets-v2/spread/types.ts +27 -0
  514. package/src/widgets-v2/state/labels.test.ts +33 -0
  515. package/src/widgets-v2/state/labels.ts +20 -0
  516. package/src/widgets-v2/state/style.ts +25 -0
  517. package/src/widgets-v2/state/widget-state.test.tsx +294 -0
  518. package/src/widgets-v2/state/widget-state.tsx +184 -0
  519. package/src/widgets-v2/stores/index.ts +49 -0
  520. package/src/widgets-v2/stores/pipeline-middleware.test.ts +187 -0
  521. package/src/widgets-v2/stores/pipeline-middleware.ts +91 -0
  522. package/src/widgets-v2/stores/transforms.test.ts +162 -0
  523. package/src/widgets-v2/stores/transforms.ts +70 -0
  524. package/src/widgets-v2/stores/types.ts +64 -0
  525. package/src/widgets-v2/stores/use-echart-instance.test.tsx +91 -0
  526. package/src/widgets-v2/stores/use-echart-instance.ts +29 -0
  527. package/src/widgets-v2/stores/use-transform-enabled.test.tsx +127 -0
  528. package/src/widgets-v2/stores/use-transform-enabled.ts +25 -0
  529. package/src/widgets-v2/stores/use-transform.test.tsx +262 -0
  530. package/src/widgets-v2/stores/use-transform.ts +158 -0
  531. package/src/widgets-v2/stores/widget-context.test.tsx +58 -0
  532. package/src/widgets-v2/stores/widget-context.ts +15 -0
  533. package/src/widgets-v2/stores/widget-store-registry.test.ts +292 -0
  534. package/src/widgets-v2/stores/widget-store-registry.ts +248 -0
  535. package/src/widgets-v2/subheader/style.ts +12 -0
  536. package/src/widgets-v2/subheader/subheader.test.tsx +30 -0
  537. package/src/widgets-v2/subheader/subheader.tsx +16 -0
  538. package/src/widgets-v2/table/download.test.ts +75 -0
  539. package/src/widgets-v2/table/download.ts +47 -0
  540. package/src/widgets-v2/table/helpers.test.ts +214 -0
  541. package/src/widgets-v2/table/helpers.ts +136 -0
  542. package/src/widgets-v2/table/index.ts +23 -0
  543. package/src/widgets-v2/table/labels.tsx +41 -0
  544. package/src/widgets-v2/table/skeleton.test.tsx +26 -0
  545. package/src/widgets-v2/table/skeleton.tsx +65 -0
  546. package/src/widgets-v2/table/style.ts +46 -0
  547. package/src/widgets-v2/table/table-ui.test.tsx +200 -0
  548. package/src/widgets-v2/table/table-ui.tsx +331 -0
  549. package/src/widgets-v2/table/table.test.tsx +119 -0
  550. package/src/widgets-v2/table/table.tsx +174 -0
  551. package/src/widgets-v2/table/types.ts +44 -0
  552. package/src/widgets-v2/test-utils.ts +107 -0
  553. package/src/widgets-v2/timeseries/download.test.ts +95 -0
  554. package/src/widgets-v2/timeseries/download.ts +86 -0
  555. package/src/widgets-v2/timeseries/index.ts +10 -0
  556. package/src/widgets-v2/timeseries/options.test.ts +379 -0
  557. package/src/widgets-v2/timeseries/options.ts +341 -0
  558. package/src/widgets-v2/timeseries/skeleton.test.tsx +13 -0
  559. package/src/widgets-v2/timeseries/skeleton.tsx +76 -0
  560. package/src/widgets-v2/timeseries/types.ts +61 -0
  561. package/src/widgets-v2/toolbox/labels.ts +9 -0
  562. package/src/widgets-v2/toolbox/style.ts +33 -0
  563. package/src/widgets-v2/toolbox/toolbox.test.tsx +200 -0
  564. package/src/widgets-v2/toolbox/toolbox.tsx +309 -0
  565. package/src/widgets-v2/utils/data-zoom-layout.ts +26 -0
  566. package/src/widgets-v2/utils/index.ts +2 -0
  567. package/src/widgets-v2/utils/merge-options.test.ts +52 -0
  568. package/src/widgets-v2/utils/merge-options.ts +50 -0
  569. package/src/widgets-v2/wrapper/index.ts +14 -0
  570. package/src/widgets-v2/wrapper/labels.ts +11 -0
  571. package/src/widgets-v2/wrapper/style.ts +134 -0
  572. package/src/widgets-v2/wrapper/widget-actions.test.tsx +52 -0
  573. package/src/widgets-v2/wrapper/widget-actions.tsx +43 -0
  574. package/src/widgets-v2/wrapper/widget-content.test.tsx +27 -0
  575. package/src/widgets-v2/wrapper/widget-content.tsx +29 -0
  576. package/src/widgets-v2/wrapper/widget-wrapper.test.tsx +159 -0
  577. package/src/widgets-v2/wrapper/widget-wrapper.tsx +178 -0
  578. package/dist/styles-BYTyKQFP.js.map +0 -1
@@ -0,0 +1,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
+ }
@@ -0,0 +1,91 @@
1
+ import { useCallback, type ComponentType } from 'react'
2
+ import { IconButton, type SvgIconProps } from '@mui/material'
3
+ import SearchIcon from '@mui/icons-material/Search'
4
+ import { Tooltip } from '../../../components'
5
+ import {
6
+ getWidgetStore,
7
+ useSingleTransform,
8
+ useWidget,
9
+ useWidgetId,
10
+ } from '../../stores'
11
+ import { filterBySearchText } from './filter'
12
+ import { DEFAULT_SEARCHER_LABELS, type SearcherLabels } from './labels'
13
+ import { styles } from './style'
14
+
15
+ const SEARCHER_DESCRIPTOR = {
16
+ id: 'searcher',
17
+ type: 'data' as const,
18
+ order: 20,
19
+ disables: ['lock-selection'],
20
+ }
21
+
22
+ export interface SearcherToggleProps {
23
+ labels?: Partial<SearcherLabels>
24
+ icon?: ComponentType<SvgIconProps>
25
+ iconProps?: SvgIconProps
26
+ /**
27
+ * Whether the searcher transform is enabled on first mount. Defaults
28
+ * to `false` so the toggle renders un-pressed and the
29
+ * `filterBySearchText` transform stays dormant until the user clicks
30
+ * it. Set to `true` for search-first widgets where the input is the
31
+ * primary affordance.
32
+ */
33
+ initialEnabled?: boolean
34
+ }
35
+
36
+ export function SearcherToggle({
37
+ labels,
38
+ icon: Icon = SearchIcon,
39
+ iconProps,
40
+ initialEnabled = false,
41
+ }: SearcherToggleProps) {
42
+ const id = useWidgetId()
43
+ const resolved = { ...DEFAULT_SEARCHER_LABELS, ...labels }
44
+ const text = useWidget(
45
+ id,
46
+ (s) => (s.transformStates.searcher?.searchText as string | undefined) ?? '',
47
+ )
48
+
49
+ // The transform fn closes over `text`. Memoize via useCallback so identity
50
+ // only changes when text changes, allowing useTransform to re-register.
51
+ const fn = useCallback(
52
+ (data: unknown) => filterBySearchText(data, text),
53
+ [text],
54
+ )
55
+
56
+ const { enabled, toggle } = useSingleTransform(id, SEARCHER_DESCRIPTOR, fn, {
57
+ initialEnabled,
58
+ })
59
+
60
+ return (
61
+ <Tooltip title={resolved.toggle}>
62
+ <IconButton
63
+ size='small'
64
+ aria-label={resolved.toggle}
65
+ aria-pressed={enabled}
66
+ onClick={toggle}
67
+ sx={{ ...styles.toggle, ...(enabled && styles.toggleActive) }}
68
+ >
69
+ <Icon fontSize='small' {...iconProps} />
70
+ </IconButton>
71
+ </Tooltip>
72
+ )
73
+ }
74
+
75
+ /**
76
+ * Imperatively writes the search text into the widget store. Used by the
77
+ * Searcher input to update text inside transformStates without going through
78
+ * a re-rendered React subscription.
79
+ */
80
+ export function setSearcherText(widgetId: string, value: string): void {
81
+ getWidgetStore(widgetId).setState((s) => ({
82
+ transformStates: {
83
+ ...s.transformStates,
84
+ searcher: {
85
+ enabled: s.transformStates.searcher?.enabled ?? false,
86
+ ...s.transformStates.searcher,
87
+ searchText: value,
88
+ },
89
+ },
90
+ }))
91
+ }
@@ -0,0 +1,92 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
2
+ import { fireEvent, render, screen, act } from '@testing-library/react'
3
+ import { Provider } from '../../provider/widget-provider'
4
+ import { clearAllWidgetStores, getWidgetStore } from '../../stores'
5
+ import { Searcher } from './searcher'
6
+ import { SearcherToggle } from './searcher-toggle'
7
+
8
+ beforeEach(() => clearAllWidgetStores())
9
+ afterEach(() => clearAllWidgetStores())
10
+
11
+ const DATA = [
12
+ [
13
+ { name: 'apple', value: 1 },
14
+ { name: 'banana', value: 2 },
15
+ { name: 'cherry', value: 3 },
16
+ ],
17
+ ]
18
+
19
+ describe('<Searcher> + <SearcherToggle>', () => {
20
+ it('toggle defaults off — aria-pressed=false and input hidden', () => {
21
+ render(
22
+ <Provider id='sr1' data={DATA}>
23
+ <SearcherToggle />
24
+ <Searcher />
25
+ </Provider>,
26
+ )
27
+ const btn = screen.getByRole('button', { name: 'Search' })
28
+ expect(btn.getAttribute('aria-pressed')).toBe('false')
29
+ expect(screen.queryByPlaceholderText('Search…')).toBeNull()
30
+ })
31
+
32
+ it('initialEnabled=true opts into the legacy "search-first" behavior', () => {
33
+ render(
34
+ <Provider id='sr1b' data={DATA}>
35
+ <SearcherToggle initialEnabled />
36
+ <Searcher />
37
+ </Provider>,
38
+ )
39
+ const btn = screen.getByRole('button', { name: 'Search' })
40
+ expect(btn.getAttribute('aria-pressed')).toBe('true')
41
+ expect(screen.getByPlaceholderText('Search…')).toBeTruthy()
42
+ })
43
+
44
+ it('clicking the toggle reveals the input and flips aria-pressed', () => {
45
+ render(
46
+ <Provider id='sr2' data={DATA}>
47
+ <SearcherToggle />
48
+ <Searcher />
49
+ </Provider>,
50
+ )
51
+ fireEvent.click(screen.getByRole('button', { name: 'Search' }))
52
+ expect(screen.getByPlaceholderText('Search…')).toBeTruthy()
53
+ expect(
54
+ screen
55
+ .getByRole('button', { name: 'Search' })
56
+ .getAttribute('aria-pressed'),
57
+ ).toBe('true')
58
+ })
59
+
60
+ it('debounces input changes; after the timer fires the searchText is committed and the data is filtered', () => {
61
+ vi.useFakeTimers({ shouldAdvanceTime: true })
62
+ try {
63
+ render(
64
+ <Provider id='sr3' data={DATA}>
65
+ <SearcherToggle initialEnabled />
66
+ <Searcher debounceMs={100} />
67
+ </Provider>,
68
+ )
69
+ // `initialEnabled` opens the input straight away — no click needed.
70
+ const input = screen.getByPlaceholderText('Search…')
71
+ fireEvent.change(input, { target: { value: 'app' } })
72
+ // Pre-debounce: store still has no committed searchText.
73
+ expect(
74
+ getWidgetStore('sr3').getState().transformStates.searcher?.searchText,
75
+ ).toBeUndefined()
76
+
77
+ act(() => {
78
+ vi.advanceTimersByTime(120)
79
+ })
80
+
81
+ expect(
82
+ getWidgetStore('sr3').getState().transformStates.searcher?.searchText,
83
+ ).toBe('app')
84
+ const filtered = getWidgetStore('sr3').getState().data as {
85
+ name: string
86
+ }[][]
87
+ expect(filtered.flat().map((r) => r.name)).toEqual(['apple'])
88
+ } finally {
89
+ vi.useRealTimers()
90
+ }
91
+ })
92
+ })
@@ -0,0 +1,112 @@
1
+ import { useCallback, useMemo, useRef, useState } from 'react'
2
+ import { IconButton, InputAdornment, TextField } from '@mui/material'
3
+ import SearchIcon from '@mui/icons-material/Search'
4
+ import ClearIcon from '@mui/icons-material/Clear'
5
+ import { debounce } from '@carto/ps-utils'
6
+ import { getWidgetStore, useWidget, useWidgetId } from '../../stores'
7
+ import { setSearcherText } from './searcher-toggle'
8
+ import { DEFAULT_SEARCHER_LABELS, type SearcherLabels } from './labels'
9
+ import { styles } from './style'
10
+
11
+ export interface SearcherProps {
12
+ labels?: Partial<SearcherLabels>
13
+ /** Debounce delay before the input value is written to the widget store. */
14
+ debounceMs?: number
15
+ }
16
+
17
+ const DEFAULT_DEBOUNCE = 300
18
+
19
+ /**
20
+ * Renders only when the matching `<SearcherToggle />` is enabled — drives the
21
+ * `transformStates['searcher'].searchText` field via a debounced setter.
22
+ */
23
+ export function Searcher({
24
+ labels,
25
+ debounceMs = DEFAULT_DEBOUNCE,
26
+ }: SearcherProps) {
27
+ const id = useWidgetId()
28
+ const resolved = { ...DEFAULT_SEARCHER_LABELS, ...labels }
29
+ const enabled = useWidget(
30
+ id,
31
+ (s) => s.transformStates.searcher?.enabled ?? false,
32
+ )
33
+
34
+ const inputRef = useRef<HTMLInputElement | null>(null)
35
+
36
+ // Hydrate from the store so re-toggling the input preserves any prior text.
37
+ const [local, setLocal] = useState<string>(
38
+ () =>
39
+ (getWidgetStore(id).getState().transformStates.searcher?.searchText as
40
+ | string
41
+ | undefined) ?? '',
42
+ )
43
+
44
+ const debouncedWrite = useMemo(
45
+ () =>
46
+ debounce(
47
+ (value: unknown) => setSearcherText(id, value as string),
48
+ debounceMs,
49
+ ),
50
+ [id, debounceMs],
51
+ )
52
+
53
+ const handleSearchTextChange = useCallback(
54
+ (e: React.ChangeEvent<HTMLInputElement>) => {
55
+ const value = e.target.value
56
+ setLocal(value)
57
+ debouncedWrite(value)
58
+ },
59
+ [debouncedWrite],
60
+ )
61
+
62
+ const handleClear = useCallback(() => {
63
+ setLocal('')
64
+ setSearcherText(id, '')
65
+ // Re-arm the debounced timer with '' so any pending stale write resolves
66
+ // to the cleared value rather than re-applying the previous text.
67
+ debouncedWrite('')
68
+ inputRef.current?.focus()
69
+ }, [id, debouncedWrite])
70
+
71
+ if (!enabled) return null
72
+
73
+ return (
74
+ <TextField
75
+ inputRef={inputRef}
76
+ size='small'
77
+ fullWidth
78
+ variant='filled'
79
+ placeholder={resolved.placeholder}
80
+ value={local}
81
+ onChange={handleSearchTextChange}
82
+ // The Searcher only mounts when the user explicitly toggles the
83
+ // SearcherToggle action — focusing the input on mount matches user
84
+ // intent, so the jsx-a11y/no-autofocus warning is the false-positive
85
+ // case (the rule targets unsolicited autofocus that disorients
86
+ // screen readers).
87
+ // eslint-disable-next-line
88
+ autoFocus
89
+ aria-label={resolved.placeholder}
90
+ sx={styles.input}
91
+ InputProps={{
92
+ startAdornment: (
93
+ <InputAdornment position='start'>
94
+ <SearchIcon fontSize='small' />
95
+ </InputAdornment>
96
+ ),
97
+ endAdornment: local ? (
98
+ <InputAdornment position='end'>
99
+ <IconButton
100
+ size='small'
101
+ edge='end'
102
+ aria-label={resolved.clearAriaLabel}
103
+ onClick={handleClear}
104
+ >
105
+ <ClearIcon fontSize='small' />
106
+ </IconButton>
107
+ </InputAdornment>
108
+ ) : null,
109
+ }}
110
+ />
111
+ )
112
+ }
@@ -0,0 +1,15 @@
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
+ input: {
12
+ width: '100%',
13
+ mb: 1,
14
+ },
15
+ } satisfies Record<string, SxProps<Theme>>
@@ -0,0 +1,3 @@
1
+ export { StackToggle, type StackToggleProps } from './stack-toggle'
2
+ export { addStack } from './transforms'
3
+ export { DEFAULT_STACK_TOGGLE_LABELS, type StackToggleLabels } from './labels'
@@ -0,0 +1,9 @@
1
+ export interface StackToggleLabels {
2
+ on: string
3
+ off: string
4
+ }
5
+
6
+ export const DEFAULT_STACK_TOGGLE_LABELS: StackToggleLabels = {
7
+ on: 'Unstack series',
8
+ off: 'Stack series',
9
+ }
@@ -0,0 +1,61 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest'
2
+ import { fireEvent, render, screen } from '@testing-library/react'
3
+ import { Provider } from '../../provider/widget-provider'
4
+ import { clearAllWidgetStores, getWidgetStore } from '../../stores'
5
+ import { StackToggle } from './stack-toggle'
6
+
7
+ beforeEach(() => clearAllWidgetStores())
8
+ afterEach(() => clearAllWidgetStores())
9
+
10
+ /**
11
+ * Stack/Zoom/Brush share the same toggle wiring. This file is the exemplar.
12
+ * The transforms themselves are tested in `transforms.test.ts` /
13
+ * `…/zoom-toggle/transforms.test.ts` / `…/brush-toggle/transforms.test.ts`.
14
+ */
15
+ describe('<StackToggle>', () => {
16
+ it('starts disabled by default and uses the off-state label', () => {
17
+ render(
18
+ <Provider id='st1' data={[]}>
19
+ <StackToggle />
20
+ </Provider>,
21
+ )
22
+ const btn = screen.getByRole('button', { name: 'Stack series' })
23
+ expect(btn.getAttribute('aria-pressed')).toBe('false')
24
+ })
25
+
26
+ it('toggles aria-pressed and label on click', () => {
27
+ render(
28
+ <Provider id='st2' data={[]}>
29
+ <StackToggle />
30
+ </Provider>,
31
+ )
32
+ fireEvent.click(screen.getByRole('button', { name: 'Stack series' }))
33
+ const after = screen.getByRole('button', { name: 'Unstack series' })
34
+ expect(after.getAttribute('aria-pressed')).toBe('true')
35
+ })
36
+
37
+ it('persists the enabled flag on the widget store under transformStates', () => {
38
+ render(
39
+ <Provider id='st3' data={[]}>
40
+ <StackToggle />
41
+ </Provider>,
42
+ )
43
+ fireEvent.click(screen.getByRole('button', { name: 'Stack series' }))
44
+ expect(
45
+ getWidgetStore('st3').getState().transformStates['stack-toggle']?.enabled,
46
+ ).toBe(true)
47
+ })
48
+
49
+ it('initialEnabled=true mounts already-on', () => {
50
+ render(
51
+ <Provider id='st4' data={[]}>
52
+ <StackToggle initialEnabled />
53
+ </Provider>,
54
+ )
55
+ expect(
56
+ screen
57
+ .getByRole('button', { name: 'Unstack series' })
58
+ .getAttribute('aria-pressed'),
59
+ ).toBe('true')
60
+ })
61
+ })