diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index c9802a5f9977e..1c6e5db1f5e19 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -49,5 +49,5 @@ jobs: - name: Run benchmarks uses: CodSpeedHQ/action@513a19673a831f139e8717bf45ead67e47f00044 with: - run: pnpm --filter @mui-x-internal/performance-charts test:performance + run: pnpm --trace-warnings --filter @mui-x-internal/performance-charts test:performance token: ${{ secrets.CODSPEED_TOKEN }} diff --git a/docs/data/charts/highlighting/ControlledHighlight.js b/docs/data/charts/highlighting/ControlledHighlight.js index e7b0a1fa951ec..1514efd466f53 100644 --- a/docs/data/charts/highlighting/ControlledHighlight.js +++ b/docs/data/charts/highlighting/ControlledHighlight.js @@ -32,6 +32,7 @@ export default function ControlledHighlight() { const handleHighLightedItem = (event) => { setHighLightedItem((prev) => ({ + seriesId: 'A', ...prev, dataIndex: Number(event.target.value), })); diff --git a/docs/data/charts/highlighting/ControlledHighlight.tsx b/docs/data/charts/highlighting/ControlledHighlight.tsx index b29d70302bbc3..589ded27e43f9 100644 --- a/docs/data/charts/highlighting/ControlledHighlight.tsx +++ b/docs/data/charts/highlighting/ControlledHighlight.tsx @@ -33,6 +33,7 @@ export default function ControlledHighlight() { const handleHighLightedItem = (event: any) => { setHighLightedItem((prev) => ({ + seriesId: 'A', ...prev, dataIndex: Number(event.target.value), })); diff --git a/docs/data/migration/migration-charts-v7/migration-charts-v7.md b/docs/data/migration/migration-charts-v7/migration-charts-v7.md index 566f62d77c6a8..67a92077d3c50 100644 --- a/docs/data/migration/migration-charts-v7/migration-charts-v7.md +++ b/docs/data/migration/migration-charts-v7/migration-charts-v7.md @@ -157,6 +157,32 @@ And you can chose another shape by adding a `shape` property to your line series The codemod only removes the `experimentalMarkRendering` prop. If you relied on the fact that marks were `path` elements, you need to update your logic. +## Replacing `useHighlighted` by `useItemHighlighted` and `useItemHighlightedGetter` + +The `useHighlighted` hook that gave access to the internal highlight state has been removed. + +To know if your item is highlighted, it is recommended to use the `useItemHighlighted` hook instead: + +```jsx +const { isFaded, isHighlighted } = useItemHighlighted({ + seriesId, + dataIndex, +}); +``` + +If you're in a case where you have multiple series id to test (for example in the tooltip), you can use the lower level hook `useItemHighlightedGetter`. +This hook being lower level only test is the item match with the highlight or fade scope. +So an item could at the same time have `isFaded` and `isHighlighted` returning `true`. + +```jsx +const { isFaded, isHighlighted } = useItemHighlightedGetter(); + +const itemIsHighlighted = isHighlighted({ seriesId, dataIndex }); + +// First make sure the item is not highlighted. +const itemIsFaded = !itemIsHighlighted && isFaded({ seriesId, dataIndex }); +``` + ## Rename `labelFontSize` and `tickFontSize` props ✅ The `labelFontSize` and `tickFontSize` props have been removed in favor of the style objects `labelStyle` and `tickStyle` respectively. diff --git a/docs/pages/x/api/charts/bar-chart-pro.json b/docs/pages/x/api/charts/bar-chart-pro.json index 3bb9df3a58e32..e9416c23a399b 100644 --- a/docs/pages/x/api/charts/bar-chart-pro.json +++ b/docs/pages/x/api/charts/bar-chart-pro.json @@ -34,7 +34,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/pages/x/api/charts/bar-chart.json b/docs/pages/x/api/charts/bar-chart.json index 4465ea7e7e9c6..c46279678e7be 100644 --- a/docs/pages/x/api/charts/bar-chart.json +++ b/docs/pages/x/api/charts/bar-chart.json @@ -34,7 +34,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/pages/x/api/charts/chart-container-pro.json b/docs/pages/x/api/charts/chart-container-pro.json index 3450c79e98f95..3d79922889e74 100644 --- a/docs/pages/x/api/charts/chart-container-pro.json +++ b/docs/pages/x/api/charts/chart-container-pro.json @@ -10,7 +10,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/pages/x/api/charts/chart-container.json b/docs/pages/x/api/charts/chart-container.json index f287b65dc9131..7774b68892f52 100644 --- a/docs/pages/x/api/charts/chart-container.json +++ b/docs/pages/x/api/charts/chart-container.json @@ -10,7 +10,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/pages/x/api/charts/chart-data-provider-pro.json b/docs/pages/x/api/charts/chart-data-provider-pro.json index 379dd6ed5d96c..db03215a8494a 100644 --- a/docs/pages/x/api/charts/chart-data-provider-pro.json +++ b/docs/pages/x/api/charts/chart-data-provider-pro.json @@ -9,7 +9,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/pages/x/api/charts/chart-data-provider.json b/docs/pages/x/api/charts/chart-data-provider.json index 77371e213cabe..50754e0133c32 100644 --- a/docs/pages/x/api/charts/chart-data-provider.json +++ b/docs/pages/x/api/charts/chart-data-provider.json @@ -2,10 +2,8 @@ "props": { "colors": { "type": { "name": "any" }, "default": "blueberryTwilightPalette" }, "height": { "type": { "name": "any" } }, - "highlightedItem": { "type": { "name": "any" } }, "id": { "type": { "name": "any" } }, "margin": { "type": { "name": "any" } }, - "onHighlightChange": { "type": { "name": "any" } }, "series": { "type": { "name": "any" } }, "skipAnimation": { "type": { "name": "any" } }, "width": { "type": { "name": "any" } } diff --git a/docs/pages/x/api/charts/heatmap.json b/docs/pages/x/api/charts/heatmap.json index 825a7c3329d84..2145a8d6bc870 100644 --- a/docs/pages/x/api/charts/heatmap.json +++ b/docs/pages/x/api/charts/heatmap.json @@ -32,7 +32,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/pages/x/api/charts/line-chart-pro.json b/docs/pages/x/api/charts/line-chart-pro.json index 41853b306bd6a..0e65f0efc1ac1 100644 --- a/docs/pages/x/api/charts/line-chart-pro.json +++ b/docs/pages/x/api/charts/line-chart-pro.json @@ -34,7 +34,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/pages/x/api/charts/line-chart.json b/docs/pages/x/api/charts/line-chart.json index c41ca9a63958d..554ae19bd1767 100644 --- a/docs/pages/x/api/charts/line-chart.json +++ b/docs/pages/x/api/charts/line-chart.json @@ -34,7 +34,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/pages/x/api/charts/pie-chart.json b/docs/pages/x/api/charts/pie-chart.json index 372d22ed3afd3..8b35de2b0ece5 100644 --- a/docs/pages/x/api/charts/pie-chart.json +++ b/docs/pages/x/api/charts/pie-chart.json @@ -15,7 +15,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/pages/x/api/charts/scatter-chart-pro.json b/docs/pages/x/api/charts/scatter-chart-pro.json index 2107b9bb5a55a..6245bc8a1d0ff 100644 --- a/docs/pages/x/api/charts/scatter-chart-pro.json +++ b/docs/pages/x/api/charts/scatter-chart-pro.json @@ -34,7 +34,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/pages/x/api/charts/scatter-chart.json b/docs/pages/x/api/charts/scatter-chart.json index af592ebc0d86f..57dcde2d5a97e 100644 --- a/docs/pages/x/api/charts/scatter-chart.json +++ b/docs/pages/x/api/charts/scatter-chart.json @@ -34,7 +34,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/pages/x/api/charts/spark-line-chart.json b/docs/pages/x/api/charts/spark-line-chart.json index 5f7bdde16634b..00dfb76362682 100644 --- a/docs/pages/x/api/charts/spark-line-chart.json +++ b/docs/pages/x/api/charts/spark-line-chart.json @@ -15,7 +15,7 @@ "highlightedItem": { "type": { "name": "shape", - "description": "{ dataIndex?: number, seriesId?: number
| string }" + "description": "{ dataIndex?: number, seriesId: number
| string }" } }, "id": { "type": { "name": "string" } }, diff --git a/docs/translations/api-docs/charts/bar-chart-pro/bar-chart-pro.json b/docs/translations/api-docs/charts/bar-chart-pro/bar-chart-pro.json index a259f1f0e06ee..a37a18289c8c1 100644 --- a/docs/translations/api-docs/charts/bar-chart-pro/bar-chart-pro.json +++ b/docs/translations/api-docs/charts/bar-chart-pro/bar-chart-pro.json @@ -25,7 +25,7 @@ }, "hideLegend": { "description": "If true, the legend is not rendered." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/docs/translations/api-docs/charts/bar-chart/bar-chart.json b/docs/translations/api-docs/charts/bar-chart/bar-chart.json index 9af62108b49d7..80f4039074e22 100644 --- a/docs/translations/api-docs/charts/bar-chart/bar-chart.json +++ b/docs/translations/api-docs/charts/bar-chart/bar-chart.json @@ -25,7 +25,7 @@ }, "hideLegend": { "description": "If true, the legend is not rendered." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/docs/translations/api-docs/charts/chart-container-pro/chart-container-pro.json b/docs/translations/api-docs/charts/chart-container-pro/chart-container-pro.json index 4ca839b3c8e08..d1b5b5e7d0f58 100644 --- a/docs/translations/api-docs/charts/chart-container-pro/chart-container-pro.json +++ b/docs/translations/api-docs/charts/chart-container-pro/chart-container-pro.json @@ -12,7 +12,7 @@ "description": "The height of the chart in px. If not defined, it takes the height of the parent element." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/docs/translations/api-docs/charts/chart-container/chart-container.json b/docs/translations/api-docs/charts/chart-container/chart-container.json index 9544108936803..fd1826dc454c7 100644 --- a/docs/translations/api-docs/charts/chart-container/chart-container.json +++ b/docs/translations/api-docs/charts/chart-container/chart-container.json @@ -12,7 +12,7 @@ "description": "The height of the chart in px. If not defined, it takes the height of the parent element." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/docs/translations/api-docs/charts/chart-data-provider-pro/chart-data-provider-pro.json b/docs/translations/api-docs/charts/chart-data-provider-pro/chart-data-provider-pro.json index dbed26cfbd469..e7e076f4f2e6b 100644 --- a/docs/translations/api-docs/charts/chart-data-provider-pro/chart-data-provider-pro.json +++ b/docs/translations/api-docs/charts/chart-data-provider-pro/chart-data-provider-pro.json @@ -9,7 +9,7 @@ "description": "The height of the chart in px. If not defined, it takes the height of the parent element." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/docs/translations/api-docs/charts/chart-data-provider/chart-data-provider.json b/docs/translations/api-docs/charts/chart-data-provider/chart-data-provider.json index ead6d2b938eec..95ad33a80593c 100644 --- a/docs/translations/api-docs/charts/chart-data-provider/chart-data-provider.json +++ b/docs/translations/api-docs/charts/chart-data-provider/chart-data-provider.json @@ -5,16 +5,12 @@ "height": { "description": "The height of the chart in px. If not defined, it takes the height of the parent element." }, - "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." - }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." }, "margin": { "description": "The margin between the SVG and the drawing area. It's used for leaving some space for extra information such as the x- and y-axis or legend. Accepts an object with the optional properties: top, bottom, left, and right." }, - "onHighlightChange": { "description": "The callback fired when the highlighted item changes." }, "series": { "description": "The array of series to display. Each type of series has its own specificity. Please refer to the appropriate docs page to learn more about it." }, diff --git a/docs/translations/api-docs/charts/heatmap/heatmap.json b/docs/translations/api-docs/charts/heatmap/heatmap.json index 5cf0f1493f10f..29658e7c90da6 100644 --- a/docs/translations/api-docs/charts/heatmap/heatmap.json +++ b/docs/translations/api-docs/charts/heatmap/heatmap.json @@ -15,7 +15,7 @@ "description": "The height of the chart in px. If not defined, it takes the height of the parent element." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/docs/translations/api-docs/charts/line-chart-pro/line-chart-pro.json b/docs/translations/api-docs/charts/line-chart-pro/line-chart-pro.json index 718a9c7a58792..db965adbaa73b 100644 --- a/docs/translations/api-docs/charts/line-chart-pro/line-chart-pro.json +++ b/docs/translations/api-docs/charts/line-chart-pro/line-chart-pro.json @@ -24,7 +24,7 @@ }, "hideLegend": { "description": "If true, the legend is not rendered." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/docs/translations/api-docs/charts/line-chart/line-chart.json b/docs/translations/api-docs/charts/line-chart/line-chart.json index bf9906a71c945..8ad7ac0d32ce0 100644 --- a/docs/translations/api-docs/charts/line-chart/line-chart.json +++ b/docs/translations/api-docs/charts/line-chart/line-chart.json @@ -24,7 +24,7 @@ }, "hideLegend": { "description": "If true, the legend is not rendered." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/docs/translations/api-docs/charts/pie-chart/pie-chart.json b/docs/translations/api-docs/charts/pie-chart/pie-chart.json index 3e7f32b845fa6..a299ba744e837 100644 --- a/docs/translations/api-docs/charts/pie-chart/pie-chart.json +++ b/docs/translations/api-docs/charts/pie-chart/pie-chart.json @@ -13,7 +13,7 @@ }, "hideLegend": { "description": "If true, the legend is not rendered." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/docs/translations/api-docs/charts/scatter-chart-pro/scatter-chart-pro.json b/docs/translations/api-docs/charts/scatter-chart-pro/scatter-chart-pro.json index e31140e8e2500..ffec6ce8a3806 100644 --- a/docs/translations/api-docs/charts/scatter-chart-pro/scatter-chart-pro.json +++ b/docs/translations/api-docs/charts/scatter-chart-pro/scatter-chart-pro.json @@ -24,7 +24,7 @@ }, "hideLegend": { "description": "If true, the legend is not rendered." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/docs/translations/api-docs/charts/scatter-chart/scatter-chart.json b/docs/translations/api-docs/charts/scatter-chart/scatter-chart.json index 960dee7bfee15..edde056f643fd 100644 --- a/docs/translations/api-docs/charts/scatter-chart/scatter-chart.json +++ b/docs/translations/api-docs/charts/scatter-chart/scatter-chart.json @@ -24,7 +24,7 @@ }, "hideLegend": { "description": "If true, the legend is not rendered." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/docs/translations/api-docs/charts/spark-line-chart/spark-line-chart.json b/docs/translations/api-docs/charts/spark-line-chart/spark-line-chart.json index c4182f4cc964c..910eeb07bf7c2 100644 --- a/docs/translations/api-docs/charts/spark-line-chart/spark-line-chart.json +++ b/docs/translations/api-docs/charts/spark-line-chart/spark-line-chart.json @@ -16,7 +16,7 @@ "description": "The height of the chart in px. If not defined, it takes the height of the parent element." }, "highlightedItem": { - "description": "The item currently highlighted. Turns highlighting into a controlled prop." + "description": "The highlighted item. Used when the highlight is controlled." }, "id": { "description": "This prop is used to help implement the accessibility logic. If you don't provide this prop. It falls back to a randomly generated id." diff --git a/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx b/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx index f4a82ead6409a..8f16329bf72a3 100644 --- a/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx +++ b/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx @@ -201,11 +201,12 @@ BarChartPro.propTypes = { */ hideLegend: PropTypes.bool, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts-pro/src/ChartContainerPro/ChartContainerPro.tsx b/packages/x-charts-pro/src/ChartContainerPro/ChartContainerPro.tsx index 6f92034b49ff2..842116e0d2d9d 100644 --- a/packages/x-charts-pro/src/ChartContainerPro/ChartContainerPro.tsx +++ b/packages/x-charts-pro/src/ChartContainerPro/ChartContainerPro.tsx @@ -87,11 +87,12 @@ ChartContainerPro.propTypes = { */ height: PropTypes.number, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts-pro/src/ChartDataProviderPro/ChartDataProviderPro.tsx b/packages/x-charts-pro/src/ChartDataProviderPro/ChartDataProviderPro.tsx index af891f61153e9..f5bb30c91a18e 100644 --- a/packages/x-charts-pro/src/ChartDataProviderPro/ChartDataProviderPro.tsx +++ b/packages/x-charts-pro/src/ChartDataProviderPro/ChartDataProviderPro.tsx @@ -7,8 +7,8 @@ import { AnimationProvider, ChartSeriesType, ChartAnyPluginSignature, + ChartProviderProps, } from '@mui/x-charts/internals'; -import { HighlightedProvider } from '@mui/x-charts/context'; import { ChartDataProviderProps } from '@mui/x-charts/ChartDataProvider'; import { useLicenseVerifier } from '@mui/x-license/useLicenseVerifier'; import { AllPluginSignatures } from '../internals/plugins/allPlugins'; @@ -21,7 +21,8 @@ const packageIdentifier = 'x-charts-pro'; export type ChartDataProviderProProps< TSeries extends ChartSeriesType = ChartSeriesType, TSignatures extends readonly ChartAnyPluginSignature[] = AllPluginSignatures, -> = ChartDataProviderProps; +> = ChartDataProviderProps & + Omit['pluginParams'], 'children'>; /** * Orchestrates the data providers for the chart components and hooks. @@ -53,19 +54,17 @@ export type ChartDataProviderProProps< function ChartDataProviderPro( props: ChartDataProviderProProps, ) { - const { children, highlightedProviderProps, animationProviderProps, chartProviderProps } = + const { children, animationProviderProps, chartProviderProps } = useChartDataProviderProProps(props); useLicenseVerifier(packageIdentifier, releaseInfo); return ( - - - {children} - - - + + {children} + + ); } @@ -95,11 +94,12 @@ ChartDataProviderPro.propTypes = { */ height: PropTypes.number, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts-pro/src/ChartDataProviderPro/useChartDataProviderProProps.ts b/packages/x-charts-pro/src/ChartDataProviderPro/useChartDataProviderProProps.ts index eba62b0bcb7f5..99401f9a916d6 100644 --- a/packages/x-charts-pro/src/ChartDataProviderPro/useChartDataProviderProProps.ts +++ b/packages/x-charts-pro/src/ChartDataProviderPro/useChartDataProviderProProps.ts @@ -1,16 +1,22 @@ 'use client'; -import { ChartSeriesType, useChartDataProviderProps } from '@mui/x-charts/internals'; +import { + ChartAnyPluginSignature, + ChartSeriesType, + useChartDataProviderProps, +} from '@mui/x-charts/internals'; import type { ChartDataProviderProProps } from './ChartDataProviderPro'; +import type { AllPluginSignatures } from '../internals/plugins/allPlugins'; -export const useChartDataProviderProProps = ( - props: ChartDataProviderProProps, +export const useChartDataProviderProProps = < + TSeries extends ChartSeriesType = ChartSeriesType, + TSignatures extends readonly ChartAnyPluginSignature[] = AllPluginSignatures, +>( + props: ChartDataProviderProProps, ) => { - const { animationProviderProps, chartProviderProps, highlightedProviderProps, children } = - useChartDataProviderProps(props); + const { animationProviderProps, chartProviderProps, children } = useChartDataProviderProps(props); return { children, - highlightedProviderProps, animationProviderProps, chartProviderProps, }; diff --git a/packages/x-charts-pro/src/Heatmap/Heatmap.tsx b/packages/x-charts-pro/src/Heatmap/Heatmap.tsx index a7f4a1d9ca533..02117c7013478 100644 --- a/packages/x-charts-pro/src/Heatmap/Heatmap.tsx +++ b/packages/x-charts-pro/src/Heatmap/Heatmap.tsx @@ -244,11 +244,12 @@ Heatmap.propTypes = { */ height: PropTypes.number, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts-pro/src/Heatmap/HeatmapItem.tsx b/packages/x-charts-pro/src/Heatmap/HeatmapItem.tsx index c1e035685b8f7..4765e37e5dbd6 100644 --- a/packages/x-charts-pro/src/Heatmap/HeatmapItem.tsx +++ b/packages/x-charts-pro/src/Heatmap/HeatmapItem.tsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { styled } from '@mui/material/styles'; import useSlotProps from '@mui/utils/useSlotProps'; import composeClasses from '@mui/utils/composeClasses'; -import { useItemHighlighted } from '@mui/x-charts/context'; +import { useItemHighlighted } from '@mui/x-charts/hooks'; import { useInteractionItemProps, SeriesId } from '@mui/x-charts/internals'; import { HeatmapClasses, getHeatmapUtilityClass } from './heatmapClasses'; diff --git a/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx b/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx index d1d10bb7a2255..3f454b29da772 100644 --- a/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx +++ b/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx @@ -261,11 +261,12 @@ LineChartPro.propTypes = { */ hideLegend: PropTypes.bool, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx b/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx index e9cf45460cee3..064c125369b87 100644 --- a/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx +++ b/packages/x-charts-pro/src/ScatterChartPro/ScatterChartPro.tsx @@ -141,11 +141,12 @@ ScatterChartPro.propTypes = { */ hideLegend: PropTypes.bool, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts-pro/src/internals/plugins/allPlugins.ts b/packages/x-charts-pro/src/internals/plugins/allPlugins.ts index f7c3b8feeb125..c8a9d29099401 100644 --- a/packages/x-charts-pro/src/internals/plugins/allPlugins.ts +++ b/packages/x-charts-pro/src/internals/plugins/allPlugins.ts @@ -9,6 +9,8 @@ import { UseChartInteractionSignature, useChartZAxis, UseChartZAxisSignature, + useChartHighlight, + UseChartHighlightSignature, } from '@mui/x-charts/internals'; import { useChartProZoom, UseChartProZoomSignature } from './useChartProZoom'; @@ -16,6 +18,7 @@ export type AllPluginSignatures, UseChartInteractionSignature, + UseChartHighlightSignature, UseChartProZoomSignature, ]; @@ -26,5 +29,6 @@ export const ALL_PLUGINS = [ useChartZAxis, useChartCartesianAxis, useChartInteraction, + useChartHighlight, useChartProZoom, ]; diff --git a/packages/x-charts/src/BarChart/BarChart.tsx b/packages/x-charts/src/BarChart/BarChart.tsx index dc168923a3e32..36ca8d6fb88b0 100644 --- a/packages/x-charts/src/BarChart/BarChart.tsx +++ b/packages/x-charts/src/BarChart/BarChart.tsx @@ -216,11 +216,12 @@ BarChart.propTypes = { */ hideLegend: PropTypes.bool, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts/src/BarChart/BarElement.tsx b/packages/x-charts/src/BarChart/BarElement.tsx index f755f388385d3..720d9c9c5bd72 100644 --- a/packages/x-charts/src/BarChart/BarElement.tsx +++ b/packages/x-charts/src/BarChart/BarElement.tsx @@ -8,7 +8,7 @@ import generateUtilityClasses from '@mui/utils/generateUtilityClasses'; import { SlotComponentPropsFromProps } from '@mui/x-internals/types'; import { useInteractionItemProps } from '../hooks/useInteractionItemProps'; import { SeriesId } from '../models/seriesType/common'; -import { useItemHighlighted } from '../context'; +import { useItemHighlighted } from '../hooks/useItemHighlighted'; import { AnimatedBarElement, BarProps } from './AnimatedBarElement'; export interface BarElementClasses { diff --git a/packages/x-charts/src/BarChart/BarLabel/BarLabelItem.tsx b/packages/x-charts/src/BarChart/BarLabel/BarLabelItem.tsx index 33a993fd7694f..644ec44891d45 100644 --- a/packages/x-charts/src/BarChart/BarLabel/BarLabelItem.tsx +++ b/packages/x-charts/src/BarChart/BarLabel/BarLabelItem.tsx @@ -6,7 +6,7 @@ import { useUtilityClasses } from './barLabelClasses'; import { BarLabelOwnerState, BarItem, BarLabelContext } from './BarLabel.types'; import { getBarLabel } from './getBarLabel'; import { BarLabel, BarLabelProps } from './BarLabel'; -import { useItemHighlighted } from '../../context'; +import { useItemHighlighted } from '../../hooks/useItemHighlighted'; export interface BarLabelSlots { /** diff --git a/packages/x-charts/src/ChartContainer/ChartContainer.tsx b/packages/x-charts/src/ChartContainer/ChartContainer.tsx index bcc7e5392881f..3faa07fdf6a3d 100644 --- a/packages/x-charts/src/ChartContainer/ChartContainer.tsx +++ b/packages/x-charts/src/ChartContainer/ChartContainer.tsx @@ -86,11 +86,12 @@ ChartContainer.propTypes = { */ height: PropTypes.number, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts/src/ChartDataProvider/ChartDataProvider.tsx b/packages/x-charts/src/ChartDataProvider/ChartDataProvider.tsx index 1f2b7c88ae20e..5fc44814c21f6 100644 --- a/packages/x-charts/src/ChartDataProvider/ChartDataProvider.tsx +++ b/packages/x-charts/src/ChartDataProvider/ChartDataProvider.tsx @@ -3,7 +3,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useChartDataProviderProps } from './useChartDataProviderProps'; import { AnimationProvider, AnimationProviderProps } from '../context/AnimationProvider'; -import { HighlightedProvider, HighlightedProviderProps } from '../context/HighlightedProvider'; import { ChartProvider, ChartProviderProps } from '../context/ChartProvider'; import { ChartSeriesType } from '../models/seriesType/config'; import { ChartAnyPluginSignature } from '../internals/plugins/models/plugin'; @@ -13,9 +12,7 @@ export type ChartDataProviderProps< TSeries extends ChartSeriesType = ChartSeriesType, TSignatures extends readonly ChartAnyPluginSignature[] = AllPluginSignatures, > = Omit< - HighlightedProviderProps & - AnimationProviderProps & - ChartProviderProps['pluginParams'], + AnimationProviderProps & ChartProviderProps['pluginParams'], 'children' > & Pick, 'seriesConfig' | 'plugins'> & { @@ -53,14 +50,11 @@ function ChartDataProvider< TSeries extends ChartSeriesType = ChartSeriesType, TSignatures extends readonly ChartAnyPluginSignature[] = AllPluginSignatures, >(props: ChartDataProviderProps) { - const { children, highlightedProviderProps, animationProviderProps, chartProviderProps } = - useChartDataProviderProps(props); + const { children, animationProviderProps, chartProviderProps } = useChartDataProviderProps(props); return ( {...chartProviderProps}> - - {children} - + {children} ); } @@ -82,10 +76,6 @@ ChartDataProvider.propTypes = { * The height of the chart in px. If not defined, it takes the height of the parent element. */ height: PropTypes.any, - /** - * The item currently highlighted. Turns highlighting into a controlled prop. - */ - highlightedItem: PropTypes.any, /** * This prop is used to help implement the accessibility logic. * If you don't provide this prop. It falls back to a randomly generated id. @@ -97,12 +87,6 @@ ChartDataProvider.propTypes = { * Accepts an object with the optional properties: `top`, `bottom`, `left`, and `right`. */ margin: PropTypes.any, - /** - * The callback fired when the highlighted item changes. - * - * @param {HighlightItemData | null} highlightedItem The newly highlighted item. - */ - onHighlightChange: PropTypes.any, /** * The array of series to display. * Each type of series has its own specificity. diff --git a/packages/x-charts/src/ChartDataProvider/useChartDataProviderProps.ts b/packages/x-charts/src/ChartDataProvider/useChartDataProviderProps.ts index c7f341193212c..023ad518b54a7 100644 --- a/packages/x-charts/src/ChartDataProvider/useChartDataProviderProps.ts +++ b/packages/x-charts/src/ChartDataProvider/useChartDataProviderProps.ts @@ -1,7 +1,6 @@ 'use client'; import { useTheme } from '@mui/material/styles'; import type { ChartDataProviderProps } from './ChartDataProvider'; -import { HighlightedProviderProps } from '../context/HighlightedProvider'; import { AnimationProviderProps } from '../context/AnimationProvider'; import { ChartProviderProps } from '../context/ChartProvider'; import { ChartAnyPluginSignature, MergeSignaturesProperty } from '../internals/plugins/models'; @@ -23,8 +22,6 @@ export const useChartDataProviderProps = < margin, colors, dataset, - highlightedItem, - onHighlightChange, children, skipAnimation, plugins, @@ -57,14 +54,8 @@ export const useChartDataProviderProps = < skipAnimation, }; - const highlightedProviderProps: Omit = { - highlightedItem, - onHighlightChange, - }; - return { children, - highlightedProviderProps, animationProviderProps, chartProviderProps, }; diff --git a/packages/x-charts/src/ChartsVoronoiHandler/ChartsVoronoiHandler.tsx b/packages/x-charts/src/ChartsVoronoiHandler/ChartsVoronoiHandler.tsx index db09c2fdda810..1620c8b41b177 100644 --- a/packages/x-charts/src/ChartsVoronoiHandler/ChartsVoronoiHandler.tsx +++ b/packages/x-charts/src/ChartsVoronoiHandler/ChartsVoronoiHandler.tsx @@ -8,12 +8,12 @@ import { useStore } from '../internals/store/useStore'; import { getSVGPoint } from '../internals/getSVGPoint'; import { ScatterItemIdentifier } from '../models'; import { SeriesId } from '../models/seriesType/common'; -import { useHighlighted } from '../context/HighlightedProvider'; import { useScatterSeries } from '../hooks/useSeries'; import { useChartContext } from '../context/ChartProvider/useChartContext'; import { useDrawingArea } from '../hooks/useDrawingArea'; import { useSvgRef } from '../hooks/useSvgRef'; import { useXAxes, useYAxes } from '../hooks'; +import { UseChartHighlightSignature } from '../internals/plugins/featurePlugins/useChartHighlight'; export type ChartsVoronoiHandlerProps = { /** @@ -35,7 +35,7 @@ function ChartsVoronoiHandler(props: ChartsVoronoiHandlerProps) { const { voronoiMaxRadius, onItemClick } = props; const svgRef = useSvgRef(); const drawingArea = useDrawingArea(); - const { instance } = useChartContext(); + const { instance } = useChartContext<[UseChartHighlightSignature]>(); const { xAxis, xAxisIds } = useXAxes(); const { yAxis, yAxisIds } = useYAxes(); @@ -47,8 +47,6 @@ function ChartsVoronoiHandler(props: ChartsVoronoiHandlerProps) { const delauneyRef = React.useRef | undefined>(undefined); const lastFind = React.useRef(undefined); - const { setHighlighted, clearHighlighted } = useHighlighted(); - const defaultXAxisId = xAxisIds[0]; const defaultYAxisId = yAxisIds[0]; @@ -170,7 +168,8 @@ function ChartsVoronoiHandler(props: ChartsVoronoiHandlerProps) { ...prev, interaction: { ...prev.interaction, axis: { x: null, y: null }, item: null }, })); - clearHighlighted(); + + instance.clearHighlight(); }; const handleMouseMove = (event: MouseEvent) => { @@ -181,7 +180,7 @@ function ChartsVoronoiHandler(props: ChartsVoronoiHandlerProps) { ...prev, interaction: { ...prev.interaction, axis: { x: null, y: null }, item: null }, })); - clearHighlighted(); + instance.clearHighlight(); return; } @@ -190,7 +189,7 @@ function ChartsVoronoiHandler(props: ChartsVoronoiHandlerProps) { ...prev, interaction: { ...prev.interaction, item: null }, })); - clearHighlighted(); + instance.clearHighlight(); return; } @@ -200,7 +199,7 @@ function ChartsVoronoiHandler(props: ChartsVoronoiHandlerProps) { interaction: { ...prev.interaction, item: { type: 'scatter', seriesId, dataIndex } }, })); - setHighlighted({ + instance.setHighlight({ seriesId, dataIndex, }); @@ -229,18 +228,7 @@ function ChartsVoronoiHandler(props: ChartsVoronoiHandlerProps) { element.removeEventListener('pointermove', handleMouseMove); element.removeEventListener('click', handleMouseClick); }; - }, [ - svgRef, - yAxis, - xAxis, - voronoiMaxRadius, - onItemClick, - setHighlighted, - clearHighlighted, - drawingArea, - store, - instance, - ]); + }, [svgRef, yAxis, xAxis, voronoiMaxRadius, onItemClick, drawingArea, store, instance]); // eslint-disable-next-line react/jsx-no-useless-fragment return ; diff --git a/packages/x-charts/src/LineChart/AreaElement.tsx b/packages/x-charts/src/LineChart/AreaElement.tsx index fe7a0216bee58..66b8a67d8fd43 100644 --- a/packages/x-charts/src/LineChart/AreaElement.tsx +++ b/packages/x-charts/src/LineChart/AreaElement.tsx @@ -7,9 +7,9 @@ import generateUtilityClass from '@mui/utils/generateUtilityClass'; import generateUtilityClasses from '@mui/utils/generateUtilityClasses'; import { SlotComponentPropsFromProps } from '@mui/x-internals/types'; import { useInteractionItemProps } from '../hooks/useInteractionItemProps'; +import { useItemHighlighted } from '../hooks/useItemHighlighted'; import { AnimatedArea, AnimatedAreaProps } from './AnimatedArea'; import { SeriesId } from '../models/seriesType/common'; -import { useItemHighlighted } from '../context'; export interface AreaElementClasses { /** Styles applied to the root element. */ diff --git a/packages/x-charts/src/LineChart/CircleMarkElement.tsx b/packages/x-charts/src/LineChart/CircleMarkElement.tsx index f72a11dff750a..1fb7765aa6db6 100644 --- a/packages/x-charts/src/LineChart/CircleMarkElement.tsx +++ b/packages/x-charts/src/LineChart/CircleMarkElement.tsx @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import { useTheme } from '@mui/material/styles'; import { animated, useSpring } from '@react-spring/web'; import { useInteractionItemProps } from '../hooks/useInteractionItemProps'; -import { useItemHighlighted } from '../context'; +import { useItemHighlighted } from '../hooks/useItemHighlighted'; import { MarkElementOwnerState, useUtilityClasses } from './markElementClasses'; import { useSelector } from '../internals/store/useSelector'; import { selectorChartsInteractionXAxis } from '../internals/plugins/featurePlugins/useChartInteraction'; diff --git a/packages/x-charts/src/LineChart/LineChart.tsx b/packages/x-charts/src/LineChart/LineChart.tsx index 25fc397d524a9..15535d21916ad 100644 --- a/packages/x-charts/src/LineChart/LineChart.tsx +++ b/packages/x-charts/src/LineChart/LineChart.tsx @@ -241,11 +241,12 @@ LineChart.propTypes = { */ hideLegend: PropTypes.bool, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts/src/LineChart/LineElement.tsx b/packages/x-charts/src/LineChart/LineElement.tsx index a251ebf47ebc9..c9626380847a1 100644 --- a/packages/x-charts/src/LineChart/LineElement.tsx +++ b/packages/x-charts/src/LineChart/LineElement.tsx @@ -9,7 +9,7 @@ import { SlotComponentPropsFromProps } from '@mui/x-internals/types'; import { useInteractionItemProps } from '../hooks/useInteractionItemProps'; import { AnimatedLine, AnimatedLineProps } from './AnimatedLine'; import { SeriesId } from '../models/seriesType/common'; -import { useItemHighlighted } from '../context'; +import { useItemHighlighted } from '../hooks/useItemHighlighted'; export interface LineElementClasses { /** Styles applied to the root element. */ diff --git a/packages/x-charts/src/LineChart/MarkElement.tsx b/packages/x-charts/src/LineChart/MarkElement.tsx index 5f1105afff2f3..c973c24ad3d05 100644 --- a/packages/x-charts/src/LineChart/MarkElement.tsx +++ b/packages/x-charts/src/LineChart/MarkElement.tsx @@ -6,7 +6,7 @@ import { symbol as d3Symbol, symbolsFill as d3SymbolsFill } from '@mui/x-charts- import { animated, to, useSpring } from '@react-spring/web'; import { getSymbol } from '../internals/getSymbol'; import { useInteractionItemProps } from '../hooks/useInteractionItemProps'; -import { useItemHighlighted } from '../context'; +import { useItemHighlighted } from '../hooks/useItemHighlighted'; import { MarkElementOwnerState, useUtilityClasses } from './markElementClasses'; import { selectorChartsInteractionXAxis } from '../internals/plugins/featurePlugins/useChartInteraction'; import { useSelector } from '../internals/store/useSelector'; diff --git a/packages/x-charts/src/PieChart/PieChart.tsx b/packages/x-charts/src/PieChart/PieChart.tsx index 4ba222284ba7a..c055852132b44 100644 --- a/packages/x-charts/src/PieChart/PieChart.tsx +++ b/packages/x-charts/src/PieChart/PieChart.tsx @@ -180,11 +180,12 @@ PieChart.propTypes = { */ hideLegend: PropTypes.bool, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts/src/PieChart/dataTransform/useTransformData.ts b/packages/x-charts/src/PieChart/dataTransform/useTransformData.ts index 765d9ce683138..55de2003eb1b9 100644 --- a/packages/x-charts/src/PieChart/dataTransform/useTransformData.ts +++ b/packages/x-charts/src/PieChart/dataTransform/useTransformData.ts @@ -5,7 +5,7 @@ import { DefaultizedPieSeriesType, DefaultizedPieValueType, } from '../../models/seriesType/pie'; -import { useHighlighted } from '../../context'; +import { useItemHighlightedGetter } from '../../hooks/useItemHighlightedGetter'; export interface AnimatedObject { innerRadius: number; @@ -41,7 +41,7 @@ export function useTransformData( cornerRadius: baseCornerRadius = 0, } = series; - const { isFaded: isItemFaded, isHighlighted: isItemHighlighted } = useHighlighted(); + const { isFaded: isItemFaded, isHighlighted: isItemHighlighted } = useItemHighlightedGetter(); const dataWithHighlight: ValueWithHighlight[] = React.useMemo( () => diff --git a/packages/x-charts/src/ScatterChart/Scatter.tsx b/packages/x-charts/src/ScatterChart/Scatter.tsx index 84442f07b95b6..f7c0dc0d6d474 100644 --- a/packages/x-charts/src/ScatterChart/Scatter.tsx +++ b/packages/x-charts/src/ScatterChart/Scatter.tsx @@ -11,7 +11,7 @@ import { useInteractionItemProps } from '../hooks/useInteractionItemProps'; import { useStore } from '../internals/store/useStore'; import { useSelector } from '../internals/store/useSelector'; import { D3Scale } from '../models/axis'; -import { useHighlighted } from '../context'; +import { useItemHighlightedGetter } from '../hooks/useItemHighlightedGetter'; import { selectorChartsInteractionIsVoronoiEnabled } from '../internals/plugins/featurePlugins/useChartInteraction'; import { useChartContext } from '../context/ChartProvider'; @@ -52,7 +52,7 @@ function Scatter(props: ScatterProps) { const skipInteractionHandlers = isVoronoiEnabled || series.disableHover; const getInteractionItemProps = useInteractionItemProps(skipInteractionHandlers); - const { isFaded, isHighlighted } = useHighlighted(); + const { isFaded, isHighlighted } = useItemHighlightedGetter(); const cleanData = React.useMemo(() => { const getXPosition = getValueToPositionMapper(xScale); diff --git a/packages/x-charts/src/ScatterChart/ScatterChart.tsx b/packages/x-charts/src/ScatterChart/ScatterChart.tsx index db5d22390f72b..7599946729a31 100644 --- a/packages/x-charts/src/ScatterChart/ScatterChart.tsx +++ b/packages/x-charts/src/ScatterChart/ScatterChart.tsx @@ -212,11 +212,12 @@ ScatterChart.propTypes = { */ hideLegend: PropTypes.bool, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx b/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx index 84cd7abbf773a..01efe01c8b582 100644 --- a/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx +++ b/packages/x-charts/src/SparkLineChart/SparkLineChart.tsx @@ -275,11 +275,12 @@ SparkLineChart.propTypes = { */ height: PropTypes.number, /** - * The item currently highlighted. Turns highlighting into a controlled prop. + * The highlighted item. + * Used when the highlight is controlled. */ highlightedItem: PropTypes.shape({ dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, }), /** * This prop is used to help implement the accessibility logic. diff --git a/packages/x-charts/src/context/ChartProvider/ChartProvider.tsx b/packages/x-charts/src/context/ChartProvider/ChartProvider.tsx index a7a8e623f4279..885381acf61f7 100644 --- a/packages/x-charts/src/context/ChartProvider/ChartProvider.tsx +++ b/packages/x-charts/src/context/ChartProvider/ChartProvider.tsx @@ -11,6 +11,7 @@ import { ChartSeriesConfig } from '../../internals/plugins/models/seriesConfig'; import { useChartCartesianAxis } from '../../internals/plugins/featurePlugins/useChartCartesianAxis'; import { useChartInteraction } from '../../internals/plugins/featurePlugins/useChartInteraction'; import { useChartZAxis } from '../../internals/plugins/featurePlugins/useChartZAxis'; +import { useChartHighlight } from '../../internals/plugins/featurePlugins/useChartHighlight/useChartHighlight'; import { plugin as barPlugin } from '../../BarChart/plugin'; import { plugin as scatterPlugin } from '../../ScatterChart/plugin'; import { plugin as linePlugin } from '../../LineChart/plugin'; @@ -26,7 +27,12 @@ export const defaultSeriesConfig: ChartSeriesConfig<'bar' | 'scatter' | 'line' | // For consistency with the v7, the cartesian axes are set by default. // To remove them, you can provide a `plugins` props. -const defaultPlugins = [useChartZAxis, useChartCartesianAxis, useChartInteraction]; +const defaultPlugins = [ + useChartZAxis, + useChartCartesianAxis, + useChartInteraction, + useChartHighlight, +]; function ChartProvider< TSeriesType extends ChartSeriesType, diff --git a/packages/x-charts/src/context/HighlightedProvider/HighlightedContext.ts b/packages/x-charts/src/context/HighlightedProvider/HighlightedContext.ts deleted file mode 100644 index f89055efd50b4..0000000000000 --- a/packages/x-charts/src/context/HighlightedProvider/HighlightedContext.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as React from 'react'; -import { SeriesId } from '../../models/seriesType/common'; -import { Initializable } from '../context.types'; - -/** - * The data of the highlighted item. - * To highlight an item, you need to provide the series id and the item id. - * If targeting the whole series, you can omit the item id. - * To clear the highlight, set the value to an empty object. - * - * @example - * // Highlight the item with the series id 'london' and the item id 0. - * { seriesId: 'london', dataIndex: 0 } - * - * // Highlight the whole series with the series id 'london'. - * { seriesId: 'london' } - * - * // Clear the highlight. - * {} - */ -export type HighlightItemData = { - /** - * The series id of the highlighted item. - */ - seriesId?: SeriesId; - /** - * The index of the item in series data. - */ - dataIndex?: number; -}; - -export type HighlightOptions = 'none' | 'item' | 'series'; - -export type FadeOptions = 'none' | 'series' | 'global'; - -export type HighlightScope = { - /** - * The scope of highlighted elements. - * - 'none': no highlight. - * - 'item': only highlight the item. - * - 'series': highlight all elements of the same series. - * @default 'none' - */ - highlight?: HighlightOptions; - /** - * The scope of faded elements. - * - 'none': no fading. - * - 'series': only fade element of the same series. - * - 'global': fade all elements that are not highlighted. - * @default 'none' - */ - fade?: FadeOptions; -}; - -export type HighlightedState = { - highlightScope?: Partial; - highlightedItem: HighlightItemData | null; - setHighlighted: (item: HighlightItemData) => void; - clearHighlighted: () => void; - isHighlighted: (input: HighlightItemData) => boolean; - isFaded: (input: HighlightItemData) => boolean; -}; - -export const HighlightedContext = React.createContext>({ - isInitialized: false, - data: { - highlightedItem: null, - setHighlighted: () => {}, - clearHighlighted: () => {}, - isHighlighted: () => false, - isFaded: () => false, - }, -}); - -if (process.env.NODE_ENV !== 'production') { - HighlightedContext.displayName = 'HighlightedContext'; -} diff --git a/packages/x-charts/src/context/HighlightedProvider/HighlightedProvider.tsx b/packages/x-charts/src/context/HighlightedProvider/HighlightedProvider.tsx deleted file mode 100644 index a5e097e067f6d..0000000000000 --- a/packages/x-charts/src/context/HighlightedProvider/HighlightedProvider.tsx +++ /dev/null @@ -1,109 +0,0 @@ -'use client'; -import * as React from 'react'; -import PropTypes from 'prop-types'; -import useControlled from '@mui/utils/useControlled'; -import { - HighlightItemData, - HighlightedContext, - HighlightScope, - HighlightedState, -} from './HighlightedContext'; -import { createIsFaded } from './createIsFaded'; -import { createIsHighlighted } from './createIsHighlighted'; -import { useSeries } from '../../hooks/useSeries'; -import { ChartSeriesType } from '../../models/seriesType/config'; -import { SeriesId } from '../../models/seriesType/common'; -import { Initializable } from '../context.types'; - -export type HighlightedProviderProps = { - children: React.ReactNode; - /** - * The item currently highlighted. Turns highlighting into a controlled prop. - */ - highlightedItem?: HighlightItemData | null; - /** - * The callback fired when the highlighted item changes. - * - * @param {HighlightItemData | null} highlightedItem The newly highlighted item. - */ - onHighlightChange?: (highlightedItem: HighlightItemData | null) => void; -}; - -function HighlightedProvider({ - children, - highlightedItem: highlightedItemProps, - onHighlightChange, -}: HighlightedProviderProps) { - const [highlightedItem, setHighlightedItem] = useControlled({ - controlled: highlightedItemProps, - default: null, - name: 'HighlightedProvider', - state: 'highlightedItem', - }); - - const series = useSeries(); - const seriesById = React.useMemo(() => { - const map: Map | undefined> = new Map(); - - Object.keys(series).forEach((seriesType) => { - const seriesData = series[seriesType as ChartSeriesType]; - Object.keys(seriesData?.series ?? {}).forEach((seriesId) => { - const seriesItem = seriesData?.series[seriesId]; - map.set(seriesId, seriesItem?.highlightScope); - }); - }); - return map; - }, [series]); - - const highlightScope = - highlightedItem && highlightedItem.seriesId - ? (seriesById.get(highlightedItem.seriesId) ?? undefined) - : undefined; - - const providerValue = React.useMemo>(() => { - return { - isInitialized: true, - data: { - highlightScope, - highlightedItem, - setHighlighted: (itemData) => { - setHighlightedItem(itemData); - onHighlightChange?.(itemData); - }, - clearHighlighted: () => { - setHighlightedItem(null); - onHighlightChange?.(null); - }, - isHighlighted: createIsHighlighted(highlightScope, highlightedItem), - isFaded: createIsFaded(highlightScope, highlightedItem), - }, - }; - }, [highlightedItem, highlightScope, setHighlightedItem, onHighlightChange]); - - return ( - {children} - ); -} - -HighlightedProvider.propTypes = { - // ----------------------------- Warning -------------------------------- - // | These PropTypes are generated from the TypeScript type definitions | - // | To update them edit the TypeScript types and run "pnpm proptypes" | - // ---------------------------------------------------------------------- - children: PropTypes.node, - /** - * The item currently highlighted. Turns highlighting into a controlled prop. - */ - highlightedItem: PropTypes.shape({ - dataIndex: PropTypes.number, - seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - }), - /** - * The callback fired when the highlighted item changes. - * - * @param {HighlightItemData | null} highlightedItem The newly highlighted item. - */ - onHighlightChange: PropTypes.func, -} as any; - -export { HighlightedProvider }; diff --git a/packages/x-charts/src/context/HighlightedProvider/createIsFaded.ts b/packages/x-charts/src/context/HighlightedProvider/createIsFaded.ts deleted file mode 100644 index 8ec92655fcacb..0000000000000 --- a/packages/x-charts/src/context/HighlightedProvider/createIsFaded.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { HighlightItemData, HighlightScope } from './HighlightedContext'; - -export const createIsFaded = - (highlightScope: HighlightScope | null | undefined, highlightedItem: HighlightItemData | null) => - (input: HighlightItemData): boolean => { - if (!highlightScope) { - return false; - } - - if (highlightScope.fade === 'series') { - return ( - input.seriesId === highlightedItem?.seriesId && - input.dataIndex !== highlightedItem?.dataIndex - ); - } - - if (highlightScope.fade === 'global') { - return ( - input.seriesId !== highlightedItem?.seriesId || - input.dataIndex !== highlightedItem?.dataIndex - ); - } - - return false; - }; diff --git a/packages/x-charts/src/context/HighlightedProvider/createIsHighlighted.ts b/packages/x-charts/src/context/HighlightedProvider/createIsHighlighted.ts deleted file mode 100644 index 3d94cd023f6fc..0000000000000 --- a/packages/x-charts/src/context/HighlightedProvider/createIsHighlighted.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { HighlightItemData, HighlightScope } from './HighlightedContext'; - -export const createIsHighlighted = - (highlightScope: HighlightScope | null | undefined, highlightedItem: HighlightItemData | null) => - (input: HighlightItemData): boolean => { - if (!highlightScope) { - return false; - } - - if (highlightScope.highlight === 'series') { - return input.seriesId === highlightedItem?.seriesId; - } - - if (highlightScope.highlight === 'item') { - return ( - input.dataIndex === highlightedItem?.dataIndex && - input.seriesId === highlightedItem?.seriesId - ); - } - - return false; - }; diff --git a/packages/x-charts/src/context/HighlightedProvider/index.ts b/packages/x-charts/src/context/HighlightedProvider/index.ts deleted file mode 100644 index c1186b1179d21..0000000000000 --- a/packages/x-charts/src/context/HighlightedProvider/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './HighlightedProvider'; -export * from './HighlightedContext'; -export * from './useHighlighted'; -export * from './useItemHighlighted'; diff --git a/packages/x-charts/src/context/HighlightedProvider/useHighlighted.test.tsx b/packages/x-charts/src/context/HighlightedProvider/useHighlighted.test.tsx deleted file mode 100644 index b16a625f62b1b..0000000000000 --- a/packages/x-charts/src/context/HighlightedProvider/useHighlighted.test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import * as React from 'react'; -import { expect } from 'chai'; -import { ErrorBoundary, createRenderer, screen, reactMajor } from '@mui/internal-test-utils'; -import { testSkipIf, isJSDOM } from 'test/utils/skipIf'; -import { useHighlighted } from './useHighlighted'; -import { HighlightedProvider } from './HighlightedProvider'; -import { ChartProvider } from '../ChartProvider'; - -function UseHighlighted() { - const { highlightedItem } = useHighlighted(); - return
{highlightedItem?.seriesId}
; -} - -describe('useHighlighted', () => { - const { render } = createRenderer(); - - // can't catch render errors in the browser for unknown reason - // tried try-catch + error boundary + window onError preventDefault - testSkipIf(!isJSDOM)('should throw an error when parent context not present', () => { - const errorRef = React.createRef(); - - const errorMessage1 = 'MUI X: Could not find the highlighted ref context.'; - const errorMessage2 = - 'It looks like you rendered your component outside of a ChartsContainer parent component.'; - const errorMessage3 = 'The above error occurred in the component:'; - const expectedError = - reactMajor < 19 - ? [errorMessage1, errorMessage2, errorMessage3] - : `${errorMessage1}\n${errorMessage2}`; - - expect(() => - render( - - - , - ), - ).toErrorDev(expectedError); - - expect((errorRef.current as any).errors).to.have.length(1); - expect((errorRef.current as any).errors[0].toString()).to.include( - 'MUI X: Could not find the highlighted ref context.', - ); - }); - - it('should not throw an error when parent context is present', () => { - render( - - - - - , - ); - - expect(screen.getByText('test-id')).toBeVisible(); - }); -}); diff --git a/packages/x-charts/src/context/HighlightedProvider/useHighlighted.ts b/packages/x-charts/src/context/HighlightedProvider/useHighlighted.ts deleted file mode 100644 index ab584861dded7..0000000000000 --- a/packages/x-charts/src/context/HighlightedProvider/useHighlighted.ts +++ /dev/null @@ -1,25 +0,0 @@ -'use client'; -import * as React from 'react'; -import { HighlightedContext, HighlightedState } from './HighlightedContext'; - -/** - * A hook to get the highlighted state of the chart. - * - * Please consider using the `useItemHighlighted` hook if you need to check the state of a specific item. - * - * @returns {HighlightedState} the state of the chart - */ -export function useHighlighted(): HighlightedState { - const { isInitialized, data } = React.useContext(HighlightedContext); - - if (!isInitialized) { - throw new Error( - [ - 'MUI X: Could not find the highlighted ref context.', - 'It looks like you rendered your component outside of a ChartsContainer parent component.', - ].join('\n'), - ); - } - - return data; -} diff --git a/packages/x-charts/src/context/HighlightedProvider/useItemHighlighted.ts b/packages/x-charts/src/context/HighlightedProvider/useItemHighlighted.ts deleted file mode 100644 index 721d7f902017e..0000000000000 --- a/packages/x-charts/src/context/HighlightedProvider/useItemHighlighted.ts +++ /dev/null @@ -1,39 +0,0 @@ -'use client'; -import { HighlightItemData } from './HighlightedContext'; -import { useHighlighted } from './useHighlighted'; - -export type ItemHighlightedState = { - /** - * Whether the item is highlighted. - */ - isHighlighted: boolean; - /** - * Whether the item is faded. - */ - isFaded: boolean; -}; - -/** - * A hook to check the highlighted state of the item. - * This function already calculates that an item is not faded if it is highlighted. - * - * If you need fine control over the state, use the `useHighlighted` hook instead. - * - * @param {HighlightItemData} item is the item to check - * @returns {ItemHighlightedState} the state of the item - */ -export function useItemHighlighted(item: HighlightItemData | null): ItemHighlightedState { - const highlighted = useHighlighted(); - - if (!item) { - return { - isHighlighted: false, - isFaded: false, - }; - } - - const isHighlighted = highlighted.isHighlighted(item); - const isFaded = !isHighlighted && highlighted.isFaded(item); - - return { isHighlighted, isFaded }; -} diff --git a/packages/x-charts/src/context/InteractionSelectors.ts b/packages/x-charts/src/context/InteractionSelectors.ts deleted file mode 100644 index 7df8523f6f9b6..0000000000000 --- a/packages/x-charts/src/context/InteractionSelectors.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { UseChartInteractionSignature } from '../internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.types'; -import { ChartState } from '../internals/plugins/models'; -import { createSelector } from '../internals/plugins/utils/selectors'; - -function selectInteraction(state: ChartState<[UseChartInteractionSignature]>) { - return state.interaction; -} - -export const selectorChartsInteractionItem = createSelector( - selectInteraction, - (interaction) => interaction.item, -); - -export const selectorChartsInteractionAxis = createSelector( - selectInteraction, - (interaction) => interaction.axis, -); - -export const selectorChartsInteractionXAxis = createSelector( - selectInteraction, - (interaction) => interaction.axis.x, -); - -export const selectorChartsInteractionYAxis = createSelector( - selectInteraction, - (interaction) => interaction.axis.y, -); - -export const selectorChartsInteractionItemIsDefined = createSelector( - selectorChartsInteractionItem, - (item) => item !== null, -); - -export const selectorChartsInteractionXAxisIsDefined = createSelector( - selectorChartsInteractionXAxis, - (x) => x !== null, -); - -export const selectorChartsInteractionYAxisIsDefined = createSelector( - selectorChartsInteractionYAxis, - (y) => y !== null, -); - -export const selectorChartsInteractionIsVoronoiEnabled = createSelector( - selectInteraction, - (interaction) => interaction.isVoronoiEnabled, -); diff --git a/packages/x-charts/src/context/index.ts b/packages/x-charts/src/context/index.ts index da6326f1f9407..45f950c838a7b 100644 --- a/packages/x-charts/src/context/index.ts +++ b/packages/x-charts/src/context/index.ts @@ -1 +1,6 @@ -export * from './HighlightedProvider'; +export type { + HighlightScope, + FadeOptions, + HighlightItemData, + HighlightOptions, +} from '../internals/plugins/featurePlugins/useChartHighlight'; diff --git a/packages/x-charts/src/hooks/index.ts b/packages/x-charts/src/hooks/index.ts index 9bbe0ac753cef..87ee20d63333e 100644 --- a/packages/x-charts/src/hooks/index.ts +++ b/packages/x-charts/src/hooks/index.ts @@ -5,6 +5,8 @@ export * from './useAxis'; export * from './useZAxis'; export * from './useColorScale'; export * from './useSvgRef'; +export * from './useItemHighlighted'; +export * from './useItemHighlightedGetter'; export { useSeries as unstable_useSeries, usePieSeries as unstable_usePieSeries, diff --git a/packages/x-charts/src/hooks/useInteractionItemProps.ts b/packages/x-charts/src/hooks/useInteractionItemProps.ts index d1230d3fbb237..feb1fafda8540 100644 --- a/packages/x-charts/src/hooks/useInteractionItemProps.ts +++ b/packages/x-charts/src/hooks/useInteractionItemProps.ts @@ -1,13 +1,13 @@ 'use client'; import * as React from 'react'; import { SeriesItemIdentifier } from '../models'; -import { useHighlighted } from '../context'; -import { useStore } from '../internals/store/useStore'; +import { useChartContext } from '../context/ChartProvider'; +import { UseChartHighlightSignature } from '../internals/plugins/featurePlugins/useChartHighlight'; +import { UseChartInteractionSignature } from '../internals/plugins/featurePlugins/useChartInteraction'; export const useInteractionItemProps = (skip?: boolean) => { - const store = useStore(); - - const { setHighlighted, clearHighlighted } = useHighlighted(); + const { instance } = + useChartContext<[UseChartInteractionSignature, UseChartHighlightSignature]>(); if (skip) { return () => ({}); @@ -19,14 +19,8 @@ export const useInteractionItemProps = (skip?: boolean) => { } }; const onPointerEnter = () => { - store.update((prev) => ({ - ...prev, - interaction: { - ...prev.interaction, - item: data, - }, - })); - setHighlighted({ + instance.setItemInteraction(data); + instance.setHighlight({ seriesId: data.seriesId, dataIndex: data.dataIndex, }); @@ -36,26 +30,8 @@ export const useInteractionItemProps = (skip?: boolean) => { event.currentTarget.releasePointerCapture(event.pointerId); } - store.update((prev) => { - const prevItem = prev.interaction.item; - if ( - prevItem === null || - Object.keys(data).some( - (key) => data[key as keyof typeof data] !== prevItem[key as keyof typeof prevItem], - ) - ) { - // The item is already something else, no need to clean it. - return prev; - } - return { - ...prev, - interaction: { - ...prev.interaction, - item: null, - }, - }; - }); - clearHighlighted(); + instance.removeItemInteraction(data); + instance.clearHighlight(); }; return { onPointerEnter, diff --git a/packages/x-charts/src/hooks/useItemHighlighted.ts b/packages/x-charts/src/hooks/useItemHighlighted.ts new file mode 100644 index 0000000000000..df17cfcf9738b --- /dev/null +++ b/packages/x-charts/src/hooks/useItemHighlighted.ts @@ -0,0 +1,43 @@ +'use client'; + +import { useStore } from '../internals/store/useStore'; +import { useSelector } from '../internals/store/useSelector'; +import { + selectorChartsIsFaded, + selectorChartsIsHighlighted, +} from '../internals/plugins/featurePlugins/useChartHighlight'; +import { + HighlightItemData, + UseChartHighlightSignature, +} from '../internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.types'; + +type UseItemHighlightedReturnType = { + /** + * Whether the item is highlighted. + */ + isHighlighted: boolean; + /** + * Whether the item is faded. + */ + isFaded: boolean; +}; + +type UseItemHighlightedParams = HighlightItemData | null; + +/** + * A hook to check the highlighted state of the item. + * This function already calculates that an item is not faded if it is highlighted. + * + * If you need fine control over the state, use the `useItemHighlightedGetter` hook instead. + * + * @param {HighlightItemData | null} item is the item to check + * @returns {UseItemHighlightedReturnType} the state of the item + */ +export function useItemHighlighted(item: UseItemHighlightedParams): UseItemHighlightedReturnType { + const store = useStore<[UseChartHighlightSignature]>(); + + const isHighlighted = useSelector(store, selectorChartsIsHighlighted, item); + const isFaded = useSelector(store, selectorChartsIsFaded, item); + + return { isHighlighted, isFaded: !isHighlighted && isFaded }; +} diff --git a/packages/x-charts/src/hooks/useItemHighlightedGetter.tsx b/packages/x-charts/src/hooks/useItemHighlightedGetter.tsx new file mode 100644 index 0000000000000..715493085753b --- /dev/null +++ b/packages/x-charts/src/hooks/useItemHighlightedGetter.tsx @@ -0,0 +1,26 @@ +'use client'; +import { useSelector } from '../internals/store/useSelector'; +import { useStore } from '../internals/store/useStore'; +import { + selectorChartsIsFadedCallback, + selectorChartsIsHighlightedCallback, +} from '../internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors'; + +/** + * A hook to check the highlighted state of multiple items. + * If you're interested by a single one, consider using `useItemHighlighted`. + * + * Warning: highlighted and faded can both be true at the same time. + * We recommend to first test if item is highlighted: `const faded = !highlighted && isFaded(item)` + * @returns {{ isHighlighted, isFaded }} callbacks to get the state of the item. + */ +export function useItemHighlightedGetter() { + const store = useStore(); + + const isHighlighted = useSelector(store, selectorChartsIsHighlightedCallback); + const isFaded = useSelector(store, selectorChartsIsFadedCallback); + return { + isHighlighted, + isFaded, + }; +} diff --git a/packages/x-charts/src/internals/index.ts b/packages/x-charts/src/internals/index.ts index bd70fa0195249..4076fbcbc3ee7 100644 --- a/packages/x-charts/src/internals/index.ts +++ b/packages/x-charts/src/internals/index.ts @@ -20,6 +20,7 @@ export * from './plugins/corePlugins/useChartDimensions'; export * from './plugins/featurePlugins/useChartZAxis'; export * from './plugins/featurePlugins/useChartCartesianAxis'; export * from './plugins/featurePlugins/useChartInteraction'; +export * from './plugins/featurePlugins/useChartHighlight'; export * from './plugins/utils/selectors'; export * from './store/useCharts'; diff --git a/packages/x-charts/src/internals/plugins/allPlugins.ts b/packages/x-charts/src/internals/plugins/allPlugins.ts index e5af78e20ddc1..4ee618225c0b7 100644 --- a/packages/x-charts/src/internals/plugins/allPlugins.ts +++ b/packages/x-charts/src/internals/plugins/allPlugins.ts @@ -4,6 +4,8 @@ import { useChartCartesianAxis, UseChartCartesianAxisSignature, } from './featurePlugins/useChartCartesianAxis'; +import { UseChartHighlightSignature } from './featurePlugins/useChartHighlight'; +import { useChartHighlight } from './featurePlugins/useChartHighlight/useChartHighlight'; import { useChartInteraction, UseChartInteractionSignature, @@ -15,9 +17,15 @@ export type AllPluginSignatures, UseChartInteractionSignature, + UseChartHighlightSignature, ]; export type AllPluginsType = ConvertSignaturesIntoPlugins>; -export const ALL_PLUGINS = [useChartZAxis, useChartCartesianAxis, useChartInteraction]; +export const ALL_PLUGINS = [ + useChartZAxis, + useChartCartesianAxis, + useChartInteraction, + useChartHighlight, +]; diff --git a/packages/x-charts/src/context/HighlightedProvider/createIsFaded.test.ts b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsFaded.test.ts similarity index 85% rename from packages/x-charts/src/context/HighlightedProvider/createIsFaded.test.ts rename to packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsFaded.test.ts index b333d94442805..d64cc199d8145 100644 --- a/packages/x-charts/src/context/HighlightedProvider/createIsFaded.test.ts +++ b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsFaded.test.ts @@ -1,10 +1,12 @@ import { expect } from 'chai'; import { createIsFaded } from './createIsFaded'; +const seriesId = 'id1'; +const dataIndex = 1; + const itemData = { - seriesId: '1s', - dataIndex: 1, - value: '1v', + seriesId, + dataIndex, }; describe('createIsFaded', () => { @@ -20,7 +22,7 @@ describe('createIsFaded', () => { }); it('should return false when input series is different than highlighted', () => { - expect(isFadedSameSeries({ ...itemData, seriesId: '2' })).to.equal(false); + expect(isFadedSameSeries({ ...itemData, seriesId: 'id2' })).to.equal(false); }); }); @@ -36,7 +38,7 @@ describe('createIsFaded', () => { }); it('should return true when series is different than highlighted', () => { - expect(isFadedGlobal({ ...itemData, seriesId: '2' })).to.equal(true); + expect(isFadedGlobal({ ...itemData, seriesId: 'id2' })).to.equal(true); }); }); diff --git a/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsFaded.ts b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsFaded.ts new file mode 100644 index 0000000000000..0d6ca20790725 --- /dev/null +++ b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsFaded.ts @@ -0,0 +1,24 @@ +import { HighlightScope } from './highlightConfig.types'; +import { HighlightItemData } from './useChartHighlight.types'; + +export const createIsFaded = + (highlightScope: HighlightScope | null | undefined, highlightedItem: HighlightItemData | null) => + (item: HighlightItemData | null): boolean => { + if (!highlightScope || !highlightedItem || !item) { + return false; + } + + if (highlightScope.fade === 'series') { + return ( + item.seriesId === highlightedItem.seriesId && item.dataIndex !== highlightedItem.dataIndex + ); + } + + if (highlightScope.fade === 'global') { + return ( + item.seriesId !== highlightedItem.seriesId || item.dataIndex !== highlightedItem.dataIndex + ); + } + + return false; + }; diff --git a/packages/x-charts/src/context/HighlightedProvider/createIsHighlighted.test.ts b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsHighlighted.test.ts similarity index 87% rename from packages/x-charts/src/context/HighlightedProvider/createIsHighlighted.test.ts rename to packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsHighlighted.test.ts index 3670226150a8d..a8b8bb2da7c49 100644 --- a/packages/x-charts/src/context/HighlightedProvider/createIsHighlighted.test.ts +++ b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsHighlighted.test.ts @@ -1,10 +1,12 @@ import { expect } from 'chai'; import { createIsHighlighted } from './createIsHighlighted'; +const seriesId = 'id1'; +const dataIndex = 1; + const itemData = { - seriesId: '1s', - dataIndex: 1, - value: '1v', + seriesId, + dataIndex, }; describe('createIsHighlighted', () => { @@ -20,7 +22,7 @@ describe('createIsHighlighted', () => { }); it('should return false when input series is different than highlighted', () => { - expect(isHighlightedSameSeries({ ...itemData, seriesId: '2' })).to.equal(false); + expect(isHighlightedSameSeries({ ...itemData, seriesId: 'id2' })).to.equal(false); }); it('should return true when input item is different than highlighted', () => { @@ -40,7 +42,7 @@ describe('createIsHighlighted', () => { }); it('should return false when input series is different than highlighted', () => { - expect(isHighlightedItem({ ...itemData, seriesId: '2' })).to.equal(false); + expect(isHighlightedItem({ ...itemData, seriesId: 'id2' })).to.equal(false); }); }); diff --git a/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsHighlighted.ts b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsHighlighted.ts new file mode 100644 index 0000000000000..d9ecb5fc562ee --- /dev/null +++ b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/createIsHighlighted.ts @@ -0,0 +1,22 @@ +import { HighlightScope } from './highlightConfig.types'; +import { HighlightItemData } from './useChartHighlight.types'; + +export const createIsHighlighted = + (highlightScope: HighlightScope | null | undefined, highlightedItem: HighlightItemData | null) => + (item: HighlightItemData | null): boolean => { + if (!highlightScope || !highlightedItem || !item) { + return false; + } + + if (highlightScope.highlight === 'series') { + return item.seriesId === highlightedItem.seriesId; + } + + if (highlightScope.highlight === 'item') { + return ( + item.dataIndex === highlightedItem.dataIndex && item.seriesId === highlightedItem.seriesId + ); + } + + return false; + }; diff --git a/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/highlightConfig.types.ts b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/highlightConfig.types.ts new file mode 100644 index 0000000000000..f50bb56d9e205 --- /dev/null +++ b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/highlightConfig.types.ts @@ -0,0 +1,22 @@ +export type HighlightOptions = 'none' | 'item' | 'series'; + +export type FadeOptions = 'none' | 'series' | 'global'; + +export type HighlightScope = { + /** + * The scope of highlighted elements. + * - 'none': no highlight. + * - 'item': only highlight the item. + * - 'series': highlight all elements of the same series. + * @default 'none' + */ + highlight?: HighlightOptions; + /** + * The scope of faded elements. + * - 'none': no fading. + * - 'series': only fade element of the same series. + * - 'global': fade all elements that are not highlighted. + * @default 'none' + */ + fade?: FadeOptions; +}; diff --git a/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/index.ts b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/index.ts new file mode 100644 index 0000000000000..e42914a8d67fc --- /dev/null +++ b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/index.ts @@ -0,0 +1,4 @@ +export { useChartHighlight } from './useChartHighlight'; +export * from './useChartHighlight.selectors'; +export type { UseChartHighlightSignature, HighlightItemData } from './useChartHighlight.types'; +export type * from './highlightConfig.types'; diff --git a/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.ts b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.ts new file mode 100644 index 0000000000000..65874fa688615 --- /dev/null +++ b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.ts @@ -0,0 +1,69 @@ +import { SeriesId } from '../../../../models/seriesType/common'; +import { ChartSeriesType } from '../../../../models/seriesType/config'; +import { UseChartSeriesSignature } from '../../corePlugins/useChartSeries/useChartSeries.types'; +import { ChartRootSelector, createSelector } from '../../utils/selectors'; +import { HighlightItemData, UseChartHighlightSignature } from './useChartHighlight.types'; +import { HighlightScope } from './highlightConfig.types'; +import { createIsHighlighted } from './createIsHighlighted'; +import { createIsFaded } from './createIsFaded'; + +const selectHighlight: ChartRootSelector = (state) => state.highlight; + +const selectSeries: ChartRootSelector = (state) => state.series; + +export const selectorChartsHighlightScopePerSeriesId = createSelector( + selectSeries, + (series): Map | undefined> => { + const map = new Map | undefined>(); + + Object.keys(series.processedSeries).forEach((seriesType) => { + const seriesData = series.processedSeries[seriesType as ChartSeriesType]; + Object.keys(seriesData?.series ?? {}).forEach((seriesId) => { + const seriesItem = seriesData?.series[seriesId]; + map.set(seriesId, seriesItem?.highlightScope); + }); + }); + return map; + }, +); + +export const selectorChartsHighlightedItem = createSelector( + selectHighlight, + (highlight) => highlight.item, +); + +export const selectorChartsHighlightScope = createSelector( + [selectorChartsHighlightScopePerSeriesId, selectorChartsHighlightedItem], + (seriesIdToHighlightScope, highlightedItem) => { + if (!highlightedItem) { + return null; + } + const highlightScope = seriesIdToHighlightScope.get(highlightedItem.seriesId); + + if (highlightScope === undefined) { + return null; + } + + return highlightScope; + }, +); + +export const selectorChartsIsHighlightedCallback = createSelector( + [selectorChartsHighlightScope, selectorChartsHighlightedItem], + createIsHighlighted, +); + +export const selectorChartsIsFadedCallback = createSelector( + [selectorChartsHighlightScope, selectorChartsHighlightedItem], + createIsFaded, +); + +export const selectorChartsIsHighlighted = createSelector( + [selectorChartsIsHighlightedCallback, (_, item: HighlightItemData | null) => item], + (callback, item) => callback(item), +); + +export const selectorChartsIsFaded = createSelector( + [selectorChartsIsFadedCallback, (_, item: HighlightItemData | null) => item], + (callback, item) => callback(item), +); diff --git a/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.ts b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.ts new file mode 100644 index 0000000000000..4c23e6eb08213 --- /dev/null +++ b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.ts @@ -0,0 +1,52 @@ +import useEventCallback from '@mui/utils/useEventCallback'; +import useEnhancedEffect from '@mui/utils/useEnhancedEffect'; +import { ChartPlugin } from '../../models'; +import { HighlightItemData, UseChartHighlightSignature } from './useChartHighlight.types'; + +export const useChartHighlight: ChartPlugin = ({ + store, + params, + models, +}) => { + useEnhancedEffect(() => { + store.update((prevState) => ({ + ...prevState, + highlight: { + ...prevState.highlight, + item: models.highlightedItem.value, + }, + })); + }, [store, models.highlightedItem.value]); + + const clearHighlight = useEventCallback(() => { + params.onHighlightChange?.(null); + models.highlightedItem.setControlledValue(null); + }); + + const setHighlight = useEventCallback((newItem: HighlightItemData) => { + params.onHighlightChange?.(newItem); + models.highlightedItem.setControlledValue(newItem); + }); + + return { + instance: { + clearHighlight, + setHighlight, + }, + }; +}; + +useChartHighlight.models = { + highlightedItem: { + getDefaultValue: () => null, + }, +}; + +useChartHighlight.getInitialState = (params) => ({ + highlight: { item: params.highlightedItem ?? null }, +}); + +useChartHighlight.params = { + highlightedItem: true, + onHighlightChange: true, +}; diff --git a/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.types.ts b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.types.ts new file mode 100644 index 0000000000000..e97243c4b7636 --- /dev/null +++ b/packages/x-charts/src/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.types.ts @@ -0,0 +1,80 @@ +import { DefaultizedProps } from '@mui/x-internals/types'; +import { ChartPluginSignature } from '../../models'; +import { SeriesId } from '../../../../models/seriesType/common'; +import { UseChartSeriesSignature } from '../../corePlugins/useChartSeries'; + +/** + * The data of the highlighted item. + * To highlight an item, you need to provide the series id and the item id. + * If targeting the whole series, you can omit the item id. + * To clear the highlight, set the value to an empty object. + * + * @example + * // Highlight the item with the series id 'london' and the item id 0. + * { seriesId: 'london', dataIndex: 0 } + * + * // Highlight the whole series with the series id 'london'. + * { seriesId: 'london' } + * + * // Clear the highlight. + * {} + */ +export type HighlightItemData = { + /** + * The series id of the highlighted item. + */ + seriesId: SeriesId; + /** + * The index of the item in series data. + */ + dataIndex?: number; +}; + +export interface UseChartHighlightInstance { + /** + * Remove all highlight. + */ + clearHighlight: () => void; + /** + * Set the highlighted item. + * @param {HighlightItemData} item The item to highlight. + */ + setHighlight: (item: HighlightItemData) => void; +} + +export interface UseChartHighlightParameters { + /** + * The highlighted item. + * Used when the highlight is controlled. + */ + highlightedItem?: HighlightItemData | null; + /** + * The callback fired when the highlighted item changes. + * + * @param {HighlightItemData | null} highlightedItem The newly highlighted item. + */ + onHighlightChange?: (highlightedItem: HighlightItemData | null) => void; +} + +export type UseChartHighlightDefaultizedParameters = DefaultizedProps< + UseChartHighlightParameters, + 'highlightedItem' +>; + +export interface UseChartHighlightState { + highlight: { + /** + * The item currently highlighted. + */ + item: HighlightItemData | null; + }; +} + +export type UseChartHighlightSignature = ChartPluginSignature<{ + instance: UseChartHighlightInstance; + state: UseChartHighlightState; + params: UseChartHighlightParameters; + defaultizedParams: UseChartHighlightDefaultizedParameters; + modelNames: 'highlightedItem'; + dependencies: [UseChartSeriesSignature]; +}>; diff --git a/packages/x-charts/src/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.ts b/packages/x-charts/src/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.ts index 2dca0b61cbbe5..a57cd95ac49b8 100644 --- a/packages/x-charts/src/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.ts +++ b/packages/x-charts/src/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.ts @@ -5,12 +5,41 @@ import { ChartItemIdentifier, ChartSeriesType } from '../../../../models/seriesT export const useChartInteraction: ChartPlugin = ({ store }) => { const cleanInteraction = useEventCallback(() => { - store.update((prev) => ({ - ...prev, - interaction: { ...prev.interaction, axis: { x: null, y: null }, item: null }, - })); + store.update((prev) => { + return { + ...prev, + interaction: { ...prev.interaction, axis: { x: null, y: null }, item: null }, + }; + }); }); + const removeItemInteraction = useEventCallback( + (itemToRemove: ChartItemIdentifier) => { + store.update((prev) => { + const prevItem = prev.interaction.item; + if ( + prevItem === null || + Object.keys(itemToRemove).some( + (key) => + itemToRemove[key as keyof typeof itemToRemove] !== + prevItem[key as keyof typeof prevItem], + ) + ) { + // The item is already something else, no need to clean it. + return prev; + } + + return { + ...prev, + interaction: { + ...prev.interaction, + item: null, + }, + }; + }); + }, + ); + const setItemInteraction = useEventCallback((newItem: ChartItemIdentifier) => { store.update((prev) => ({ ...prev, @@ -69,6 +98,7 @@ export const useChartInteraction: ChartPlugin = ({ instance: { cleanInteraction, setItemInteraction, + removeItemInteraction, setAxisInteraction, enableVoronoid, disableVoronoid, diff --git a/packages/x-charts/src/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.types.ts b/packages/x-charts/src/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.types.ts index 76c97c2c803c8..ed5befb91a0f5 100644 --- a/packages/x-charts/src/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.types.ts +++ b/packages/x-charts/src/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.types.ts @@ -11,6 +11,11 @@ export interface UseChartInteractionInstance { * @param {ChartItemIdentifier} newItem The identifier of the item. */ setItemInteraction: (newItem: ChartItemIdentifier) => void; + /** + * Remove item interaction if the current if the provided item is still the one interacting. + * @param {ChartItemIdentifier} itemToRemove The identifier of the item. + */ + removeItemInteraction: (itemToRemove: ChartItemIdentifier) => void; /** * Set the new axis the user is interacting with. * @param {Partial} newAxis The new axis identifier. diff --git a/packages/x-charts/src/internals/store/useStore.ts b/packages/x-charts/src/internals/store/useStore.ts index 9a82698b4b2ce..a86d046f69753 100644 --- a/packages/x-charts/src/internals/store/useStore.ts +++ b/packages/x-charts/src/internals/store/useStore.ts @@ -1,11 +1,12 @@ import { useChartContext } from '../../context/ChartProvider'; import { ChartStore } from '../plugins/utils/ChartStore'; -import { UseChartInteractionSignature } from '../plugins/featurePlugins/useChartInteraction/useChartInteraction.types'; +import { UseChartInteractionSignature } from '../plugins/featurePlugins/useChartInteraction'; +import { UseChartHighlightSignature } from '../plugins/featurePlugins/useChartHighlight'; import { ChartAnyPluginSignature } from '../plugins/models'; // This hook should be removed because user and us should not interact with the store directly, but with public/private APIs export function useStore(): ChartStore< - [...TSignatures, UseChartInteractionSignature] + [...TSignatures, UseChartInteractionSignature, UseChartHighlightSignature] > { const context = useChartContext(); diff --git a/packages/x-charts/src/models/seriesType/common.ts b/packages/x-charts/src/models/seriesType/common.ts index 084d3d302dd1a..c3835bad2ff3b 100644 --- a/packages/x-charts/src/models/seriesType/common.ts +++ b/packages/x-charts/src/models/seriesType/common.ts @@ -1,5 +1,5 @@ import type { ChartsLabelMarkProps } from '../../ChartsLabel'; -import type { HighlightScope } from '../../context'; +import { HighlightScope } from '../../internals/plugins/featurePlugins/useChartHighlight/highlightConfig.types'; import type { StackOffsetType, StackOrderType } from '../stacking'; export type SeriesId = number | string; diff --git a/scripts/x-charts-pro.exports.json b/scripts/x-charts-pro.exports.json index a68e0179c5c42..6c4e484f3ca1b 100644 --- a/scripts/x-charts-pro.exports.json +++ b/scripts/x-charts-pro.exports.json @@ -184,17 +184,12 @@ { "name": "HeatmapPlot", "kind": "Function" }, { "name": "HeatmapTooltip", "kind": "Function" }, { "name": "HeatmapTooltipProps", "kind": "Interface" }, - { "name": "HighlightedContext", "kind": "Variable" }, - { "name": "HighlightedProvider", "kind": "Function" }, - { "name": "HighlightedProviderProps", "kind": "TypeAlias" }, - { "name": "HighlightedState", "kind": "TypeAlias" }, { "name": "HighlightElementClassKey", "kind": "TypeAlias" }, { "name": "HighlightItemData", "kind": "TypeAlias" }, { "name": "HighlightOptions", "kind": "TypeAlias" }, { "name": "HighlightScope", "kind": "TypeAlias" }, { "name": "isBarSeries", "kind": "Function" }, { "name": "isDefaultizedBarSeries", "kind": "Function" }, - { "name": "ItemHighlightedState", "kind": "TypeAlias" }, { "name": "labelClasses", "kind": "Variable" }, { "name": "labelGradientClasses", "kind": "Variable" }, { "name": "labelMarkClasses", "kind": "Variable" }, @@ -320,8 +315,8 @@ { "name": "useChartId", "kind": "Function" }, { "name": "useDrawingArea", "kind": "Function" }, { "name": "useGaugeState", "kind": "Function" }, - { "name": "useHighlighted", "kind": "Function" }, { "name": "useItemHighlighted", "kind": "Function" }, + { "name": "useItemHighlightedGetter", "kind": "Function" }, { "name": "useItemTooltip", "kind": "Function" }, { "name": "UseItemTooltipReturnValue", "kind": "Interface" }, { "name": "useLegend", "kind": "Function" }, diff --git a/scripts/x-charts.exports.json b/scripts/x-charts.exports.json index d23e021e2ab54..870e8f14743fc 100644 --- a/scripts/x-charts.exports.json +++ b/scripts/x-charts.exports.json @@ -172,17 +172,12 @@ { "name": "getPieCoordinates", "kind": "Function" }, { "name": "getReferenceLineUtilityClass", "kind": "Function" }, { "name": "getValueToPositionMapper", "kind": "Function" }, - { "name": "HighlightedContext", "kind": "Variable" }, - { "name": "HighlightedProvider", "kind": "Function" }, - { "name": "HighlightedProviderProps", "kind": "TypeAlias" }, - { "name": "HighlightedState", "kind": "TypeAlias" }, { "name": "HighlightElementClassKey", "kind": "TypeAlias" }, { "name": "HighlightItemData", "kind": "TypeAlias" }, { "name": "HighlightOptions", "kind": "TypeAlias" }, { "name": "HighlightScope", "kind": "TypeAlias" }, { "name": "isBarSeries", "kind": "Function" }, { "name": "isDefaultizedBarSeries", "kind": "Function" }, - { "name": "ItemHighlightedState", "kind": "TypeAlias" }, { "name": "labelClasses", "kind": "Variable" }, { "name": "labelGradientClasses", "kind": "Variable" }, { "name": "labelMarkClasses", "kind": "Variable" }, @@ -304,8 +299,8 @@ { "name": "useChartId", "kind": "Function" }, { "name": "useDrawingArea", "kind": "Function" }, { "name": "useGaugeState", "kind": "Function" }, - { "name": "useHighlighted", "kind": "Function" }, { "name": "useItemHighlighted", "kind": "Function" }, + { "name": "useItemHighlightedGetter", "kind": "Function" }, { "name": "useItemTooltip", "kind": "Function" }, { "name": "UseItemTooltipReturnValue", "kind": "Interface" }, { "name": "useLegend", "kind": "Function" },