@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,55 @@
1
+ import type { Theme } from '@mui/material'
2
+ import type { EChartsOption } from 'echarts'
3
+
4
+ /** A single point — `[x, y]` tuple. */
5
+ export type ScatterplotDatum = readonly [number, number]
6
+
7
+ /** Scatterplot widget data — array of series, each a list of `[x, y]` tuples. */
8
+ export type ScatterplotWidgetData = readonly (readonly ScatterplotDatum[])[]
9
+
10
+ /** Inputs to the structural-only {@link scatterplotOptions} builder. */
11
+ export interface ScatterplotOptionsInput {
12
+ theme: Theme
13
+ /** Optional formatter for x-axis values. */
14
+ xFormatter?: (value: number) => string
15
+ /** Optional formatter for y-axis values. */
16
+ yFormatter?: (value: number) => string
17
+ }
18
+
19
+ /**
20
+ * Combined inputs for the scatterplot option factory creator. Carries
21
+ * everything the widget needs across BOTH phases — the structural-build
22
+ * (`theme`, `xFormatter`, `yFormatter`, `optionsOverride`) AND the data
23
+ * merge (`seriesNames`, `symbolSize`, `selection`).
24
+ */
25
+ export interface ScatterplotOptionFactoryInput {
26
+ theme: Theme
27
+ /**
28
+ * Optional x-axis value formatter. Drives the structural x-axis
29
+ * label and the reactive tooltip path: when RelativeData overrides
30
+ * `state.formatter` (the y formatter) the merger rebuilds the tooltip
31
+ * and reads `xFormatter` to render coordinates correctly. xFormatter
32
+ * itself isn't relativized — x stays raw.
33
+ */
34
+ xFormatter?: (value: number) => string
35
+ /** Optional formatter for y-axis values (structural baseline). */
36
+ yFormatter?: (value: number) => string
37
+ /** Series names — drives the legend and `series[i].name`. */
38
+ seriesNames?: readonly string[]
39
+ /** Symbol size in px (default `8`). */
40
+ symbolSize?: number
41
+ /**
42
+ * Selected point keys, one per `${seriesIndex}:${dataIndex}` pair. Points
43
+ * not in this list render dimmed (`itemStyle.opacity: 0.15`). `null`/empty
44
+ * means no selection.
45
+ */
46
+ selection?: readonly string[] | null
47
+ /**
48
+ * Consumer-supplied partial option merged into the structural option at
49
+ * structural-build time. Lets stories override pieces of the theme-aware
50
+ * base without forking the structural builder.
51
+ */
52
+ optionsOverride?: Partial<EChartsOption>
53
+ }
54
+
55
+ export type ScatterplotEChartsOption = EChartsOption
@@ -0,0 +1,11 @@
1
+ export interface SelectionSummaryLabels {
2
+ allSelected: string
3
+ selections: (count: number) => string
4
+ clear: string
5
+ }
6
+
7
+ export const DEFAULT_SELECTION_SUMMARY_LABELS: SelectionSummaryLabels = {
8
+ allSelected: 'All selected',
9
+ selections: (count) => `${count} selected`,
10
+ clear: 'Clear',
11
+ }
@@ -0,0 +1,53 @@
1
+ import { describe, it, expect, vi } from 'vitest'
2
+ import { fireEvent, render, screen } from '@testing-library/react'
3
+ import StarIcon from '@mui/icons-material/Star'
4
+ import { SelectionSummary } from './selection-summary'
5
+
6
+ describe('<SelectionSummary>', () => {
7
+ it('renders nothing when total === 0 (no data to summarize)', () => {
8
+ const { container } = render(<SelectionSummary count={0} total={0} />)
9
+ expect(container.textContent).toBe('')
10
+ })
11
+
12
+ it('renders the "All selected" label when count === 0 and total > 0 (R34)', () => {
13
+ render(<SelectionSummary count={0} total={10} />)
14
+ expect(screen.getByText('All selected')).toBeTruthy()
15
+ })
16
+
17
+ it('renders the count + Clear link when count > 0', () => {
18
+ const onClear = vi.fn()
19
+ render(<SelectionSummary count={3} total={10} onClear={onClear} />)
20
+ expect(screen.getByText(/3/)).toBeTruthy()
21
+ fireEvent.click(screen.getByText('Clear'))
22
+ expect(onClear).toHaveBeenCalledTimes(1)
23
+ })
24
+
25
+ it('hides the Clear link when no onClear is provided', () => {
26
+ render(<SelectionSummary count={3} total={10} />)
27
+ expect(screen.queryByText('Clear')).toBeNull()
28
+ })
29
+
30
+ it('honors custom labels for empty + populated + clear', () => {
31
+ render(
32
+ <SelectionSummary
33
+ count={3}
34
+ total={10}
35
+ labels={{
36
+ allSelected: 'Showing all',
37
+ selections: (n) => `${n} pinned`,
38
+ clear: 'Reset',
39
+ }}
40
+ onClear={() => undefined}
41
+ />,
42
+ )
43
+ expect(screen.getByText('3 pinned')).toBeTruthy()
44
+ expect(screen.getByText('Reset')).toBeTruthy()
45
+ })
46
+
47
+ it('renders the custom icon component when provided in the empty state', () => {
48
+ const { container } = render(
49
+ <SelectionSummary count={0} total={10} icon={StarIcon} />,
50
+ )
51
+ expect(container.querySelector('[data-testid="StarIcon"]')).toBeTruthy()
52
+ })
53
+ })
@@ -0,0 +1,62 @@
1
+ import { Box, Button, Typography, type SvgIconProps } from '@mui/material'
2
+ import type { ComponentType } from 'react'
3
+ import {
4
+ DEFAULT_SELECTION_SUMMARY_LABELS,
5
+ type SelectionSummaryLabels,
6
+ } from './labels'
7
+ import { styles } from './style'
8
+
9
+ export interface SelectionSummaryProps {
10
+ /** Number of currently selected items. */
11
+ count: number
12
+ /** Optional total — when 0 the component renders nothing (no data to summarize). */
13
+ total?: number
14
+ /** Clear callback. Shown only when count > 0. */
15
+ onClear?: () => void
16
+ labels?: Partial<SelectionSummaryLabels>
17
+ icon?: ComponentType<SvgIconProps>
18
+ iconProps?: SvgIconProps
19
+ }
20
+
21
+ /**
22
+ * Render rules:
23
+ * - `total === 0` → render nothing.
24
+ * - `count === 0` → render `labels.allSelected` (matches v1 default),
25
+ * prefixed with the optional `icon` glyph when provided.
26
+ * - `count > 0` → render `labels.selections(count)` + Clear (when `onClear`).
27
+ */
28
+ export function SelectionSummary({
29
+ count,
30
+ total,
31
+ onClear,
32
+ labels,
33
+ icon: Icon,
34
+ iconProps,
35
+ }: SelectionSummaryProps) {
36
+ if (total === 0) return null
37
+ const _labels = { ...DEFAULT_SELECTION_SUMMARY_LABELS, ...labels }
38
+
39
+ if (count === 0) {
40
+ return (
41
+ <Box sx={styles.root}>
42
+ {Icon ? <Icon fontSize='small' {...iconProps} /> : null}
43
+ <Typography variant='caption' sx={styles.label}>
44
+ {_labels.allSelected}
45
+ </Typography>
46
+ </Box>
47
+ )
48
+ }
49
+
50
+ return (
51
+ <Box sx={styles.root}>
52
+ <Typography variant='caption' sx={styles.label}>
53
+ {_labels.selections(count)}
54
+ </Typography>
55
+ {onClear && (
56
+ <Button size='small' variant='text' onClick={onClear}>
57
+ {_labels.clear}
58
+ </Button>
59
+ )}
60
+ </Box>
61
+ )
62
+ }
@@ -0,0 +1,23 @@
1
+ import type { SxProps, Theme } from '@mui/material'
2
+
3
+ export const styles = {
4
+ root: {
5
+ display: 'flex',
6
+ alignItems: 'center',
7
+ gap: 0.5,
8
+ minHeight: 24,
9
+ },
10
+ label: {
11
+ color: 'text.secondary',
12
+ },
13
+ clear: {
14
+ color: 'primary.main',
15
+ cursor: 'pointer',
16
+ fontWeight: 500,
17
+ '&:hover': { textDecoration: 'underline' },
18
+ },
19
+ icon: {
20
+ fontSize: 16,
21
+ color: 'text.secondary',
22
+ },
23
+ } satisfies Record<string, SxProps<Theme>>
@@ -0,0 +1,64 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest'
2
+ import { createSpreadDownloadConfig } from './download'
3
+ import type { SpreadWidgetData } from './types'
4
+
5
+ const data: SpreadWidgetData = [
6
+ {
7
+ min: 1,
8
+ max: 9,
9
+ prefix: '$',
10
+ suffix: 'k',
11
+ note: 'q1',
12
+ series: { name: 'Revenue' },
13
+ },
14
+ { min: 0, max: 10 },
15
+ ]
16
+
17
+ let csvText = ''
18
+
19
+ beforeEach(() => {
20
+ csvText = ''
21
+ vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock')
22
+ vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => undefined)
23
+ const RealBlob = global.Blob
24
+ vi.stubGlobal(
25
+ 'Blob',
26
+ class extends RealBlob {
27
+ constructor(parts: BlobPart[], opts?: BlobPropertyBag) {
28
+ csvText = typeof parts[0] === 'string' ? parts[0] : ''
29
+ super(parts, opts)
30
+ }
31
+ },
32
+ )
33
+ })
34
+
35
+ describe('createSpreadDownloadConfig', () => {
36
+ it('CSV-only by default', () => {
37
+ expect(
38
+ createSpreadDownloadConfig({ filename: 's', getData: () => data }).map(
39
+ (i) => i.id,
40
+ ),
41
+ ).toEqual(['csv'])
42
+ })
43
+
44
+ it('prepends PNG when getCaptureEl is provided', () => {
45
+ const items = createSpreadDownloadConfig({
46
+ filename: 's',
47
+ getData: () => data,
48
+ getCaptureEl: () => document.createElement('div'),
49
+ })
50
+ expect(items.map((i) => i.id)).toEqual(['png', 'csv'])
51
+ })
52
+
53
+ it('CSV resolve emits one row per item with optional fields blanked', async () => {
54
+ const items = createSpreadDownloadConfig({
55
+ filename: 's',
56
+ getData: () => data,
57
+ })
58
+ const handle = await items.find((i) => i.id === 'csv')!.resolve()
59
+ expect(handle.filename).toBe('s.csv')
60
+ expect(csvText).toBe(
61
+ 'series,prefix,min,max,suffix,note\nRevenue,$,1,9,k,q1\n,,0,10,,',
62
+ )
63
+ })
64
+ })
@@ -0,0 +1,59 @@
1
+ import {
2
+ buildPngDownloadItem,
3
+ downloadToCSV,
4
+ type DownloadItem,
5
+ } from '../actions/download'
6
+ import type { SpreadWidgetData } from './types'
7
+
8
+ /**
9
+ * Download menu items for the Spread widget. Always includes a CSV item
10
+ * with `series, prefix, min, max, suffix, note` columns (one row per
11
+ * entry). When `getCaptureEl` is supplied, prepends a PNG item that
12
+ * rasterises the captured element via `html2canvas`.
13
+ */
14
+ export function createSpreadDownloadConfig(args: {
15
+ filename: string
16
+ getData: () => SpreadWidgetData
17
+ getCaptureEl?: () => HTMLElement | null
18
+ pngPixelRatio?: number
19
+ pngBackgroundColor?: string | null
20
+ }): DownloadItem[] {
21
+ const items: DownloadItem[] = []
22
+ if (args.getCaptureEl) {
23
+ items.push(
24
+ buildPngDownloadItem({
25
+ filename: args.filename,
26
+ getCaptureEl: args.getCaptureEl,
27
+ pixelRatio: args.pngPixelRatio,
28
+ backgroundColor: args.pngBackgroundColor,
29
+ }),
30
+ )
31
+ }
32
+ items.push({
33
+ id: 'csv',
34
+ label: 'Download as CSV',
35
+ resolve: () => {
36
+ const data = args.getData()
37
+ const rows: unknown[][] = [
38
+ ['series', 'prefix', 'min', 'max', 'suffix', 'note'],
39
+ ]
40
+ for (const item of data) {
41
+ rows.push([
42
+ item.series?.name ?? '',
43
+ item.prefix ?? '',
44
+ item.min,
45
+ item.max,
46
+ item.suffix ?? '',
47
+ item.note ?? '',
48
+ ])
49
+ }
50
+ const handle = downloadToCSV(rows)
51
+ return Promise.resolve({
52
+ url: handle.url,
53
+ filename: `${args.filename}.csv`,
54
+ revoke: handle.revoke,
55
+ })
56
+ },
57
+ })
58
+ return items
59
+ }
@@ -0,0 +1,6 @@
1
+ export { Spread } from './spread'
2
+ export { SpreadUI, type SpreadUIProps } from './spread-ui'
3
+ export { Separator } from './separator'
4
+ export { SpreadSkeleton, type SpreadSkeletonProps } from './skeleton'
5
+ export { createSpreadDownloadConfig } from './download'
6
+ export type { SpreadDataItem, SpreadWidgetData } from './types'
@@ -0,0 +1,11 @@
1
+ import { Value } from '../formula'
2
+
3
+ /**
4
+ * Em-dash separator placed between a Spread row's `min` and `max` values.
5
+ * Built from the Formula {@link Value} primitive so typography (h5/600,
6
+ * baseline alignment) matches the numbers around it. Renders with
7
+ * `text.secondary` so it visually recedes between the two bounds.
8
+ */
9
+ export function Separator() {
10
+ return <Value color='inherit'>-</Value>
11
+ }
@@ -0,0 +1,17 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { render } from '@testing-library/react'
3
+ import { SpreadSkeleton } from './skeleton'
4
+
5
+ describe('<SpreadSkeleton>', () => {
6
+ it('renders the default skeleton', () => {
7
+ const { container } = render(<SpreadSkeleton />)
8
+ expect(container.firstChild).not.toBeNull()
9
+ })
10
+
11
+ it('renders the requested number of rows', () => {
12
+ const { container } = render(<SpreadSkeleton count={2} />)
13
+ expect(
14
+ container.querySelectorAll('.MuiSkeleton-root').length,
15
+ ).toBeGreaterThan(1)
16
+ })
17
+ })
@@ -0,0 +1,38 @@
1
+ import { Box, Skeleton } from '@mui/material'
2
+ import type { SxProps, Theme } from '@mui/material'
3
+
4
+ const styles = {
5
+ root: {
6
+ display: 'flex',
7
+ flexDirection: 'column',
8
+ gap: 2,
9
+ py: 1,
10
+ },
11
+ row: {
12
+ display: 'flex',
13
+ alignItems: 'center',
14
+ gap: 1.5,
15
+ },
16
+ block: { width: 200, height: 32 },
17
+ } satisfies Record<string, SxProps<Theme>>
18
+
19
+ export interface SpreadSkeletonProps {
20
+ count?: number
21
+ }
22
+
23
+ /**
24
+ * Loading placeholder for the Spread widget. Renders `count` rows, each
25
+ * sized for the `min — max` pair so the layout doesn't jump once data
26
+ * resolves. Mirrors the row-per-item structure of {@link SpreadUI}.
27
+ */
28
+ export function SpreadSkeleton({ count = 1 }: SpreadSkeletonProps) {
29
+ return (
30
+ <Box sx={styles.root}>
31
+ {Array.from({ length: count }).map((_, i) => (
32
+ <Box key={`row-${i}`} sx={styles.row}>
33
+ <Skeleton variant='rectangular' sx={styles.block} />
34
+ </Box>
35
+ ))}
36
+ </Box>
37
+ )
38
+ }
@@ -0,0 +1,108 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { render, screen } from '@testing-library/react'
3
+ import { SpreadUI } from './spread-ui'
4
+
5
+ describe('<SpreadUI>', () => {
6
+ it('renders a single min/max pair', () => {
7
+ render(<SpreadUI items={[{ min: 10, max: 100 }]} />)
8
+ expect(screen.getByText('10')).toBeTruthy()
9
+ expect(screen.getByText('100')).toBeTruthy()
10
+ expect(screen.getByText('-')).toBeTruthy()
11
+ })
12
+
13
+ it('applies the formatter to both bounds', () => {
14
+ render(
15
+ <SpreadUI
16
+ items={[{ min: 1234, max: 9876 }]}
17
+ formatter={(n) => n.toLocaleString('en-US')}
18
+ />,
19
+ )
20
+ expect(screen.getByText('1,234')).toBeTruthy()
21
+ expect(screen.getByText('9,876')).toBeTruthy()
22
+ })
23
+
24
+ it('renders prefix and suffix when provided', () => {
25
+ render(
26
+ <SpreadUI
27
+ items={[{ min: 5, max: 95, prefix: 'Range', suffix: 'kWh' }]}
28
+ />,
29
+ )
30
+ expect(screen.getByText('Range')).toBeTruthy()
31
+ expect(screen.getByText('kWh')).toBeTruthy()
32
+ })
33
+
34
+ it('renders multiple items as separate rows', () => {
35
+ render(
36
+ <SpreadUI
37
+ items={[
38
+ { min: 0, max: 100, prefix: 'Q1' },
39
+ { min: 50, max: 200, prefix: 'Q2' },
40
+ { min: 100, max: 300, prefix: 'Q3' },
41
+ ]}
42
+ />,
43
+ )
44
+ expect(screen.getByText('Q1')).toBeTruthy()
45
+ expect(screen.getByText('Q2')).toBeTruthy()
46
+ expect(screen.getByText('Q3')).toBeTruthy()
47
+ // One separator dash per item.
48
+ expect(screen.getAllByText('-')).toHaveLength(3)
49
+ })
50
+
51
+ it('renders nothing visible when items is empty', () => {
52
+ const { container } = render(<SpreadUI items={[]} />)
53
+ expect(container.querySelectorAll('h5').length).toBe(0)
54
+ })
55
+
56
+ it('renders a series avatar with the first letter of the name', () => {
57
+ render(
58
+ <SpreadUI
59
+ items={[
60
+ { min: 1, max: 9, series: { name: 'Revenue', color: '#1E5BB5' } },
61
+ ]}
62
+ />,
63
+ )
64
+ expect(screen.getByLabelText('Revenue').textContent).toBe('R')
65
+ })
66
+
67
+ it('renders the note when provided', () => {
68
+ render(<SpreadUI items={[{ min: 1, max: 9, note: 'Last 7 days' }]} />)
69
+ expect(screen.getByText('Last 7 days')).toBeTruthy()
70
+ })
71
+
72
+ it('omits series / note when fields are absent', () => {
73
+ const { container } = render(<SpreadUI items={[{ min: 1, max: 2 }]} />)
74
+ expect(container.querySelector('.MuiAvatar-root')).toBeNull()
75
+ expect(container.querySelector('p')).toBeNull()
76
+ })
77
+
78
+ it('renders the row in order: Series → Prefix → Min → — → Max → Suffix', () => {
79
+ const { container } = render(
80
+ <SpreadUI
81
+ items={[
82
+ {
83
+ min: 10,
84
+ max: 20,
85
+ prefix: '$',
86
+ suffix: 'USD',
87
+ series: { name: 'Revenue' },
88
+ },
89
+ ]}
90
+ />,
91
+ )
92
+ // h5 / h6 / caption typography variants cover prefix, value, separator, suffix.
93
+ const typographies = Array.from(
94
+ container.querySelectorAll('.MuiTypography-root'),
95
+ ).map((el) => el.textContent ?? '')
96
+ // The Series avatar is not Typography; we look at the inline-row text.
97
+ expect(typographies).toEqual(['$', '10', '-', '20', 'USD'])
98
+ })
99
+
100
+ it('still renders both bounds when a per-item color is supplied', () => {
101
+ // Color threading goes through MUI's `sx` so the runtime inline style
102
+ // isn't populated in JSDOM — we just check that both bounds render
103
+ // normally with the color prop set.
104
+ render(<SpreadUI items={[{ min: 1, max: 2, color: 'success.main' }]} />)
105
+ expect(screen.getByText('1')).toBeTruthy()
106
+ expect(screen.getByText('2')).toBeTruthy()
107
+ })
108
+ })
@@ -0,0 +1,52 @@
1
+ import { Box } from '@mui/material'
2
+ import type { Ref } from 'react'
3
+ import { Note, Prefix, Series, Suffix, Value } from '../formula'
4
+ import { styles } from '../formula/style'
5
+ import { Separator } from './separator'
6
+ import type { SpreadDataItem } from './types'
7
+
8
+ export interface SpreadUIProps {
9
+ items: readonly SpreadDataItem[]
10
+ /** Number formatter — applied to each item's `min` and `max`. */
11
+ formatter?: (value: number) => string
12
+ /** Forwarded to the root `<Box>` so consumers can capture the DOM (PNG export). */
13
+ ref?: Ref<HTMLDivElement>
14
+ }
15
+
16
+ /**
17
+ * Pure presentational component for the Spread widget. Each item renders as
18
+ * a row containing (in order): optional `Series` avatar, a body with
19
+ * `[prefix] min — max [suffix]` plus optional `Note`. Reuses the Formula
20
+ * primitives ({@link Series}, {@link Prefix}, {@link Value}, {@link Suffix},
21
+ * {@link Note}) and the Formula row styles so Spread and Formula stay
22
+ * visually aligned when used together.
23
+ */
24
+ export function SpreadUI({ items, formatter, ref }: SpreadUIProps) {
25
+ const fmt = formatter ?? ((n: number) => String(n))
26
+ return (
27
+ <Box ref={ref} sx={styles.root}>
28
+ {items.map((item, i) => (
29
+ // Composite of series name + min/max bounds for stability across
30
+ // reorders; falls back to the index when bounds happen to collide.
31
+ <Box
32
+ key={`spread-${item.series?.name ?? ''}-${item.min}-${item.max}-${i}`}
33
+ sx={styles.row}
34
+ >
35
+ {item.series ? (
36
+ <Series name={item.series.name} color={item.series.color} />
37
+ ) : null}
38
+ <Box sx={styles.body}>
39
+ <Box sx={styles.valueRow}>
40
+ {item.prefix ? <Prefix>{item.prefix}</Prefix> : null}
41
+ <Value color={item.color}>{fmt(item.min)}</Value>
42
+ <Separator />
43
+ <Value color={item.color}>{fmt(item.max)}</Value>
44
+ {item.suffix ? <Suffix>{item.suffix}</Suffix> : null}
45
+ </Box>
46
+ {item.note ? <Note>{item.note}</Note> : null}
47
+ </Box>
48
+ </Box>
49
+ ))}
50
+ </Box>
51
+ )
52
+ }
@@ -0,0 +1,50 @@
1
+ import { describe, it, expect, vi } from 'vitest'
2
+ import { render } from '@testing-library/react'
3
+ import { Spread } from './spread'
4
+ import { Provider } from '../provider/widget-provider'
5
+ import type { SpreadWidgetData } from './types'
6
+
7
+ vi.mock('./spread-ui', () => ({
8
+ SpreadUI: ({
9
+ items,
10
+ formatter,
11
+ }: {
12
+ items: SpreadWidgetData
13
+ formatter?: (value: number) => string
14
+ }) => (
15
+ <div data-testid='spread-ui' data-count={items.length}>
16
+ {items
17
+ .map(
18
+ (it) =>
19
+ `${formatter ? formatter(it.min) : it.min}—${formatter ? formatter(it.max) : it.max}`,
20
+ )
21
+ .join('|')}
22
+ </div>
23
+ ),
24
+ }))
25
+
26
+ describe('<Spread> bridge', () => {
27
+ it('forwards data + formatter to SpreadUI', () => {
28
+ const data: SpreadWidgetData = [
29
+ { min: 1, max: 9 },
30
+ { min: 0, max: 10 },
31
+ ]
32
+ const { getByTestId } = render(
33
+ <Provider id='sp-1' data={data} formatter={(n) => `${n}k`}>
34
+ <Spread />
35
+ </Provider>,
36
+ )
37
+ const ui = getByTestId('spread-ui')
38
+ expect(ui.dataset.count).toBe('2')
39
+ expect(ui.textContent).toBe('1k—9k|0k—10k')
40
+ })
41
+
42
+ it('renders zero items when data is null', () => {
43
+ const { getByTestId } = render(
44
+ <Provider id='sp-2' data={null}>
45
+ <Spread />
46
+ </Provider>,
47
+ )
48
+ expect(getByTestId('spread-ui').dataset.count).toBe('0')
49
+ })
50
+ })
@@ -0,0 +1,31 @@
1
+ import { useWidgetId, useWidgetShallow } from '../stores'
2
+ import { SpreadUI } from './spread-ui'
3
+ import type { SpreadWidgetData } from './types'
4
+
5
+ interface SpreadSlice {
6
+ data: SpreadWidgetData
7
+ formatter?: (value: number) => string
8
+ }
9
+
10
+ // Stable empty-data sentinel — keeps the slice's `data` reference stable
11
+ // when the underlying store value is null/undefined so the shallow-equality
12
+ // gate in `useWidgetShallow` doesn't re-render every commit.
13
+ const EMPTY_DATA: SpreadWidgetData = Object.freeze([]) as SpreadWidgetData
14
+
15
+ const spreadSelector = (s: {
16
+ data: unknown
17
+ formatter?: (value: number) => string
18
+ }): SpreadSlice => ({
19
+ data: (s.data ?? EMPTY_DATA) as SpreadWidgetData,
20
+ formatter: s.formatter,
21
+ })
22
+
23
+ /**
24
+ * Stateful Spread bridge — reads `data` (post-pipeline) and `formatter` from
25
+ * the per-widget store and forwards them to the pure {@link SpreadUI}.
26
+ */
27
+ export function Spread() {
28
+ const id = useWidgetId()
29
+ const slice = useWidgetShallow(id, spreadSelector)
30
+ return <SpreadUI items={slice.data} formatter={slice.formatter} />
31
+ }
@@ -0,0 +1,27 @@
1
+ import type { FormulaSeries } from '../formula'
2
+
3
+ /**
4
+ * A single min/max pair rendered by the Spread widget. Mirrors
5
+ * {@link FormulaDataItem} — same optional `series`, `prefix`, `suffix`,
6
+ * `color`, and `note` slots — but the value is a range (`min` … `max`)
7
+ * rather than a single `value`.
8
+ */
9
+ export interface SpreadDataItem {
10
+ min: number
11
+ max: number
12
+ prefix?: string
13
+ suffix?: string
14
+ /** Override the values' text colour (e.g. `'success.main'`). */
15
+ color?: string
16
+ /** Optional series indicator — coloured avatar with first letter of `name`. */
17
+ series?: FormulaSeries
18
+ /** Optional caption rendered below the values. */
19
+ note?: string
20
+ }
21
+
22
+ /**
23
+ * Spread widget data — an array of `{min, max, …}` pairs rendered
24
+ * top-to-bottom, one row per entry. Visual structure matches the Formula
25
+ * widget so the two can sit side-by-side without style drift.
26
+ */
27
+ export type SpreadWidgetData = readonly SpreadDataItem[]