@carto/ps-react-ui 4.7.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/category-DwaeYjpX.js +656 -0
- package/dist/category-DwaeYjpX.js.map +1 -0
- package/dist/change-column-Cidl_M-4.js +1110 -0
- package/dist/change-column-Cidl_M-4.js.map +1 -0
- package/dist/data-zoom-layout-BH0LPwSy.js +28 -0
- package/dist/data-zoom-layout-BH0LPwSy.js.map +1 -0
- package/dist/echart-CU0KmClP.js +176 -0
- package/dist/echart-CU0KmClP.js.map +1 -0
- package/dist/exports-Cx-f6m6U.js +63 -0
- package/dist/exports-Cx-f6m6U.js.map +1 -0
- package/dist/formula-DuC0NQLH.js +79 -0
- package/dist/formula-DuC0NQLH.js.map +1 -0
- package/dist/markdown-BD1jcknS.js +8326 -0
- package/dist/markdown-BD1jcknS.js.map +1 -0
- package/dist/merge-options-DCkkHZIf.js +34 -0
- package/dist/merge-options-DCkkHZIf.js.map +1 -0
- package/dist/{styles-BYTyKQFP.js → option-builders-F-c9ELi1.js} +25 -45
- package/dist/option-builders-F-c9ELi1.js.map +1 -0
- package/dist/png-item-CS4z1iSH.js +45 -0
- package/dist/png-item-CS4z1iSH.js.map +1 -0
- package/dist/range-DsqTjSpg.js +186 -0
- package/dist/range-DsqTjSpg.js.map +1 -0
- package/dist/spread-CTuIXZSM.js +67 -0
- package/dist/spread-CTuIXZSM.js.map +1 -0
- package/dist/style-DVnT6HC1.js +131 -0
- package/dist/style-DVnT6HC1.js.map +1 -0
- package/dist/styles-cohnxh9F.js +23 -0
- package/dist/styles-cohnxh9F.js.map +1 -0
- package/dist/table-HIpXuq4G.js +390 -0
- package/dist/table-HIpXuq4G.js.map +1 -0
- package/dist/transforms-Cdx4fkU5.js +106 -0
- package/dist/transforms-Cdx4fkU5.js.map +1 -0
- package/dist/types/widgets/echart/utils.test.d.ts +1 -0
- package/dist/types/widgets/formula/config.test.d.ts +1 -0
- package/dist/types/widgets/stores/widget-store-branches.test.d.ts +1 -0
- package/dist/types/widgets/table/config.test.d.ts +1 -0
- package/dist/types/widgets-v2/actions/brush-toggle/brush-toggle.d.ts +56 -0
- package/dist/types/widgets-v2/actions/brush-toggle/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/brush-toggle/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/brush-toggle/style.d.ts +12 -0
- package/dist/types/widgets-v2/actions/brush-toggle/transforms.d.ts +11 -0
- package/dist/types/widgets-v2/actions/brush-toggle/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/actions/change-column/change-column-icon.d.ts +2 -0
- package/dist/types/widgets-v2/actions/change-column/change-column.d.ts +29 -0
- package/dist/types/widgets-v2/actions/change-column/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/change-column/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/change-column/sortable-column-item.d.ts +14 -0
- package/dist/types/widgets-v2/actions/change-column/style.d.ts +33 -0
- package/dist/types/widgets-v2/actions/change-column/types.d.ts +10 -0
- package/dist/types/widgets-v2/actions/download/download.d.ts +18 -0
- package/dist/types/widgets-v2/actions/download/exports.d.ts +37 -0
- package/dist/types/widgets-v2/actions/download/icons.d.ts +12 -0
- package/dist/types/widgets-v2/actions/download/index.d.ts +6 -0
- package/dist/types/widgets-v2/actions/download/labels.d.ts +11 -0
- package/dist/types/widgets-v2/actions/download/png-item.d.ts +24 -0
- package/dist/types/widgets-v2/actions/download/style.d.ts +1 -0
- package/dist/types/widgets-v2/actions/download/types.d.ts +35 -0
- package/dist/types/widgets-v2/actions/fullscreen/fullscreen.d.ts +59 -0
- package/dist/types/widgets-v2/actions/fullscreen/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/fullscreen/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/fullscreen/style.d.ts +48 -0
- package/dist/types/widgets-v2/actions/fullscreen/types.d.ts +14 -0
- package/dist/types/widgets-v2/actions/index.d.ts +9 -0
- package/dist/types/widgets-v2/actions/lock-selection/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/lock-selection/labels.d.ts +6 -0
- package/dist/types/widgets-v2/actions/lock-selection/lock-selection.d.ts +36 -0
- package/dist/types/widgets-v2/actions/lock-selection/style.d.ts +12 -0
- package/dist/types/widgets-v2/actions/lock-selection/transforms.d.ts +6 -0
- package/dist/types/widgets-v2/actions/relative-data/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/relative-data/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/relative-data/relative-data.d.ts +39 -0
- package/dist/types/widgets-v2/actions/relative-data/style.d.ts +12 -0
- package/dist/types/widgets-v2/actions/relative-data/transforms.d.ts +30 -0
- package/dist/types/widgets-v2/actions/relative-data/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/actions/searcher/filter.d.ts +6 -0
- package/dist/types/widgets-v2/actions/searcher/index.d.ts +4 -0
- package/dist/types/widgets-v2/actions/searcher/labels.d.ts +7 -0
- package/dist/types/widgets-v2/actions/searcher/searcher-toggle.d.ts +23 -0
- package/dist/types/widgets-v2/actions/searcher/searcher.d.ts +11 -0
- package/dist/types/widgets-v2/actions/searcher/style.d.ts +16 -0
- package/dist/types/widgets-v2/actions/stack-toggle/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/stack-toggle/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/stack-toggle/stack-toggle.d.ts +10 -0
- package/dist/types/widgets-v2/actions/stack-toggle/style.d.ts +12 -0
- package/dist/types/widgets-v2/actions/stack-toggle/transforms.d.ts +13 -0
- package/dist/types/widgets-v2/actions/stack-toggle/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/style.d.ts +12 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/transforms.d.ts +51 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/zoom-toggle.d.ts +35 -0
- package/dist/types/widgets-v2/bar/download.d.ts +24 -0
- package/dist/types/widgets-v2/bar/index.d.ts +4 -0
- package/dist/types/widgets-v2/bar/options.d.ts +43 -0
- package/dist/types/widgets-v2/bar/options.test.d.ts +1 -0
- package/dist/types/widgets-v2/bar/skeleton.d.ts +6 -0
- package/dist/types/widgets-v2/bar/types.d.ts +41 -0
- package/dist/types/widgets-v2/category/category-ui.d.ts +81 -0
- package/dist/types/widgets-v2/category/category.d.ts +48 -0
- package/dist/types/widgets-v2/category/components/category-bar-stacked.d.ts +28 -0
- package/dist/types/widgets-v2/category/components/category-bar.d.ts +23 -0
- package/dist/types/widgets-v2/category/components/category-legend.d.ts +18 -0
- package/dist/types/widgets-v2/category/components/category-row-multi.d.ts +31 -0
- package/dist/types/widgets-v2/category/components/category-row-other.d.ts +13 -0
- package/dist/types/widgets-v2/category/components/category-row-single.d.ts +28 -0
- package/dist/types/widgets-v2/category/components/category-row-stacked.d.ts +38 -0
- package/dist/types/widgets-v2/category/download.d.ts +16 -0
- package/dist/types/widgets-v2/category/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/category/index.d.ts +10 -0
- package/dist/types/widgets-v2/category/skeleton.d.ts +11 -0
- package/dist/types/widgets-v2/category/style.d.ts +166 -0
- package/dist/types/widgets-v2/category/types.d.ts +49 -0
- package/dist/types/widgets-v2/echart/echart-ui.d.ts +44 -0
- package/dist/types/widgets-v2/echart/echart.d.ts +75 -0
- package/dist/types/widgets-v2/echart/index.d.ts +4 -0
- package/dist/types/widgets-v2/echart/shared-resize-observer.d.ts +5 -0
- package/dist/types/widgets-v2/echart/shared-resize-observer.test.d.ts +1 -0
- package/dist/types/widgets-v2/echart/style.d.ts +6 -0
- package/dist/types/widgets-v2/echart/use-chart-selection.d.ts +51 -0
- package/dist/types/widgets-v2/formula/delta.d.ts +22 -0
- package/dist/types/widgets-v2/formula/download.d.ts +20 -0
- package/dist/types/widgets-v2/formula/formula-ui.d.ts +20 -0
- package/dist/types/widgets-v2/formula/formula.d.ts +8 -0
- package/dist/types/widgets-v2/formula/index.d.ts +11 -0
- package/dist/types/widgets-v2/formula/note.d.ts +11 -0
- package/dist/types/widgets-v2/formula/prefix.d.ts +12 -0
- package/dist/types/widgets-v2/formula/series.d.ts +16 -0
- package/dist/types/widgets-v2/formula/skeleton.d.ts +4 -0
- package/dist/types/widgets-v2/formula/style.d.ts +29 -0
- package/dist/types/widgets-v2/formula/suffix.d.ts +12 -0
- package/dist/types/widgets-v2/formula/types.d.ts +40 -0
- package/dist/types/widgets-v2/formula/value.d.ts +14 -0
- package/dist/types/widgets-v2/histogram/download.d.ts +17 -0
- package/dist/types/widgets-v2/histogram/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/histogram/index.d.ts +5 -0
- package/dist/types/widgets-v2/histogram/options.d.ts +42 -0
- package/dist/types/widgets-v2/histogram/options.test.d.ts +1 -0
- package/dist/types/widgets-v2/histogram/skeleton.d.ts +9 -0
- package/dist/types/widgets-v2/histogram/transforms.d.ts +17 -0
- package/dist/types/widgets-v2/histogram/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/histogram/types.d.ts +47 -0
- package/dist/types/widgets-v2/index.d.ts +107 -0
- package/dist/types/widgets-v2/markdown/download.d.ts +16 -0
- package/dist/types/widgets-v2/markdown/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/markdown/index.d.ts +6 -0
- package/dist/types/widgets-v2/markdown/markdown-content.d.ts +34 -0
- package/dist/types/widgets-v2/markdown/markdown-ui.d.ts +12 -0
- package/dist/types/widgets-v2/markdown/markdown.d.ts +6 -0
- package/dist/types/widgets-v2/markdown/skeleton.d.ts +4 -0
- package/dist/types/widgets-v2/markdown/style.d.ts +61 -0
- package/dist/types/widgets-v2/markdown/types.d.ts +4 -0
- package/dist/types/widgets-v2/note/labels.d.ts +5 -0
- package/dist/types/widgets-v2/note/style.d.ts +26 -0
- package/dist/types/widgets-v2/note/widget-note.d.ts +46 -0
- package/dist/types/widgets-v2/pie/download.d.ts +17 -0
- package/dist/types/widgets-v2/pie/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/pie/index.d.ts +4 -0
- package/dist/types/widgets-v2/pie/options.d.ts +35 -0
- package/dist/types/widgets-v2/pie/options.test.d.ts +1 -0
- package/dist/types/widgets-v2/pie/skeleton.d.ts +4 -0
- package/dist/types/widgets-v2/pie/types.d.ts +50 -0
- package/dist/types/widgets-v2/provider/widget-provider.d.ts +32 -0
- package/dist/types/widgets-v2/range/index.d.ts +4 -0
- package/dist/types/widgets-v2/range/range-ui.d.ts +19 -0
- package/dist/types/widgets-v2/range/range.d.ts +19 -0
- package/dist/types/widgets-v2/range/skeleton.d.ts +9 -0
- package/dist/types/widgets-v2/range/style.d.ts +40 -0
- package/dist/types/widgets-v2/range/types.d.ts +37 -0
- package/dist/types/widgets-v2/scatterplot/download.d.ts +16 -0
- package/dist/types/widgets-v2/scatterplot/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/scatterplot/index.d.ts +5 -0
- package/dist/types/widgets-v2/scatterplot/options.d.ts +42 -0
- package/dist/types/widgets-v2/scatterplot/options.test.d.ts +1 -0
- package/dist/types/widgets-v2/scatterplot/skeleton.d.ts +12 -0
- package/dist/types/widgets-v2/scatterplot/transforms.d.ts +17 -0
- package/dist/types/widgets-v2/scatterplot/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/scatterplot/types.d.ts +50 -0
- package/dist/types/widgets-v2/selection-summary/labels.d.ts +6 -0
- package/dist/types/widgets-v2/selection-summary/selection-summary.d.ts +22 -0
- package/dist/types/widgets-v2/selection-summary/style.d.ts +23 -0
- package/dist/types/widgets-v2/spread/download.d.ts +15 -0
- package/dist/types/widgets-v2/spread/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/spread/index.d.ts +6 -0
- package/dist/types/widgets-v2/spread/separator.d.ts +7 -0
- package/dist/types/widgets-v2/spread/skeleton.d.ts +9 -0
- package/dist/types/widgets-v2/spread/spread-ui.d.ts +18 -0
- package/dist/types/widgets-v2/spread/spread.d.ts +5 -0
- package/dist/types/widgets-v2/spread/types.d.ts +25 -0
- package/dist/types/widgets-v2/state/labels.d.ts +7 -0
- package/dist/types/widgets-v2/state/labels.test.d.ts +1 -0
- package/dist/types/widgets-v2/state/style.d.ts +19 -0
- package/dist/types/widgets-v2/state/widget-state.d.ts +19 -0
- package/dist/types/widgets-v2/stores/index.d.ts +8 -0
- package/dist/types/widgets-v2/stores/pipeline-middleware.d.ts +5 -0
- package/dist/types/widgets-v2/stores/pipeline-middleware.test.d.ts +1 -0
- package/dist/types/widgets-v2/stores/transforms.d.ts +4 -0
- package/dist/types/widgets-v2/stores/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/stores/types.d.ts +55 -0
- package/dist/types/widgets-v2/stores/use-echart-instance.d.ts +15 -0
- package/dist/types/widgets-v2/stores/use-transform-enabled.d.ts +17 -0
- package/dist/types/widgets-v2/stores/use-transform.d.ts +12 -0
- package/dist/types/widgets-v2/stores/widget-context.d.ts +2 -0
- package/dist/types/widgets-v2/stores/widget-store-registry.d.ts +74 -0
- package/dist/types/widgets-v2/stores/widget-store-registry.test.d.ts +1 -0
- package/dist/types/widgets-v2/subheader/style.d.ts +10 -0
- package/dist/types/widgets-v2/subheader/subheader.d.ts +11 -0
- package/dist/types/widgets-v2/table/download.d.ts +18 -0
- package/dist/types/widgets-v2/table/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/table/helpers.d.ts +32 -0
- package/dist/types/widgets-v2/table/helpers.test.d.ts +1 -0
- package/dist/types/widgets-v2/table/index.d.ts +7 -0
- package/dist/types/widgets-v2/table/labels.d.ts +22 -0
- package/dist/types/widgets-v2/table/skeleton.d.ts +22 -0
- package/dist/types/widgets-v2/table/style.d.ts +44 -0
- package/dist/types/widgets-v2/table/table-ui.d.ts +38 -0
- package/dist/types/widgets-v2/table/table.d.ts +50 -0
- package/dist/types/widgets-v2/table/types.d.ts +37 -0
- package/dist/types/widgets-v2/test-utils.d.ts +52 -0
- package/dist/types/widgets-v2/timeseries/download.d.ts +17 -0
- package/dist/types/widgets-v2/timeseries/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/timeseries/index.d.ts +4 -0
- package/dist/types/widgets-v2/timeseries/options.d.ts +39 -0
- package/dist/types/widgets-v2/timeseries/options.test.d.ts +1 -0
- package/dist/types/widgets-v2/timeseries/skeleton.d.ts +8 -0
- package/dist/types/widgets-v2/timeseries/types.d.ts +56 -0
- package/dist/types/widgets-v2/toolbox/labels.d.ts +5 -0
- package/dist/types/widgets-v2/toolbox/style.d.ts +30 -0
- package/dist/types/widgets-v2/toolbox/toolbox.d.ts +49 -0
- package/dist/types/widgets-v2/utils/data-zoom-layout.d.ts +11 -0
- package/dist/types/widgets-v2/utils/index.d.ts +2 -0
- package/dist/types/widgets-v2/utils/merge-options.d.ts +12 -0
- package/dist/types/widgets-v2/utils/merge-options.test.d.ts +1 -0
- package/dist/types/widgets-v2/wrapper/index.d.ts +4 -0
- package/dist/types/widgets-v2/wrapper/labels.d.ts +6 -0
- package/dist/types/widgets-v2/wrapper/style.d.ts +111 -0
- package/dist/types/widgets-v2/wrapper/widget-actions.d.ts +22 -0
- package/dist/types/widgets-v2/wrapper/widget-content.d.ts +12 -0
- package/dist/types/widgets-v2/wrapper/widget-wrapper.d.ts +51 -0
- package/dist/use-transform-DXPN3nY7.js +110 -0
- package/dist/use-transform-DXPN3nY7.js.map +1 -0
- package/dist/widget-context-DTGO0Yta.js +13 -0
- package/dist/widget-context-DTGO0Yta.js.map +1 -0
- package/dist/widget-store-registry-_W4Z4xp-.js +178 -0
- package/dist/widget-store-registry-_W4Z4xp-.js.map +1 -0
- package/dist/widgets/actions.js +688 -668
- package/dist/widgets/actions.js.map +1 -1
- package/dist/widgets/bar.js +14 -13
- package/dist/widgets/bar.js.map +1 -1
- package/dist/widgets/histogram.js +38 -37
- package/dist/widgets/histogram.js.map +1 -1
- package/dist/widgets/pie.js +19 -18
- package/dist/widgets/pie.js.map +1 -1
- package/dist/widgets/scatterplot.js +8 -7
- package/dist/widgets/scatterplot.js.map +1 -1
- package/dist/widgets/timeseries.js +11 -10
- package/dist/widgets/timeseries.js.map +1 -1
- package/dist/widgets/utils.js +8 -7
- package/dist/widgets/utils.js.map +1 -1
- package/dist/widgets-v2/actions.js +43 -0
- package/dist/widgets-v2/actions.js.map +1 -0
- package/dist/widgets-v2/bar.js +327 -0
- package/dist/widgets-v2/bar.js.map +1 -0
- package/dist/widgets-v2/category.js +104 -0
- package/dist/widgets-v2/category.js.map +1 -0
- package/dist/widgets-v2/echart.js +57 -0
- package/dist/widgets-v2/echart.js.map +1 -0
- package/dist/widgets-v2/formula.js +74 -0
- package/dist/widgets-v2/formula.js.map +1 -0
- package/dist/widgets-v2/histogram.js +350 -0
- package/dist/widgets-v2/histogram.js.map +1 -0
- package/dist/widgets-v2/markdown.js +68 -0
- package/dist/widgets-v2/markdown.js.map +1 -0
- package/dist/widgets-v2/pie.js +381 -0
- package/dist/widgets-v2/pie.js.map +1 -0
- package/dist/widgets-v2/range.js +52 -0
- package/dist/widgets-v2/range.js.map +1 -0
- package/dist/widgets-v2/scatterplot.js +405 -0
- package/dist/widgets-v2/scatterplot.js.map +1 -0
- package/dist/widgets-v2/spread.js +72 -0
- package/dist/widgets-v2/spread.js.map +1 -0
- package/dist/widgets-v2/stores.js +42 -0
- package/dist/widgets-v2/stores.js.map +1 -0
- package/dist/widgets-v2/table.js +78 -0
- package/dist/widgets-v2/table.js.map +1 -0
- package/dist/widgets-v2/timeseries.js +352 -0
- package/dist/widgets-v2/timeseries.js.map +1 -0
- package/dist/widgets-v2/utils.js +7 -0
- package/dist/widgets-v2/utils.js.map +1 -0
- package/dist/widgets-v2.js +953 -0
- package/dist/widgets-v2.js.map +1 -0
- package/package.json +73 -5
- package/src/components/lasso-tool/chip.test.tsx +176 -0
- package/src/components/lasso-tool/lasso-tool-inline.test.tsx +171 -0
- package/src/components/lasso-tool/lasso-tool.test.tsx +198 -0
- package/src/components/list-data/list-data.test.tsx +73 -0
- package/src/components/no-data-alert/no-data-alert.test.tsx +38 -0
- package/src/components/responsive-drawer/responsive-drawer.test.tsx +68 -0
- package/src/widgets/actions/brush-toggle/brush-overlay.test.tsx +465 -0
- package/src/widgets/actions/brush-toggle/brush-overlay.tsx +24 -2
- package/src/widgets/actions/brush-toggle/brush-toggle.test.tsx +208 -0
- package/src/widgets/actions/change-column/change-column-dnd.test.tsx +193 -0
- package/src/widgets/actions/change-column/sortable-column-item.test.tsx +124 -0
- package/src/widgets/actions/zoom-toggle/zoom-toggle.test.tsx +322 -0
- package/src/widgets/category/components/category-rows.test.tsx +213 -0
- package/src/widgets/echart/utils.test.ts +277 -0
- package/src/widgets/formula/config.test.ts +37 -0
- package/src/widgets/histogram/config.ts +1 -3
- package/src/widgets/range/components/range-item.test.tsx +243 -0
- package/src/widgets/stores/widget-store-branches.test.ts +275 -0
- package/src/widgets/table/config.test.ts +65 -0
- package/src/widgets/utils/chart-config/option-builders.test.ts +188 -0
- package/src/widgets-v2/PERFORMANCE.md +189 -0
- package/src/widgets-v2/actions/brush-toggle/brush-toggle.test.tsx +180 -0
- package/src/widgets-v2/actions/brush-toggle/brush-toggle.tsx +154 -0
- package/src/widgets-v2/actions/brush-toggle/index.ts +3 -0
- package/src/widgets-v2/actions/brush-toggle/labels.ts +9 -0
- package/src/widgets-v2/actions/brush-toggle/style.ts +11 -0
- package/src/widgets-v2/actions/brush-toggle/transforms.test.ts +47 -0
- package/src/widgets-v2/actions/brush-toggle/transforms.ts +31 -0
- package/src/widgets-v2/actions/change-column/change-column-icon.tsx +14 -0
- package/src/widgets-v2/actions/change-column/change-column.test.tsx +59 -0
- package/src/widgets-v2/actions/change-column/change-column.tsx +180 -0
- package/src/widgets-v2/actions/change-column/index.ts +7 -0
- package/src/widgets-v2/actions/change-column/labels.ts +9 -0
- package/src/widgets-v2/actions/change-column/sortable-column-item.tsx +56 -0
- package/src/widgets-v2/actions/change-column/style.ts +32 -0
- package/src/widgets-v2/actions/change-column/types.ts +11 -0
- package/src/widgets-v2/actions/download/download.test.tsx +327 -0
- package/src/widgets-v2/actions/download/download.tsx +144 -0
- package/src/widgets-v2/actions/download/exports.test.tsx +198 -0
- package/src/widgets-v2/actions/download/exports.ts +115 -0
- package/src/widgets-v2/actions/download/icons.tsx +26 -0
- package/src/widgets-v2/actions/download/index.ts +13 -0
- package/src/widgets-v2/actions/download/labels.ts +16 -0
- package/src/widgets-v2/actions/download/png-item.test.tsx +72 -0
- package/src/widgets-v2/actions/download/png-item.tsx +52 -0
- package/src/widgets-v2/actions/download/style.ts +3 -0
- package/src/widgets-v2/actions/download/types.ts +32 -0
- package/src/widgets-v2/actions/fullscreen/fullscreen.test.tsx +150 -0
- package/src/widgets-v2/actions/fullscreen/fullscreen.tsx +230 -0
- package/src/widgets-v2/actions/fullscreen/index.ts +7 -0
- package/src/widgets-v2/actions/fullscreen/labels.ts +9 -0
- package/src/widgets-v2/actions/fullscreen/style.ts +59 -0
- package/src/widgets-v2/actions/fullscreen/types.ts +15 -0
- package/src/widgets-v2/actions/index.ts +82 -0
- package/src/widgets-v2/actions/lock-selection/index.ts +10 -0
- package/src/widgets-v2/actions/lock-selection/labels.ts +11 -0
- package/src/widgets-v2/actions/lock-selection/lock-selection.test.tsx +187 -0
- package/src/widgets-v2/actions/lock-selection/lock-selection.tsx +130 -0
- package/src/widgets-v2/actions/lock-selection/style.ts +11 -0
- package/src/widgets-v2/actions/lock-selection/transforms.ts +27 -0
- package/src/widgets-v2/actions/relative-data/index.ts +3 -0
- package/src/widgets-v2/actions/relative-data/labels.ts +9 -0
- package/src/widgets-v2/actions/relative-data/relative-data.test.tsx +71 -0
- package/src/widgets-v2/actions/relative-data/relative-data.tsx +107 -0
- package/src/widgets-v2/actions/relative-data/style.ts +11 -0
- package/src/widgets-v2/actions/relative-data/transforms.test.ts +151 -0
- package/src/widgets-v2/actions/relative-data/transforms.ts +70 -0
- package/src/widgets-v2/actions/searcher/filter.ts +28 -0
- package/src/widgets-v2/actions/searcher/index.ts +8 -0
- package/src/widgets-v2/actions/searcher/labels.ts +13 -0
- package/src/widgets-v2/actions/searcher/searcher-toggle.tsx +91 -0
- package/src/widgets-v2/actions/searcher/searcher.test.tsx +92 -0
- package/src/widgets-v2/actions/searcher/searcher.tsx +112 -0
- package/src/widgets-v2/actions/searcher/style.ts +15 -0
- package/src/widgets-v2/actions/stack-toggle/index.ts +3 -0
- package/src/widgets-v2/actions/stack-toggle/labels.ts +9 -0
- package/src/widgets-v2/actions/stack-toggle/stack-toggle.test.tsx +61 -0
- package/src/widgets-v2/actions/stack-toggle/stack-toggle.tsx +54 -0
- package/src/widgets-v2/actions/stack-toggle/style.ts +11 -0
- package/src/widgets-v2/actions/stack-toggle/transforms.test.ts +43 -0
- package/src/widgets-v2/actions/stack-toggle/transforms.ts +25 -0
- package/src/widgets-v2/actions/zoom-toggle/index.ts +9 -0
- package/src/widgets-v2/actions/zoom-toggle/labels.ts +9 -0
- package/src/widgets-v2/actions/zoom-toggle/style.ts +11 -0
- package/src/widgets-v2/actions/zoom-toggle/transforms.test.ts +148 -0
- package/src/widgets-v2/actions/zoom-toggle/transforms.ts +171 -0
- package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.test.tsx +107 -0
- package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.tsx +106 -0
- package/src/widgets-v2/bar/download.test.tsx +91 -0
- package/src/widgets-v2/bar/download.tsx +66 -0
- package/src/widgets-v2/bar/index.ts +10 -0
- package/src/widgets-v2/bar/options.test.ts +317 -0
- package/src/widgets-v2/bar/options.ts +326 -0
- package/src/widgets-v2/bar/skeleton.test.tsx +19 -0
- package/src/widgets-v2/bar/skeleton.tsx +69 -0
- package/src/widgets-v2/bar/types.ts +46 -0
- package/src/widgets-v2/category/category-ui.test.tsx +746 -0
- package/src/widgets-v2/category/category-ui.tsx +389 -0
- package/src/widgets-v2/category/category.relative-data.test.tsx +107 -0
- package/src/widgets-v2/category/category.stack-toggle.test.tsx +85 -0
- package/src/widgets-v2/category/category.test.tsx +305 -0
- package/src/widgets-v2/category/category.tsx +121 -0
- package/src/widgets-v2/category/components/category-bar-stacked.test.tsx +121 -0
- package/src/widgets-v2/category/components/category-bar-stacked.tsx +73 -0
- package/src/widgets-v2/category/components/category-bar.test.tsx +64 -0
- package/src/widgets-v2/category/components/category-bar.tsx +49 -0
- package/src/widgets-v2/category/components/category-legend.test.tsx +51 -0
- package/src/widgets-v2/category/components/category-legend.tsx +39 -0
- package/src/widgets-v2/category/components/category-row-multi.tsx +86 -0
- package/src/widgets-v2/category/components/category-row-other.test.tsx +28 -0
- package/src/widgets-v2/category/components/category-row-other.tsx +33 -0
- package/src/widgets-v2/category/components/category-row-single.tsx +76 -0
- package/src/widgets-v2/category/components/category-row-stacked.test.tsx +244 -0
- package/src/widgets-v2/category/components/category-row-stacked.tsx +99 -0
- package/src/widgets-v2/category/download.test.ts +71 -0
- package/src/widgets-v2/category/download.ts +54 -0
- package/src/widgets-v2/category/index.ts +32 -0
- package/src/widgets-v2/category/skeleton.test.tsx +26 -0
- package/src/widgets-v2/category/skeleton.tsx +74 -0
- package/src/widgets-v2/category/style.ts +290 -0
- package/src/widgets-v2/category/types.ts +54 -0
- package/src/widgets-v2/echart/echart-ui.test.tsx +232 -0
- package/src/widgets-v2/echart/echart-ui.tsx +184 -0
- package/src/widgets-v2/echart/echart.test.tsx +229 -0
- package/src/widgets-v2/echart/echart.tsx +199 -0
- package/src/widgets-v2/echart/index.ts +22 -0
- package/src/widgets-v2/echart/shared-resize-observer.test.ts +91 -0
- package/src/widgets-v2/echart/shared-resize-observer.ts +56 -0
- package/src/widgets-v2/echart/style.ts +8 -0
- package/src/widgets-v2/echart/use-chart-selection.test.tsx +118 -0
- package/src/widgets-v2/echart/use-chart-selection.ts +115 -0
- package/src/widgets-v2/formula/delta.tsx +61 -0
- package/src/widgets-v2/formula/download.test.tsx +65 -0
- package/src/widgets-v2/formula/download.tsx +69 -0
- package/src/widgets-v2/formula/formula-ui.test.tsx +91 -0
- package/src/widgets-v2/formula/formula-ui.tsx +66 -0
- package/src/widgets-v2/formula/formula.test.tsx +50 -0
- package/src/widgets-v2/formula/formula.tsx +34 -0
- package/src/widgets-v2/formula/index.ts +17 -0
- package/src/widgets-v2/formula/note.tsx +25 -0
- package/src/widgets-v2/formula/prefix.tsx +25 -0
- package/src/widgets-v2/formula/series.tsx +67 -0
- package/src/widgets-v2/formula/skeleton.test.tsx +21 -0
- package/src/widgets-v2/formula/skeleton.tsx +27 -0
- package/src/widgets-v2/formula/style.ts +31 -0
- package/src/widgets-v2/formula/subcomponents.test.tsx +107 -0
- package/src/widgets-v2/formula/suffix.tsx +25 -0
- package/src/widgets-v2/formula/types.ts +44 -0
- package/src/widgets-v2/formula/value.tsx +31 -0
- package/src/widgets-v2/histogram/download.test.ts +94 -0
- package/src/widgets-v2/histogram/download.ts +60 -0
- package/src/widgets-v2/histogram/index.ts +10 -0
- package/src/widgets-v2/histogram/options.test.ts +304 -0
- package/src/widgets-v2/histogram/options.ts +337 -0
- package/src/widgets-v2/histogram/skeleton.test.tsx +16 -0
- package/src/widgets-v2/histogram/skeleton.tsx +70 -0
- package/src/widgets-v2/histogram/transforms.test.ts +46 -0
- package/src/widgets-v2/histogram/transforms.ts +30 -0
- package/src/widgets-v2/histogram/types.ts +51 -0
- package/src/widgets-v2/index.ts +201 -0
- package/src/widgets-v2/markdown/download.test.ts +66 -0
- package/src/widgets-v2/markdown/download.ts +53 -0
- package/src/widgets-v2/markdown/index.ts +6 -0
- package/src/widgets-v2/markdown/markdown-content.test.tsx +155 -0
- package/src/widgets-v2/markdown/markdown-content.tsx +72 -0
- package/src/widgets-v2/markdown/markdown-ui.test.tsx +75 -0
- package/src/widgets-v2/markdown/markdown-ui.tsx +55 -0
- package/src/widgets-v2/markdown/markdown.test.tsx +39 -0
- package/src/widgets-v2/markdown/markdown.tsx +17 -0
- package/src/widgets-v2/markdown/skeleton.test.tsx +15 -0
- package/src/widgets-v2/markdown/skeleton.tsx +32 -0
- package/src/widgets-v2/markdown/style.ts +53 -0
- package/src/widgets-v2/markdown/types.ts +4 -0
- package/src/widgets-v2/note/labels.ts +9 -0
- package/src/widgets-v2/note/style.ts +26 -0
- package/src/widgets-v2/note/widget-note.test.tsx +158 -0
- package/src/widgets-v2/note/widget-note.tsx +172 -0
- package/src/widgets-v2/pie/download.test.ts +78 -0
- package/src/widgets-v2/pie/download.ts +55 -0
- package/src/widgets-v2/pie/index.ts +10 -0
- package/src/widgets-v2/pie/options.test.ts +585 -0
- package/src/widgets-v2/pie/options.ts +509 -0
- package/src/widgets-v2/pie/skeleton.test.tsx +17 -0
- package/src/widgets-v2/pie/skeleton.tsx +32 -0
- package/src/widgets-v2/pie/types.ts +55 -0
- package/src/widgets-v2/provider/widget-provider.test.tsx +119 -0
- package/src/widgets-v2/provider/widget-provider.tsx +111 -0
- package/src/widgets-v2/range/index.ts +4 -0
- package/src/widgets-v2/range/range-ui.test.tsx +130 -0
- package/src/widgets-v2/range/range-ui.tsx +211 -0
- package/src/widgets-v2/range/range.test.tsx +68 -0
- package/src/widgets-v2/range/range.tsx +46 -0
- package/src/widgets-v2/range/skeleton.test.tsx +17 -0
- package/src/widgets-v2/range/skeleton.tsx +47 -0
- package/src/widgets-v2/range/style.ts +41 -0
- package/src/widgets-v2/range/types.ts +37 -0
- package/src/widgets-v2/scatterplot/download.test.ts +71 -0
- package/src/widgets-v2/scatterplot/download.ts +54 -0
- package/src/widgets-v2/scatterplot/index.ts +11 -0
- package/src/widgets-v2/scatterplot/options.test.ts +399 -0
- package/src/widgets-v2/scatterplot/options.ts +421 -0
- package/src/widgets-v2/scatterplot/skeleton.test.tsx +17 -0
- package/src/widgets-v2/scatterplot/skeleton.tsx +84 -0
- package/src/widgets-v2/scatterplot/transforms.test.ts +97 -0
- package/src/widgets-v2/scatterplot/transforms.ts +38 -0
- package/src/widgets-v2/scatterplot/types.ts +55 -0
- package/src/widgets-v2/selection-summary/labels.ts +11 -0
- package/src/widgets-v2/selection-summary/selection-summary.test.tsx +53 -0
- package/src/widgets-v2/selection-summary/selection-summary.tsx +62 -0
- package/src/widgets-v2/selection-summary/style.ts +23 -0
- package/src/widgets-v2/spread/download.test.ts +64 -0
- package/src/widgets-v2/spread/download.ts +59 -0
- package/src/widgets-v2/spread/index.ts +6 -0
- package/src/widgets-v2/spread/separator.tsx +11 -0
- package/src/widgets-v2/spread/skeleton.test.tsx +17 -0
- package/src/widgets-v2/spread/skeleton.tsx +38 -0
- package/src/widgets-v2/spread/spread-ui.test.tsx +108 -0
- package/src/widgets-v2/spread/spread-ui.tsx +52 -0
- package/src/widgets-v2/spread/spread.test.tsx +50 -0
- package/src/widgets-v2/spread/spread.tsx +31 -0
- package/src/widgets-v2/spread/types.ts +27 -0
- package/src/widgets-v2/state/labels.test.ts +33 -0
- package/src/widgets-v2/state/labels.ts +20 -0
- package/src/widgets-v2/state/style.ts +25 -0
- package/src/widgets-v2/state/widget-state.test.tsx +294 -0
- package/src/widgets-v2/state/widget-state.tsx +184 -0
- package/src/widgets-v2/stores/index.ts +49 -0
- package/src/widgets-v2/stores/pipeline-middleware.test.ts +187 -0
- package/src/widgets-v2/stores/pipeline-middleware.ts +91 -0
- package/src/widgets-v2/stores/transforms.test.ts +162 -0
- package/src/widgets-v2/stores/transforms.ts +70 -0
- package/src/widgets-v2/stores/types.ts +64 -0
- package/src/widgets-v2/stores/use-echart-instance.test.tsx +91 -0
- package/src/widgets-v2/stores/use-echart-instance.ts +29 -0
- package/src/widgets-v2/stores/use-transform-enabled.test.tsx +127 -0
- package/src/widgets-v2/stores/use-transform-enabled.ts +25 -0
- package/src/widgets-v2/stores/use-transform.test.tsx +262 -0
- package/src/widgets-v2/stores/use-transform.ts +158 -0
- package/src/widgets-v2/stores/widget-context.test.tsx +58 -0
- package/src/widgets-v2/stores/widget-context.ts +15 -0
- package/src/widgets-v2/stores/widget-store-registry.test.ts +292 -0
- package/src/widgets-v2/stores/widget-store-registry.ts +248 -0
- package/src/widgets-v2/subheader/style.ts +12 -0
- package/src/widgets-v2/subheader/subheader.test.tsx +30 -0
- package/src/widgets-v2/subheader/subheader.tsx +16 -0
- package/src/widgets-v2/table/download.test.ts +75 -0
- package/src/widgets-v2/table/download.ts +47 -0
- package/src/widgets-v2/table/helpers.test.ts +214 -0
- package/src/widgets-v2/table/helpers.ts +136 -0
- package/src/widgets-v2/table/index.ts +23 -0
- package/src/widgets-v2/table/labels.tsx +41 -0
- package/src/widgets-v2/table/skeleton.test.tsx +26 -0
- package/src/widgets-v2/table/skeleton.tsx +65 -0
- package/src/widgets-v2/table/style.ts +46 -0
- package/src/widgets-v2/table/table-ui.test.tsx +200 -0
- package/src/widgets-v2/table/table-ui.tsx +331 -0
- package/src/widgets-v2/table/table.test.tsx +119 -0
- package/src/widgets-v2/table/table.tsx +174 -0
- package/src/widgets-v2/table/types.ts +44 -0
- package/src/widgets-v2/test-utils.ts +107 -0
- package/src/widgets-v2/timeseries/download.test.ts +95 -0
- package/src/widgets-v2/timeseries/download.ts +86 -0
- package/src/widgets-v2/timeseries/index.ts +10 -0
- package/src/widgets-v2/timeseries/options.test.ts +379 -0
- package/src/widgets-v2/timeseries/options.ts +341 -0
- package/src/widgets-v2/timeseries/skeleton.test.tsx +13 -0
- package/src/widgets-v2/timeseries/skeleton.tsx +76 -0
- package/src/widgets-v2/timeseries/types.ts +61 -0
- package/src/widgets-v2/toolbox/labels.ts +9 -0
- package/src/widgets-v2/toolbox/style.ts +33 -0
- package/src/widgets-v2/toolbox/toolbox.test.tsx +200 -0
- package/src/widgets-v2/toolbox/toolbox.tsx +309 -0
- package/src/widgets-v2/utils/data-zoom-layout.ts +26 -0
- package/src/widgets-v2/utils/index.ts +2 -0
- package/src/widgets-v2/utils/merge-options.test.ts +52 -0
- package/src/widgets-v2/utils/merge-options.ts +50 -0
- package/src/widgets-v2/wrapper/index.ts +14 -0
- package/src/widgets-v2/wrapper/labels.ts +11 -0
- package/src/widgets-v2/wrapper/style.ts +134 -0
- package/src/widgets-v2/wrapper/widget-actions.test.tsx +52 -0
- package/src/widgets-v2/wrapper/widget-actions.tsx +43 -0
- package/src/widgets-v2/wrapper/widget-content.test.tsx +27 -0
- package/src/widgets-v2/wrapper/widget-content.tsx +29 -0
- package/src/widgets-v2/wrapper/widget-wrapper.test.tsx +159 -0
- package/src/widgets-v2/wrapper/widget-wrapper.tsx +178 -0
- package/dist/styles-BYTyKQFP.js.map +0 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { KeyboardEvent } from 'react'
|
|
2
|
+
import { Box, Typography } from '@mui/material'
|
|
3
|
+
import { CategoryBarStacked } from './category-bar-stacked'
|
|
4
|
+
import type { CategoryKey, CategorySize } from '../types'
|
|
5
|
+
import { styles } from '../style'
|
|
6
|
+
|
|
7
|
+
export interface CategoryRowStackedProps {
|
|
8
|
+
/** Raw category key — what gets emitted to `onToggle`. */
|
|
9
|
+
name: CategoryKey
|
|
10
|
+
/** Display label (post-`labelFormatter`). Falls back to `name`. */
|
|
11
|
+
displayName?: string | number
|
|
12
|
+
/** One value per series. Zero values still appear in the breakdown row. */
|
|
13
|
+
values: readonly number[]
|
|
14
|
+
/** One color per series (palette + per-series overrides resolved upstream). */
|
|
15
|
+
colors: readonly string[]
|
|
16
|
+
/** Series names for the breakdown row. Missing entries fall back to `Series N`. */
|
|
17
|
+
seriesNames: readonly string[]
|
|
18
|
+
formatter: (n: number) => string
|
|
19
|
+
selected: boolean
|
|
20
|
+
onToggle: (name: CategoryKey) => void
|
|
21
|
+
/** Bar visual density. Forwarded to the inner {@link CategoryBarStacked}. */
|
|
22
|
+
size?: CategorySize
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Stacked-mode category row: label + total share a header line; a single
|
|
27
|
+
* segmented bar sits below; an inline breakdown lists each series with its
|
|
28
|
+
* formatted value. Click anywhere in the row toggles selection by `name`.
|
|
29
|
+
*
|
|
30
|
+
* Per-row normalization: the stacked bar always fills 100% of the track,
|
|
31
|
+
* with each segment sized as `value_i / sum(values)`. This is intentionally
|
|
32
|
+
* different from `CategoryRowMulti` (which scales bars against the global
|
|
33
|
+
* `maxValue` for cross-row comparison) — in stacked mode the comparable
|
|
34
|
+
* axis is the proportion of each series within the row, not the row's
|
|
35
|
+
* total relative to other rows. The total numeric value is still shown in
|
|
36
|
+
* the header so the per-row magnitude isn't lost.
|
|
37
|
+
*
|
|
38
|
+
* Visual selection / dim signal lives entirely in the segment colors
|
|
39
|
+
* (`colors` prop) — every series in a dimmed row receives
|
|
40
|
+
* `theme.palette.action.disabled`. The bar visually collapses to a single
|
|
41
|
+
* grey shape when dimmed, but the breakdown text stays at full color so the
|
|
42
|
+
* per-series values remain legible.
|
|
43
|
+
*/
|
|
44
|
+
export function CategoryRowStacked({
|
|
45
|
+
name,
|
|
46
|
+
displayName,
|
|
47
|
+
values,
|
|
48
|
+
colors,
|
|
49
|
+
seriesNames,
|
|
50
|
+
formatter,
|
|
51
|
+
selected,
|
|
52
|
+
onToggle,
|
|
53
|
+
size,
|
|
54
|
+
}: CategoryRowStackedProps) {
|
|
55
|
+
const handleKey = (e: KeyboardEvent<HTMLDivElement>): void => {
|
|
56
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
57
|
+
e.preventDefault()
|
|
58
|
+
onToggle(name)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const total = values.reduce((a, b) => a + b, 0)
|
|
62
|
+
return (
|
|
63
|
+
<Box
|
|
64
|
+
role='button'
|
|
65
|
+
aria-pressed={selected}
|
|
66
|
+
tabIndex={0}
|
|
67
|
+
onClick={() => onToggle(name)}
|
|
68
|
+
onKeyDown={handleKey}
|
|
69
|
+
sx={styles.rowStacked}
|
|
70
|
+
>
|
|
71
|
+
<Box sx={styles.stackedHeader}>
|
|
72
|
+
<Typography variant='body2' sx={styles.multiName}>
|
|
73
|
+
{displayName ?? name}
|
|
74
|
+
</Typography>
|
|
75
|
+
<Typography variant='body2' sx={styles.stackedTotal}>
|
|
76
|
+
{formatter(total)}
|
|
77
|
+
</Typography>
|
|
78
|
+
</Box>
|
|
79
|
+
<CategoryBarStacked
|
|
80
|
+
values={values}
|
|
81
|
+
colors={colors}
|
|
82
|
+
maxValue={total}
|
|
83
|
+
size={size}
|
|
84
|
+
/>
|
|
85
|
+
<Box sx={styles.stackedBreakdown}>
|
|
86
|
+
{values.map((v, i) => (
|
|
87
|
+
// Series name is the stable identity for the breakdown line.
|
|
88
|
+
<Typography
|
|
89
|
+
key={`breakdown-${seriesNames[i] ?? `series-${i}`}`}
|
|
90
|
+
variant='body2'
|
|
91
|
+
sx={styles.stackedBreakdownItem}
|
|
92
|
+
>
|
|
93
|
+
{`${seriesNames[i] ?? `Series ${i + 1}`}: ${formatter(v)}`}
|
|
94
|
+
</Typography>
|
|
95
|
+
))}
|
|
96
|
+
</Box>
|
|
97
|
+
</Box>
|
|
98
|
+
)
|
|
99
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
|
2
|
+
import { createCategoryDownloadConfig } from './download'
|
|
3
|
+
import type { CategoryWidgetData } from './types'
|
|
4
|
+
|
|
5
|
+
const data: CategoryWidgetData = [
|
|
6
|
+
[
|
|
7
|
+
{ name: 'a', value: 1 },
|
|
8
|
+
{ name: 'b', value: 2 },
|
|
9
|
+
],
|
|
10
|
+
[{ name: 'a', value: 10 }],
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
let csvText = ''
|
|
14
|
+
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
csvText = ''
|
|
17
|
+
vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock')
|
|
18
|
+
vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => undefined)
|
|
19
|
+
const RealBlob = global.Blob
|
|
20
|
+
vi.stubGlobal(
|
|
21
|
+
'Blob',
|
|
22
|
+
class extends RealBlob {
|
|
23
|
+
constructor(parts: BlobPart[], opts?: BlobPropertyBag) {
|
|
24
|
+
csvText = typeof parts[0] === 'string' ? parts[0] : ''
|
|
25
|
+
super(parts, opts)
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
describe('createCategoryDownloadConfig', () => {
|
|
32
|
+
it('CSV-only by default', () => {
|
|
33
|
+
expect(
|
|
34
|
+
createCategoryDownloadConfig({ filename: 'c', getData: () => data }).map(
|
|
35
|
+
(i) => i.id,
|
|
36
|
+
),
|
|
37
|
+
).toEqual(['csv'])
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('prepends PNG when getCaptureEl is provided', () => {
|
|
41
|
+
const items = createCategoryDownloadConfig({
|
|
42
|
+
filename: 'c',
|
|
43
|
+
getData: () => data,
|
|
44
|
+
getCaptureEl: () => document.createElement('div'),
|
|
45
|
+
})
|
|
46
|
+
expect(items.map((i) => i.id)).toEqual(['png', 'csv'])
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('CSV resolve emits series × items with default names', async () => {
|
|
50
|
+
const items = createCategoryDownloadConfig({
|
|
51
|
+
filename: 'c',
|
|
52
|
+
getData: () => data,
|
|
53
|
+
})
|
|
54
|
+
const handle = await items.find((i) => i.id === 'csv')!.resolve()
|
|
55
|
+
expect(handle.filename).toBe('c.csv')
|
|
56
|
+
expect(csvText).toBe(
|
|
57
|
+
'series,name,value\nseries_1,a,1\nseries_1,b,2\nseries_2,a,10',
|
|
58
|
+
)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('CSV honours supplied seriesNames', async () => {
|
|
62
|
+
const items = createCategoryDownloadConfig({
|
|
63
|
+
filename: 'c',
|
|
64
|
+
getData: () => data,
|
|
65
|
+
seriesNames: ['baseline', 'override'],
|
|
66
|
+
})
|
|
67
|
+
await items.find((i) => i.id === 'csv')!.resolve()
|
|
68
|
+
expect(csvText.split('\n')[1]).toBe('baseline,a,1')
|
|
69
|
+
expect(csvText.split('\n')[3]).toBe('override,a,10')
|
|
70
|
+
})
|
|
71
|
+
})
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildPngDownloadItem,
|
|
3
|
+
downloadToCSV,
|
|
4
|
+
type DownloadItem,
|
|
5
|
+
} from '../actions/download'
|
|
6
|
+
import type { CategoryWidgetData } from './types'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Download menu items for the Category widget. Always includes a CSV item
|
|
10
|
+
* with `series, name, value` columns (one row per item). When
|
|
11
|
+
* `getCaptureEl` is supplied, prepends a PNG item that rasterises the
|
|
12
|
+
* captured element via `html2canvas`.
|
|
13
|
+
*/
|
|
14
|
+
export function createCategoryDownloadConfig(args: {
|
|
15
|
+
filename: string
|
|
16
|
+
getData: () => CategoryWidgetData
|
|
17
|
+
seriesNames?: readonly string[]
|
|
18
|
+
getCaptureEl?: () => HTMLElement | null
|
|
19
|
+
pngPixelRatio?: number
|
|
20
|
+
pngBackgroundColor?: string | null
|
|
21
|
+
}): DownloadItem[] {
|
|
22
|
+
const items: DownloadItem[] = []
|
|
23
|
+
if (args.getCaptureEl) {
|
|
24
|
+
items.push(
|
|
25
|
+
buildPngDownloadItem({
|
|
26
|
+
filename: args.filename,
|
|
27
|
+
getCaptureEl: args.getCaptureEl,
|
|
28
|
+
pixelRatio: args.pngPixelRatio,
|
|
29
|
+
backgroundColor: args.pngBackgroundColor,
|
|
30
|
+
}),
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
items.push({
|
|
34
|
+
id: 'csv',
|
|
35
|
+
label: 'Download as CSV',
|
|
36
|
+
resolve: () => {
|
|
37
|
+
const data = args.getData()
|
|
38
|
+
const rows: unknown[][] = [['series', 'name', 'value']]
|
|
39
|
+
for (const [i, series] of data.entries()) {
|
|
40
|
+
const seriesName = args.seriesNames?.[i] ?? `series_${i + 1}`
|
|
41
|
+
for (const item of series) {
|
|
42
|
+
rows.push([seriesName, item.name, item.value])
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const handle = downloadToCSV(rows)
|
|
46
|
+
return Promise.resolve({
|
|
47
|
+
url: handle.url,
|
|
48
|
+
filename: `${args.filename}.csv`,
|
|
49
|
+
revoke: handle.revoke,
|
|
50
|
+
})
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
return items
|
|
54
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export { Category, type CategoryProps } from './category'
|
|
2
|
+
export { CategoryUI, type CategoryUIProps } from './category-ui'
|
|
3
|
+
export { CategorySkeleton, type CategorySkeletonProps } from './skeleton'
|
|
4
|
+
export { createCategoryDownloadConfig } from './download'
|
|
5
|
+
|
|
6
|
+
// Sub-components — subpath-only (not on the curated `Widget` namespace).
|
|
7
|
+
export { CategoryBar, type CategoryBarProps } from './components/category-bar'
|
|
8
|
+
export {
|
|
9
|
+
CategoryRowSingle,
|
|
10
|
+
type CategoryRowSingleProps,
|
|
11
|
+
} from './components/category-row-single'
|
|
12
|
+
export {
|
|
13
|
+
CategoryRowMulti,
|
|
14
|
+
type CategoryRowMultiProps,
|
|
15
|
+
} from './components/category-row-multi'
|
|
16
|
+
export {
|
|
17
|
+
CategoryRowOther,
|
|
18
|
+
type CategoryRowOtherProps,
|
|
19
|
+
} from './components/category-row-other'
|
|
20
|
+
export {
|
|
21
|
+
CategoryLegend,
|
|
22
|
+
type CategoryLegendProps,
|
|
23
|
+
} from './components/category-legend'
|
|
24
|
+
|
|
25
|
+
export type {
|
|
26
|
+
CategoryDataItem,
|
|
27
|
+
CategoryWidgetData,
|
|
28
|
+
CategoryKey,
|
|
29
|
+
CategorySeriesConfig,
|
|
30
|
+
CategoryLabels,
|
|
31
|
+
CategorySize,
|
|
32
|
+
} from './types'
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import { CategorySkeleton } from './skeleton'
|
|
4
|
+
|
|
5
|
+
describe('<CategorySkeleton>', () => {
|
|
6
|
+
it('renders without crashing with defaults', () => {
|
|
7
|
+
const { container } = render(<CategorySkeleton />)
|
|
8
|
+
expect(container.firstChild).not.toBeNull()
|
|
9
|
+
expect(
|
|
10
|
+
container.querySelectorAll('.MuiSkeleton-root').length,
|
|
11
|
+
).toBeGreaterThan(0)
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
it('renders the requested row count', () => {
|
|
15
|
+
const { container } = render(<CategorySkeleton rows={3} />)
|
|
16
|
+
// Each row emits a label + value + bar skeleton, so > rows.
|
|
17
|
+
expect(
|
|
18
|
+
container.querySelectorAll('.MuiSkeleton-root').length,
|
|
19
|
+
).toBeGreaterThanOrEqual(3)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('renders the medium size variant', () => {
|
|
23
|
+
const { container } = render(<CategorySkeleton size='medium' rows={2} />)
|
|
24
|
+
expect(container.firstChild).not.toBeNull()
|
|
25
|
+
})
|
|
26
|
+
})
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Box, Skeleton } from '@mui/material'
|
|
2
|
+
import type { SxProps, Theme } from '@mui/material'
|
|
3
|
+
import type { CategorySize } from './types'
|
|
4
|
+
|
|
5
|
+
const styles = {
|
|
6
|
+
root: {
|
|
7
|
+
display: 'flex',
|
|
8
|
+
flexDirection: 'column',
|
|
9
|
+
gap: 1,
|
|
10
|
+
py: 0.5,
|
|
11
|
+
},
|
|
12
|
+
// Mirror the real row layout: label + value on top, bar below.
|
|
13
|
+
row: {
|
|
14
|
+
display: 'flex',
|
|
15
|
+
flexDirection: 'column',
|
|
16
|
+
gap: 0.5,
|
|
17
|
+
},
|
|
18
|
+
rowHeader: {
|
|
19
|
+
display: 'flex',
|
|
20
|
+
justifyContent: 'space-between',
|
|
21
|
+
alignItems: 'center',
|
|
22
|
+
gap: 1,
|
|
23
|
+
},
|
|
24
|
+
// Small fixed-width shimmer pills — matches the visual density of the
|
|
25
|
+
// real label / value cells without claiming the full row width.
|
|
26
|
+
name: { height: 14, width: 80 },
|
|
27
|
+
value: { height: 14, width: 48 },
|
|
28
|
+
} satisfies Record<string, SxProps<Theme>>
|
|
29
|
+
|
|
30
|
+
// Bar shimmer height matches the live bar track for each size variant so
|
|
31
|
+
// the skeleton doesn't visibly resize the row on data settle.
|
|
32
|
+
const BAR_HEIGHT: Record<CategorySize, number> = {
|
|
33
|
+
small: 4,
|
|
34
|
+
medium: 12,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Varied widths give the bar shimmer a more realistic, less uniform feel.
|
|
38
|
+
// Cycles when `rows > WIDTH_PATTERNS.length`.
|
|
39
|
+
const WIDTH_PATTERNS = ['95%', '80%', '55%', '75%', '60%']
|
|
40
|
+
|
|
41
|
+
export interface CategorySkeletonProps {
|
|
42
|
+
rows?: number
|
|
43
|
+
/**
|
|
44
|
+
* Visual density. Mirrors the live widget's `size` prop so the loading
|
|
45
|
+
* shimmer's bar height matches what's about to render — no row jump
|
|
46
|
+
* on data settle.
|
|
47
|
+
*/
|
|
48
|
+
size?: CategorySize
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function CategorySkeleton({
|
|
52
|
+
rows = 5,
|
|
53
|
+
size = 'small',
|
|
54
|
+
}: CategorySkeletonProps) {
|
|
55
|
+
return (
|
|
56
|
+
<Box sx={styles.root}>
|
|
57
|
+
{Array.from({ length: rows }).map((_, i) => (
|
|
58
|
+
<Box key={`row-${i}`} sx={styles.row}>
|
|
59
|
+
<Box sx={styles.rowHeader}>
|
|
60
|
+
<Skeleton variant='rectangular' sx={styles.name} />
|
|
61
|
+
<Skeleton variant='rectangular' sx={styles.value} />
|
|
62
|
+
</Box>
|
|
63
|
+
<Skeleton
|
|
64
|
+
variant='rectangular'
|
|
65
|
+
sx={{
|
|
66
|
+
height: BAR_HEIGHT[size],
|
|
67
|
+
width: WIDTH_PATTERNS[i % WIDTH_PATTERNS.length],
|
|
68
|
+
}}
|
|
69
|
+
/>
|
|
70
|
+
</Box>
|
|
71
|
+
))}
|
|
72
|
+
</Box>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import type { SxProps, Theme } from '@mui/material'
|
|
2
|
+
import type { CategorySize } from './types'
|
|
3
|
+
|
|
4
|
+
// Size-keyed bar styles — scoped strictly to the bar primitive
|
|
5
|
+
// (track + fill height & corner radius). `small` preserves the
|
|
6
|
+
// historical look (4px-tall pill); `medium` renders a 12px-tall track
|
|
7
|
+
// with a 2px corner radius. Every other token (gap, padding, hover,
|
|
8
|
+
// transitions, label/value typography) is size-invariant.
|
|
9
|
+
const bar: Record<CategorySize, SxProps<Theme>> = {
|
|
10
|
+
small: {
|
|
11
|
+
position: 'relative',
|
|
12
|
+
height: 4,
|
|
13
|
+
bgcolor: 'action.hover',
|
|
14
|
+
borderRadius: 1,
|
|
15
|
+
overflow: 'hidden',
|
|
16
|
+
transition: 'background-color 150ms ease',
|
|
17
|
+
},
|
|
18
|
+
medium: {
|
|
19
|
+
position: 'relative',
|
|
20
|
+
height: 12,
|
|
21
|
+
bgcolor: 'action.hover',
|
|
22
|
+
borderRadius: 0.25,
|
|
23
|
+
overflow: 'hidden',
|
|
24
|
+
transition: 'background-color 150ms ease',
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const barFill: Record<CategorySize, SxProps<Theme>> = {
|
|
29
|
+
small: {
|
|
30
|
+
position: 'absolute',
|
|
31
|
+
inset: '0 auto 0 0',
|
|
32
|
+
borderRadius: 1,
|
|
33
|
+
transition:
|
|
34
|
+
'width 300ms ease-in-out, background-color 150ms ease, filter 150ms ease',
|
|
35
|
+
},
|
|
36
|
+
medium: {
|
|
37
|
+
position: 'absolute',
|
|
38
|
+
inset: '0 auto 0 0',
|
|
39
|
+
borderRadius: 0.25,
|
|
40
|
+
transition:
|
|
41
|
+
'width 300ms ease-in-out, background-color 150ms ease, filter 150ms ease',
|
|
42
|
+
},
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Square-cornered segment for the stacked bar. Adjacent segments meet
|
|
46
|
+
// cleanly; the parent `bar[size]` track clips the outer ends via its
|
|
47
|
+
// own borderRadius + overflow:hidden, so the stacked bar still has the
|
|
48
|
+
// same rounded silhouette as a single `CategoryBar`.
|
|
49
|
+
const stackedSegment: Record<CategorySize, SxProps<Theme>> = {
|
|
50
|
+
small: {
|
|
51
|
+
position: 'absolute',
|
|
52
|
+
top: 0,
|
|
53
|
+
bottom: 0,
|
|
54
|
+
transition:
|
|
55
|
+
'left 300ms ease-in-out, width 300ms ease-in-out, background-color 150ms ease, filter 150ms ease',
|
|
56
|
+
},
|
|
57
|
+
medium: {
|
|
58
|
+
position: 'absolute',
|
|
59
|
+
top: 0,
|
|
60
|
+
bottom: 0,
|
|
61
|
+
transition:
|
|
62
|
+
'left 300ms ease-in-out, width 300ms ease-in-out, background-color 150ms ease, filter 150ms ease',
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const styles = {
|
|
67
|
+
// ── Top-level container ────────────────────────────────────────────
|
|
68
|
+
root: {
|
|
69
|
+
display: 'flex',
|
|
70
|
+
flexDirection: 'column',
|
|
71
|
+
position: 'relative',
|
|
72
|
+
width: '100%',
|
|
73
|
+
},
|
|
74
|
+
// Flat list of category rows. Holds both single + multi rows.
|
|
75
|
+
list: {
|
|
76
|
+
display: 'flex',
|
|
77
|
+
flexDirection: 'column',
|
|
78
|
+
gap: 1,
|
|
79
|
+
py: 0.5,
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
// ── Single-series row ─────────────────────────────────────────────
|
|
83
|
+
// v1 layout: label + value share a top flex row (justify-between); the
|
|
84
|
+
// bar fills the row width below. Mirrors `rowMulti` for visual
|
|
85
|
+
// consistency.
|
|
86
|
+
rowSingle: {
|
|
87
|
+
display: 'flex',
|
|
88
|
+
flexDirection: 'column',
|
|
89
|
+
gap: 0.5,
|
|
90
|
+
// py: 0.5,
|
|
91
|
+
// px: 0.5,
|
|
92
|
+
cursor: 'pointer',
|
|
93
|
+
userSelect: 'none',
|
|
94
|
+
transition: 'background-color 80ms ease',
|
|
95
|
+
// Hovering anywhere in the row also brightens the bar fill, matching
|
|
96
|
+
// what the bar got from `bar:hover` before. `data-bar-fill` is set
|
|
97
|
+
// on `barFill` by <CategoryBar>; descendant selector reaches it
|
|
98
|
+
// through `bar` in single rows and through `multiBarRow > bar` in
|
|
99
|
+
// multi rows.
|
|
100
|
+
'&:hover [data-bar-fill="true"]': {
|
|
101
|
+
filter: 'brightness(1.2)',
|
|
102
|
+
},
|
|
103
|
+
'&:focus-visible': {
|
|
104
|
+
outline: '2px solid',
|
|
105
|
+
outlineColor: 'primary.main',
|
|
106
|
+
outlineOffset: -2,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
// Top row of `rowSingle`: label on the left, value on the right.
|
|
110
|
+
rowHeader: {
|
|
111
|
+
display: 'flex',
|
|
112
|
+
justifyContent: 'space-between',
|
|
113
|
+
alignItems: 'center',
|
|
114
|
+
gap: 1,
|
|
115
|
+
},
|
|
116
|
+
// ── Multi-series row ──────────────────────────────────────────────
|
|
117
|
+
// Flex column: label fills the top row; bar+value pairs stack below.
|
|
118
|
+
// Bars get full track width — better legibility for N>=2 series than a
|
|
119
|
+
// shared grid would give.
|
|
120
|
+
rowMulti: {
|
|
121
|
+
display: 'flex',
|
|
122
|
+
flexDirection: 'column',
|
|
123
|
+
gap: 0.5,
|
|
124
|
+
// py: 0.5,
|
|
125
|
+
// px: 0.5,
|
|
126
|
+
cursor: 'pointer',
|
|
127
|
+
userSelect: 'none',
|
|
128
|
+
transition: 'background-color 80ms ease',
|
|
129
|
+
// Row-hover brightens every bar fill inside the multi-row.
|
|
130
|
+
'&:hover [data-bar-fill="true"]': {
|
|
131
|
+
filter: 'brightness(1.2)',
|
|
132
|
+
},
|
|
133
|
+
'&:focus-visible': {
|
|
134
|
+
outline: '2px solid',
|
|
135
|
+
outlineColor: 'primary.main',
|
|
136
|
+
outlineOffset: -2,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
// ── Row labels / values ───────────────────────────────────────────
|
|
140
|
+
// Matches v1: name uses medium-weight body2 in primary text color,
|
|
141
|
+
// value uses regular body2 in secondary text color. Same font size,
|
|
142
|
+
// visual hierarchy via weight + color.
|
|
143
|
+
name: {
|
|
144
|
+
overflow: 'hidden',
|
|
145
|
+
whiteSpace: 'nowrap',
|
|
146
|
+
textOverflow: 'ellipsis',
|
|
147
|
+
color: 'text.primary',
|
|
148
|
+
fontWeight: 'medium',
|
|
149
|
+
},
|
|
150
|
+
multiName: {
|
|
151
|
+
overflow: 'hidden',
|
|
152
|
+
whiteSpace: 'nowrap',
|
|
153
|
+
textOverflow: 'ellipsis',
|
|
154
|
+
color: 'text.primary',
|
|
155
|
+
fontWeight: 'medium',
|
|
156
|
+
},
|
|
157
|
+
value: {
|
|
158
|
+
color: 'text.secondary',
|
|
159
|
+
fontVariantNumeric: 'tabular-nums',
|
|
160
|
+
// Right-align + minWidth keeps `rowMulti`'s per-bar value column
|
|
161
|
+
// tidy (where the bar grows on the left and the number sits at a
|
|
162
|
+
// fixed right edge). `rowSingle` uses `rowHeader`'s flex
|
|
163
|
+
// justify-between to push the value to the trailing edge, so the
|
|
164
|
+
// minWidth here is also harmless in that context.
|
|
165
|
+
minWidth: 48,
|
|
166
|
+
textAlign: 'right',
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
// ── Bar (track + fill) ────────────────────────────────────────────
|
|
170
|
+
// Size-keyed maps live above the `styles` object; `<CategoryBar>` picks
|
|
171
|
+
// the variant via its `size` prop. Hover brightening still fires from
|
|
172
|
+
// the parent row (`&:hover [data-bar-fill]`), so it works regardless
|
|
173
|
+
// of which size variant the bar uses.
|
|
174
|
+
bar,
|
|
175
|
+
barFill,
|
|
176
|
+
stackedSegment,
|
|
177
|
+
|
|
178
|
+
// ── Multi-series internals ────────────────────────────────────────
|
|
179
|
+
// One [bar | value] flex row per series, inside `rowMulti`'s column.
|
|
180
|
+
multiBarRow: {
|
|
181
|
+
display: 'flex',
|
|
182
|
+
alignItems: 'center',
|
|
183
|
+
gap: 1,
|
|
184
|
+
},
|
|
185
|
+
multiBarContainer: {
|
|
186
|
+
flex: 1,
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
// ── Stacked-mode row ──────────────────────────────────────────────
|
|
190
|
+
// Mirror `rowMulti`'s outer shape (click target + hover brightening +
|
|
191
|
+
// focus ring) but stack three children vertically: header line, bar,
|
|
192
|
+
// breakdown line.
|
|
193
|
+
rowStacked: {
|
|
194
|
+
display: 'flex',
|
|
195
|
+
flexDirection: 'column',
|
|
196
|
+
gap: 0.5,
|
|
197
|
+
cursor: 'pointer',
|
|
198
|
+
userSelect: 'none',
|
|
199
|
+
transition: 'background-color 80ms ease',
|
|
200
|
+
'&:hover [data-bar-fill="true"]': {
|
|
201
|
+
filter: 'brightness(1.2)',
|
|
202
|
+
},
|
|
203
|
+
'&:focus-visible': {
|
|
204
|
+
outline: '2px solid',
|
|
205
|
+
outlineColor: 'primary.main',
|
|
206
|
+
outlineOffset: -2,
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
stackedHeader: {
|
|
210
|
+
display: 'flex',
|
|
211
|
+
justifyContent: 'space-between',
|
|
212
|
+
alignItems: 'center',
|
|
213
|
+
gap: 1,
|
|
214
|
+
},
|
|
215
|
+
// Right-aligned total in the header. Tabular-nums keeps totals lined
|
|
216
|
+
// up vertically across rows; minWidth reuses the per-series-value
|
|
217
|
+
// column width so the right edge sits at the same spot as `rowMulti`'s
|
|
218
|
+
// value column when both modes co-exist in the same widget card.
|
|
219
|
+
stackedTotal: {
|
|
220
|
+
color: 'text.primary',
|
|
221
|
+
fontWeight: 'medium',
|
|
222
|
+
fontVariantNumeric: 'tabular-nums',
|
|
223
|
+
minWidth: 48,
|
|
224
|
+
textAlign: 'right',
|
|
225
|
+
},
|
|
226
|
+
// Flex row of "{seriesName}: {value}" pairs. Wraps gracefully when
|
|
227
|
+
// series names are long or there are many series.
|
|
228
|
+
stackedBreakdown: {
|
|
229
|
+
display: 'flex',
|
|
230
|
+
flexWrap: 'wrap',
|
|
231
|
+
columnGap: 2,
|
|
232
|
+
rowGap: 0.25,
|
|
233
|
+
},
|
|
234
|
+
stackedBreakdownItem: {
|
|
235
|
+
color: 'text.secondary',
|
|
236
|
+
fontVariantNumeric: 'tabular-nums',
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
// ── Legend (sticky bottom) ────────────────────────────────────────
|
|
240
|
+
legend: {
|
|
241
|
+
display: 'flex',
|
|
242
|
+
alignItems: 'center',
|
|
243
|
+
gap: 2,
|
|
244
|
+
flexWrap: 'wrap',
|
|
245
|
+
pt: 2,
|
|
246
|
+
mt: 2,
|
|
247
|
+
position: 'sticky',
|
|
248
|
+
bottom: 0,
|
|
249
|
+
bgcolor: 'background.paper',
|
|
250
|
+
borderTop: (theme: Theme) => `1px solid ${theme.palette.divider}`,
|
|
251
|
+
},
|
|
252
|
+
legendItem: {
|
|
253
|
+
display: 'flex',
|
|
254
|
+
alignItems: 'center',
|
|
255
|
+
gap: 1,
|
|
256
|
+
},
|
|
257
|
+
legendDot: {
|
|
258
|
+
width: 8,
|
|
259
|
+
height: 8,
|
|
260
|
+
borderRadius: '50%',
|
|
261
|
+
},
|
|
262
|
+
legendLabel: {
|
|
263
|
+
color: 'text.secondary',
|
|
264
|
+
textTransform: 'uppercase',
|
|
265
|
+
fontWeight: 'medium',
|
|
266
|
+
},
|
|
267
|
+
|
|
268
|
+
// ── "Other" overflow row ──────────────────────────────────────────
|
|
269
|
+
otherRow: {
|
|
270
|
+
display: 'flex',
|
|
271
|
+
justifyContent: 'space-between',
|
|
272
|
+
alignItems: 'center',
|
|
273
|
+
py: 0.5,
|
|
274
|
+
px: 0.5,
|
|
275
|
+
},
|
|
276
|
+
otherLabel: {
|
|
277
|
+
fontStyle: 'italic',
|
|
278
|
+
color: 'text.secondary',
|
|
279
|
+
fontWeight: 'medium',
|
|
280
|
+
},
|
|
281
|
+
otherCount: {
|
|
282
|
+
color: 'text.disabled',
|
|
283
|
+
},
|
|
284
|
+
// `bar` / `barFill` are size-keyed (`Record<CategorySize, SxProps>`);
|
|
285
|
+
// every other entry is a single `SxProps<Theme>`. The mixed shape means
|
|
286
|
+
// we can't apply the file-wide `satisfies Record<string, SxProps<Theme>>`
|
|
287
|
+
// constraint that the other widget style files use — consumers of
|
|
288
|
+
// individual tokens still get full type-checking at the call site via
|
|
289
|
+
// the typed `Box`/`Typography` `sx` prop.
|
|
290
|
+
}
|