@carto/ps-react-ui 4.7.1 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (574) hide show
  1. package/dist/category-DwaeYjpX.js +656 -0
  2. package/dist/category-DwaeYjpX.js.map +1 -0
  3. package/dist/change-column-Cidl_M-4.js +1110 -0
  4. package/dist/change-column-Cidl_M-4.js.map +1 -0
  5. package/dist/data-zoom-layout-BH0LPwSy.js +28 -0
  6. package/dist/data-zoom-layout-BH0LPwSy.js.map +1 -0
  7. package/dist/echart-CU0KmClP.js +176 -0
  8. package/dist/echart-CU0KmClP.js.map +1 -0
  9. package/dist/exports-Cx-f6m6U.js +63 -0
  10. package/dist/exports-Cx-f6m6U.js.map +1 -0
  11. package/dist/formula-DuC0NQLH.js +79 -0
  12. package/dist/formula-DuC0NQLH.js.map +1 -0
  13. package/dist/markdown-BD1jcknS.js +8326 -0
  14. package/dist/markdown-BD1jcknS.js.map +1 -0
  15. package/dist/merge-options-DCkkHZIf.js +34 -0
  16. package/dist/merge-options-DCkkHZIf.js.map +1 -0
  17. package/dist/{styles-BYTyKQFP.js → option-builders-F-c9ELi1.js} +25 -45
  18. package/dist/option-builders-F-c9ELi1.js.map +1 -0
  19. package/dist/png-item-CS4z1iSH.js +45 -0
  20. package/dist/png-item-CS4z1iSH.js.map +1 -0
  21. package/dist/range-DsqTjSpg.js +186 -0
  22. package/dist/range-DsqTjSpg.js.map +1 -0
  23. package/dist/spread-CTuIXZSM.js +67 -0
  24. package/dist/spread-CTuIXZSM.js.map +1 -0
  25. package/dist/style-DVnT6HC1.js +131 -0
  26. package/dist/style-DVnT6HC1.js.map +1 -0
  27. package/dist/styles-cohnxh9F.js +23 -0
  28. package/dist/styles-cohnxh9F.js.map +1 -0
  29. package/dist/table-HIpXuq4G.js +390 -0
  30. package/dist/table-HIpXuq4G.js.map +1 -0
  31. package/dist/transforms-Cdx4fkU5.js +106 -0
  32. package/dist/transforms-Cdx4fkU5.js.map +1 -0
  33. package/dist/types/widgets/echart/utils.test.d.ts +1 -0
  34. package/dist/types/widgets/formula/config.test.d.ts +1 -0
  35. package/dist/types/widgets/stores/widget-store-branches.test.d.ts +1 -0
  36. package/dist/types/widgets/table/config.test.d.ts +1 -0
  37. package/dist/types/widgets-v2/actions/brush-toggle/brush-toggle.d.ts +56 -0
  38. package/dist/types/widgets-v2/actions/brush-toggle/index.d.ts +3 -0
  39. package/dist/types/widgets-v2/actions/brush-toggle/labels.d.ts +5 -0
  40. package/dist/types/widgets-v2/actions/brush-toggle/style.d.ts +12 -0
  41. package/dist/types/widgets-v2/actions/brush-toggle/transforms.d.ts +11 -0
  42. package/dist/types/widgets-v2/actions/brush-toggle/transforms.test.d.ts +1 -0
  43. package/dist/types/widgets-v2/actions/change-column/change-column-icon.d.ts +2 -0
  44. package/dist/types/widgets-v2/actions/change-column/change-column.d.ts +29 -0
  45. package/dist/types/widgets-v2/actions/change-column/index.d.ts +3 -0
  46. package/dist/types/widgets-v2/actions/change-column/labels.d.ts +5 -0
  47. package/dist/types/widgets-v2/actions/change-column/sortable-column-item.d.ts +14 -0
  48. package/dist/types/widgets-v2/actions/change-column/style.d.ts +33 -0
  49. package/dist/types/widgets-v2/actions/change-column/types.d.ts +10 -0
  50. package/dist/types/widgets-v2/actions/download/download.d.ts +18 -0
  51. package/dist/types/widgets-v2/actions/download/exports.d.ts +37 -0
  52. package/dist/types/widgets-v2/actions/download/icons.d.ts +12 -0
  53. package/dist/types/widgets-v2/actions/download/index.d.ts +6 -0
  54. package/dist/types/widgets-v2/actions/download/labels.d.ts +11 -0
  55. package/dist/types/widgets-v2/actions/download/png-item.d.ts +24 -0
  56. package/dist/types/widgets-v2/actions/download/style.d.ts +1 -0
  57. package/dist/types/widgets-v2/actions/download/types.d.ts +35 -0
  58. package/dist/types/widgets-v2/actions/fullscreen/fullscreen.d.ts +59 -0
  59. package/dist/types/widgets-v2/actions/fullscreen/index.d.ts +3 -0
  60. package/dist/types/widgets-v2/actions/fullscreen/labels.d.ts +5 -0
  61. package/dist/types/widgets-v2/actions/fullscreen/style.d.ts +48 -0
  62. package/dist/types/widgets-v2/actions/fullscreen/types.d.ts +14 -0
  63. package/dist/types/widgets-v2/actions/index.d.ts +9 -0
  64. package/dist/types/widgets-v2/actions/lock-selection/index.d.ts +3 -0
  65. package/dist/types/widgets-v2/actions/lock-selection/labels.d.ts +6 -0
  66. package/dist/types/widgets-v2/actions/lock-selection/lock-selection.d.ts +36 -0
  67. package/dist/types/widgets-v2/actions/lock-selection/style.d.ts +12 -0
  68. package/dist/types/widgets-v2/actions/lock-selection/transforms.d.ts +6 -0
  69. package/dist/types/widgets-v2/actions/relative-data/index.d.ts +3 -0
  70. package/dist/types/widgets-v2/actions/relative-data/labels.d.ts +5 -0
  71. package/dist/types/widgets-v2/actions/relative-data/relative-data.d.ts +39 -0
  72. package/dist/types/widgets-v2/actions/relative-data/style.d.ts +12 -0
  73. package/dist/types/widgets-v2/actions/relative-data/transforms.d.ts +30 -0
  74. package/dist/types/widgets-v2/actions/relative-data/transforms.test.d.ts +1 -0
  75. package/dist/types/widgets-v2/actions/searcher/filter.d.ts +6 -0
  76. package/dist/types/widgets-v2/actions/searcher/index.d.ts +4 -0
  77. package/dist/types/widgets-v2/actions/searcher/labels.d.ts +7 -0
  78. package/dist/types/widgets-v2/actions/searcher/searcher-toggle.d.ts +23 -0
  79. package/dist/types/widgets-v2/actions/searcher/searcher.d.ts +11 -0
  80. package/dist/types/widgets-v2/actions/searcher/style.d.ts +16 -0
  81. package/dist/types/widgets-v2/actions/stack-toggle/index.d.ts +3 -0
  82. package/dist/types/widgets-v2/actions/stack-toggle/labels.d.ts +5 -0
  83. package/dist/types/widgets-v2/actions/stack-toggle/stack-toggle.d.ts +10 -0
  84. package/dist/types/widgets-v2/actions/stack-toggle/style.d.ts +12 -0
  85. package/dist/types/widgets-v2/actions/stack-toggle/transforms.d.ts +13 -0
  86. package/dist/types/widgets-v2/actions/stack-toggle/transforms.test.d.ts +1 -0
  87. package/dist/types/widgets-v2/actions/zoom-toggle/index.d.ts +3 -0
  88. package/dist/types/widgets-v2/actions/zoom-toggle/labels.d.ts +5 -0
  89. package/dist/types/widgets-v2/actions/zoom-toggle/style.d.ts +12 -0
  90. package/dist/types/widgets-v2/actions/zoom-toggle/transforms.d.ts +51 -0
  91. package/dist/types/widgets-v2/actions/zoom-toggle/transforms.test.d.ts +1 -0
  92. package/dist/types/widgets-v2/actions/zoom-toggle/zoom-toggle.d.ts +35 -0
  93. package/dist/types/widgets-v2/bar/download.d.ts +24 -0
  94. package/dist/types/widgets-v2/bar/index.d.ts +4 -0
  95. package/dist/types/widgets-v2/bar/options.d.ts +43 -0
  96. package/dist/types/widgets-v2/bar/options.test.d.ts +1 -0
  97. package/dist/types/widgets-v2/bar/skeleton.d.ts +6 -0
  98. package/dist/types/widgets-v2/bar/types.d.ts +41 -0
  99. package/dist/types/widgets-v2/category/category-ui.d.ts +81 -0
  100. package/dist/types/widgets-v2/category/category.d.ts +48 -0
  101. package/dist/types/widgets-v2/category/components/category-bar-stacked.d.ts +28 -0
  102. package/dist/types/widgets-v2/category/components/category-bar.d.ts +23 -0
  103. package/dist/types/widgets-v2/category/components/category-legend.d.ts +18 -0
  104. package/dist/types/widgets-v2/category/components/category-row-multi.d.ts +31 -0
  105. package/dist/types/widgets-v2/category/components/category-row-other.d.ts +13 -0
  106. package/dist/types/widgets-v2/category/components/category-row-single.d.ts +28 -0
  107. package/dist/types/widgets-v2/category/components/category-row-stacked.d.ts +38 -0
  108. package/dist/types/widgets-v2/category/download.d.ts +16 -0
  109. package/dist/types/widgets-v2/category/download.test.d.ts +1 -0
  110. package/dist/types/widgets-v2/category/index.d.ts +10 -0
  111. package/dist/types/widgets-v2/category/skeleton.d.ts +11 -0
  112. package/dist/types/widgets-v2/category/style.d.ts +166 -0
  113. package/dist/types/widgets-v2/category/types.d.ts +49 -0
  114. package/dist/types/widgets-v2/echart/echart-ui.d.ts +44 -0
  115. package/dist/types/widgets-v2/echart/echart.d.ts +75 -0
  116. package/dist/types/widgets-v2/echart/index.d.ts +4 -0
  117. package/dist/types/widgets-v2/echart/shared-resize-observer.d.ts +5 -0
  118. package/dist/types/widgets-v2/echart/shared-resize-observer.test.d.ts +1 -0
  119. package/dist/types/widgets-v2/echart/style.d.ts +6 -0
  120. package/dist/types/widgets-v2/echart/use-chart-selection.d.ts +51 -0
  121. package/dist/types/widgets-v2/formula/delta.d.ts +22 -0
  122. package/dist/types/widgets-v2/formula/download.d.ts +20 -0
  123. package/dist/types/widgets-v2/formula/formula-ui.d.ts +20 -0
  124. package/dist/types/widgets-v2/formula/formula.d.ts +8 -0
  125. package/dist/types/widgets-v2/formula/index.d.ts +11 -0
  126. package/dist/types/widgets-v2/formula/note.d.ts +11 -0
  127. package/dist/types/widgets-v2/formula/prefix.d.ts +12 -0
  128. package/dist/types/widgets-v2/formula/series.d.ts +16 -0
  129. package/dist/types/widgets-v2/formula/skeleton.d.ts +4 -0
  130. package/dist/types/widgets-v2/formula/style.d.ts +29 -0
  131. package/dist/types/widgets-v2/formula/suffix.d.ts +12 -0
  132. package/dist/types/widgets-v2/formula/types.d.ts +40 -0
  133. package/dist/types/widgets-v2/formula/value.d.ts +14 -0
  134. package/dist/types/widgets-v2/histogram/download.d.ts +17 -0
  135. package/dist/types/widgets-v2/histogram/download.test.d.ts +1 -0
  136. package/dist/types/widgets-v2/histogram/index.d.ts +5 -0
  137. package/dist/types/widgets-v2/histogram/options.d.ts +42 -0
  138. package/dist/types/widgets-v2/histogram/options.test.d.ts +1 -0
  139. package/dist/types/widgets-v2/histogram/skeleton.d.ts +9 -0
  140. package/dist/types/widgets-v2/histogram/transforms.d.ts +17 -0
  141. package/dist/types/widgets-v2/histogram/transforms.test.d.ts +1 -0
  142. package/dist/types/widgets-v2/histogram/types.d.ts +47 -0
  143. package/dist/types/widgets-v2/index.d.ts +107 -0
  144. package/dist/types/widgets-v2/markdown/download.d.ts +16 -0
  145. package/dist/types/widgets-v2/markdown/download.test.d.ts +1 -0
  146. package/dist/types/widgets-v2/markdown/index.d.ts +6 -0
  147. package/dist/types/widgets-v2/markdown/markdown-content.d.ts +34 -0
  148. package/dist/types/widgets-v2/markdown/markdown-ui.d.ts +12 -0
  149. package/dist/types/widgets-v2/markdown/markdown.d.ts +6 -0
  150. package/dist/types/widgets-v2/markdown/skeleton.d.ts +4 -0
  151. package/dist/types/widgets-v2/markdown/style.d.ts +61 -0
  152. package/dist/types/widgets-v2/markdown/types.d.ts +4 -0
  153. package/dist/types/widgets-v2/note/labels.d.ts +5 -0
  154. package/dist/types/widgets-v2/note/style.d.ts +26 -0
  155. package/dist/types/widgets-v2/note/widget-note.d.ts +46 -0
  156. package/dist/types/widgets-v2/pie/download.d.ts +17 -0
  157. package/dist/types/widgets-v2/pie/download.test.d.ts +1 -0
  158. package/dist/types/widgets-v2/pie/index.d.ts +4 -0
  159. package/dist/types/widgets-v2/pie/options.d.ts +35 -0
  160. package/dist/types/widgets-v2/pie/options.test.d.ts +1 -0
  161. package/dist/types/widgets-v2/pie/skeleton.d.ts +4 -0
  162. package/dist/types/widgets-v2/pie/types.d.ts +50 -0
  163. package/dist/types/widgets-v2/provider/widget-provider.d.ts +32 -0
  164. package/dist/types/widgets-v2/range/index.d.ts +4 -0
  165. package/dist/types/widgets-v2/range/range-ui.d.ts +19 -0
  166. package/dist/types/widgets-v2/range/range.d.ts +19 -0
  167. package/dist/types/widgets-v2/range/skeleton.d.ts +9 -0
  168. package/dist/types/widgets-v2/range/style.d.ts +40 -0
  169. package/dist/types/widgets-v2/range/types.d.ts +37 -0
  170. package/dist/types/widgets-v2/scatterplot/download.d.ts +16 -0
  171. package/dist/types/widgets-v2/scatterplot/download.test.d.ts +1 -0
  172. package/dist/types/widgets-v2/scatterplot/index.d.ts +5 -0
  173. package/dist/types/widgets-v2/scatterplot/options.d.ts +42 -0
  174. package/dist/types/widgets-v2/scatterplot/options.test.d.ts +1 -0
  175. package/dist/types/widgets-v2/scatterplot/skeleton.d.ts +12 -0
  176. package/dist/types/widgets-v2/scatterplot/transforms.d.ts +17 -0
  177. package/dist/types/widgets-v2/scatterplot/transforms.test.d.ts +1 -0
  178. package/dist/types/widgets-v2/scatterplot/types.d.ts +50 -0
  179. package/dist/types/widgets-v2/selection-summary/labels.d.ts +6 -0
  180. package/dist/types/widgets-v2/selection-summary/selection-summary.d.ts +22 -0
  181. package/dist/types/widgets-v2/selection-summary/style.d.ts +23 -0
  182. package/dist/types/widgets-v2/spread/download.d.ts +15 -0
  183. package/dist/types/widgets-v2/spread/download.test.d.ts +1 -0
  184. package/dist/types/widgets-v2/spread/index.d.ts +6 -0
  185. package/dist/types/widgets-v2/spread/separator.d.ts +7 -0
  186. package/dist/types/widgets-v2/spread/skeleton.d.ts +9 -0
  187. package/dist/types/widgets-v2/spread/spread-ui.d.ts +18 -0
  188. package/dist/types/widgets-v2/spread/spread.d.ts +5 -0
  189. package/dist/types/widgets-v2/spread/types.d.ts +25 -0
  190. package/dist/types/widgets-v2/state/labels.d.ts +7 -0
  191. package/dist/types/widgets-v2/state/labels.test.d.ts +1 -0
  192. package/dist/types/widgets-v2/state/style.d.ts +19 -0
  193. package/dist/types/widgets-v2/state/widget-state.d.ts +19 -0
  194. package/dist/types/widgets-v2/stores/index.d.ts +8 -0
  195. package/dist/types/widgets-v2/stores/pipeline-middleware.d.ts +5 -0
  196. package/dist/types/widgets-v2/stores/pipeline-middleware.test.d.ts +1 -0
  197. package/dist/types/widgets-v2/stores/transforms.d.ts +4 -0
  198. package/dist/types/widgets-v2/stores/transforms.test.d.ts +1 -0
  199. package/dist/types/widgets-v2/stores/types.d.ts +55 -0
  200. package/dist/types/widgets-v2/stores/use-echart-instance.d.ts +15 -0
  201. package/dist/types/widgets-v2/stores/use-transform-enabled.d.ts +17 -0
  202. package/dist/types/widgets-v2/stores/use-transform.d.ts +12 -0
  203. package/dist/types/widgets-v2/stores/widget-context.d.ts +2 -0
  204. package/dist/types/widgets-v2/stores/widget-store-registry.d.ts +74 -0
  205. package/dist/types/widgets-v2/stores/widget-store-registry.test.d.ts +1 -0
  206. package/dist/types/widgets-v2/subheader/style.d.ts +10 -0
  207. package/dist/types/widgets-v2/subheader/subheader.d.ts +11 -0
  208. package/dist/types/widgets-v2/table/download.d.ts +18 -0
  209. package/dist/types/widgets-v2/table/download.test.d.ts +1 -0
  210. package/dist/types/widgets-v2/table/helpers.d.ts +32 -0
  211. package/dist/types/widgets-v2/table/helpers.test.d.ts +1 -0
  212. package/dist/types/widgets-v2/table/index.d.ts +7 -0
  213. package/dist/types/widgets-v2/table/labels.d.ts +22 -0
  214. package/dist/types/widgets-v2/table/skeleton.d.ts +22 -0
  215. package/dist/types/widgets-v2/table/style.d.ts +44 -0
  216. package/dist/types/widgets-v2/table/table-ui.d.ts +38 -0
  217. package/dist/types/widgets-v2/table/table.d.ts +50 -0
  218. package/dist/types/widgets-v2/table/types.d.ts +37 -0
  219. package/dist/types/widgets-v2/test-utils.d.ts +52 -0
  220. package/dist/types/widgets-v2/timeseries/download.d.ts +17 -0
  221. package/dist/types/widgets-v2/timeseries/download.test.d.ts +1 -0
  222. package/dist/types/widgets-v2/timeseries/index.d.ts +4 -0
  223. package/dist/types/widgets-v2/timeseries/options.d.ts +39 -0
  224. package/dist/types/widgets-v2/timeseries/options.test.d.ts +1 -0
  225. package/dist/types/widgets-v2/timeseries/skeleton.d.ts +8 -0
  226. package/dist/types/widgets-v2/timeseries/types.d.ts +56 -0
  227. package/dist/types/widgets-v2/toolbox/labels.d.ts +5 -0
  228. package/dist/types/widgets-v2/toolbox/style.d.ts +30 -0
  229. package/dist/types/widgets-v2/toolbox/toolbox.d.ts +49 -0
  230. package/dist/types/widgets-v2/utils/data-zoom-layout.d.ts +11 -0
  231. package/dist/types/widgets-v2/utils/index.d.ts +2 -0
  232. package/dist/types/widgets-v2/utils/merge-options.d.ts +12 -0
  233. package/dist/types/widgets-v2/utils/merge-options.test.d.ts +1 -0
  234. package/dist/types/widgets-v2/wrapper/index.d.ts +4 -0
  235. package/dist/types/widgets-v2/wrapper/labels.d.ts +6 -0
  236. package/dist/types/widgets-v2/wrapper/style.d.ts +111 -0
  237. package/dist/types/widgets-v2/wrapper/widget-actions.d.ts +22 -0
  238. package/dist/types/widgets-v2/wrapper/widget-content.d.ts +12 -0
  239. package/dist/types/widgets-v2/wrapper/widget-wrapper.d.ts +51 -0
  240. package/dist/use-transform-DXPN3nY7.js +110 -0
  241. package/dist/use-transform-DXPN3nY7.js.map +1 -0
  242. package/dist/widget-context-DTGO0Yta.js +13 -0
  243. package/dist/widget-context-DTGO0Yta.js.map +1 -0
  244. package/dist/widget-store-registry-_W4Z4xp-.js +178 -0
  245. package/dist/widget-store-registry-_W4Z4xp-.js.map +1 -0
  246. package/dist/widgets/bar.js +14 -13
  247. package/dist/widgets/bar.js.map +1 -1
  248. package/dist/widgets/histogram.js +8 -7
  249. package/dist/widgets/histogram.js.map +1 -1
  250. package/dist/widgets/pie.js +19 -18
  251. package/dist/widgets/pie.js.map +1 -1
  252. package/dist/widgets/scatterplot.js +8 -7
  253. package/dist/widgets/scatterplot.js.map +1 -1
  254. package/dist/widgets/timeseries.js +11 -10
  255. package/dist/widgets/timeseries.js.map +1 -1
  256. package/dist/widgets/utils.js +8 -7
  257. package/dist/widgets/utils.js.map +1 -1
  258. package/dist/widgets-v2/actions.js +43 -0
  259. package/dist/widgets-v2/actions.js.map +1 -0
  260. package/dist/widgets-v2/bar.js +327 -0
  261. package/dist/widgets-v2/bar.js.map +1 -0
  262. package/dist/widgets-v2/category.js +104 -0
  263. package/dist/widgets-v2/category.js.map +1 -0
  264. package/dist/widgets-v2/echart.js +57 -0
  265. package/dist/widgets-v2/echart.js.map +1 -0
  266. package/dist/widgets-v2/formula.js +74 -0
  267. package/dist/widgets-v2/formula.js.map +1 -0
  268. package/dist/widgets-v2/histogram.js +350 -0
  269. package/dist/widgets-v2/histogram.js.map +1 -0
  270. package/dist/widgets-v2/markdown.js +68 -0
  271. package/dist/widgets-v2/markdown.js.map +1 -0
  272. package/dist/widgets-v2/pie.js +381 -0
  273. package/dist/widgets-v2/pie.js.map +1 -0
  274. package/dist/widgets-v2/range.js +52 -0
  275. package/dist/widgets-v2/range.js.map +1 -0
  276. package/dist/widgets-v2/scatterplot.js +405 -0
  277. package/dist/widgets-v2/scatterplot.js.map +1 -0
  278. package/dist/widgets-v2/spread.js +72 -0
  279. package/dist/widgets-v2/spread.js.map +1 -0
  280. package/dist/widgets-v2/stores.js +42 -0
  281. package/dist/widgets-v2/stores.js.map +1 -0
  282. package/dist/widgets-v2/table.js +78 -0
  283. package/dist/widgets-v2/table.js.map +1 -0
  284. package/dist/widgets-v2/timeseries.js +352 -0
  285. package/dist/widgets-v2/timeseries.js.map +1 -0
  286. package/dist/widgets-v2/utils.js +7 -0
  287. package/dist/widgets-v2/utils.js.map +1 -0
  288. package/dist/widgets-v2.js +953 -0
  289. package/dist/widgets-v2.js.map +1 -0
  290. package/package.json +73 -5
  291. package/src/components/lasso-tool/chip.test.tsx +176 -0
  292. package/src/components/lasso-tool/lasso-tool-inline.test.tsx +171 -0
  293. package/src/components/lasso-tool/lasso-tool.test.tsx +198 -0
  294. package/src/components/list-data/list-data.test.tsx +73 -0
  295. package/src/components/no-data-alert/no-data-alert.test.tsx +38 -0
  296. package/src/components/responsive-drawer/responsive-drawer.test.tsx +68 -0
  297. package/src/widgets/actions/brush-toggle/brush-overlay.test.tsx +465 -0
  298. package/src/widgets/actions/brush-toggle/brush-toggle.test.tsx +208 -0
  299. package/src/widgets/actions/change-column/change-column-dnd.test.tsx +193 -0
  300. package/src/widgets/actions/change-column/sortable-column-item.test.tsx +124 -0
  301. package/src/widgets/actions/zoom-toggle/zoom-toggle.test.tsx +322 -0
  302. package/src/widgets/category/components/category-rows.test.tsx +213 -0
  303. package/src/widgets/echart/utils.test.ts +277 -0
  304. package/src/widgets/formula/config.test.ts +37 -0
  305. package/src/widgets/range/components/range-item.test.tsx +243 -0
  306. package/src/widgets/stores/widget-store-branches.test.ts +275 -0
  307. package/src/widgets/table/config.test.ts +65 -0
  308. package/src/widgets/utils/chart-config/option-builders.test.ts +188 -0
  309. package/src/widgets-v2/PERFORMANCE.md +189 -0
  310. package/src/widgets-v2/actions/brush-toggle/brush-toggle.test.tsx +180 -0
  311. package/src/widgets-v2/actions/brush-toggle/brush-toggle.tsx +154 -0
  312. package/src/widgets-v2/actions/brush-toggle/index.ts +3 -0
  313. package/src/widgets-v2/actions/brush-toggle/labels.ts +9 -0
  314. package/src/widgets-v2/actions/brush-toggle/style.ts +11 -0
  315. package/src/widgets-v2/actions/brush-toggle/transforms.test.ts +47 -0
  316. package/src/widgets-v2/actions/brush-toggle/transforms.ts +31 -0
  317. package/src/widgets-v2/actions/change-column/change-column-icon.tsx +14 -0
  318. package/src/widgets-v2/actions/change-column/change-column.test.tsx +59 -0
  319. package/src/widgets-v2/actions/change-column/change-column.tsx +180 -0
  320. package/src/widgets-v2/actions/change-column/index.ts +7 -0
  321. package/src/widgets-v2/actions/change-column/labels.ts +9 -0
  322. package/src/widgets-v2/actions/change-column/sortable-column-item.tsx +56 -0
  323. package/src/widgets-v2/actions/change-column/style.ts +32 -0
  324. package/src/widgets-v2/actions/change-column/types.ts +11 -0
  325. package/src/widgets-v2/actions/download/download.test.tsx +327 -0
  326. package/src/widgets-v2/actions/download/download.tsx +144 -0
  327. package/src/widgets-v2/actions/download/exports.test.tsx +198 -0
  328. package/src/widgets-v2/actions/download/exports.ts +115 -0
  329. package/src/widgets-v2/actions/download/icons.tsx +26 -0
  330. package/src/widgets-v2/actions/download/index.ts +13 -0
  331. package/src/widgets-v2/actions/download/labels.ts +16 -0
  332. package/src/widgets-v2/actions/download/png-item.test.tsx +72 -0
  333. package/src/widgets-v2/actions/download/png-item.tsx +52 -0
  334. package/src/widgets-v2/actions/download/style.ts +3 -0
  335. package/src/widgets-v2/actions/download/types.ts +32 -0
  336. package/src/widgets-v2/actions/fullscreen/fullscreen.test.tsx +150 -0
  337. package/src/widgets-v2/actions/fullscreen/fullscreen.tsx +230 -0
  338. package/src/widgets-v2/actions/fullscreen/index.ts +7 -0
  339. package/src/widgets-v2/actions/fullscreen/labels.ts +9 -0
  340. package/src/widgets-v2/actions/fullscreen/style.ts +59 -0
  341. package/src/widgets-v2/actions/fullscreen/types.ts +15 -0
  342. package/src/widgets-v2/actions/index.ts +82 -0
  343. package/src/widgets-v2/actions/lock-selection/index.ts +10 -0
  344. package/src/widgets-v2/actions/lock-selection/labels.ts +11 -0
  345. package/src/widgets-v2/actions/lock-selection/lock-selection.test.tsx +187 -0
  346. package/src/widgets-v2/actions/lock-selection/lock-selection.tsx +130 -0
  347. package/src/widgets-v2/actions/lock-selection/style.ts +11 -0
  348. package/src/widgets-v2/actions/lock-selection/transforms.ts +27 -0
  349. package/src/widgets-v2/actions/relative-data/index.ts +3 -0
  350. package/src/widgets-v2/actions/relative-data/labels.ts +9 -0
  351. package/src/widgets-v2/actions/relative-data/relative-data.test.tsx +71 -0
  352. package/src/widgets-v2/actions/relative-data/relative-data.tsx +107 -0
  353. package/src/widgets-v2/actions/relative-data/style.ts +11 -0
  354. package/src/widgets-v2/actions/relative-data/transforms.test.ts +151 -0
  355. package/src/widgets-v2/actions/relative-data/transforms.ts +70 -0
  356. package/src/widgets-v2/actions/searcher/filter.ts +28 -0
  357. package/src/widgets-v2/actions/searcher/index.ts +8 -0
  358. package/src/widgets-v2/actions/searcher/labels.ts +13 -0
  359. package/src/widgets-v2/actions/searcher/searcher-toggle.tsx +91 -0
  360. package/src/widgets-v2/actions/searcher/searcher.test.tsx +92 -0
  361. package/src/widgets-v2/actions/searcher/searcher.tsx +112 -0
  362. package/src/widgets-v2/actions/searcher/style.ts +15 -0
  363. package/src/widgets-v2/actions/stack-toggle/index.ts +3 -0
  364. package/src/widgets-v2/actions/stack-toggle/labels.ts +9 -0
  365. package/src/widgets-v2/actions/stack-toggle/stack-toggle.test.tsx +61 -0
  366. package/src/widgets-v2/actions/stack-toggle/stack-toggle.tsx +54 -0
  367. package/src/widgets-v2/actions/stack-toggle/style.ts +11 -0
  368. package/src/widgets-v2/actions/stack-toggle/transforms.test.ts +43 -0
  369. package/src/widgets-v2/actions/stack-toggle/transforms.ts +25 -0
  370. package/src/widgets-v2/actions/zoom-toggle/index.ts +9 -0
  371. package/src/widgets-v2/actions/zoom-toggle/labels.ts +9 -0
  372. package/src/widgets-v2/actions/zoom-toggle/style.ts +11 -0
  373. package/src/widgets-v2/actions/zoom-toggle/transforms.test.ts +148 -0
  374. package/src/widgets-v2/actions/zoom-toggle/transforms.ts +171 -0
  375. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.test.tsx +107 -0
  376. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.tsx +106 -0
  377. package/src/widgets-v2/bar/download.test.tsx +91 -0
  378. package/src/widgets-v2/bar/download.tsx +66 -0
  379. package/src/widgets-v2/bar/index.ts +10 -0
  380. package/src/widgets-v2/bar/options.test.ts +317 -0
  381. package/src/widgets-v2/bar/options.ts +326 -0
  382. package/src/widgets-v2/bar/skeleton.test.tsx +19 -0
  383. package/src/widgets-v2/bar/skeleton.tsx +69 -0
  384. package/src/widgets-v2/bar/types.ts +46 -0
  385. package/src/widgets-v2/category/category-ui.test.tsx +746 -0
  386. package/src/widgets-v2/category/category-ui.tsx +389 -0
  387. package/src/widgets-v2/category/category.relative-data.test.tsx +107 -0
  388. package/src/widgets-v2/category/category.stack-toggle.test.tsx +85 -0
  389. package/src/widgets-v2/category/category.test.tsx +305 -0
  390. package/src/widgets-v2/category/category.tsx +121 -0
  391. package/src/widgets-v2/category/components/category-bar-stacked.test.tsx +121 -0
  392. package/src/widgets-v2/category/components/category-bar-stacked.tsx +73 -0
  393. package/src/widgets-v2/category/components/category-bar.test.tsx +64 -0
  394. package/src/widgets-v2/category/components/category-bar.tsx +49 -0
  395. package/src/widgets-v2/category/components/category-legend.test.tsx +51 -0
  396. package/src/widgets-v2/category/components/category-legend.tsx +39 -0
  397. package/src/widgets-v2/category/components/category-row-multi.tsx +86 -0
  398. package/src/widgets-v2/category/components/category-row-other.test.tsx +28 -0
  399. package/src/widgets-v2/category/components/category-row-other.tsx +33 -0
  400. package/src/widgets-v2/category/components/category-row-single.tsx +76 -0
  401. package/src/widgets-v2/category/components/category-row-stacked.test.tsx +244 -0
  402. package/src/widgets-v2/category/components/category-row-stacked.tsx +99 -0
  403. package/src/widgets-v2/category/download.test.ts +71 -0
  404. package/src/widgets-v2/category/download.ts +54 -0
  405. package/src/widgets-v2/category/index.ts +32 -0
  406. package/src/widgets-v2/category/skeleton.test.tsx +26 -0
  407. package/src/widgets-v2/category/skeleton.tsx +74 -0
  408. package/src/widgets-v2/category/style.ts +290 -0
  409. package/src/widgets-v2/category/types.ts +54 -0
  410. package/src/widgets-v2/echart/echart-ui.test.tsx +232 -0
  411. package/src/widgets-v2/echart/echart-ui.tsx +184 -0
  412. package/src/widgets-v2/echart/echart.test.tsx +229 -0
  413. package/src/widgets-v2/echart/echart.tsx +199 -0
  414. package/src/widgets-v2/echart/index.ts +22 -0
  415. package/src/widgets-v2/echart/shared-resize-observer.test.ts +91 -0
  416. package/src/widgets-v2/echart/shared-resize-observer.ts +56 -0
  417. package/src/widgets-v2/echart/style.ts +8 -0
  418. package/src/widgets-v2/echart/use-chart-selection.test.tsx +118 -0
  419. package/src/widgets-v2/echart/use-chart-selection.ts +115 -0
  420. package/src/widgets-v2/formula/delta.tsx +61 -0
  421. package/src/widgets-v2/formula/download.test.tsx +65 -0
  422. package/src/widgets-v2/formula/download.tsx +69 -0
  423. package/src/widgets-v2/formula/formula-ui.test.tsx +91 -0
  424. package/src/widgets-v2/formula/formula-ui.tsx +66 -0
  425. package/src/widgets-v2/formula/formula.test.tsx +50 -0
  426. package/src/widgets-v2/formula/formula.tsx +34 -0
  427. package/src/widgets-v2/formula/index.ts +17 -0
  428. package/src/widgets-v2/formula/note.tsx +25 -0
  429. package/src/widgets-v2/formula/prefix.tsx +25 -0
  430. package/src/widgets-v2/formula/series.tsx +67 -0
  431. package/src/widgets-v2/formula/skeleton.test.tsx +21 -0
  432. package/src/widgets-v2/formula/skeleton.tsx +27 -0
  433. package/src/widgets-v2/formula/style.ts +31 -0
  434. package/src/widgets-v2/formula/subcomponents.test.tsx +107 -0
  435. package/src/widgets-v2/formula/suffix.tsx +25 -0
  436. package/src/widgets-v2/formula/types.ts +44 -0
  437. package/src/widgets-v2/formula/value.tsx +31 -0
  438. package/src/widgets-v2/histogram/download.test.ts +94 -0
  439. package/src/widgets-v2/histogram/download.ts +60 -0
  440. package/src/widgets-v2/histogram/index.ts +10 -0
  441. package/src/widgets-v2/histogram/options.test.ts +304 -0
  442. package/src/widgets-v2/histogram/options.ts +337 -0
  443. package/src/widgets-v2/histogram/skeleton.test.tsx +16 -0
  444. package/src/widgets-v2/histogram/skeleton.tsx +70 -0
  445. package/src/widgets-v2/histogram/transforms.test.ts +46 -0
  446. package/src/widgets-v2/histogram/transforms.ts +30 -0
  447. package/src/widgets-v2/histogram/types.ts +51 -0
  448. package/src/widgets-v2/index.ts +201 -0
  449. package/src/widgets-v2/markdown/download.test.ts +66 -0
  450. package/src/widgets-v2/markdown/download.ts +53 -0
  451. package/src/widgets-v2/markdown/index.ts +6 -0
  452. package/src/widgets-v2/markdown/markdown-content.test.tsx +155 -0
  453. package/src/widgets-v2/markdown/markdown-content.tsx +72 -0
  454. package/src/widgets-v2/markdown/markdown-ui.test.tsx +75 -0
  455. package/src/widgets-v2/markdown/markdown-ui.tsx +55 -0
  456. package/src/widgets-v2/markdown/markdown.test.tsx +39 -0
  457. package/src/widgets-v2/markdown/markdown.tsx +17 -0
  458. package/src/widgets-v2/markdown/skeleton.test.tsx +15 -0
  459. package/src/widgets-v2/markdown/skeleton.tsx +32 -0
  460. package/src/widgets-v2/markdown/style.ts +53 -0
  461. package/src/widgets-v2/markdown/types.ts +4 -0
  462. package/src/widgets-v2/note/labels.ts +9 -0
  463. package/src/widgets-v2/note/style.ts +26 -0
  464. package/src/widgets-v2/note/widget-note.test.tsx +158 -0
  465. package/src/widgets-v2/note/widget-note.tsx +172 -0
  466. package/src/widgets-v2/pie/download.test.ts +78 -0
  467. package/src/widgets-v2/pie/download.ts +55 -0
  468. package/src/widgets-v2/pie/index.ts +10 -0
  469. package/src/widgets-v2/pie/options.test.ts +585 -0
  470. package/src/widgets-v2/pie/options.ts +509 -0
  471. package/src/widgets-v2/pie/skeleton.test.tsx +17 -0
  472. package/src/widgets-v2/pie/skeleton.tsx +32 -0
  473. package/src/widgets-v2/pie/types.ts +55 -0
  474. package/src/widgets-v2/provider/widget-provider.test.tsx +119 -0
  475. package/src/widgets-v2/provider/widget-provider.tsx +111 -0
  476. package/src/widgets-v2/range/index.ts +4 -0
  477. package/src/widgets-v2/range/range-ui.test.tsx +130 -0
  478. package/src/widgets-v2/range/range-ui.tsx +211 -0
  479. package/src/widgets-v2/range/range.test.tsx +68 -0
  480. package/src/widgets-v2/range/range.tsx +46 -0
  481. package/src/widgets-v2/range/skeleton.test.tsx +17 -0
  482. package/src/widgets-v2/range/skeleton.tsx +47 -0
  483. package/src/widgets-v2/range/style.ts +41 -0
  484. package/src/widgets-v2/range/types.ts +37 -0
  485. package/src/widgets-v2/scatterplot/download.test.ts +71 -0
  486. package/src/widgets-v2/scatterplot/download.ts +54 -0
  487. package/src/widgets-v2/scatterplot/index.ts +11 -0
  488. package/src/widgets-v2/scatterplot/options.test.ts +399 -0
  489. package/src/widgets-v2/scatterplot/options.ts +421 -0
  490. package/src/widgets-v2/scatterplot/skeleton.test.tsx +17 -0
  491. package/src/widgets-v2/scatterplot/skeleton.tsx +84 -0
  492. package/src/widgets-v2/scatterplot/transforms.test.ts +97 -0
  493. package/src/widgets-v2/scatterplot/transforms.ts +38 -0
  494. package/src/widgets-v2/scatterplot/types.ts +55 -0
  495. package/src/widgets-v2/selection-summary/labels.ts +11 -0
  496. package/src/widgets-v2/selection-summary/selection-summary.test.tsx +53 -0
  497. package/src/widgets-v2/selection-summary/selection-summary.tsx +62 -0
  498. package/src/widgets-v2/selection-summary/style.ts +23 -0
  499. package/src/widgets-v2/spread/download.test.ts +64 -0
  500. package/src/widgets-v2/spread/download.ts +59 -0
  501. package/src/widgets-v2/spread/index.ts +6 -0
  502. package/src/widgets-v2/spread/separator.tsx +11 -0
  503. package/src/widgets-v2/spread/skeleton.test.tsx +17 -0
  504. package/src/widgets-v2/spread/skeleton.tsx +38 -0
  505. package/src/widgets-v2/spread/spread-ui.test.tsx +108 -0
  506. package/src/widgets-v2/spread/spread-ui.tsx +52 -0
  507. package/src/widgets-v2/spread/spread.test.tsx +50 -0
  508. package/src/widgets-v2/spread/spread.tsx +31 -0
  509. package/src/widgets-v2/spread/types.ts +27 -0
  510. package/src/widgets-v2/state/labels.test.ts +33 -0
  511. package/src/widgets-v2/state/labels.ts +20 -0
  512. package/src/widgets-v2/state/style.ts +25 -0
  513. package/src/widgets-v2/state/widget-state.test.tsx +294 -0
  514. package/src/widgets-v2/state/widget-state.tsx +184 -0
  515. package/src/widgets-v2/stores/index.ts +49 -0
  516. package/src/widgets-v2/stores/pipeline-middleware.test.ts +187 -0
  517. package/src/widgets-v2/stores/pipeline-middleware.ts +91 -0
  518. package/src/widgets-v2/stores/transforms.test.ts +162 -0
  519. package/src/widgets-v2/stores/transforms.ts +70 -0
  520. package/src/widgets-v2/stores/types.ts +64 -0
  521. package/src/widgets-v2/stores/use-echart-instance.test.tsx +91 -0
  522. package/src/widgets-v2/stores/use-echart-instance.ts +29 -0
  523. package/src/widgets-v2/stores/use-transform-enabled.test.tsx +127 -0
  524. package/src/widgets-v2/stores/use-transform-enabled.ts +25 -0
  525. package/src/widgets-v2/stores/use-transform.test.tsx +262 -0
  526. package/src/widgets-v2/stores/use-transform.ts +158 -0
  527. package/src/widgets-v2/stores/widget-context.test.tsx +58 -0
  528. package/src/widgets-v2/stores/widget-context.ts +15 -0
  529. package/src/widgets-v2/stores/widget-store-registry.test.ts +292 -0
  530. package/src/widgets-v2/stores/widget-store-registry.ts +248 -0
  531. package/src/widgets-v2/subheader/style.ts +12 -0
  532. package/src/widgets-v2/subheader/subheader.test.tsx +30 -0
  533. package/src/widgets-v2/subheader/subheader.tsx +16 -0
  534. package/src/widgets-v2/table/download.test.ts +75 -0
  535. package/src/widgets-v2/table/download.ts +47 -0
  536. package/src/widgets-v2/table/helpers.test.ts +214 -0
  537. package/src/widgets-v2/table/helpers.ts +136 -0
  538. package/src/widgets-v2/table/index.ts +23 -0
  539. package/src/widgets-v2/table/labels.tsx +41 -0
  540. package/src/widgets-v2/table/skeleton.test.tsx +26 -0
  541. package/src/widgets-v2/table/skeleton.tsx +65 -0
  542. package/src/widgets-v2/table/style.ts +46 -0
  543. package/src/widgets-v2/table/table-ui.test.tsx +200 -0
  544. package/src/widgets-v2/table/table-ui.tsx +331 -0
  545. package/src/widgets-v2/table/table.test.tsx +119 -0
  546. package/src/widgets-v2/table/table.tsx +174 -0
  547. package/src/widgets-v2/table/types.ts +44 -0
  548. package/src/widgets-v2/test-utils.ts +107 -0
  549. package/src/widgets-v2/timeseries/download.test.ts +95 -0
  550. package/src/widgets-v2/timeseries/download.ts +86 -0
  551. package/src/widgets-v2/timeseries/index.ts +10 -0
  552. package/src/widgets-v2/timeseries/options.test.ts +379 -0
  553. package/src/widgets-v2/timeseries/options.ts +341 -0
  554. package/src/widgets-v2/timeseries/skeleton.test.tsx +13 -0
  555. package/src/widgets-v2/timeseries/skeleton.tsx +76 -0
  556. package/src/widgets-v2/timeseries/types.ts +61 -0
  557. package/src/widgets-v2/toolbox/labels.ts +9 -0
  558. package/src/widgets-v2/toolbox/style.ts +33 -0
  559. package/src/widgets-v2/toolbox/toolbox.test.tsx +200 -0
  560. package/src/widgets-v2/toolbox/toolbox.tsx +309 -0
  561. package/src/widgets-v2/utils/data-zoom-layout.ts +26 -0
  562. package/src/widgets-v2/utils/index.ts +2 -0
  563. package/src/widgets-v2/utils/merge-options.test.ts +52 -0
  564. package/src/widgets-v2/utils/merge-options.ts +50 -0
  565. package/src/widgets-v2/wrapper/index.ts +14 -0
  566. package/src/widgets-v2/wrapper/labels.ts +11 -0
  567. package/src/widgets-v2/wrapper/style.ts +134 -0
  568. package/src/widgets-v2/wrapper/widget-actions.test.tsx +52 -0
  569. package/src/widgets-v2/wrapper/widget-actions.tsx +43 -0
  570. package/src/widgets-v2/wrapper/widget-content.test.tsx +27 -0
  571. package/src/widgets-v2/wrapper/widget-content.tsx +29 -0
  572. package/src/widgets-v2/wrapper/widget-wrapper.test.tsx +159 -0
  573. package/src/widgets-v2/wrapper/widget-wrapper.tsx +178 -0
  574. package/dist/styles-BYTyKQFP.js.map +0 -1
@@ -0,0 +1,187 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest'
2
+ import {
3
+ clearAllWidgetStores,
4
+ createWidgetStore,
5
+ } from './widget-store-registry'
6
+ import type { Transform, WidgetStoreApi } from './types'
7
+
8
+ const t = (
9
+ over: Partial<Transform> & { id: string; fn: Transform['fn']; order: number },
10
+ ): Transform => ({
11
+ type: 'data',
12
+ enabled: true,
13
+ ...over,
14
+ })
15
+
16
+ describe('pipeline-middleware', () => {
17
+ let store: WidgetStoreApi
18
+
19
+ beforeEach(() => {
20
+ store = createWidgetStore('pm-test', { data: 1 })
21
+ })
22
+
23
+ afterEach(() => {
24
+ clearAllWidgetStores()
25
+ })
26
+
27
+ it('runs the data pipeline when rawData changes', () => {
28
+ store.setState({
29
+ dataTransforms: [
30
+ t({ id: 'd', type: 'data', order: 1, fn: (n) => (n as number) * 2 }),
31
+ ],
32
+ })
33
+ store.setState({ rawData: 5 })
34
+ expect(store.getState().data).toBe(10)
35
+ })
36
+
37
+ it('skips the pipeline when neither rawData nor dataTransforms change', () => {
38
+ let runs = 0
39
+ store.setState({
40
+ dataTransforms: [
41
+ t({
42
+ id: 'd',
43
+ type: 'data',
44
+ order: 1,
45
+ fn: (n) => {
46
+ runs++
47
+ return n
48
+ },
49
+ }),
50
+ ],
51
+ })
52
+ const baseline = runs
53
+ store.setState({ isLoading: true })
54
+ expect(runs).toBe(baseline)
55
+ })
56
+
57
+ it('sets the error field when a transform throws', () => {
58
+ const bad = t({
59
+ id: 'bad',
60
+ type: 'data',
61
+ order: 1,
62
+ fn: () => {
63
+ throw new Error('pipeline-throw')
64
+ },
65
+ })
66
+ store.setState({ dataTransforms: [bad], rawData: 1 })
67
+ expect(store.getState().error).toBeInstanceOf(Error)
68
+ expect((store.getState().error as Error).message).toBe('pipeline-throw')
69
+ })
70
+
71
+ it('clears a stale error once a clean pipeline run completes', () => {
72
+ // First run throws and stamps `error` into state.
73
+ const bad = t({
74
+ id: 'bad',
75
+ type: 'data',
76
+ order: 1,
77
+ fn: () => {
78
+ throw new Error('one-shot-throw')
79
+ },
80
+ })
81
+ store.setState({ dataTransforms: [bad], rawData: 1 })
82
+ expect(store.getState().error).toBeInstanceOf(Error)
83
+ // Next pipeline run completes cleanly — the prior error must be cleared.
84
+ const ok = t({
85
+ id: 'ok',
86
+ type: 'data',
87
+ order: 1,
88
+ fn: (n) => n,
89
+ })
90
+ store.setState({ dataTransforms: [ok], rawData: 2 })
91
+ expect(store.getState().error).toBeUndefined()
92
+ })
93
+
94
+ it('preserves a consumer-set error when a clean pipeline runs (e.g. action mount adds dataTransforms)', () => {
95
+ // Regression: an action like StackToggle mounts and registers a
96
+ // dataTransforms entry; that triggers a pipeline run with no throw.
97
+ // The consumer-supplied error (Provider's `error` prop) must survive.
98
+ const consumerError = new Error('fetch failed')
99
+ store.setState({ error: consumerError })
100
+ // Action mount: a new dataTransforms array reference flows in.
101
+ store.setState({
102
+ dataTransforms: [
103
+ t({
104
+ id: 'noop',
105
+ type: 'data',
106
+ order: 1,
107
+ fn: (n) => n,
108
+ }),
109
+ ],
110
+ })
111
+ expect(store.getState().error).toBe(consumerError)
112
+ })
113
+
114
+ it('clears a consumer-set error when the consumer explicitly writes a new one mid-pipeline-run', () => {
115
+ const initial = new Error('first')
116
+ const next = new Error('second')
117
+ store.setState({ error: initial })
118
+ // Consumer writes `error` AND triggers the pipeline in the same call.
119
+ store.setState({
120
+ error: next,
121
+ rawData: 99,
122
+ })
123
+ expect(store.getState().error).toBe(next)
124
+ })
125
+
126
+ it('preserves the first error when multiple transforms throw', () => {
127
+ const a = t({
128
+ id: 'a',
129
+ type: 'data',
130
+ order: 1,
131
+ fn: () => {
132
+ throw new Error('first')
133
+ },
134
+ })
135
+ const b = t({
136
+ id: 'b',
137
+ type: 'data',
138
+ order: 2,
139
+ fn: () => {
140
+ throw new Error('second')
141
+ },
142
+ })
143
+ store.setState({ dataTransforms: [a, b], rawData: 1 })
144
+ expect((store.getState().error as Error).message).toBe('first')
145
+ })
146
+
147
+ it('passes incoming non-pipeline updates through unchanged', () => {
148
+ store.setState({ isFetching: true, isLoading: true })
149
+ expect(store.getState().isFetching).toBe(true)
150
+ expect(store.getState().isLoading).toBe(true)
151
+ })
152
+
153
+ it('runs the data pipeline when dataTransforms reference changes', () => {
154
+ const id1 = t({
155
+ id: 'a',
156
+ type: 'data',
157
+ order: 1,
158
+ fn: (n) => (n as number) + 1,
159
+ })
160
+ store.setState({ dataTransforms: [id1] })
161
+ expect(store.getState().data).toBe(2)
162
+ const id2 = t({
163
+ id: 'a',
164
+ type: 'data',
165
+ order: 1,
166
+ fn: (n) => (n as number) + 100,
167
+ })
168
+ store.setState({ dataTransforms: [id2] })
169
+ expect(store.getState().data).toBe(101)
170
+ })
171
+
172
+ it('one set call → one render — atomic raw + derived', () => {
173
+ let renders = 0
174
+ const unsub = store.subscribe(() => {
175
+ renders++
176
+ })
177
+ store.setState({
178
+ rawData: 5,
179
+ dataTransforms: [
180
+ t({ id: 'd', type: 'data', order: 1, fn: (n) => (n as number) * 2 }),
181
+ ],
182
+ })
183
+ expect(renders).toBe(1)
184
+ expect(store.getState().data).toBe(10)
185
+ unsub()
186
+ })
187
+ })
@@ -0,0 +1,91 @@
1
+ import type { StateCreator, StoreApi, StoreMutatorIdentifier } from 'zustand'
2
+ import type { Transform, WidgetState } from './types'
3
+ import { applyTransforms } from './transforms'
4
+
5
+ type PipelineMiddleware = <
6
+ T extends WidgetState,
7
+ Mps extends [StoreMutatorIdentifier, unknown][] = [],
8
+ Mcs extends [StoreMutatorIdentifier, unknown][] = [],
9
+ >(
10
+ config: StateCreator<T, Mps, Mcs>,
11
+ ) => StateCreator<T, Mps, Mcs>
12
+
13
+ type SetFn<T> = StoreApi<T>['setState']
14
+
15
+ // Per-store flag: true iff the current `state.error` was authored by the
16
+ // pipeline (a transform threw) rather than by the consumer (Provider's
17
+ // `error` prop or a direct setState). Lets the middleware clear stale
18
+ // pipeline errors on a subsequent clean run without clobbering errors a
19
+ // consumer set out-of-band.
20
+ const pipelineOwnedError = new WeakSet<StoreApi<WidgetState>>()
21
+
22
+ export const pipelineMiddleware: PipelineMiddleware = ((config) =>
23
+ (set, get, api) => {
24
+ const origSetState = api.setState as SetFn<WidgetState>
25
+ const typedApi = api as StoreApi<WidgetState>
26
+
27
+ const wrap = (delegate: SetFn<WidgetState>): SetFn<WidgetState> =>
28
+ ((partial, replace) => {
29
+ const current = (api.getState as () => WidgetState)()
30
+ const incoming =
31
+ typeof partial === 'function'
32
+ ? (partial as (s: WidgetState) => Partial<WidgetState>)(current)
33
+ : (partial as Partial<WidgetState>)
34
+
35
+ const has = (key: keyof WidgetState) =>
36
+ Object.prototype.hasOwnProperty.call(incoming, key)
37
+
38
+ const rawDataChanged =
39
+ has('rawData') && !Object.is(incoming.rawData, current.rawData)
40
+ const dataXfChanged =
41
+ has('dataTransforms') &&
42
+ incoming.dataTransforms !== current.dataTransforms
43
+
44
+ if (!rawDataChanged && !dataXfChanged) {
45
+ // Consumer-authored writes that don't trigger the pipeline. If the
46
+ // consumer is explicitly touching `error`, the next pipeline run is
47
+ // no longer responsible for it — drop the pipeline-owned marker.
48
+ if (has('error')) pipelineOwnedError.delete(typedApi)
49
+ return delegate(incoming, replace as false)
50
+ }
51
+
52
+ const augmented: Partial<WidgetState> = { ...incoming }
53
+ let firstError: unknown = undefined
54
+ const onError = (_id: string, err: Error) => {
55
+ if (firstError === undefined) firstError = err
56
+ }
57
+
58
+ const nextRaw = rawDataChanged ? incoming.rawData : current.rawData
59
+ const nextXf: readonly Transform[] = dataXfChanged
60
+ ? incoming.dataTransforms!
61
+ : current.dataTransforms
62
+ augmented.data = applyTransforms(nextRaw, nextXf, onError)
63
+
64
+ // Reconcile `error` based on who authored the previous value:
65
+ // - pipeline throw → stamp the new error, mark pipeline-owned.
66
+ // - clean run AND previous error was pipeline-owned → clear it.
67
+ // - clean run AND previous error was consumer-set → leave it.
68
+ // Consumer-authored `error` in `incoming` also wins over the marker
69
+ // (and resets the marker via the early-return branch above).
70
+ if (firstError !== undefined) {
71
+ augmented.error = firstError
72
+ pipelineOwnedError.add(typedApi)
73
+ } else if (pipelineOwnedError.has(typedApi) && !has('error')) {
74
+ augmented.error = undefined
75
+ pipelineOwnedError.delete(typedApi)
76
+ } else if (has('error')) {
77
+ // Consumer set error in the same call that ran the pipeline — honor
78
+ // their write and surrender ownership.
79
+ pipelineOwnedError.delete(typedApi)
80
+ }
81
+
82
+ return delegate(augmented, replace as false)
83
+ }) as SetFn<WidgetState>
84
+
85
+ // Wrap both the public setState (used by store.setState() callers) and
86
+ // the inner set passed into the state creator (used by actions inside config).
87
+ api.setState = wrap(origSetState) as typeof api.setState
88
+ const wrappedInnerSet = wrap(set as SetFn<WidgetState>)
89
+
90
+ return config(wrappedInnerSet as typeof set, get, api)
91
+ }) as PipelineMiddleware
@@ -0,0 +1,162 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { applyTransforms, upsertTransform, removeTransform } from './transforms'
3
+ import type { Transform } from './types'
4
+
5
+ const t = (
6
+ over: Partial<Transform> & { id: string; fn: Transform['fn']; order: number },
7
+ ): Transform => ({
8
+ type: 'data',
9
+ enabled: true,
10
+ ...over,
11
+ })
12
+
13
+ describe('applyTransforms', () => {
14
+ it('returns input when transforms array is empty', () => {
15
+ expect(applyTransforms({ a: 1 }, [])).toEqual({ a: 1 })
16
+ })
17
+
18
+ it('applies a single enabled transform', () => {
19
+ const out = applyTransforms(2, [
20
+ t({ id: 'x2', order: 1, fn: (n) => (n as number) * 2 }),
21
+ ])
22
+ expect(out).toBe(4)
23
+ })
24
+
25
+ it('chains transforms in order', () => {
26
+ const xs = [
27
+ t({ id: 'a', order: 1, fn: (n) => (n as number) + 1 }),
28
+ t({ id: 'b', order: 2, fn: (n) => (n as number) * 10 }),
29
+ ]
30
+ expect(applyTransforms(1, xs)).toBe(20)
31
+ })
32
+
33
+ it('skips disabled transforms', () => {
34
+ const xs = [
35
+ t({ id: 'a', order: 1, fn: (n) => (n as number) + 1 }),
36
+ t({ id: 'b', order: 2, fn: (n) => (n as number) * 10, enabled: false }),
37
+ ]
38
+ expect(applyTransforms(1, xs)).toBe(2)
39
+ })
40
+
41
+ it('respects disables map: enabled transform disables another', () => {
42
+ const xs = [
43
+ t({ id: 'a', order: 1, fn: (n) => (n as number) + 1, disables: ['b'] }),
44
+ t({ id: 'b', order: 2, fn: (n) => (n as number) * 10 }),
45
+ ]
46
+ expect(applyTransforms(1, xs)).toBe(2)
47
+ })
48
+
49
+ it('does not apply disables when the disabling transform itself is disabled', () => {
50
+ const xs = [
51
+ t({
52
+ id: 'a',
53
+ order: 1,
54
+ fn: (n) => (n as number) + 1,
55
+ disables: ['b'],
56
+ enabled: false,
57
+ }),
58
+ t({ id: 'b', order: 2, fn: (n) => (n as number) * 10 }),
59
+ ]
60
+ expect(applyTransforms(1, xs)).toBe(10)
61
+ })
62
+
63
+ it('captures the first error and continues with remaining transforms', () => {
64
+ const errors: { id: string; msg: string }[] = []
65
+ const xs = [
66
+ t({
67
+ id: 'bad',
68
+ order: 1,
69
+ fn: () => {
70
+ throw new Error('boom')
71
+ },
72
+ }),
73
+ t({ id: 'good', order: 2, fn: (n) => (n as number) * 2 }),
74
+ ]
75
+ const out = applyTransforms(3, xs, (id, err) =>
76
+ errors.push({ id, msg: err.message }),
77
+ )
78
+ expect(out).toBe(6)
79
+ expect(errors).toEqual([{ id: 'bad', msg: 'boom' }])
80
+ })
81
+
82
+ it('wraps non-Error throws as Error', () => {
83
+ const errors: Error[] = []
84
+ applyTransforms(
85
+ 1,
86
+ [
87
+ t({
88
+ id: 'x',
89
+ order: 1,
90
+ fn: () => {
91
+ // eslint-disable-next-line @typescript-eslint/only-throw-error -- exercising non-Error wrap
92
+ throw 'string-throw'
93
+ },
94
+ }),
95
+ ],
96
+ (_id, err) => errors.push(err),
97
+ )
98
+ expect(errors[0]).toBeInstanceOf(Error)
99
+ expect(errors[0]?.message).toBe('string-throw')
100
+ })
101
+ })
102
+
103
+ describe('upsertTransform', () => {
104
+ it('inserts new transforms in ascending order', () => {
105
+ const a = t({ id: 'a', order: 10, fn: (n) => n })
106
+ const b = t({ id: 'b', order: 5, fn: (n) => n })
107
+ const c = t({ id: 'c', order: 20, fn: (n) => n })
108
+ const out = upsertTransform(upsertTransform(upsertTransform([], a), b), c)
109
+ expect(out.map((x) => x.id)).toEqual(['b', 'a', 'c'])
110
+ })
111
+
112
+ it('returns the same array reference when transform is identical', () => {
113
+ const fn = (n: unknown) => n
114
+ const a = t({ id: 'a', order: 1, fn })
115
+ const arr = upsertTransform([], a)
116
+ const next = upsertTransform(arr, t({ id: 'a', order: 1, fn }))
117
+ expect(next).toBe(arr)
118
+ })
119
+
120
+ it('replaces an existing transform when fn changes', () => {
121
+ const a1 = t({ id: 'a', order: 1, fn: (n) => n })
122
+ const a2 = t({ id: 'a', order: 1, fn: (n) => (n as number) + 1 })
123
+ const arr = upsertTransform([], a1)
124
+ const next = upsertTransform(arr, a2)
125
+ expect(next).not.toBe(arr)
126
+ expect(next.find((x) => x.id === 'a')?.fn).toBe(a2.fn)
127
+ })
128
+
129
+ it('reorders when order changes', () => {
130
+ const a = t({ id: 'a', order: 10, fn: (n) => n })
131
+ const b = t({ id: 'b', order: 20, fn: (n) => n })
132
+ const arr = [a, b]
133
+ const next = upsertTransform(arr, t({ id: 'a', order: 30, fn: a.fn }))
134
+ expect(next.map((x) => x.id)).toEqual(['b', 'a'])
135
+ })
136
+
137
+ it('treats different disables as a structural change', () => {
138
+ const a1 = t({ id: 'a', order: 1, fn: (n) => n, disables: ['b'] })
139
+ const a2 = t({ id: 'a', order: 1, fn: a1.fn, disables: ['c'] })
140
+ const arr = upsertTransform([], a1)
141
+ const next = upsertTransform(arr, a2)
142
+ expect(next).not.toBe(arr)
143
+ expect(next.find((x) => x.id === 'a')?.disables).toEqual(['c'])
144
+ })
145
+ })
146
+
147
+ describe('removeTransform', () => {
148
+ it('removes a transform by id', () => {
149
+ const arr = [
150
+ t({ id: 'a', order: 1, fn: (n) => n }),
151
+ t({ id: 'b', order: 2, fn: (n) => n }),
152
+ ]
153
+ const next = removeTransform(arr, 'a')
154
+ expect(next.map((x) => x.id)).toEqual(['b'])
155
+ })
156
+
157
+ it('returns the same array reference when id is absent', () => {
158
+ const arr = [t({ id: 'a', order: 1, fn: (n) => n })]
159
+ const next = removeTransform(arr, 'missing')
160
+ expect(next).toBe(arr)
161
+ })
162
+ })
@@ -0,0 +1,70 @@
1
+ import type { Transform } from './types'
2
+
3
+ export function applyTransforms(
4
+ input: unknown,
5
+ transforms: readonly Transform[],
6
+ onError?: (id: string, error: Error) => void,
7
+ ): unknown {
8
+ const disabledIds = new Set<string>()
9
+ for (const t of transforms) {
10
+ if (t.enabled && t.disables?.length) {
11
+ for (const id of t.disables) disabledIds.add(id)
12
+ }
13
+ }
14
+ let acc: unknown = input
15
+ for (const t of transforms) {
16
+ if (!t.enabled) continue
17
+ if (disabledIds.has(t.id)) continue
18
+ try {
19
+ acc = t.fn(acc)
20
+ } catch (e) {
21
+ const err = e instanceof Error ? e : new Error(String(e))
22
+ // eslint-disable-next-line no-console
23
+ console.warn(`[widgets-v2] Transform "${t.id}" failed:`, err)
24
+ onError?.(t.id, err)
25
+ }
26
+ }
27
+ return acc
28
+ }
29
+
30
+ export function upsertTransform(
31
+ transforms: readonly Transform[],
32
+ next: Transform,
33
+ ): readonly Transform[] {
34
+ const existing = transforms.find((t) => t.id === next.id)
35
+ if (
36
+ existing?.order === next.order &&
37
+ existing?.enabled === next.enabled &&
38
+ existing?.fn === next.fn &&
39
+ existing?.type === next.type &&
40
+ sameStringArray(existing?.disables, next.disables) &&
41
+ sameStringArray(existing?.replaceMergeKeys, next.replaceMergeKeys)
42
+ ) {
43
+ return transforms
44
+ }
45
+ const filtered = transforms.filter((t) => t.id !== next.id)
46
+ const idx = filtered.findIndex((t) => t.order > next.order)
47
+ const out = filtered.slice()
48
+ out.splice(idx === -1 ? out.length : idx, 0, next)
49
+ return out
50
+ }
51
+
52
+ export function removeTransform(
53
+ transforms: readonly Transform[],
54
+ id: string,
55
+ ): readonly Transform[] {
56
+ if (!transforms.some((t) => t.id === id)) return transforms
57
+ return transforms.filter((t) => t.id !== id)
58
+ }
59
+
60
+ function sameStringArray(
61
+ a?: readonly string[],
62
+ b?: readonly string[],
63
+ ): boolean {
64
+ if (a === b) return true
65
+ if (!a) return !b?.length
66
+ if (!b) return !a.length
67
+ if (a.length !== b.length) return false
68
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false
69
+ return true
70
+ }
@@ -0,0 +1,64 @@
1
+ import type { StoreApi } from 'zustand'
2
+
3
+ export type TransformType = 'data' | 'config'
4
+
5
+ export interface TransformDescriptor {
6
+ id: string
7
+ type: TransformType
8
+ order: number
9
+ disables?: string[]
10
+ replaceMergeKeys?: string[]
11
+ }
12
+
13
+ export type TransformFn = (input: unknown) => unknown
14
+
15
+ export interface Transform extends TransformDescriptor {
16
+ fn: TransformFn
17
+ enabled: boolean
18
+ }
19
+
20
+ export interface TransformPair {
21
+ descriptor: TransformDescriptor
22
+ fn: TransformFn
23
+ }
24
+
25
+ export interface WidgetState {
26
+ rawData: unknown
27
+ data: unknown
28
+
29
+ dataTransforms: readonly Transform[]
30
+ configTransforms: readonly Transform[]
31
+
32
+ transformStates: Record<string, { enabled: boolean; [k: string]: unknown }>
33
+
34
+ isLoading: boolean
35
+ isFetching: boolean
36
+ error: unknown
37
+
38
+ /**
39
+ * Original formatter as supplied by the consumer (Provider's `formatter`
40
+ * prop). Always live-synced — never overridden by actions. Actions that need
41
+ * to display a different formatter (e.g. {@link RelativeData}'s percent
42
+ * formatter) should write to {@link WidgetState.formatter} and read this
43
+ * field when restoring the absolute view.
44
+ */
45
+ rawFormatter?: (value: number) => string
46
+ /**
47
+ * Active formatter — what consumer code (tooltips, axis labels, legends,
48
+ * etc.) reads. Defaults to {@link WidgetState.rawFormatter}; actions may
49
+ * override it temporarily and restore it from `rawFormatter` later.
50
+ */
51
+ formatter?: (value: number) => string
52
+ labelFormatter?: (value: string | number) => string | number
53
+ }
54
+
55
+ export interface WidgetInit {
56
+ data: unknown
57
+ isLoading?: boolean
58
+ isFetching?: boolean
59
+ error?: unknown
60
+ formatter?: (value: number) => string
61
+ labelFormatter?: (value: string | number) => string | number
62
+ }
63
+
64
+ export type WidgetStoreApi = StoreApi<WidgetState>
@@ -0,0 +1,91 @@
1
+ import { useEffect } from 'react'
2
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest'
3
+ import { act, render } from '@testing-library/react'
4
+ import type { ECharts } from 'echarts'
5
+ import { useEchartInstance } from './use-echart-instance'
6
+ import {
7
+ clearAllWidgetStores,
8
+ setEchartInstance,
9
+ } from './widget-store-registry'
10
+
11
+ const captured: { value: ECharts | null; renders: number } = {
12
+ value: null,
13
+ renders: 0,
14
+ }
15
+
16
+ function Probe({ id }: { id: string }) {
17
+ const chart = useEchartInstance(id)
18
+ // Capture in an effect so the React Compiler doesn't flag the
19
+ // outside-component mutations during render.
20
+ useEffect(() => {
21
+ captured.value = chart
22
+ captured.renders += 1
23
+ })
24
+ return null
25
+ }
26
+
27
+ beforeEach(() => {
28
+ clearAllWidgetStores()
29
+ captured.value = null
30
+ captured.renders = 0
31
+ })
32
+ afterEach(() => clearAllWidgetStores())
33
+
34
+ function makeChart(): ECharts {
35
+ return {} as unknown as ECharts
36
+ }
37
+
38
+ describe('useEchartInstance', () => {
39
+ it('returns null when no instance is registered', () => {
40
+ render(<Probe id='h1' />)
41
+ expect(captured.value).toBeNull()
42
+ })
43
+
44
+ it('re-renders the consumer when the instance arrives', () => {
45
+ render(<Probe id='h2' />)
46
+ const initialRenders = captured.renders
47
+ const chart = makeChart()
48
+ act(() => setEchartInstance('h2', chart))
49
+ expect(captured.value).toBe(chart)
50
+ expect(captured.renders).toBeGreaterThan(initialRenders)
51
+ })
52
+
53
+ it('re-renders again when the instance changes', () => {
54
+ render(<Probe id='h3' />)
55
+ const a = makeChart()
56
+ const b = makeChart()
57
+ act(() => setEchartInstance('h3', a))
58
+ expect(captured.value).toBe(a)
59
+ act(() => setEchartInstance('h3', b))
60
+ expect(captured.value).toBe(b)
61
+ })
62
+
63
+ it('re-renders with null when the instance is cleared', () => {
64
+ render(<Probe id='h4' />)
65
+ act(() => setEchartInstance('h4', makeChart()))
66
+ expect(captured.value).not.toBeNull()
67
+ act(() => setEchartInstance('h4', null))
68
+ expect(captured.value).toBeNull()
69
+ })
70
+
71
+ it('isolates ids', () => {
72
+ const latest: { a: ECharts | null; b: ECharts | null } = {
73
+ a: null,
74
+ b: null,
75
+ }
76
+ function ProbeMulti() {
77
+ const a = useEchartInstance('h5-a')
78
+ const b = useEchartInstance('h5-b')
79
+ useEffect(() => {
80
+ latest.a = a
81
+ latest.b = b
82
+ })
83
+ return null
84
+ }
85
+ render(<ProbeMulti />)
86
+ const aChart = makeChart()
87
+ act(() => setEchartInstance('h5-a', aChart))
88
+ expect(latest.a).toBe(aChart)
89
+ expect(latest.b).toBeNull()
90
+ })
91
+ })
@@ -0,0 +1,29 @@
1
+ import { useSyncExternalStore } from 'react'
2
+ import type { ECharts } from 'echarts'
3
+ import {
4
+ getEchartInstance,
5
+ subscribeEchartInstance,
6
+ } from './widget-store-registry'
7
+
8
+ const SSR_SNAPSHOT = (): ECharts | null => null
9
+
10
+ /**
11
+ * Reactive read of the live ECharts instance for a widget. Returns
12
+ * `null` before the `Widget.Echart` bridge has mounted (or after it's
13
+ * disposed); the consumer re-renders when the instance arrives /
14
+ * departs / changes.
15
+ *
16
+ * Wraps {@link subscribeEchartInstance} via `useSyncExternalStore`, so
17
+ * actions can use it inside an effect's deps array to react to chart
18
+ * lifecycle events without polling. Required for actions like
19
+ * `BrushToggle` whose effect needs to dispatch `takeGlobalCursor` the
20
+ * moment the chart exists, then re-dispatch on every `'finished'`
21
+ * event.
22
+ */
23
+ export function useEchartInstance(id: string): ECharts | null {
24
+ return useSyncExternalStore(
25
+ (cb) => subscribeEchartInstance(id, cb),
26
+ () => getEchartInstance(id),
27
+ SSR_SNAPSHOT,
28
+ )
29
+ }