@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,119 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest'
2
+ import { render } from '@testing-library/react'
3
+ import { Provider } from './widget-provider'
4
+ import {
5
+ clearAllWidgetStores,
6
+ getWidgetStore,
7
+ hasWidgetStore,
8
+ useWidgetId,
9
+ } from '../stores'
10
+
11
+ beforeEach(() => clearAllWidgetStores())
12
+ afterEach(() => clearAllWidgetStores())
13
+
14
+ function ChildSpy({ onMount }: { onMount: (id: string) => void }) {
15
+ const id = useWidgetId()
16
+ onMount(id)
17
+ return null
18
+ }
19
+
20
+ describe('<Provider>', () => {
21
+ it('creates a store and exposes the id via context', () => {
22
+ const ids: string[] = []
23
+ render(
24
+ <Provider id='p1' data={{ x: 1 }}>
25
+ <ChildSpy onMount={(i) => ids.push(i)} />
26
+ </Provider>,
27
+ )
28
+ expect(ids).toEqual(['p1'])
29
+ expect(hasWidgetStore('p1')).toBe(true)
30
+ const s = getWidgetStore('p1').getState()
31
+ expect(s.rawData).toEqual({ x: 1 })
32
+ // Provider is renderer-agnostic — option pipeline state lives in
33
+ // `<Widget.Echart>`, not on the store.
34
+ expect(
35
+ (s as unknown as { rawOptions?: unknown }).rawOptions,
36
+ ).toBeUndefined()
37
+ })
38
+
39
+ it('removes the store on unmount when keepAlive is false (default)', () => {
40
+ const { unmount } = render(
41
+ <Provider id='p2' data={null}>
42
+ <span />
43
+ </Provider>,
44
+ )
45
+ unmount()
46
+ expect(hasWidgetStore('p2')).toBe(false)
47
+ })
48
+
49
+ it('preserves the store on unmount when keepAlive is true', () => {
50
+ const { unmount } = render(
51
+ <Provider id='p3' data={null} keepAlive>
52
+ <span />
53
+ </Provider>,
54
+ )
55
+ unmount()
56
+ expect(hasWidgetStore('p3')).toBe(true)
57
+ })
58
+
59
+ it('reuses an existing keepAlive store on remount and preserves transformStates', () => {
60
+ const { unmount } = render(
61
+ <Provider id='p4' data={null} keepAlive>
62
+ <span />
63
+ </Provider>,
64
+ )
65
+ getWidgetStore('p4').setState({
66
+ transformStates: { foo: { enabled: false } },
67
+ })
68
+ unmount()
69
+ render(
70
+ <Provider id='p4' data={null} keepAlive>
71
+ <span />
72
+ </Provider>,
73
+ )
74
+ expect(getWidgetStore('p4').getState().transformStates.foo).toEqual({
75
+ enabled: false,
76
+ })
77
+ })
78
+
79
+ it('syncs data / isLoading / error / formatter prop changes onto the store', () => {
80
+ const fmt = (n: number): string => `$${n}`
81
+ const { rerender } = render(
82
+ <Provider id='p5' data={1} formatter={fmt}>
83
+ <span />
84
+ </Provider>,
85
+ )
86
+ expect(getWidgetStore('p5').getState().rawData).toBe(1)
87
+ rerender(
88
+ <Provider
89
+ id='p5'
90
+ data={2}
91
+ isLoading
92
+ error={{ message: 'oops' }}
93
+ formatter={fmt}
94
+ >
95
+ <span />
96
+ </Provider>,
97
+ )
98
+ const s = getWidgetStore('p5').getState()
99
+ expect(s.rawData).toBe(2)
100
+ expect(s.isLoading).toBe(true)
101
+ expect(s.error).toEqual({ message: 'oops' })
102
+ expect(s.formatter).toBe(fmt)
103
+ })
104
+
105
+ it('descendants see the store on first render (sync registration in lazy init)', () => {
106
+ function Spy() {
107
+ const id = useWidgetId()
108
+ // If the store wasn't registered synchronously this would throw.
109
+ const data = getWidgetStore(id).getState().rawData
110
+ return <span data-testid='data'>{JSON.stringify(data)}</span>
111
+ }
112
+ const { getByTestId } = render(
113
+ <Provider id='p6' data={{ initial: true }}>
114
+ <Spy />
115
+ </Provider>,
116
+ )
117
+ expect(getByTestId('data').textContent).toBe('{"initial":true}')
118
+ })
119
+ })
@@ -0,0 +1,111 @@
1
+ import { useLayoutEffect, useState, type ReactNode } from 'react'
2
+ import {
3
+ WidgetContext,
4
+ createWidgetStore,
5
+ hasWidgetStore,
6
+ getWidgetStore,
7
+ registerWidgetStore,
8
+ setWidgetStoreEntry,
9
+ unregisterWidgetStore,
10
+ } from '../stores'
11
+ import type { WidgetStoreApi } from '../stores'
12
+
13
+ export interface ProviderProps {
14
+ id: string
15
+ data: unknown
16
+ isLoading?: boolean
17
+ isFetching?: boolean
18
+ error?: unknown
19
+ formatter?: (value: number) => string
20
+ labelFormatter?: (value: string | number) => string | number
21
+ /**
22
+ * When `true`, the per-widget store survives unmount so transformStates,
23
+ * search text, fullscreen state, etc. are preserved across remounts.
24
+ * Consumers using keepAlive must call `deleteWidgetStore(id)` themselves
25
+ * when the widget is permanently removed — there is no automatic GC.
26
+ */
27
+ keepAlive?: boolean
28
+ children: ReactNode
29
+ }
30
+
31
+ /**
32
+ * Renderer-agnostic widget shell. Creates a per-widget Zustand store
33
+ * keyed by `id`, syncs the consumer props (`data`, `isLoading`, `error`,
34
+ * `formatter`, …) onto it, and exposes the `id` via `WidgetContext` so
35
+ * descendants can resolve their store with `useWidgetId()`.
36
+ *
37
+ * The Provider deliberately doesn't know about ECharts — there's no
38
+ * `optionFactory` prop here. ECharts-backed widgets pass their factory
39
+ * to `<Widget.Echart optionFactory={…}>`, which owns the structural
40
+ * seed + the data-fusion render step entirely. Non-Echart widgets
41
+ * (Formula, Spread, Range, Table, Category, Markdown) just don't pass
42
+ * anything ECharts-shaped.
43
+ */
44
+ export function Provider({
45
+ id,
46
+ data,
47
+ isLoading,
48
+ isFetching,
49
+ error,
50
+ formatter,
51
+ labelFormatter,
52
+ keepAlive = false,
53
+ children,
54
+ }: ProviderProps) {
55
+ // Lazy init — reuse an existing keepAlive store, otherwise create one and
56
+ // synchronously place it in the registry so descendants can call
57
+ // useWidget(id, ...) on first render. Refcounting + dup-id detection happen
58
+ // in the mount layout-effect below.
59
+ const [store] = useState<WidgetStoreApi>(() => {
60
+ if (hasWidgetStore(id)) return getWidgetStore(id)
61
+ const created = createWidgetStore(id, {
62
+ data,
63
+ isLoading,
64
+ isFetching,
65
+ error,
66
+ formatter,
67
+ labelFormatter,
68
+ })
69
+ setWidgetStoreEntry(id, created)
70
+ return created
71
+ })
72
+
73
+ // Registration: refcount the mount for dup-id detection; unregister on
74
+ // unmount or when the id/store/keepAlive triple changes.
75
+ useLayoutEffect(() => {
76
+ registerWidgetStore(id, store)
77
+ return () => {
78
+ unregisterWidgetStore(id, { keepAlive })
79
+ }
80
+ }, [id, store, keepAlive])
81
+
82
+ // Per-prop sync. `useLayoutEffect` so kept-alive remounts apply incoming
83
+ // props before paint (no flash of stale data when reusing a store).
84
+ // The pipeline middleware bypasses unchanged fields, so unchanged props
85
+ // are a no-op even though setState is called every effect run.
86
+ useLayoutEffect(() => {
87
+ store.setState({ rawData: data })
88
+ }, [store, data])
89
+
90
+ useLayoutEffect(() => {
91
+ store.setState({
92
+ isLoading: isLoading ?? false,
93
+ isFetching: isFetching ?? false,
94
+ error,
95
+ })
96
+ }, [store, isLoading, isFetching, error])
97
+
98
+ // Sync the consumer's formatter prop to BOTH `rawFormatter` (kept canonical
99
+ // for actions that need to restore the absolute view) and `formatter` (the
100
+ // active value). Actions like RelativeData re-apply their override after
101
+ // `rawFormatter` changes.
102
+ useLayoutEffect(() => {
103
+ store.setState({
104
+ rawFormatter: formatter,
105
+ formatter,
106
+ labelFormatter,
107
+ })
108
+ }, [store, formatter, labelFormatter])
109
+
110
+ return <WidgetContext.Provider value={id}>{children}</WidgetContext.Provider>
111
+ }
@@ -0,0 +1,4 @@
1
+ export { Range, type RangeProps } from './range'
2
+ export { RangeUI, type RangeUIProps } from './range-ui'
3
+ export { RangeSkeleton, type RangeSkeletonProps } from './skeleton'
4
+ export type { RangeDataItem, RangeWidgetData, RangeItemValue } from './types'
@@ -0,0 +1,130 @@
1
+ import { describe, it, expect, vi } from 'vitest'
2
+ import { fireEvent, render, screen } from '@testing-library/react'
3
+ import { RangeUI } from './range-ui'
4
+
5
+ describe('<RangeUI>', () => {
6
+ it('renders a two-thumb slider per item', () => {
7
+ render(<RangeUI items={[{ min: 0, max: 100, value: [20, 80] }]} />)
8
+ const sliders = screen.getAllByRole('slider')
9
+ expect(sliders).toHaveLength(2)
10
+ expect(sliders[0]?.getAttribute('aria-valuenow')).toBe('20')
11
+ expect(sliders[1]?.getAttribute('aria-valuenow')).toBe('80')
12
+ })
13
+
14
+ it('defaults the value to [min, max] when omitted', () => {
15
+ render(<RangeUI items={[{ min: 10, max: 90 }]} />)
16
+ const sliders = screen.getAllByRole('slider')
17
+ expect(sliders[0]?.getAttribute('aria-valuenow')).toBe('10')
18
+ expect(sliders[1]?.getAttribute('aria-valuenow')).toBe('90')
19
+ })
20
+
21
+ it('renders editable min/max text inputs below the slider', () => {
22
+ render(<RangeUI items={[{ min: 0, max: 100, value: [20, 80] }]} />)
23
+ const min = screen.getByLabelText<HTMLInputElement>('Minimum value')
24
+ const max = screen.getByLabelText<HTMLInputElement>('Maximum value')
25
+ expect(min).toBeTruthy()
26
+ expect(max).toBeTruthy()
27
+ // The displayed value passes through the formatter (default toString).
28
+ expect(min.value).toBe('20')
29
+ expect(max.value).toBe('80')
30
+ })
31
+
32
+ it('runs the formatter through the text inputs', () => {
33
+ render(
34
+ <RangeUI
35
+ items={[{ min: 0, max: 1000, value: [100, 900] }]}
36
+ formatter={(n) => `$${n}`}
37
+ />,
38
+ )
39
+ const min = screen.getByLabelText<HTMLInputElement>('Minimum value')
40
+ const max = screen.getByLabelText<HTMLInputElement>('Maximum value')
41
+ expect(min.value).toBe('$100')
42
+ expect(max.value).toBe('$900')
43
+ })
44
+
45
+ it('renders a caption below the inputs when `note` is provided', () => {
46
+ render(
47
+ <RangeUI
48
+ items={[{ min: 0, max: 100, value: [25, 75], note: 'Filter window' }]}
49
+ />,
50
+ )
51
+ expect(screen.getByText('Filter window')).toBeTruthy()
52
+ })
53
+
54
+ it('renders multiple sliders stacked', () => {
55
+ render(
56
+ <RangeUI
57
+ items={[
58
+ { min: 0, max: 100, value: [10, 50], note: 'A' },
59
+ { min: 0, max: 100, value: [25, 75], note: 'B' },
60
+ { min: 0, max: 50, value: [10, 30], note: 'C' },
61
+ ]}
62
+ />,
63
+ )
64
+ expect(screen.getByText('A')).toBeTruthy()
65
+ expect(screen.getByText('B')).toBeTruthy()
66
+ expect(screen.getByText('C')).toBeTruthy()
67
+ // Three two-thumb sliders → 6 thumbs total.
68
+ expect(screen.getAllByRole('slider')).toHaveLength(6)
69
+ })
70
+
71
+ it('fires onChange with the item index and a clamped [low, high] tuple', () => {
72
+ const onChange = vi.fn()
73
+ render(
74
+ <RangeUI
75
+ items={[
76
+ { min: 0, max: 100, value: [10, 90] },
77
+ { min: 0, max: 100, value: [20, 80] },
78
+ ]}
79
+ onChange={onChange}
80
+ />,
81
+ )
82
+ // Drag the second item's lower thumb to 42.
83
+ const sliders = screen.getAllByRole('slider')
84
+ fireEvent.change(sliders[2]!, { target: { value: '42' } })
85
+ expect(onChange).toHaveBeenCalled()
86
+ const call = onChange.mock.calls[0] as [number, readonly [number, number]]
87
+ expect(call[0]).toBe(1)
88
+ expect(Array.isArray(call[1])).toBe(true)
89
+ expect(call[1]).toHaveLength(2)
90
+ })
91
+
92
+ it('respects per-item disabled on both slider and inputs', () => {
93
+ render(
94
+ <RangeUI
95
+ items={[{ min: 0, max: 100, value: [10, 90], disabled: true }]}
96
+ />,
97
+ )
98
+ const sliders = screen.getAllByRole('slider')
99
+ expect(sliders[0]?.hasAttribute('disabled')).toBe(true)
100
+ expect(sliders[1]?.hasAttribute('disabled')).toBe(true)
101
+ expect(
102
+ screen.getByLabelText('Minimum value').hasAttribute('disabled'),
103
+ ).toBe(true)
104
+ expect(
105
+ screen.getByLabelText('Maximum value').hasAttribute('disabled'),
106
+ ).toBe(true)
107
+ })
108
+
109
+ it('commits a typed value to onChange on Enter, clamped to [min, max]', () => {
110
+ const onChange = vi.fn()
111
+ render(
112
+ <RangeUI
113
+ items={[{ min: 0, max: 100, value: [10, 90] }]}
114
+ onChange={onChange}
115
+ />,
116
+ )
117
+ const min = screen.getByLabelText('Minimum value')
118
+ // Type 150 — should clamp to max (100), then preserve ordering (low <= high).
119
+ fireEvent.change(min, { target: { value: '150' } })
120
+ fireEvent.keyDown(min, { key: 'Enter' })
121
+ expect(onChange).toHaveBeenCalled()
122
+ const last = onChange.mock.calls.at(-1) as [
123
+ number,
124
+ readonly [number, number],
125
+ ]
126
+ expect(last[0]).toBe(0)
127
+ expect(last[1][0]).toBeLessThanOrEqual(last[1][1])
128
+ expect(last[1][1]).toBeLessThanOrEqual(100)
129
+ })
130
+ })
@@ -0,0 +1,211 @@
1
+ import {
2
+ useCallback,
3
+ useState,
4
+ type FocusEvent,
5
+ type KeyboardEvent,
6
+ } from 'react'
7
+ import { Box, Slider, TextField, Typography } from '@mui/material'
8
+ import type { RangeDataItem, RangeItemValue } from './types'
9
+ import { styles } from './style'
10
+
11
+ export interface RangeUIProps {
12
+ items: readonly RangeDataItem[]
13
+ /**
14
+ * Fires when the user drags a thumb or commits a new value via the text
15
+ * inputs. Per the destination-owned principle, the consumer owns the
16
+ * value — this widget surfaces changes but does not store them.
17
+ */
18
+ onChange?: (index: number, value: RangeItemValue) => void
19
+ /** Number formatter for the slider tooltip and the text input display. */
20
+ formatter?: (value: number) => string
21
+ }
22
+
23
+ type Bound = 'min' | 'max'
24
+
25
+ /**
26
+ * Pure presentational component for the Range widget. Renders one MUI Slider
27
+ * per item with editable min/max text inputs below — matching the Range v1
28
+ * UX. Each item is always a two-thumb range; supply `value` to seed the
29
+ * starting selection, otherwise it defaults to `[min, max]`.
30
+ */
31
+ export function RangeUI({ items, onChange, formatter }: RangeUIProps) {
32
+ const fmt = formatter ?? ((n: number) => String(n))
33
+ return (
34
+ <Box sx={styles.root}>
35
+ {items.map((item, i) => (
36
+ // Composite of the row's track bounds — stable across reorders for
37
+ // any realistic widget configuration. Falls back to a literal +
38
+ // index when bounds collide (degenerate same-min-same-max rows).
39
+ <RangeRow
40
+ key={`range-${item.min}-${item.max}-${i}`}
41
+ index={i}
42
+ item={item}
43
+ fmt={fmt}
44
+ onChange={onChange}
45
+ />
46
+ ))}
47
+ </Box>
48
+ )
49
+ }
50
+
51
+ interface RangeRowProps {
52
+ index: number
53
+ item: RangeDataItem
54
+ fmt: (n: number) => string
55
+ onChange?: (index: number, value: RangeItemValue) => void
56
+ }
57
+
58
+ function RangeRow({ index, item, fmt, onChange }: RangeRowProps) {
59
+ const current: readonly [number, number] = item.value ?? [item.min, item.max]
60
+ const [editing, setEditing] = useState<'' | Bound>('')
61
+
62
+ const commit = useCallback(
63
+ (next: readonly [number, number]) => {
64
+ // Clamp inside [min, max] and keep `low <= high`.
65
+ const [lowRaw, highRaw] = next
66
+ const low = Math.min(Math.max(lowRaw, item.min), item.max)
67
+ const high = Math.min(Math.max(highRaw, item.min), item.max)
68
+ const ordered: readonly [number, number] =
69
+ low <= high ? [low, high] : [high, low]
70
+ onChange?.(index, ordered)
71
+ },
72
+ [index, item.min, item.max, onChange],
73
+ )
74
+
75
+ const handleSlider = (_: Event, raw: number | number[]) => {
76
+ if (!Array.isArray(raw)) return
77
+ // Hoist defaults out of the destructure: react-compiler can't safely
78
+ // reorder MemberExpression defaults inside an array pattern.
79
+ const low = raw[0] ?? item.min
80
+ const high = raw[1] ?? item.max
81
+ commit([low, high])
82
+ }
83
+
84
+ return (
85
+ <Box sx={styles.item}>
86
+ <Box sx={styles.sliderContainer}>
87
+ <Slider
88
+ sx={{
89
+ ...styles.slider,
90
+ ...(item.color ? { color: item.color } : null),
91
+ }}
92
+ value={[...current]}
93
+ min={item.min}
94
+ max={item.max}
95
+ step={item.step ?? 1}
96
+ marks={resolveMarks(item.marks)}
97
+ disabled={item.disabled}
98
+ valueLabelDisplay='auto'
99
+ valueLabelFormat={fmt}
100
+ onChange={handleSlider}
101
+ />
102
+ </Box>
103
+ <Box sx={styles.inputsRow}>
104
+ <BoundInput
105
+ // Bumping the key on a fresh external value resets the local
106
+ // editing state — matches v1's RangeItem behaviour.
107
+ key={`min-${current[0]}`}
108
+ name='min'
109
+ value={current[0]}
110
+ item={item}
111
+ fmt={fmt}
112
+ editing={editing}
113
+ setEditing={setEditing}
114
+ commit={commit}
115
+ current={current}
116
+ ariaLabel='Minimum value'
117
+ />
118
+ <BoundInput
119
+ key={`max-${current[1]}`}
120
+ name='max'
121
+ value={current[1]}
122
+ item={item}
123
+ fmt={fmt}
124
+ editing={editing}
125
+ setEditing={setEditing}
126
+ commit={commit}
127
+ current={current}
128
+ ariaLabel='Maximum value'
129
+ />
130
+ </Box>
131
+ {item.note ? (
132
+ <Typography variant='caption' sx={styles.note}>
133
+ {item.note}
134
+ </Typography>
135
+ ) : null}
136
+ </Box>
137
+ )
138
+ }
139
+
140
+ interface BoundInputProps {
141
+ name: Bound
142
+ value: number
143
+ item: RangeDataItem
144
+ fmt: (n: number) => string
145
+ editing: '' | Bound
146
+ setEditing: (next: '' | Bound) => void
147
+ commit: (next: readonly [number, number]) => void
148
+ current: readonly [number, number]
149
+ ariaLabel: string
150
+ }
151
+
152
+ function BoundInput({
153
+ name,
154
+ value,
155
+ item,
156
+ fmt,
157
+ editing,
158
+ setEditing,
159
+ commit,
160
+ current,
161
+ ariaLabel,
162
+ }: BoundInputProps) {
163
+ const [raw, setRaw] = useState<string>(String(value))
164
+
165
+ const beginEditing = () => {
166
+ setEditing(name)
167
+ }
168
+ const finishEditingAndCommit = (e: FocusEvent<HTMLInputElement>) => {
169
+ setEditing('')
170
+ commitFromText(e.target.value)
171
+ }
172
+ const commitOnEnter = (e: KeyboardEvent<HTMLInputElement>) => {
173
+ if (e.key === 'Enter') {
174
+ commitFromText((e.target as HTMLInputElement).value)
175
+ ;(e.target as HTMLInputElement).blur()
176
+ }
177
+ }
178
+
179
+ function commitFromText(input: string) {
180
+ const parsed = parseFloat(input)
181
+ const safe = Number.isFinite(parsed) ? parsed : value
182
+ const next: readonly [number, number] =
183
+ name === 'min' ? [safe, current[1]] : [current[0], safe]
184
+ commit(next)
185
+ }
186
+
187
+ const display = editing === name ? raw : fmt(Number(raw))
188
+
189
+ return (
190
+ <TextField
191
+ name={name}
192
+ value={display}
193
+ onChange={(e) => setRaw(e.target.value)}
194
+ onFocus={beginEditing}
195
+ onBlur={finishEditingAndCommit}
196
+ onKeyDown={commitOnEnter}
197
+ disabled={item.disabled}
198
+ size='small'
199
+ sx={styles.input}
200
+ inputProps={{ 'aria-label': ariaLabel }}
201
+ />
202
+ )
203
+ }
204
+
205
+ function resolveMarks(
206
+ marks: RangeDataItem['marks'],
207
+ ): boolean | { value: number; label?: string }[] | undefined {
208
+ if (marks == null) return undefined
209
+ if (typeof marks === 'boolean') return marks
210
+ return [...marks]
211
+ }
@@ -0,0 +1,68 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
2
+ import { fireEvent, render, screen } from '@testing-library/react'
3
+ import { Provider } from '../provider/widget-provider'
4
+ import { clearAllWidgetStores } from '../stores'
5
+ import { Range } from './range'
6
+ import type { RangeWidgetData } from './types'
7
+
8
+ beforeEach(() => clearAllWidgetStores())
9
+ afterEach(() => clearAllWidgetStores())
10
+
11
+ describe('<Range> bridge', () => {
12
+ it('renders two-thumb sliders for each row', () => {
13
+ const data: RangeWidgetData = [
14
+ { min: 0, max: 100, value: [25, 75] },
15
+ { min: 0, max: 50, value: [10, 40] },
16
+ ]
17
+ render(
18
+ <Provider id='rng-1' data={data}>
19
+ <Range />
20
+ </Provider>,
21
+ )
22
+ // Two items × two thumbs each = 4.
23
+ expect(screen.getAllByRole('slider').length).toBe(4)
24
+ })
25
+
26
+ it('defaults a row without `value` to [min, max]', () => {
27
+ const data: RangeWidgetData = [{ min: 10, max: 90 }]
28
+ render(
29
+ <Provider id='rng-2' data={data}>
30
+ <Range />
31
+ </Provider>,
32
+ )
33
+ const sliders = screen.getAllByRole('slider')
34
+ expect(sliders[0]?.getAttribute('aria-valuenow')).toBe('10')
35
+ expect(sliders[1]?.getAttribute('aria-valuenow')).toBe('90')
36
+ })
37
+
38
+ it('fires onChange with item index and the new tuple', () => {
39
+ const onChange = vi.fn()
40
+ const data: RangeWidgetData = [{ min: 0, max: 100, value: [25, 75] }]
41
+ render(
42
+ <Provider id='rng-3' data={data}>
43
+ <Range onChange={onChange} />
44
+ </Provider>,
45
+ )
46
+ const sliders = screen.getAllByRole('slider')
47
+ fireEvent.change(sliders[0]!, { target: { value: '60' } })
48
+ expect(onChange).toHaveBeenCalled()
49
+ const call = onChange.mock.calls[0] as [number, readonly [number, number]]
50
+ expect(call[0]).toBe(0)
51
+ expect(Array.isArray(call[1])).toBe(true)
52
+ expect(call[1]).toHaveLength(2)
53
+ })
54
+
55
+ it('honours per-item disabled', () => {
56
+ const data: RangeWidgetData = [
57
+ { min: 0, max: 100, value: [25, 75], disabled: true },
58
+ ]
59
+ render(
60
+ <Provider id='rng-4' data={data}>
61
+ <Range />
62
+ </Provider>,
63
+ )
64
+ const sliders = screen.getAllByRole('slider')
65
+ expect((sliders[0] as HTMLInputElement).disabled).toBe(true)
66
+ expect((sliders[1] as HTMLInputElement).disabled).toBe(true)
67
+ })
68
+ })
@@ -0,0 +1,46 @@
1
+ import { useWidgetId, useWidgetShallow } from '../stores'
2
+ import { RangeUI } from './range-ui'
3
+ import type { RangeItemValue, RangeWidgetData } from './types'
4
+
5
+ interface RangeSlice {
6
+ data: RangeWidgetData
7
+ formatter?: (value: number) => string
8
+ }
9
+
10
+ const rangeSelector = (s: {
11
+ data: unknown
12
+ formatter?: (value: number) => string
13
+ }): RangeSlice => ({
14
+ data: (s.data ?? []) as RangeWidgetData,
15
+ formatter: s.formatter,
16
+ })
17
+
18
+ export interface RangeProps {
19
+ /**
20
+ * Fires when the user moves a slider thumb or commits a new value via the
21
+ * text inputs. Receives the item index in `state.data` and the new
22
+ * `[low, high]` tuple. The consumer owns the data state — the widget
23
+ * surfaces changes but does not persist them.
24
+ */
25
+ onChange?: (index: number, value: RangeItemValue) => void
26
+ }
27
+
28
+ /**
29
+ * Stateful Range bridge — reads `data` (post-pipeline) and `formatter` from
30
+ * the per-widget store and forwards them to the pure {@link RangeUI}. Per
31
+ * the destination-owned principle, value changes flow back through
32
+ * `onChange` — the consumer is expected to update the data prop on
33
+ * `<Provider>`. Use `disabled` on individual `RangeDataItem`s to disable
34
+ * specific rows.
35
+ */
36
+ export function Range({ onChange }: RangeProps) {
37
+ const id = useWidgetId()
38
+ const slice = useWidgetShallow(id, rangeSelector)
39
+ return (
40
+ <RangeUI
41
+ items={slice.data}
42
+ formatter={slice.formatter}
43
+ onChange={onChange}
44
+ />
45
+ )
46
+ }