@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.
- 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/{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-l4fNHLEg.js +213 -0
- package/dist/range-l4fNHLEg.js.map +1 -0
- package/dist/resolve-theme-color-BdojIw0K.js +47 -0
- package/dist/resolve-theme-color-BdojIw0K.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-CQCAnDLb.js +388 -0
- package/dist/table-CQCAnDLb.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 +46 -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 +53 -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 +43 -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 +51 -0
- package/dist/types/widgets-v2/index.d.ts +108 -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 +57 -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 +27 -0
- package/dist/types/widgets-v2/range/range.d.ts +24 -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 +54 -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 +40 -0
- package/dist/types/widgets-v2/table/table-ui.d.ts +44 -0
- package/dist/types/widgets-v2/table/table.d.ts +50 -0
- package/dist/types/widgets-v2/table/types.d.ts +48 -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 +60 -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/types.d.ts +25 -0
- package/dist/types/widgets-v2/utils/data-zoom-layout.d.ts +11 -0
- package/dist/types/widgets-v2/utils/index.d.ts +3 -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/utils/resolve-theme-color.d.ts +18 -0
- package/dist/types/widgets-v2/utils/resolve-theme-color.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/bar.js +14 -13
- package/dist/widgets/bar.js.map +1 -1
- package/dist/widgets/histogram.js +8 -7
- 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 +330 -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 +353 -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 +387 -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 +411 -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 +358 -0
- package/dist/widgets-v2/timeseries.js.map +1 -0
- package/dist/widgets-v2/utils.js +8 -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 +71 -3
- 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-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/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 +334 -0
- package/src/widgets-v2/bar/options.ts +332 -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 +51 -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 +59 -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 +48 -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 +318 -0
- package/src/widgets-v2/histogram/options.ts +338 -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 +55 -0
- package/src/widgets-v2/index.ts +204 -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 +601 -0
- package/src/widgets-v2/pie/options.ts +513 -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 +62 -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 +136 -0
- package/src/widgets-v2/range/range-ui.tsx +278 -0
- package/src/widgets-v2/range/range.test.tsx +68 -0
- package/src/widgets-v2/range/range.tsx +52 -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 +411 -0
- package/src/widgets-v2/scatterplot/options.ts +425 -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 +59 -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 +43 -0
- package/src/widgets-v2/table/table-ui.test.tsx +200 -0
- package/src/widgets-v2/table/table-ui.tsx +364 -0
- package/src/widgets-v2/table/table.test.tsx +119 -0
- package/src/widgets-v2/table/table.tsx +179 -0
- package/src/widgets-v2/table/types.ts +55 -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 +394 -0
- package/src/widgets-v2/timeseries/options.ts +348 -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 +65 -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/types.ts +25 -0
- package/src/widgets-v2/utils/data-zoom-layout.ts +26 -0
- package/src/widgets-v2/utils/index.ts +3 -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/utils/resolve-theme-color.test.ts +43 -0
- package/src/widgets-v2/utils/resolve-theme-color.ts +34 -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,292 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
4
|
+
const noop = (): void => {}
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
__debugListWidgetStores,
|
|
8
|
+
clearAllCaptureEls,
|
|
9
|
+
clearAllEchartInstances,
|
|
10
|
+
clearAllWidgetStores,
|
|
11
|
+
createWidgetStore,
|
|
12
|
+
deleteWidgetStore,
|
|
13
|
+
getCaptureEl,
|
|
14
|
+
getEchartInstance,
|
|
15
|
+
getWidgetStore,
|
|
16
|
+
hasWidgetStore,
|
|
17
|
+
registerWidgetStore,
|
|
18
|
+
resetWidgetStore,
|
|
19
|
+
setCaptureEl,
|
|
20
|
+
setEchartInstance,
|
|
21
|
+
subscribeEchartInstance,
|
|
22
|
+
unregisterWidgetStore,
|
|
23
|
+
} from './widget-store-registry'
|
|
24
|
+
import type { ECharts } from 'echarts'
|
|
25
|
+
|
|
26
|
+
describe('widget-store-registry', () => {
|
|
27
|
+
beforeEach(() => clearAllWidgetStores())
|
|
28
|
+
afterEach(() => clearAllWidgetStores())
|
|
29
|
+
|
|
30
|
+
it('register + get round-trip', () => {
|
|
31
|
+
const s = createWidgetStore('w1', { data: 1 })
|
|
32
|
+
registerWidgetStore('w1', s)
|
|
33
|
+
expect(getWidgetStore('w1')).toBe(s)
|
|
34
|
+
expect(hasWidgetStore('w1')).toBe(true)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('getWidgetStore throws for unknown id', () => {
|
|
38
|
+
expect(() => getWidgetStore('missing')).toThrow(
|
|
39
|
+
/Widget store "missing" not found/,
|
|
40
|
+
)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('isolates state across stores', () => {
|
|
44
|
+
const a = createWidgetStore('a', { data: 1 })
|
|
45
|
+
const b = createWidgetStore('b', { data: 2 })
|
|
46
|
+
registerWidgetStore('a', a)
|
|
47
|
+
registerWidgetStore('b', b)
|
|
48
|
+
a.setState({ rawData: 10 })
|
|
49
|
+
expect(b.getState().rawData).toBe(2)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('deleteWidgetStore removes the store from the registry', () => {
|
|
53
|
+
const s = createWidgetStore('w', { data: 1 })
|
|
54
|
+
registerWidgetStore('w', s)
|
|
55
|
+
deleteWidgetStore('w')
|
|
56
|
+
expect(hasWidgetStore('w')).toBe(false)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('resetWidgetStore clears transformStates and keeps the store', () => {
|
|
60
|
+
const s = createWidgetStore('w', { data: 1 })
|
|
61
|
+
registerWidgetStore('w', s)
|
|
62
|
+
s.setState({ transformStates: { foo: { enabled: true } } })
|
|
63
|
+
resetWidgetStore('w')
|
|
64
|
+
expect(s.getState().transformStates).toEqual({})
|
|
65
|
+
expect(hasWidgetStore('w')).toBe(true)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('clearAllWidgetStores empties everything', () => {
|
|
69
|
+
registerWidgetStore('a', createWidgetStore('a', { data: 1 }))
|
|
70
|
+
registerWidgetStore('b', createWidgetStore('b', { data: 2 }))
|
|
71
|
+
clearAllWidgetStores()
|
|
72
|
+
expect(__debugListWidgetStores()).toEqual([])
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('unregisterWidgetStore drops the store on last unmount when keepAlive is false', () => {
|
|
76
|
+
registerWidgetStore('w', createWidgetStore('w', { data: 1 }))
|
|
77
|
+
unregisterWidgetStore('w', { keepAlive: false })
|
|
78
|
+
expect(hasWidgetStore('w')).toBe(false)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('unregisterWidgetStore preserves the store when keepAlive is true', () => {
|
|
82
|
+
registerWidgetStore('w', createWidgetStore('w', { data: 1 }))
|
|
83
|
+
unregisterWidgetStore('w', { keepAlive: true })
|
|
84
|
+
expect(hasWidgetStore('w')).toBe(true)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('refcounts overlapping registers — store stays until both unregister', () => {
|
|
88
|
+
const s = createWidgetStore('w', { data: 1 })
|
|
89
|
+
registerWidgetStore('w', s)
|
|
90
|
+
registerWidgetStore('w', s)
|
|
91
|
+
unregisterWidgetStore('w', { keepAlive: false })
|
|
92
|
+
expect(hasWidgetStore('w')).toBe(true)
|
|
93
|
+
unregisterWidgetStore('w', { keepAlive: false })
|
|
94
|
+
expect(hasWidgetStore('w')).toBe(false)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('warns once on duplicate concurrent registration with the same id', () => {
|
|
98
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(noop)
|
|
99
|
+
const s = createWidgetStore('dup', { data: 1 })
|
|
100
|
+
registerWidgetStore('dup', s)
|
|
101
|
+
registerWidgetStore('dup', s)
|
|
102
|
+
expect(warn).toHaveBeenCalledTimes(1)
|
|
103
|
+
expect(warn.mock.calls[0]?.[0]).toMatch(
|
|
104
|
+
/Duplicate <Widget.Provider id="dup">/,
|
|
105
|
+
)
|
|
106
|
+
warn.mockRestore()
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('does not warn again on subsequent re-registrations after the first warning', () => {
|
|
110
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(noop)
|
|
111
|
+
const s = createWidgetStore('dup', { data: 1 })
|
|
112
|
+
registerWidgetStore('dup', s)
|
|
113
|
+
registerWidgetStore('dup', s)
|
|
114
|
+
registerWidgetStore('dup', s)
|
|
115
|
+
expect(warn).toHaveBeenCalledTimes(1)
|
|
116
|
+
warn.mockRestore()
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('createWidgetStore seeds rawData/data from init.data', () => {
|
|
120
|
+
const s = createWidgetStore('w', { data: { x: 1 } })
|
|
121
|
+
expect(s.getState().rawData).toEqual({ x: 1 })
|
|
122
|
+
expect(s.getState().data).toEqual({ x: 1 })
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('createWidgetStore seeds isLoading/isFetching defaults to false', () => {
|
|
126
|
+
const s = createWidgetStore('w', { data: 1 })
|
|
127
|
+
expect(s.getState().isLoading).toBe(false)
|
|
128
|
+
expect(s.getState().isFetching).toBe(false)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it('createWidgetStore preserves init.error', () => {
|
|
132
|
+
const err = { title: 'oops' }
|
|
133
|
+
const s = createWidgetStore('w', { data: 1, error: err })
|
|
134
|
+
expect(s.getState().error).toBe(err)
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
it('__debugListWidgetStores reflects registered ids', () => {
|
|
138
|
+
registerWidgetStore('a', createWidgetStore('a', { data: 1 }))
|
|
139
|
+
registerWidgetStore('b', createWidgetStore('b', { data: 1 }))
|
|
140
|
+
expect(__debugListWidgetStores().sort()).toEqual(['a', 'b'])
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
describe('capture-el registry', () => {
|
|
144
|
+
it('returns null for unregistered ids', () => {
|
|
145
|
+
expect(getCaptureEl('missing')).toBeNull()
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('round-trips a set value', () => {
|
|
149
|
+
const el = document.createElement('div')
|
|
150
|
+
setCaptureEl('w1', el)
|
|
151
|
+
expect(getCaptureEl('w1')).toBe(el)
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
it('clears when set to null', () => {
|
|
155
|
+
const el = document.createElement('div')
|
|
156
|
+
setCaptureEl('w1', el)
|
|
157
|
+
setCaptureEl('w1', null)
|
|
158
|
+
expect(getCaptureEl('w1')).toBeNull()
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
it('isolates ids', () => {
|
|
162
|
+
const a = document.createElement('div')
|
|
163
|
+
const b = document.createElement('section')
|
|
164
|
+
setCaptureEl('a', a)
|
|
165
|
+
setCaptureEl('b', b)
|
|
166
|
+
expect(getCaptureEl('a')).toBe(a)
|
|
167
|
+
expect(getCaptureEl('b')).toBe(b)
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
it('clearAllWidgetStores wipes the capture-el map too', () => {
|
|
171
|
+
setCaptureEl('w', document.createElement('div'))
|
|
172
|
+
clearAllWidgetStores()
|
|
173
|
+
expect(getCaptureEl('w')).toBeNull()
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('clearAllCaptureEls wipes only the capture-el map', () => {
|
|
177
|
+
registerWidgetStore('w', createWidgetStore('w', { data: 1 }))
|
|
178
|
+
setCaptureEl('w', document.createElement('div'))
|
|
179
|
+
clearAllCaptureEls()
|
|
180
|
+
expect(getCaptureEl('w')).toBeNull()
|
|
181
|
+
expect(hasWidgetStore('w')).toBe(true)
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
describe('echart-instance registry', () => {
|
|
186
|
+
function makeChart(): ECharts {
|
|
187
|
+
// Minimal stand-in — only the methods used by registry tests need to
|
|
188
|
+
// exist. Cast through unknown to keep the signature opaque.
|
|
189
|
+
return {} as unknown as ECharts
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
it('returns null for unregistered ids', () => {
|
|
193
|
+
expect(getEchartInstance('missing')).toBeNull()
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
it('round-trips a set value', () => {
|
|
197
|
+
const chart = makeChart()
|
|
198
|
+
setEchartInstance('w1', chart)
|
|
199
|
+
expect(getEchartInstance('w1')).toBe(chart)
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('clears when set to null', () => {
|
|
203
|
+
setEchartInstance('w1', makeChart())
|
|
204
|
+
setEchartInstance('w1', null)
|
|
205
|
+
expect(getEchartInstance('w1')).toBeNull()
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
it('isolates ids', () => {
|
|
209
|
+
const a = makeChart()
|
|
210
|
+
const b = makeChart()
|
|
211
|
+
setEchartInstance('a', a)
|
|
212
|
+
setEchartInstance('b', b)
|
|
213
|
+
expect(getEchartInstance('a')).toBe(a)
|
|
214
|
+
expect(getEchartInstance('b')).toBe(b)
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
it('clearAllWidgetStores wipes the echart-instance map too', () => {
|
|
218
|
+
setEchartInstance('w', makeChart())
|
|
219
|
+
clearAllWidgetStores()
|
|
220
|
+
expect(getEchartInstance('w')).toBeNull()
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
it('clearAllEchartInstances wipes only the echart-instance map', () => {
|
|
224
|
+
registerWidgetStore('w', createWidgetStore('w', { data: 1 }))
|
|
225
|
+
setEchartInstance('w', makeChart())
|
|
226
|
+
clearAllEchartInstances()
|
|
227
|
+
expect(getEchartInstance('w')).toBeNull()
|
|
228
|
+
expect(hasWidgetStore('w')).toBe(true)
|
|
229
|
+
})
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
describe('subscribeEchartInstance', () => {
|
|
233
|
+
function makeChart(): ECharts {
|
|
234
|
+
return {} as unknown as ECharts
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
it('fires the listener whenever setEchartInstance writes a new value', () => {
|
|
238
|
+
const seen: (ECharts | null)[] = []
|
|
239
|
+
const off = subscribeEchartInstance('s1', (chart) => seen.push(chart))
|
|
240
|
+
const a = makeChart()
|
|
241
|
+
const b = makeChart()
|
|
242
|
+
setEchartInstance('s1', a)
|
|
243
|
+
setEchartInstance('s1', b)
|
|
244
|
+
setEchartInstance('s1', null)
|
|
245
|
+
expect(seen).toEqual([a, b, null])
|
|
246
|
+
off()
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
it('the returned unsubscribe stops the listener', () => {
|
|
250
|
+
const fn = vi.fn()
|
|
251
|
+
const off = subscribeEchartInstance('s2', fn)
|
|
252
|
+
setEchartInstance('s2', makeChart())
|
|
253
|
+
off()
|
|
254
|
+
setEchartInstance('s2', makeChart())
|
|
255
|
+
expect(fn).toHaveBeenCalledTimes(1)
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it('multiple listeners per id all fire', () => {
|
|
259
|
+
const a = vi.fn()
|
|
260
|
+
const b = vi.fn()
|
|
261
|
+
subscribeEchartInstance('s3', a)
|
|
262
|
+
subscribeEchartInstance('s3', b)
|
|
263
|
+
setEchartInstance('s3', makeChart())
|
|
264
|
+
expect(a).toHaveBeenCalledTimes(1)
|
|
265
|
+
expect(b).toHaveBeenCalledTimes(1)
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
it('listeners are isolated by id', () => {
|
|
269
|
+
const a = vi.fn()
|
|
270
|
+
const b = vi.fn()
|
|
271
|
+
subscribeEchartInstance('s4', a)
|
|
272
|
+
subscribeEchartInstance('s5', b)
|
|
273
|
+
setEchartInstance('s4', makeChart())
|
|
274
|
+
expect(a).toHaveBeenCalledTimes(1)
|
|
275
|
+
expect(b).not.toHaveBeenCalled()
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
it('clearAllEchartInstances and clearAllWidgetStores clear subscribers too', () => {
|
|
279
|
+
const fn = vi.fn()
|
|
280
|
+
subscribeEchartInstance('s6', fn)
|
|
281
|
+
clearAllEchartInstances()
|
|
282
|
+
setEchartInstance('s6', makeChart())
|
|
283
|
+
expect(fn).not.toHaveBeenCalled()
|
|
284
|
+
|
|
285
|
+
const fn2 = vi.fn()
|
|
286
|
+
subscribeEchartInstance('s7', fn2)
|
|
287
|
+
clearAllWidgetStores()
|
|
288
|
+
setEchartInstance('s7', makeChart())
|
|
289
|
+
expect(fn2).not.toHaveBeenCalled()
|
|
290
|
+
})
|
|
291
|
+
})
|
|
292
|
+
})
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import type { ECharts } from 'echarts'
|
|
2
|
+
import { useStore, type StoreApi } from 'zustand'
|
|
3
|
+
import { createStore } from 'zustand/vanilla'
|
|
4
|
+
import { devtools } from 'zustand/middleware'
|
|
5
|
+
import { useShallow } from 'zustand/react/shallow'
|
|
6
|
+
import { pipelineMiddleware } from './pipeline-middleware'
|
|
7
|
+
import type { WidgetInit, WidgetState, WidgetStoreApi } from './types'
|
|
8
|
+
|
|
9
|
+
const widgetStores = new Map<string, WidgetStoreApi>()
|
|
10
|
+
|
|
11
|
+
const widgetMountCounts = new Map<string, number>()
|
|
12
|
+
const warnedDuplicates = new Set<string>()
|
|
13
|
+
|
|
14
|
+
// Per-widget capture-element registry. Held outside the reactive store so
|
|
15
|
+
// publishing the element doesn't trigger any consumer re-renders — these
|
|
16
|
+
// handles are read imperatively by per-widget download configs at click time
|
|
17
|
+
// only. `Widget.State` writes its success-path content wrapper here on mount
|
|
18
|
+
// (auto-cleared on unmount via callback ref), and `create*DownloadConfig`
|
|
19
|
+
// looks it up to feed `html2canvas` for PNG export.
|
|
20
|
+
const captureEls = new Map<string, HTMLElement>()
|
|
21
|
+
|
|
22
|
+
// Per-widget live ECharts instance registry. Same imperative-only contract
|
|
23
|
+
// as `captureEls`: published by the `Widget.Echart` bridge on mount /
|
|
24
|
+
// dispose, read at click time by actions that need to dispatch on the live
|
|
25
|
+
// chart (e.g. `ZoomToggle`'s disable handler issuing
|
|
26
|
+
// `setOption({}, { replaceMerge: ['dataZoom'] })` to clear the slider).
|
|
27
|
+
// Held outside the reactive store so publishing never triggers consumer
|
|
28
|
+
// re-renders.
|
|
29
|
+
const echartInstances = new Map<string, ECharts>()
|
|
30
|
+
|
|
31
|
+
// Per-id subscribers notified whenever `setEchartInstance` writes a new
|
|
32
|
+
// value. Powers `useEchartInstance(id)` (a `useSyncExternalStore` wrapper)
|
|
33
|
+
// so actions like `BrushToggle` can react when the chart becomes available
|
|
34
|
+
// — required for lifecycle effects that need the instance on mount but
|
|
35
|
+
// arrive in the tree before the `Widget.Echart` bridge has run its init
|
|
36
|
+
// `useEffect`.
|
|
37
|
+
type EchartInstanceListener = (chart: ECharts | null) => void
|
|
38
|
+
const echartInstanceSubscribers = new Map<string, Set<EchartInstanceListener>>()
|
|
39
|
+
|
|
40
|
+
const isDev = (): boolean => {
|
|
41
|
+
try {
|
|
42
|
+
return Boolean(
|
|
43
|
+
(import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV,
|
|
44
|
+
)
|
|
45
|
+
} catch {
|
|
46
|
+
return false
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function getWidgetStore(id: string): WidgetStoreApi {
|
|
51
|
+
const store = widgetStores.get(id)
|
|
52
|
+
if (!store) throw new Error(`[widgets-v2] Widget store "${id}" not found.`)
|
|
53
|
+
return store
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function hasWidgetStore(id: string): boolean {
|
|
57
|
+
return widgetStores.has(id)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function deleteWidgetStore(id: string): void {
|
|
61
|
+
widgetStores.delete(id)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function resetWidgetStore(id: string): void {
|
|
65
|
+
const store = widgetStores.get(id)
|
|
66
|
+
if (store) store.setState({ transformStates: {} })
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function clearAllWidgetStores(): void {
|
|
70
|
+
widgetStores.clear()
|
|
71
|
+
widgetMountCounts.clear()
|
|
72
|
+
warnedDuplicates.clear()
|
|
73
|
+
captureEls.clear()
|
|
74
|
+
echartInstances.clear()
|
|
75
|
+
echartInstanceSubscribers.clear()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Register or clear the capture element for a widget. Pass `null` to clear.
|
|
80
|
+
* Called by `Widget.State` via a callback ref on its success-path content
|
|
81
|
+
* wrapper. The element is read by per-widget download configs at click time
|
|
82
|
+
* to feed `html2canvas` for PNG export.
|
|
83
|
+
*/
|
|
84
|
+
export function setCaptureEl(id: string, el: HTMLElement | null): void {
|
|
85
|
+
if (el == null) captureEls.delete(id)
|
|
86
|
+
else captureEls.set(id, el)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Read the currently registered capture element for a widget. Returns `null`
|
|
91
|
+
* when no `Widget.State` is on its success path (loading / error / empty)
|
|
92
|
+
* or when the widget hasn't mounted.
|
|
93
|
+
*/
|
|
94
|
+
export function getCaptureEl(id: string): HTMLElement | null {
|
|
95
|
+
return captureEls.get(id) ?? null
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** @internal — exposed for tests and debugging only. */
|
|
99
|
+
export function clearAllCaptureEls(): void {
|
|
100
|
+
captureEls.clear()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Register or clear the live ECharts instance for a widget. Pass `null`
|
|
105
|
+
* to clear. Called by the `Widget.Echart` bridge on mount / dispose.
|
|
106
|
+
* Read by actions (e.g. `ZoomToggle`'s disable handler) that need to
|
|
107
|
+
* dispatch on the live chart without going through the pipeline.
|
|
108
|
+
*
|
|
109
|
+
* Notifies subscribers registered via {@link subscribeEchartInstance}
|
|
110
|
+
* after the map mutation, so reactive consumers (the
|
|
111
|
+
* `useEchartInstance` hook) re-render with the new value.
|
|
112
|
+
*/
|
|
113
|
+
export function setEchartInstance(id: string, chart: ECharts | null): void {
|
|
114
|
+
if (chart == null) echartInstances.delete(id)
|
|
115
|
+
else echartInstances.set(id, chart)
|
|
116
|
+
echartInstanceSubscribers.get(id)?.forEach((fn) => fn(chart))
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Read the currently registered ECharts instance for a widget. Returns
|
|
121
|
+
* `null` when no `Widget.Echart` is mounted, or before the bridge has
|
|
122
|
+
* created the instance.
|
|
123
|
+
*/
|
|
124
|
+
export function getEchartInstance(id: string): ECharts | null {
|
|
125
|
+
return echartInstances.get(id) ?? null
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Subscribe to changes of the registered ECharts instance for a widget.
|
|
130
|
+
* The listener is called *after* every {@link setEchartInstance} (with
|
|
131
|
+
* the new chart, or `null` when cleared). Returns an unsubscribe
|
|
132
|
+
* function. Used by the `useEchartInstance` hook to drive React effects
|
|
133
|
+
* that need to react to instance arrival / departure (e.g.
|
|
134
|
+
* `BrushToggle`'s `'finished'` re-dispatch loop).
|
|
135
|
+
*/
|
|
136
|
+
export function subscribeEchartInstance(
|
|
137
|
+
id: string,
|
|
138
|
+
listener: EchartInstanceListener,
|
|
139
|
+
): () => void {
|
|
140
|
+
let listeners = echartInstanceSubscribers.get(id)
|
|
141
|
+
if (!listeners) {
|
|
142
|
+
listeners = new Set()
|
|
143
|
+
echartInstanceSubscribers.set(id, listeners)
|
|
144
|
+
}
|
|
145
|
+
listeners.add(listener)
|
|
146
|
+
return () => {
|
|
147
|
+
const set = echartInstanceSubscribers.get(id)
|
|
148
|
+
if (!set) return
|
|
149
|
+
set.delete(listener)
|
|
150
|
+
if (set.size === 0) echartInstanceSubscribers.delete(id)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** @internal — exposed for tests and debugging only. */
|
|
155
|
+
export function clearAllEchartInstances(): void {
|
|
156
|
+
echartInstances.clear()
|
|
157
|
+
echartInstanceSubscribers.clear()
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** @internal — exposed for tests and debugging only. */
|
|
161
|
+
export function __debugListWidgetStores(): string[] {
|
|
162
|
+
return Array.from(widgetStores.keys())
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Insert or replace a store entry in the registry without refcounting or
|
|
167
|
+
* duplicate-id detection. Used by Provider's lazy `useState` init so the
|
|
168
|
+
* store is reachable from `useWidget(id)` calls in children that render
|
|
169
|
+
* before the Provider's mount effect runs. Refcounting and dev warns happen
|
|
170
|
+
* in {@link registerWidgetStore} during the mount effect.
|
|
171
|
+
*
|
|
172
|
+
* @internal
|
|
173
|
+
*/
|
|
174
|
+
export function setWidgetStoreEntry(id: string, store: WidgetStoreApi): void {
|
|
175
|
+
widgetStores.set(id, store)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** @internal — used by Provider; not part of the public API. */
|
|
179
|
+
export function createWidgetStore(
|
|
180
|
+
id: string,
|
|
181
|
+
init: WidgetInit,
|
|
182
|
+
): WidgetStoreApi {
|
|
183
|
+
const builder = pipelineMiddleware<WidgetState>(() => ({
|
|
184
|
+
rawData: init.data,
|
|
185
|
+
data: init.data,
|
|
186
|
+
dataTransforms: [],
|
|
187
|
+
configTransforms: [],
|
|
188
|
+
transformStates: {},
|
|
189
|
+
isLoading: init.isLoading ?? false,
|
|
190
|
+
isFetching: init.isFetching ?? false,
|
|
191
|
+
error: init.error,
|
|
192
|
+
rawFormatter: init.formatter,
|
|
193
|
+
formatter: init.formatter,
|
|
194
|
+
labelFormatter: init.labelFormatter,
|
|
195
|
+
}))
|
|
196
|
+
|
|
197
|
+
const store = createStore<WidgetState>()(
|
|
198
|
+
devtools(builder, { name: `widget-${id}`, enabled: isDev() }),
|
|
199
|
+
) as unknown as WidgetStoreApi
|
|
200
|
+
|
|
201
|
+
return store
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** @internal — registers a Provider mount and tracks/warns on duplicate ids in dev. */
|
|
205
|
+
export function registerWidgetStore(id: string, store: WidgetStoreApi): void {
|
|
206
|
+
widgetStores.set(id, store)
|
|
207
|
+
const count = (widgetMountCounts.get(id) ?? 0) + 1
|
|
208
|
+
widgetMountCounts.set(id, count)
|
|
209
|
+
if (count > 1 && isDev() && !warnedDuplicates.has(id)) {
|
|
210
|
+
// eslint-disable-next-line no-console
|
|
211
|
+
console.warn(
|
|
212
|
+
`[widgets-v2] Duplicate <Widget.Provider id="${id}"> detected. ` +
|
|
213
|
+
`Multiple providers sharing an id will race on prop sync and corrupt the store. ` +
|
|
214
|
+
`Use unique ids per widget instance.`,
|
|
215
|
+
)
|
|
216
|
+
warnedDuplicates.add(id)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** @internal — Provider unmount counterpart; on last unmount removes the refcount entry. */
|
|
221
|
+
export function unregisterWidgetStore(
|
|
222
|
+
id: string,
|
|
223
|
+
options: { keepAlive: boolean },
|
|
224
|
+
): void {
|
|
225
|
+
const count = (widgetMountCounts.get(id) ?? 1) - 1
|
|
226
|
+
if (count <= 0) {
|
|
227
|
+
widgetMountCounts.delete(id)
|
|
228
|
+
if (!options.keepAlive) widgetStores.delete(id)
|
|
229
|
+
} else {
|
|
230
|
+
widgetMountCounts.set(id, count)
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export function useWidget<T, S extends WidgetState = WidgetState>(
|
|
235
|
+
id: string,
|
|
236
|
+
selector: (state: S) => T,
|
|
237
|
+
): T {
|
|
238
|
+
const store = getWidgetStore(id) as unknown as StoreApi<S>
|
|
239
|
+
return useStore(store, selector)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function useWidgetShallow<T, S extends WidgetState = WidgetState>(
|
|
243
|
+
id: string,
|
|
244
|
+
selector: (state: S) => T,
|
|
245
|
+
): T {
|
|
246
|
+
const store = getWidgetStore(id) as unknown as StoreApi<S>
|
|
247
|
+
return useStore(store, useShallow(selector))
|
|
248
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import { Subheader } from './subheader'
|
|
4
|
+
|
|
5
|
+
describe('<Subheader>', () => {
|
|
6
|
+
it('renders children inside a Box', () => {
|
|
7
|
+
const { getByText } = render(
|
|
8
|
+
<Subheader>
|
|
9
|
+
<span>left</span>
|
|
10
|
+
<span>right</span>
|
|
11
|
+
</Subheader>,
|
|
12
|
+
)
|
|
13
|
+
expect(getByText('left')).toBeTruthy()
|
|
14
|
+
expect(getByText('right')).toBeTruthy()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('merges caller-supplied sx onto the root', () => {
|
|
18
|
+
const { container } = render(
|
|
19
|
+
<Subheader sx={{ mt: 4 }}>
|
|
20
|
+
<span>x</span>
|
|
21
|
+
</Subheader>,
|
|
22
|
+
)
|
|
23
|
+
expect(container.firstChild).not.toBeNull()
|
|
24
|
+
// Class-based assertions are brittle; settle for "an element renders + a
|
|
25
|
+
// single child slot exists" — sx forwarding gets exercised at the
|
|
26
|
+
// import/MUI level so we don't need to inspect emotion-generated class
|
|
27
|
+
// names.
|
|
28
|
+
expect(container.querySelectorAll('span').length).toBe(1)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Box, type SxProps, type Theme } from '@mui/material'
|
|
2
|
+
import type { ReactNode } from 'react'
|
|
3
|
+
import { styles } from './style'
|
|
4
|
+
|
|
5
|
+
export interface SubheaderProps {
|
|
6
|
+
sx?: SxProps<Theme>
|
|
7
|
+
children: ReactNode
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Stateless layout: CSS grid `1fr auto`. Children self-place — typically
|
|
12
|
+
* `<Widget.SelectionSummary />` (left) and `<Widget.Toolbox>` (right).
|
|
13
|
+
*/
|
|
14
|
+
export function Subheader({ sx, children }: SubheaderProps) {
|
|
15
|
+
return <Box sx={{ ...styles.root, ...sx }}>{children}</Box>
|
|
16
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
|
2
|
+
import { createTableDownloadConfig } from './download'
|
|
3
|
+
import type { TableColumn, TableWidgetData } from './types'
|
|
4
|
+
|
|
5
|
+
const columns: TableColumn[] = [
|
|
6
|
+
{ id: 'name', label: 'Name' },
|
|
7
|
+
{ id: 'score', label: 'Score' },
|
|
8
|
+
]
|
|
9
|
+
const data: TableWidgetData = [
|
|
10
|
+
{ id: 1, name: 'Alpha', score: 10 },
|
|
11
|
+
{ id: 2, name: 'Beta', score: 20 },
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
let csvText = ''
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
csvText = ''
|
|
18
|
+
vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock')
|
|
19
|
+
vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => undefined)
|
|
20
|
+
const RealBlob = global.Blob
|
|
21
|
+
vi.stubGlobal(
|
|
22
|
+
'Blob',
|
|
23
|
+
class extends RealBlob {
|
|
24
|
+
constructor(parts: BlobPart[], opts?: BlobPropertyBag) {
|
|
25
|
+
csvText = typeof parts[0] === 'string' ? parts[0] : ''
|
|
26
|
+
super(parts, opts)
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
describe('createTableDownloadConfig', () => {
|
|
33
|
+
it('CSV-only by default', () => {
|
|
34
|
+
expect(
|
|
35
|
+
createTableDownloadConfig({
|
|
36
|
+
filename: 't',
|
|
37
|
+
getData: () => data,
|
|
38
|
+
columns,
|
|
39
|
+
}).map((i) => i.id),
|
|
40
|
+
).toEqual(['csv'])
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('prepends PNG when getCaptureEl is provided', () => {
|
|
44
|
+
const items = createTableDownloadConfig({
|
|
45
|
+
filename: 't',
|
|
46
|
+
getData: () => data,
|
|
47
|
+
columns,
|
|
48
|
+
getCaptureEl: () => document.createElement('div'),
|
|
49
|
+
})
|
|
50
|
+
expect(items.map((i) => i.id)).toEqual(['png', 'csv'])
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('CSV resolve uses tableDataToCsv with the supplied columns', async () => {
|
|
54
|
+
const items = createTableDownloadConfig({
|
|
55
|
+
filename: 't',
|
|
56
|
+
getData: () => data,
|
|
57
|
+
columns,
|
|
58
|
+
})
|
|
59
|
+
const handle = await items.find((i) => i.id === 'csv')!.resolve()
|
|
60
|
+
expect(handle.filename).toBe('t.csv')
|
|
61
|
+
expect(csvText).toBe('Name,Score\nAlpha,10\nBeta,20')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('CSV calls getData() at click time (not at config creation)', async () => {
|
|
65
|
+
let snapshot: TableWidgetData = data
|
|
66
|
+
const items = createTableDownloadConfig({
|
|
67
|
+
filename: 't',
|
|
68
|
+
getData: () => snapshot,
|
|
69
|
+
columns,
|
|
70
|
+
})
|
|
71
|
+
snapshot = [{ id: 9, name: 'Gamma', score: 99 }]
|
|
72
|
+
await items.find((i) => i.id === 'csv')!.resolve()
|
|
73
|
+
expect(csvText).toBe('Name,Score\nGamma,99')
|
|
74
|
+
})
|
|
75
|
+
})
|