@carto/ps-react-ui 4.7.1 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (580) hide show
  1. package/dist/category-DwaeYjpX.js +656 -0
  2. package/dist/category-DwaeYjpX.js.map +1 -0
  3. package/dist/change-column-Cidl_M-4.js +1110 -0
  4. package/dist/change-column-Cidl_M-4.js.map +1 -0
  5. package/dist/data-zoom-layout-BH0LPwSy.js +28 -0
  6. package/dist/data-zoom-layout-BH0LPwSy.js.map +1 -0
  7. package/dist/echart-CU0KmClP.js +176 -0
  8. package/dist/echart-CU0KmClP.js.map +1 -0
  9. package/dist/exports-Cx-f6m6U.js +63 -0
  10. package/dist/exports-Cx-f6m6U.js.map +1 -0
  11. package/dist/formula-DuC0NQLH.js +79 -0
  12. package/dist/formula-DuC0NQLH.js.map +1 -0
  13. package/dist/markdown-BD1jcknS.js +8326 -0
  14. package/dist/markdown-BD1jcknS.js.map +1 -0
  15. package/dist/{styles-BYTyKQFP.js → option-builders-F-c9ELi1.js} +25 -45
  16. package/dist/option-builders-F-c9ELi1.js.map +1 -0
  17. package/dist/png-item-CS4z1iSH.js +45 -0
  18. package/dist/png-item-CS4z1iSH.js.map +1 -0
  19. package/dist/range-l4fNHLEg.js +213 -0
  20. package/dist/range-l4fNHLEg.js.map +1 -0
  21. package/dist/resolve-theme-color-BdojIw0K.js +47 -0
  22. package/dist/resolve-theme-color-BdojIw0K.js.map +1 -0
  23. package/dist/spread-CTuIXZSM.js +67 -0
  24. package/dist/spread-CTuIXZSM.js.map +1 -0
  25. package/dist/style-DVnT6HC1.js +131 -0
  26. package/dist/style-DVnT6HC1.js.map +1 -0
  27. package/dist/styles-cohnxh9F.js +23 -0
  28. package/dist/styles-cohnxh9F.js.map +1 -0
  29. package/dist/table-CQCAnDLb.js +388 -0
  30. package/dist/table-CQCAnDLb.js.map +1 -0
  31. package/dist/transforms-Cdx4fkU5.js +106 -0
  32. package/dist/transforms-Cdx4fkU5.js.map +1 -0
  33. package/dist/types/widgets/echart/utils.test.d.ts +1 -0
  34. package/dist/types/widgets/formula/config.test.d.ts +1 -0
  35. package/dist/types/widgets/stores/widget-store-branches.test.d.ts +1 -0
  36. package/dist/types/widgets/table/config.test.d.ts +1 -0
  37. package/dist/types/widgets-v2/actions/brush-toggle/brush-toggle.d.ts +56 -0
  38. package/dist/types/widgets-v2/actions/brush-toggle/index.d.ts +3 -0
  39. package/dist/types/widgets-v2/actions/brush-toggle/labels.d.ts +5 -0
  40. package/dist/types/widgets-v2/actions/brush-toggle/style.d.ts +12 -0
  41. package/dist/types/widgets-v2/actions/brush-toggle/transforms.d.ts +11 -0
  42. package/dist/types/widgets-v2/actions/brush-toggle/transforms.test.d.ts +1 -0
  43. package/dist/types/widgets-v2/actions/change-column/change-column-icon.d.ts +2 -0
  44. package/dist/types/widgets-v2/actions/change-column/change-column.d.ts +29 -0
  45. package/dist/types/widgets-v2/actions/change-column/index.d.ts +3 -0
  46. package/dist/types/widgets-v2/actions/change-column/labels.d.ts +5 -0
  47. package/dist/types/widgets-v2/actions/change-column/sortable-column-item.d.ts +14 -0
  48. package/dist/types/widgets-v2/actions/change-column/style.d.ts +33 -0
  49. package/dist/types/widgets-v2/actions/change-column/types.d.ts +10 -0
  50. package/dist/types/widgets-v2/actions/download/download.d.ts +18 -0
  51. package/dist/types/widgets-v2/actions/download/exports.d.ts +37 -0
  52. package/dist/types/widgets-v2/actions/download/icons.d.ts +12 -0
  53. package/dist/types/widgets-v2/actions/download/index.d.ts +6 -0
  54. package/dist/types/widgets-v2/actions/download/labels.d.ts +11 -0
  55. package/dist/types/widgets-v2/actions/download/png-item.d.ts +24 -0
  56. package/dist/types/widgets-v2/actions/download/style.d.ts +1 -0
  57. package/dist/types/widgets-v2/actions/download/types.d.ts +35 -0
  58. package/dist/types/widgets-v2/actions/fullscreen/fullscreen.d.ts +59 -0
  59. package/dist/types/widgets-v2/actions/fullscreen/index.d.ts +3 -0
  60. package/dist/types/widgets-v2/actions/fullscreen/labels.d.ts +5 -0
  61. package/dist/types/widgets-v2/actions/fullscreen/style.d.ts +48 -0
  62. package/dist/types/widgets-v2/actions/fullscreen/types.d.ts +14 -0
  63. package/dist/types/widgets-v2/actions/index.d.ts +9 -0
  64. package/dist/types/widgets-v2/actions/lock-selection/index.d.ts +3 -0
  65. package/dist/types/widgets-v2/actions/lock-selection/labels.d.ts +6 -0
  66. package/dist/types/widgets-v2/actions/lock-selection/lock-selection.d.ts +36 -0
  67. package/dist/types/widgets-v2/actions/lock-selection/style.d.ts +12 -0
  68. package/dist/types/widgets-v2/actions/lock-selection/transforms.d.ts +6 -0
  69. package/dist/types/widgets-v2/actions/relative-data/index.d.ts +3 -0
  70. package/dist/types/widgets-v2/actions/relative-data/labels.d.ts +5 -0
  71. package/dist/types/widgets-v2/actions/relative-data/relative-data.d.ts +39 -0
  72. package/dist/types/widgets-v2/actions/relative-data/style.d.ts +12 -0
  73. package/dist/types/widgets-v2/actions/relative-data/transforms.d.ts +30 -0
  74. package/dist/types/widgets-v2/actions/relative-data/transforms.test.d.ts +1 -0
  75. package/dist/types/widgets-v2/actions/searcher/filter.d.ts +6 -0
  76. package/dist/types/widgets-v2/actions/searcher/index.d.ts +4 -0
  77. package/dist/types/widgets-v2/actions/searcher/labels.d.ts +7 -0
  78. package/dist/types/widgets-v2/actions/searcher/searcher-toggle.d.ts +23 -0
  79. package/dist/types/widgets-v2/actions/searcher/searcher.d.ts +11 -0
  80. package/dist/types/widgets-v2/actions/searcher/style.d.ts +16 -0
  81. package/dist/types/widgets-v2/actions/stack-toggle/index.d.ts +3 -0
  82. package/dist/types/widgets-v2/actions/stack-toggle/labels.d.ts +5 -0
  83. package/dist/types/widgets-v2/actions/stack-toggle/stack-toggle.d.ts +10 -0
  84. package/dist/types/widgets-v2/actions/stack-toggle/style.d.ts +12 -0
  85. package/dist/types/widgets-v2/actions/stack-toggle/transforms.d.ts +13 -0
  86. package/dist/types/widgets-v2/actions/stack-toggle/transforms.test.d.ts +1 -0
  87. package/dist/types/widgets-v2/actions/zoom-toggle/index.d.ts +3 -0
  88. package/dist/types/widgets-v2/actions/zoom-toggle/labels.d.ts +5 -0
  89. package/dist/types/widgets-v2/actions/zoom-toggle/style.d.ts +12 -0
  90. package/dist/types/widgets-v2/actions/zoom-toggle/transforms.d.ts +51 -0
  91. package/dist/types/widgets-v2/actions/zoom-toggle/transforms.test.d.ts +1 -0
  92. package/dist/types/widgets-v2/actions/zoom-toggle/zoom-toggle.d.ts +35 -0
  93. package/dist/types/widgets-v2/bar/download.d.ts +24 -0
  94. package/dist/types/widgets-v2/bar/index.d.ts +4 -0
  95. package/dist/types/widgets-v2/bar/options.d.ts +43 -0
  96. package/dist/types/widgets-v2/bar/options.test.d.ts +1 -0
  97. package/dist/types/widgets-v2/bar/skeleton.d.ts +6 -0
  98. package/dist/types/widgets-v2/bar/types.d.ts +46 -0
  99. package/dist/types/widgets-v2/category/category-ui.d.ts +81 -0
  100. package/dist/types/widgets-v2/category/category.d.ts +48 -0
  101. package/dist/types/widgets-v2/category/components/category-bar-stacked.d.ts +28 -0
  102. package/dist/types/widgets-v2/category/components/category-bar.d.ts +23 -0
  103. package/dist/types/widgets-v2/category/components/category-legend.d.ts +18 -0
  104. package/dist/types/widgets-v2/category/components/category-row-multi.d.ts +31 -0
  105. package/dist/types/widgets-v2/category/components/category-row-other.d.ts +13 -0
  106. package/dist/types/widgets-v2/category/components/category-row-single.d.ts +28 -0
  107. package/dist/types/widgets-v2/category/components/category-row-stacked.d.ts +38 -0
  108. package/dist/types/widgets-v2/category/download.d.ts +16 -0
  109. package/dist/types/widgets-v2/category/download.test.d.ts +1 -0
  110. package/dist/types/widgets-v2/category/index.d.ts +10 -0
  111. package/dist/types/widgets-v2/category/skeleton.d.ts +11 -0
  112. package/dist/types/widgets-v2/category/style.d.ts +166 -0
  113. package/dist/types/widgets-v2/category/types.d.ts +53 -0
  114. package/dist/types/widgets-v2/echart/echart-ui.d.ts +44 -0
  115. package/dist/types/widgets-v2/echart/echart.d.ts +75 -0
  116. package/dist/types/widgets-v2/echart/index.d.ts +4 -0
  117. package/dist/types/widgets-v2/echart/shared-resize-observer.d.ts +5 -0
  118. package/dist/types/widgets-v2/echart/shared-resize-observer.test.d.ts +1 -0
  119. package/dist/types/widgets-v2/echart/style.d.ts +6 -0
  120. package/dist/types/widgets-v2/echart/use-chart-selection.d.ts +51 -0
  121. package/dist/types/widgets-v2/formula/delta.d.ts +22 -0
  122. package/dist/types/widgets-v2/formula/download.d.ts +20 -0
  123. package/dist/types/widgets-v2/formula/formula-ui.d.ts +20 -0
  124. package/dist/types/widgets-v2/formula/formula.d.ts +8 -0
  125. package/dist/types/widgets-v2/formula/index.d.ts +11 -0
  126. package/dist/types/widgets-v2/formula/note.d.ts +11 -0
  127. package/dist/types/widgets-v2/formula/prefix.d.ts +12 -0
  128. package/dist/types/widgets-v2/formula/series.d.ts +16 -0
  129. package/dist/types/widgets-v2/formula/skeleton.d.ts +4 -0
  130. package/dist/types/widgets-v2/formula/style.d.ts +29 -0
  131. package/dist/types/widgets-v2/formula/suffix.d.ts +12 -0
  132. package/dist/types/widgets-v2/formula/types.d.ts +43 -0
  133. package/dist/types/widgets-v2/formula/value.d.ts +14 -0
  134. package/dist/types/widgets-v2/histogram/download.d.ts +17 -0
  135. package/dist/types/widgets-v2/histogram/download.test.d.ts +1 -0
  136. package/dist/types/widgets-v2/histogram/index.d.ts +5 -0
  137. package/dist/types/widgets-v2/histogram/options.d.ts +42 -0
  138. package/dist/types/widgets-v2/histogram/options.test.d.ts +1 -0
  139. package/dist/types/widgets-v2/histogram/skeleton.d.ts +9 -0
  140. package/dist/types/widgets-v2/histogram/transforms.d.ts +17 -0
  141. package/dist/types/widgets-v2/histogram/transforms.test.d.ts +1 -0
  142. package/dist/types/widgets-v2/histogram/types.d.ts +51 -0
  143. package/dist/types/widgets-v2/index.d.ts +108 -0
  144. package/dist/types/widgets-v2/markdown/download.d.ts +16 -0
  145. package/dist/types/widgets-v2/markdown/download.test.d.ts +1 -0
  146. package/dist/types/widgets-v2/markdown/index.d.ts +6 -0
  147. package/dist/types/widgets-v2/markdown/markdown-content.d.ts +34 -0
  148. package/dist/types/widgets-v2/markdown/markdown-ui.d.ts +12 -0
  149. package/dist/types/widgets-v2/markdown/markdown.d.ts +6 -0
  150. package/dist/types/widgets-v2/markdown/skeleton.d.ts +4 -0
  151. package/dist/types/widgets-v2/markdown/style.d.ts +61 -0
  152. package/dist/types/widgets-v2/markdown/types.d.ts +4 -0
  153. package/dist/types/widgets-v2/note/labels.d.ts +5 -0
  154. package/dist/types/widgets-v2/note/style.d.ts +26 -0
  155. package/dist/types/widgets-v2/note/widget-note.d.ts +46 -0
  156. package/dist/types/widgets-v2/pie/download.d.ts +17 -0
  157. package/dist/types/widgets-v2/pie/download.test.d.ts +1 -0
  158. package/dist/types/widgets-v2/pie/index.d.ts +4 -0
  159. package/dist/types/widgets-v2/pie/options.d.ts +35 -0
  160. package/dist/types/widgets-v2/pie/options.test.d.ts +1 -0
  161. package/dist/types/widgets-v2/pie/skeleton.d.ts +4 -0
  162. package/dist/types/widgets-v2/pie/types.d.ts +57 -0
  163. package/dist/types/widgets-v2/provider/widget-provider.d.ts +32 -0
  164. package/dist/types/widgets-v2/range/index.d.ts +4 -0
  165. package/dist/types/widgets-v2/range/range-ui.d.ts +27 -0
  166. package/dist/types/widgets-v2/range/range.d.ts +24 -0
  167. package/dist/types/widgets-v2/range/skeleton.d.ts +9 -0
  168. package/dist/types/widgets-v2/range/style.d.ts +40 -0
  169. package/dist/types/widgets-v2/range/types.d.ts +37 -0
  170. package/dist/types/widgets-v2/scatterplot/download.d.ts +16 -0
  171. package/dist/types/widgets-v2/scatterplot/download.test.d.ts +1 -0
  172. package/dist/types/widgets-v2/scatterplot/index.d.ts +5 -0
  173. package/dist/types/widgets-v2/scatterplot/options.d.ts +42 -0
  174. package/dist/types/widgets-v2/scatterplot/options.test.d.ts +1 -0
  175. package/dist/types/widgets-v2/scatterplot/skeleton.d.ts +12 -0
  176. package/dist/types/widgets-v2/scatterplot/transforms.d.ts +17 -0
  177. package/dist/types/widgets-v2/scatterplot/transforms.test.d.ts +1 -0
  178. package/dist/types/widgets-v2/scatterplot/types.d.ts +54 -0
  179. package/dist/types/widgets-v2/selection-summary/labels.d.ts +6 -0
  180. package/dist/types/widgets-v2/selection-summary/selection-summary.d.ts +22 -0
  181. package/dist/types/widgets-v2/selection-summary/style.d.ts +23 -0
  182. package/dist/types/widgets-v2/spread/download.d.ts +15 -0
  183. package/dist/types/widgets-v2/spread/download.test.d.ts +1 -0
  184. package/dist/types/widgets-v2/spread/index.d.ts +6 -0
  185. package/dist/types/widgets-v2/spread/separator.d.ts +7 -0
  186. package/dist/types/widgets-v2/spread/skeleton.d.ts +9 -0
  187. package/dist/types/widgets-v2/spread/spread-ui.d.ts +18 -0
  188. package/dist/types/widgets-v2/spread/spread.d.ts +5 -0
  189. package/dist/types/widgets-v2/spread/types.d.ts +25 -0
  190. package/dist/types/widgets-v2/state/labels.d.ts +7 -0
  191. package/dist/types/widgets-v2/state/labels.test.d.ts +1 -0
  192. package/dist/types/widgets-v2/state/style.d.ts +19 -0
  193. package/dist/types/widgets-v2/state/widget-state.d.ts +19 -0
  194. package/dist/types/widgets-v2/stores/index.d.ts +8 -0
  195. package/dist/types/widgets-v2/stores/pipeline-middleware.d.ts +5 -0
  196. package/dist/types/widgets-v2/stores/pipeline-middleware.test.d.ts +1 -0
  197. package/dist/types/widgets-v2/stores/transforms.d.ts +4 -0
  198. package/dist/types/widgets-v2/stores/transforms.test.d.ts +1 -0
  199. package/dist/types/widgets-v2/stores/types.d.ts +55 -0
  200. package/dist/types/widgets-v2/stores/use-echart-instance.d.ts +15 -0
  201. package/dist/types/widgets-v2/stores/use-transform-enabled.d.ts +17 -0
  202. package/dist/types/widgets-v2/stores/use-transform.d.ts +12 -0
  203. package/dist/types/widgets-v2/stores/widget-context.d.ts +2 -0
  204. package/dist/types/widgets-v2/stores/widget-store-registry.d.ts +74 -0
  205. package/dist/types/widgets-v2/stores/widget-store-registry.test.d.ts +1 -0
  206. package/dist/types/widgets-v2/subheader/style.d.ts +10 -0
  207. package/dist/types/widgets-v2/subheader/subheader.d.ts +11 -0
  208. package/dist/types/widgets-v2/table/download.d.ts +18 -0
  209. package/dist/types/widgets-v2/table/download.test.d.ts +1 -0
  210. package/dist/types/widgets-v2/table/helpers.d.ts +32 -0
  211. package/dist/types/widgets-v2/table/helpers.test.d.ts +1 -0
  212. package/dist/types/widgets-v2/table/index.d.ts +7 -0
  213. package/dist/types/widgets-v2/table/labels.d.ts +22 -0
  214. package/dist/types/widgets-v2/table/skeleton.d.ts +22 -0
  215. package/dist/types/widgets-v2/table/style.d.ts +40 -0
  216. package/dist/types/widgets-v2/table/table-ui.d.ts +44 -0
  217. package/dist/types/widgets-v2/table/table.d.ts +50 -0
  218. package/dist/types/widgets-v2/table/types.d.ts +48 -0
  219. package/dist/types/widgets-v2/test-utils.d.ts +52 -0
  220. package/dist/types/widgets-v2/timeseries/download.d.ts +17 -0
  221. package/dist/types/widgets-v2/timeseries/download.test.d.ts +1 -0
  222. package/dist/types/widgets-v2/timeseries/index.d.ts +4 -0
  223. package/dist/types/widgets-v2/timeseries/options.d.ts +39 -0
  224. package/dist/types/widgets-v2/timeseries/options.test.d.ts +1 -0
  225. package/dist/types/widgets-v2/timeseries/skeleton.d.ts +8 -0
  226. package/dist/types/widgets-v2/timeseries/types.d.ts +60 -0
  227. package/dist/types/widgets-v2/toolbox/labels.d.ts +5 -0
  228. package/dist/types/widgets-v2/toolbox/style.d.ts +30 -0
  229. package/dist/types/widgets-v2/toolbox/toolbox.d.ts +49 -0
  230. package/dist/types/widgets-v2/types.d.ts +25 -0
  231. package/dist/types/widgets-v2/utils/data-zoom-layout.d.ts +11 -0
  232. package/dist/types/widgets-v2/utils/index.d.ts +3 -0
  233. package/dist/types/widgets-v2/utils/merge-options.d.ts +12 -0
  234. package/dist/types/widgets-v2/utils/merge-options.test.d.ts +1 -0
  235. package/dist/types/widgets-v2/utils/resolve-theme-color.d.ts +18 -0
  236. package/dist/types/widgets-v2/utils/resolve-theme-color.test.d.ts +1 -0
  237. package/dist/types/widgets-v2/wrapper/index.d.ts +4 -0
  238. package/dist/types/widgets-v2/wrapper/labels.d.ts +6 -0
  239. package/dist/types/widgets-v2/wrapper/style.d.ts +111 -0
  240. package/dist/types/widgets-v2/wrapper/widget-actions.d.ts +22 -0
  241. package/dist/types/widgets-v2/wrapper/widget-content.d.ts +12 -0
  242. package/dist/types/widgets-v2/wrapper/widget-wrapper.d.ts +51 -0
  243. package/dist/use-transform-DXPN3nY7.js +110 -0
  244. package/dist/use-transform-DXPN3nY7.js.map +1 -0
  245. package/dist/widget-context-DTGO0Yta.js +13 -0
  246. package/dist/widget-context-DTGO0Yta.js.map +1 -0
  247. package/dist/widget-store-registry-_W4Z4xp-.js +178 -0
  248. package/dist/widget-store-registry-_W4Z4xp-.js.map +1 -0
  249. package/dist/widgets/bar.js +14 -13
  250. package/dist/widgets/bar.js.map +1 -1
  251. package/dist/widgets/histogram.js +8 -7
  252. package/dist/widgets/histogram.js.map +1 -1
  253. package/dist/widgets/pie.js +19 -18
  254. package/dist/widgets/pie.js.map +1 -1
  255. package/dist/widgets/scatterplot.js +8 -7
  256. package/dist/widgets/scatterplot.js.map +1 -1
  257. package/dist/widgets/timeseries.js +11 -10
  258. package/dist/widgets/timeseries.js.map +1 -1
  259. package/dist/widgets/utils.js +8 -7
  260. package/dist/widgets/utils.js.map +1 -1
  261. package/dist/widgets-v2/actions.js +43 -0
  262. package/dist/widgets-v2/actions.js.map +1 -0
  263. package/dist/widgets-v2/bar.js +330 -0
  264. package/dist/widgets-v2/bar.js.map +1 -0
  265. package/dist/widgets-v2/category.js +104 -0
  266. package/dist/widgets-v2/category.js.map +1 -0
  267. package/dist/widgets-v2/echart.js +57 -0
  268. package/dist/widgets-v2/echart.js.map +1 -0
  269. package/dist/widgets-v2/formula.js +74 -0
  270. package/dist/widgets-v2/formula.js.map +1 -0
  271. package/dist/widgets-v2/histogram.js +353 -0
  272. package/dist/widgets-v2/histogram.js.map +1 -0
  273. package/dist/widgets-v2/markdown.js +68 -0
  274. package/dist/widgets-v2/markdown.js.map +1 -0
  275. package/dist/widgets-v2/pie.js +387 -0
  276. package/dist/widgets-v2/pie.js.map +1 -0
  277. package/dist/widgets-v2/range.js +52 -0
  278. package/dist/widgets-v2/range.js.map +1 -0
  279. package/dist/widgets-v2/scatterplot.js +411 -0
  280. package/dist/widgets-v2/scatterplot.js.map +1 -0
  281. package/dist/widgets-v2/spread.js +72 -0
  282. package/dist/widgets-v2/spread.js.map +1 -0
  283. package/dist/widgets-v2/stores.js +42 -0
  284. package/dist/widgets-v2/stores.js.map +1 -0
  285. package/dist/widgets-v2/table.js +78 -0
  286. package/dist/widgets-v2/table.js.map +1 -0
  287. package/dist/widgets-v2/timeseries.js +358 -0
  288. package/dist/widgets-v2/timeseries.js.map +1 -0
  289. package/dist/widgets-v2/utils.js +8 -0
  290. package/dist/widgets-v2/utils.js.map +1 -0
  291. package/dist/widgets-v2.js +953 -0
  292. package/dist/widgets-v2.js.map +1 -0
  293. package/package.json +71 -3
  294. package/src/components/lasso-tool/chip.test.tsx +176 -0
  295. package/src/components/lasso-tool/lasso-tool-inline.test.tsx +171 -0
  296. package/src/components/lasso-tool/lasso-tool.test.tsx +198 -0
  297. package/src/components/list-data/list-data.test.tsx +73 -0
  298. package/src/components/no-data-alert/no-data-alert.test.tsx +38 -0
  299. package/src/components/responsive-drawer/responsive-drawer.test.tsx +68 -0
  300. package/src/widgets/actions/brush-toggle/brush-overlay.test.tsx +465 -0
  301. package/src/widgets/actions/brush-toggle/brush-toggle.test.tsx +208 -0
  302. package/src/widgets/actions/change-column/change-column-dnd.test.tsx +193 -0
  303. package/src/widgets/actions/change-column/sortable-column-item.test.tsx +124 -0
  304. package/src/widgets/actions/zoom-toggle/zoom-toggle.test.tsx +322 -0
  305. package/src/widgets/category/components/category-rows.test.tsx +213 -0
  306. package/src/widgets/echart/utils.test.ts +277 -0
  307. package/src/widgets/formula/config.test.ts +37 -0
  308. package/src/widgets/range/components/range-item.test.tsx +243 -0
  309. package/src/widgets/stores/widget-store-branches.test.ts +275 -0
  310. package/src/widgets/table/config.test.ts +65 -0
  311. package/src/widgets/utils/chart-config/option-builders.test.ts +188 -0
  312. package/src/widgets-v2/PERFORMANCE.md +189 -0
  313. package/src/widgets-v2/actions/brush-toggle/brush-toggle.test.tsx +180 -0
  314. package/src/widgets-v2/actions/brush-toggle/brush-toggle.tsx +154 -0
  315. package/src/widgets-v2/actions/brush-toggle/index.ts +3 -0
  316. package/src/widgets-v2/actions/brush-toggle/labels.ts +9 -0
  317. package/src/widgets-v2/actions/brush-toggle/style.ts +11 -0
  318. package/src/widgets-v2/actions/brush-toggle/transforms.test.ts +47 -0
  319. package/src/widgets-v2/actions/brush-toggle/transforms.ts +31 -0
  320. package/src/widgets-v2/actions/change-column/change-column-icon.tsx +14 -0
  321. package/src/widgets-v2/actions/change-column/change-column.test.tsx +59 -0
  322. package/src/widgets-v2/actions/change-column/change-column.tsx +180 -0
  323. package/src/widgets-v2/actions/change-column/index.ts +7 -0
  324. package/src/widgets-v2/actions/change-column/labels.ts +9 -0
  325. package/src/widgets-v2/actions/change-column/sortable-column-item.tsx +56 -0
  326. package/src/widgets-v2/actions/change-column/style.ts +32 -0
  327. package/src/widgets-v2/actions/change-column/types.ts +11 -0
  328. package/src/widgets-v2/actions/download/download.test.tsx +327 -0
  329. package/src/widgets-v2/actions/download/download.tsx +144 -0
  330. package/src/widgets-v2/actions/download/exports.test.tsx +198 -0
  331. package/src/widgets-v2/actions/download/exports.ts +115 -0
  332. package/src/widgets-v2/actions/download/icons.tsx +26 -0
  333. package/src/widgets-v2/actions/download/index.ts +13 -0
  334. package/src/widgets-v2/actions/download/labels.ts +16 -0
  335. package/src/widgets-v2/actions/download/png-item.test.tsx +72 -0
  336. package/src/widgets-v2/actions/download/png-item.tsx +52 -0
  337. package/src/widgets-v2/actions/download/style.ts +3 -0
  338. package/src/widgets-v2/actions/download/types.ts +32 -0
  339. package/src/widgets-v2/actions/fullscreen/fullscreen.test.tsx +150 -0
  340. package/src/widgets-v2/actions/fullscreen/fullscreen.tsx +230 -0
  341. package/src/widgets-v2/actions/fullscreen/index.ts +7 -0
  342. package/src/widgets-v2/actions/fullscreen/labels.ts +9 -0
  343. package/src/widgets-v2/actions/fullscreen/style.ts +59 -0
  344. package/src/widgets-v2/actions/fullscreen/types.ts +15 -0
  345. package/src/widgets-v2/actions/index.ts +82 -0
  346. package/src/widgets-v2/actions/lock-selection/index.ts +10 -0
  347. package/src/widgets-v2/actions/lock-selection/labels.ts +11 -0
  348. package/src/widgets-v2/actions/lock-selection/lock-selection.test.tsx +187 -0
  349. package/src/widgets-v2/actions/lock-selection/lock-selection.tsx +130 -0
  350. package/src/widgets-v2/actions/lock-selection/style.ts +11 -0
  351. package/src/widgets-v2/actions/lock-selection/transforms.ts +27 -0
  352. package/src/widgets-v2/actions/relative-data/index.ts +3 -0
  353. package/src/widgets-v2/actions/relative-data/labels.ts +9 -0
  354. package/src/widgets-v2/actions/relative-data/relative-data.test.tsx +71 -0
  355. package/src/widgets-v2/actions/relative-data/relative-data.tsx +107 -0
  356. package/src/widgets-v2/actions/relative-data/style.ts +11 -0
  357. package/src/widgets-v2/actions/relative-data/transforms.test.ts +151 -0
  358. package/src/widgets-v2/actions/relative-data/transforms.ts +70 -0
  359. package/src/widgets-v2/actions/searcher/filter.ts +28 -0
  360. package/src/widgets-v2/actions/searcher/index.ts +8 -0
  361. package/src/widgets-v2/actions/searcher/labels.ts +13 -0
  362. package/src/widgets-v2/actions/searcher/searcher-toggle.tsx +91 -0
  363. package/src/widgets-v2/actions/searcher/searcher.test.tsx +92 -0
  364. package/src/widgets-v2/actions/searcher/searcher.tsx +112 -0
  365. package/src/widgets-v2/actions/searcher/style.ts +15 -0
  366. package/src/widgets-v2/actions/stack-toggle/index.ts +3 -0
  367. package/src/widgets-v2/actions/stack-toggle/labels.ts +9 -0
  368. package/src/widgets-v2/actions/stack-toggle/stack-toggle.test.tsx +61 -0
  369. package/src/widgets-v2/actions/stack-toggle/stack-toggle.tsx +54 -0
  370. package/src/widgets-v2/actions/stack-toggle/style.ts +11 -0
  371. package/src/widgets-v2/actions/stack-toggle/transforms.test.ts +43 -0
  372. package/src/widgets-v2/actions/stack-toggle/transforms.ts +25 -0
  373. package/src/widgets-v2/actions/zoom-toggle/index.ts +9 -0
  374. package/src/widgets-v2/actions/zoom-toggle/labels.ts +9 -0
  375. package/src/widgets-v2/actions/zoom-toggle/style.ts +11 -0
  376. package/src/widgets-v2/actions/zoom-toggle/transforms.test.ts +148 -0
  377. package/src/widgets-v2/actions/zoom-toggle/transforms.ts +171 -0
  378. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.test.tsx +107 -0
  379. package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.tsx +106 -0
  380. package/src/widgets-v2/bar/download.test.tsx +91 -0
  381. package/src/widgets-v2/bar/download.tsx +66 -0
  382. package/src/widgets-v2/bar/index.ts +10 -0
  383. package/src/widgets-v2/bar/options.test.ts +334 -0
  384. package/src/widgets-v2/bar/options.ts +332 -0
  385. package/src/widgets-v2/bar/skeleton.test.tsx +19 -0
  386. package/src/widgets-v2/bar/skeleton.tsx +69 -0
  387. package/src/widgets-v2/bar/types.ts +51 -0
  388. package/src/widgets-v2/category/category-ui.test.tsx +746 -0
  389. package/src/widgets-v2/category/category-ui.tsx +389 -0
  390. package/src/widgets-v2/category/category.relative-data.test.tsx +107 -0
  391. package/src/widgets-v2/category/category.stack-toggle.test.tsx +85 -0
  392. package/src/widgets-v2/category/category.test.tsx +305 -0
  393. package/src/widgets-v2/category/category.tsx +121 -0
  394. package/src/widgets-v2/category/components/category-bar-stacked.test.tsx +121 -0
  395. package/src/widgets-v2/category/components/category-bar-stacked.tsx +73 -0
  396. package/src/widgets-v2/category/components/category-bar.test.tsx +64 -0
  397. package/src/widgets-v2/category/components/category-bar.tsx +49 -0
  398. package/src/widgets-v2/category/components/category-legend.test.tsx +51 -0
  399. package/src/widgets-v2/category/components/category-legend.tsx +39 -0
  400. package/src/widgets-v2/category/components/category-row-multi.tsx +86 -0
  401. package/src/widgets-v2/category/components/category-row-other.test.tsx +28 -0
  402. package/src/widgets-v2/category/components/category-row-other.tsx +33 -0
  403. package/src/widgets-v2/category/components/category-row-single.tsx +76 -0
  404. package/src/widgets-v2/category/components/category-row-stacked.test.tsx +244 -0
  405. package/src/widgets-v2/category/components/category-row-stacked.tsx +99 -0
  406. package/src/widgets-v2/category/download.test.ts +71 -0
  407. package/src/widgets-v2/category/download.ts +54 -0
  408. package/src/widgets-v2/category/index.ts +32 -0
  409. package/src/widgets-v2/category/skeleton.test.tsx +26 -0
  410. package/src/widgets-v2/category/skeleton.tsx +74 -0
  411. package/src/widgets-v2/category/style.ts +290 -0
  412. package/src/widgets-v2/category/types.ts +59 -0
  413. package/src/widgets-v2/echart/echart-ui.test.tsx +232 -0
  414. package/src/widgets-v2/echart/echart-ui.tsx +184 -0
  415. package/src/widgets-v2/echart/echart.test.tsx +229 -0
  416. package/src/widgets-v2/echart/echart.tsx +199 -0
  417. package/src/widgets-v2/echart/index.ts +22 -0
  418. package/src/widgets-v2/echart/shared-resize-observer.test.ts +91 -0
  419. package/src/widgets-v2/echart/shared-resize-observer.ts +56 -0
  420. package/src/widgets-v2/echart/style.ts +8 -0
  421. package/src/widgets-v2/echart/use-chart-selection.test.tsx +118 -0
  422. package/src/widgets-v2/echart/use-chart-selection.ts +115 -0
  423. package/src/widgets-v2/formula/delta.tsx +61 -0
  424. package/src/widgets-v2/formula/download.test.tsx +65 -0
  425. package/src/widgets-v2/formula/download.tsx +69 -0
  426. package/src/widgets-v2/formula/formula-ui.test.tsx +91 -0
  427. package/src/widgets-v2/formula/formula-ui.tsx +66 -0
  428. package/src/widgets-v2/formula/formula.test.tsx +50 -0
  429. package/src/widgets-v2/formula/formula.tsx +34 -0
  430. package/src/widgets-v2/formula/index.ts +17 -0
  431. package/src/widgets-v2/formula/note.tsx +25 -0
  432. package/src/widgets-v2/formula/prefix.tsx +25 -0
  433. package/src/widgets-v2/formula/series.tsx +67 -0
  434. package/src/widgets-v2/formula/skeleton.test.tsx +21 -0
  435. package/src/widgets-v2/formula/skeleton.tsx +27 -0
  436. package/src/widgets-v2/formula/style.ts +31 -0
  437. package/src/widgets-v2/formula/subcomponents.test.tsx +107 -0
  438. package/src/widgets-v2/formula/suffix.tsx +25 -0
  439. package/src/widgets-v2/formula/types.ts +48 -0
  440. package/src/widgets-v2/formula/value.tsx +31 -0
  441. package/src/widgets-v2/histogram/download.test.ts +94 -0
  442. package/src/widgets-v2/histogram/download.ts +60 -0
  443. package/src/widgets-v2/histogram/index.ts +10 -0
  444. package/src/widgets-v2/histogram/options.test.ts +318 -0
  445. package/src/widgets-v2/histogram/options.ts +338 -0
  446. package/src/widgets-v2/histogram/skeleton.test.tsx +16 -0
  447. package/src/widgets-v2/histogram/skeleton.tsx +70 -0
  448. package/src/widgets-v2/histogram/transforms.test.ts +46 -0
  449. package/src/widgets-v2/histogram/transforms.ts +30 -0
  450. package/src/widgets-v2/histogram/types.ts +55 -0
  451. package/src/widgets-v2/index.ts +204 -0
  452. package/src/widgets-v2/markdown/download.test.ts +66 -0
  453. package/src/widgets-v2/markdown/download.ts +53 -0
  454. package/src/widgets-v2/markdown/index.ts +6 -0
  455. package/src/widgets-v2/markdown/markdown-content.test.tsx +155 -0
  456. package/src/widgets-v2/markdown/markdown-content.tsx +72 -0
  457. package/src/widgets-v2/markdown/markdown-ui.test.tsx +75 -0
  458. package/src/widgets-v2/markdown/markdown-ui.tsx +55 -0
  459. package/src/widgets-v2/markdown/markdown.test.tsx +39 -0
  460. package/src/widgets-v2/markdown/markdown.tsx +17 -0
  461. package/src/widgets-v2/markdown/skeleton.test.tsx +15 -0
  462. package/src/widgets-v2/markdown/skeleton.tsx +32 -0
  463. package/src/widgets-v2/markdown/style.ts +53 -0
  464. package/src/widgets-v2/markdown/types.ts +4 -0
  465. package/src/widgets-v2/note/labels.ts +9 -0
  466. package/src/widgets-v2/note/style.ts +26 -0
  467. package/src/widgets-v2/note/widget-note.test.tsx +158 -0
  468. package/src/widgets-v2/note/widget-note.tsx +172 -0
  469. package/src/widgets-v2/pie/download.test.ts +78 -0
  470. package/src/widgets-v2/pie/download.ts +55 -0
  471. package/src/widgets-v2/pie/index.ts +10 -0
  472. package/src/widgets-v2/pie/options.test.ts +601 -0
  473. package/src/widgets-v2/pie/options.ts +513 -0
  474. package/src/widgets-v2/pie/skeleton.test.tsx +17 -0
  475. package/src/widgets-v2/pie/skeleton.tsx +32 -0
  476. package/src/widgets-v2/pie/types.ts +62 -0
  477. package/src/widgets-v2/provider/widget-provider.test.tsx +119 -0
  478. package/src/widgets-v2/provider/widget-provider.tsx +111 -0
  479. package/src/widgets-v2/range/index.ts +4 -0
  480. package/src/widgets-v2/range/range-ui.test.tsx +136 -0
  481. package/src/widgets-v2/range/range-ui.tsx +278 -0
  482. package/src/widgets-v2/range/range.test.tsx +68 -0
  483. package/src/widgets-v2/range/range.tsx +52 -0
  484. package/src/widgets-v2/range/skeleton.test.tsx +17 -0
  485. package/src/widgets-v2/range/skeleton.tsx +47 -0
  486. package/src/widgets-v2/range/style.ts +41 -0
  487. package/src/widgets-v2/range/types.ts +37 -0
  488. package/src/widgets-v2/scatterplot/download.test.ts +71 -0
  489. package/src/widgets-v2/scatterplot/download.ts +54 -0
  490. package/src/widgets-v2/scatterplot/index.ts +11 -0
  491. package/src/widgets-v2/scatterplot/options.test.ts +411 -0
  492. package/src/widgets-v2/scatterplot/options.ts +425 -0
  493. package/src/widgets-v2/scatterplot/skeleton.test.tsx +17 -0
  494. package/src/widgets-v2/scatterplot/skeleton.tsx +84 -0
  495. package/src/widgets-v2/scatterplot/transforms.test.ts +97 -0
  496. package/src/widgets-v2/scatterplot/transforms.ts +38 -0
  497. package/src/widgets-v2/scatterplot/types.ts +59 -0
  498. package/src/widgets-v2/selection-summary/labels.ts +11 -0
  499. package/src/widgets-v2/selection-summary/selection-summary.test.tsx +53 -0
  500. package/src/widgets-v2/selection-summary/selection-summary.tsx +62 -0
  501. package/src/widgets-v2/selection-summary/style.ts +23 -0
  502. package/src/widgets-v2/spread/download.test.ts +64 -0
  503. package/src/widgets-v2/spread/download.ts +59 -0
  504. package/src/widgets-v2/spread/index.ts +6 -0
  505. package/src/widgets-v2/spread/separator.tsx +11 -0
  506. package/src/widgets-v2/spread/skeleton.test.tsx +17 -0
  507. package/src/widgets-v2/spread/skeleton.tsx +38 -0
  508. package/src/widgets-v2/spread/spread-ui.test.tsx +108 -0
  509. package/src/widgets-v2/spread/spread-ui.tsx +52 -0
  510. package/src/widgets-v2/spread/spread.test.tsx +50 -0
  511. package/src/widgets-v2/spread/spread.tsx +31 -0
  512. package/src/widgets-v2/spread/types.ts +27 -0
  513. package/src/widgets-v2/state/labels.test.ts +33 -0
  514. package/src/widgets-v2/state/labels.ts +20 -0
  515. package/src/widgets-v2/state/style.ts +25 -0
  516. package/src/widgets-v2/state/widget-state.test.tsx +294 -0
  517. package/src/widgets-v2/state/widget-state.tsx +184 -0
  518. package/src/widgets-v2/stores/index.ts +49 -0
  519. package/src/widgets-v2/stores/pipeline-middleware.test.ts +187 -0
  520. package/src/widgets-v2/stores/pipeline-middleware.ts +91 -0
  521. package/src/widgets-v2/stores/transforms.test.ts +162 -0
  522. package/src/widgets-v2/stores/transforms.ts +70 -0
  523. package/src/widgets-v2/stores/types.ts +64 -0
  524. package/src/widgets-v2/stores/use-echart-instance.test.tsx +91 -0
  525. package/src/widgets-v2/stores/use-echart-instance.ts +29 -0
  526. package/src/widgets-v2/stores/use-transform-enabled.test.tsx +127 -0
  527. package/src/widgets-v2/stores/use-transform-enabled.ts +25 -0
  528. package/src/widgets-v2/stores/use-transform.test.tsx +262 -0
  529. package/src/widgets-v2/stores/use-transform.ts +158 -0
  530. package/src/widgets-v2/stores/widget-context.test.tsx +58 -0
  531. package/src/widgets-v2/stores/widget-context.ts +15 -0
  532. package/src/widgets-v2/stores/widget-store-registry.test.ts +292 -0
  533. package/src/widgets-v2/stores/widget-store-registry.ts +248 -0
  534. package/src/widgets-v2/subheader/style.ts +12 -0
  535. package/src/widgets-v2/subheader/subheader.test.tsx +30 -0
  536. package/src/widgets-v2/subheader/subheader.tsx +16 -0
  537. package/src/widgets-v2/table/download.test.ts +75 -0
  538. package/src/widgets-v2/table/download.ts +47 -0
  539. package/src/widgets-v2/table/helpers.test.ts +214 -0
  540. package/src/widgets-v2/table/helpers.ts +136 -0
  541. package/src/widgets-v2/table/index.ts +23 -0
  542. package/src/widgets-v2/table/labels.tsx +41 -0
  543. package/src/widgets-v2/table/skeleton.test.tsx +26 -0
  544. package/src/widgets-v2/table/skeleton.tsx +65 -0
  545. package/src/widgets-v2/table/style.ts +43 -0
  546. package/src/widgets-v2/table/table-ui.test.tsx +200 -0
  547. package/src/widgets-v2/table/table-ui.tsx +364 -0
  548. package/src/widgets-v2/table/table.test.tsx +119 -0
  549. package/src/widgets-v2/table/table.tsx +179 -0
  550. package/src/widgets-v2/table/types.ts +55 -0
  551. package/src/widgets-v2/test-utils.ts +107 -0
  552. package/src/widgets-v2/timeseries/download.test.ts +95 -0
  553. package/src/widgets-v2/timeseries/download.ts +86 -0
  554. package/src/widgets-v2/timeseries/index.ts +10 -0
  555. package/src/widgets-v2/timeseries/options.test.ts +394 -0
  556. package/src/widgets-v2/timeseries/options.ts +348 -0
  557. package/src/widgets-v2/timeseries/skeleton.test.tsx +13 -0
  558. package/src/widgets-v2/timeseries/skeleton.tsx +76 -0
  559. package/src/widgets-v2/timeseries/types.ts +65 -0
  560. package/src/widgets-v2/toolbox/labels.ts +9 -0
  561. package/src/widgets-v2/toolbox/style.ts +33 -0
  562. package/src/widgets-v2/toolbox/toolbox.test.tsx +200 -0
  563. package/src/widgets-v2/toolbox/toolbox.tsx +309 -0
  564. package/src/widgets-v2/types.ts +25 -0
  565. package/src/widgets-v2/utils/data-zoom-layout.ts +26 -0
  566. package/src/widgets-v2/utils/index.ts +3 -0
  567. package/src/widgets-v2/utils/merge-options.test.ts +52 -0
  568. package/src/widgets-v2/utils/merge-options.ts +50 -0
  569. package/src/widgets-v2/utils/resolve-theme-color.test.ts +43 -0
  570. package/src/widgets-v2/utils/resolve-theme-color.ts +34 -0
  571. package/src/widgets-v2/wrapper/index.ts +14 -0
  572. package/src/widgets-v2/wrapper/labels.ts +11 -0
  573. package/src/widgets-v2/wrapper/style.ts +134 -0
  574. package/src/widgets-v2/wrapper/widget-actions.test.tsx +52 -0
  575. package/src/widgets-v2/wrapper/widget-actions.tsx +43 -0
  576. package/src/widgets-v2/wrapper/widget-content.test.tsx +27 -0
  577. package/src/widgets-v2/wrapper/widget-content.tsx +29 -0
  578. package/src/widgets-v2/wrapper/widget-wrapper.test.tsx +159 -0
  579. package/src/widgets-v2/wrapper/widget-wrapper.tsx +178 -0
  580. package/dist/styles-BYTyKQFP.js.map +0 -1
@@ -0,0 +1,59 @@
1
+ import type { Theme } from '@mui/material'
2
+ import type { EChartsOption } from 'echarts'
3
+ import type { WidgetSeries } from '../types'
4
+
5
+ /** A single point — `[x, y]` tuple. */
6
+ export type ScatterplotDatum = readonly [number, number]
7
+
8
+ /** Scatterplot widget data — array of series, each a list of `[x, y]` tuples. */
9
+ export type ScatterplotWidgetData = readonly (readonly ScatterplotDatum[])[]
10
+
11
+ /** Inputs to the structural-only {@link scatterplotOptions} builder. */
12
+ export interface ScatterplotOptionsInput {
13
+ theme: Theme
14
+ /** Optional formatter for x-axis values. */
15
+ xFormatter?: (value: number) => string
16
+ /** Optional formatter for y-axis values. */
17
+ yFormatter?: (value: number) => string
18
+ }
19
+
20
+ /**
21
+ * Combined inputs for the scatterplot option factory creator. Carries
22
+ * everything the widget needs across BOTH phases — the structural-build
23
+ * (`theme`, `xFormatter`, `yFormatter`, `optionsOverride`) AND the data
24
+ * merge (`series`, `symbolSize`, `selection`).
25
+ */
26
+ export interface ScatterplotOptionFactoryInput {
27
+ theme: Theme
28
+ /**
29
+ * Optional x-axis value formatter. Drives the structural x-axis
30
+ * label and the reactive tooltip path: when RelativeData overrides
31
+ * `state.formatter` (the y formatter) the merger rebuilds the tooltip
32
+ * and reads `xFormatter` to render coordinates correctly. xFormatter
33
+ * itself isn't relativized — x stays raw.
34
+ */
35
+ xFormatter?: (value: number) => string
36
+ /** Optional formatter for y-axis values (structural baseline). */
37
+ yFormatter?: (value: number) => string
38
+ /**
39
+ * Per-series metadata — drives the legend, `series[i].name`, and
40
+ * (when `color` is set) a per-series colour override on the points.
41
+ */
42
+ series?: readonly WidgetSeries[]
43
+ /** Symbol size in px (default `8`). */
44
+ symbolSize?: number
45
+ /**
46
+ * Selected point keys, one per `${seriesIndex}:${dataIndex}` pair. Points
47
+ * not in this list render dimmed (`itemStyle.opacity: 0.15`). `null`/empty
48
+ * means no selection.
49
+ */
50
+ selection?: readonly string[] | null
51
+ /**
52
+ * Consumer-supplied partial option merged into the structural option at
53
+ * structural-build time. Lets stories override pieces of the theme-aware
54
+ * base without forking the structural builder.
55
+ */
56
+ optionsOverride?: Partial<EChartsOption>
57
+ }
58
+
59
+ 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
+ }