From d3853e36235462c32f9bf7dc5a72b4c94bf9fc84 Mon Sep 17 00:00:00 2001 From: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> Date: Thu, 26 Sep 2024 22:57:32 +0100 Subject: [PATCH] [charts] Fix area appearing (#14711) --- .../x-charts/src/LineChart/AnimatedArea.tsx | 32 +++---------- .../x-charts/src/LineChart/AnimatedLine.tsx | 40 +++------------- .../x-charts/src/LineChart/AppearingMask.tsx | 48 +++++++++++++++++++ 3 files changed, 60 insertions(+), 60 deletions(-) create mode 100644 packages/x-charts/src/LineChart/AppearingMask.tsx diff --git a/packages/x-charts/src/LineChart/AnimatedArea.tsx b/packages/x-charts/src/LineChart/AnimatedArea.tsx index f52f623159612..c88c8be9d585f 100644 --- a/packages/x-charts/src/LineChart/AnimatedArea.tsx +++ b/packages/x-charts/src/LineChart/AnimatedArea.tsx @@ -4,10 +4,9 @@ import PropTypes from 'prop-types'; import { styled } from '@mui/material/styles'; import { animated, useTransition } from '@react-spring/web'; import { color as d3Color } from '@mui/x-charts-vendor/d3-color'; -import { cleanId } from '../internals/cleanId'; import type { AreaElementOwnerState } from './AreaElement'; -import { useChartId, useDrawingArea } from '../hooks'; import { useStringInterpolator } from '../internals/useStringInterpolator'; +import { AppearingMask } from './AppearingMask'; export const AreaElementPath = styled(animated.path, { name: 'MuiAreaElement', @@ -45,20 +44,9 @@ export interface AnimatedAreaProps extends React.ComponentPropsWithoutRef<'path' */ function AnimatedArea(props: AnimatedAreaProps) { const { d, skipAnimation, ownerState, ...other } = props; - const { left, top, right, bottom, width, height } = useDrawingArea(); - const chartId = useChartId(); const stringInterpolator = useStringInterpolator(d); - const transitionAppear = useTransition([1], { - from: { animatedWidth: left }, - to: { animatedWidth: width + left + right }, - enter: { animatedWidth: width + left + right }, - leave: { animatedWidth: left }, - reset: false, - immediate: skipAnimation, - }); - const transitionChange = useTransition([stringInterpolator], { from: { value: 0 }, to: { value: 1 }, @@ -67,20 +55,12 @@ function AnimatedArea(props: AnimatedAreaProps) { immediate: skipAnimation, }); - const clipId = cleanId(`${chartId}-${ownerState.id}-area-clip`); return ( - - - {transitionAppear((style) => ( - - ))} - - - {transitionChange((style, interpolator) => ( - - ))} - - + + {transitionChange((style, interpolator) => ( + + ))} + ); } diff --git a/packages/x-charts/src/LineChart/AnimatedLine.tsx b/packages/x-charts/src/LineChart/AnimatedLine.tsx index c0e66f8e370ba..6c2eeb435102c 100644 --- a/packages/x-charts/src/LineChart/AnimatedLine.tsx +++ b/packages/x-charts/src/LineChart/AnimatedLine.tsx @@ -4,11 +4,9 @@ import PropTypes from 'prop-types'; import { animated, useTransition } from '@react-spring/web'; import { color as d3Color } from '@mui/x-charts-vendor/d3-color'; import { styled } from '@mui/material/styles'; -import { cleanId } from '../internals/cleanId'; import type { LineElementOwnerState } from './LineElement'; -import { useChartId } from '../hooks/useChartId'; -import { useDrawingArea } from '../hooks/useDrawingArea'; import { useStringInterpolator } from '../internals/useStringInterpolator'; +import { AppearingMask } from './AppearingMask'; export const LineElementPath = styled(animated.path, { name: 'MuiLineElement', @@ -48,22 +46,9 @@ export interface AnimatedLineProps extends React.ComponentPropsWithoutRef<'path' */ function AnimatedLine(props: AnimatedLineProps) { const { d, skipAnimation, ownerState, ...other } = props; - const drawingArea = useDrawingArea(); - const chartId = useChartId(); const stringInterpolator = useStringInterpolator(d); - const transitionAppear = useTransition( - [drawingArea], - { - from: (v) => ({ animatedWidth: v.left }), - enter: (v) => ({ animatedWidth: v.width + v.left + v.right }), - leave: (v) => ({ animatedWidth: v.width + v.left + v.right }), - reset: false, - immediate: skipAnimation, - }, - ); - const transitionChange = useTransition([stringInterpolator], { from: { value: 0 }, to: { value: 1 }, @@ -72,25 +57,12 @@ function AnimatedLine(props: AnimatedLineProps) { immediate: skipAnimation, }); - const clipId = cleanId(`${chartId}-${ownerState.id}-line-clip`); return ( - - - {transitionAppear((style) => ( - - ))} - - - {transitionChange((style, interpolator) => ( - - ))} - - + + {transitionChange((style, interpolator) => ( + + ))} + ); } diff --git a/packages/x-charts/src/LineChart/AppearingMask.tsx b/packages/x-charts/src/LineChart/AppearingMask.tsx new file mode 100644 index 0000000000000..cbf7a341f375e --- /dev/null +++ b/packages/x-charts/src/LineChart/AppearingMask.tsx @@ -0,0 +1,48 @@ +'use client'; +import * as React from 'react'; +import { animated, useTransition } from '@react-spring/web'; +import { cleanId } from '../internals/cleanId'; +import { useChartId, useDrawingArea } from '../hooks'; +import { SeriesId } from '../models/seriesType/common'; + +interface AppearingMaskProps { + id: SeriesId; + skipAnimation?: boolean; + children: React.ReactNode; +} + +/** + * @ignore - internal component. + */ +export function AppearingMask(props: AppearingMaskProps) { + const drawingArea = useDrawingArea(); + const chartId = useChartId(); + + const transitionAppear = useTransition( + [drawingArea], + { + from: (v) => ({ animatedWidth: v.left }), + enter: (v) => ({ animatedWidth: v.width + v.left + v.right }), + leave: (v) => ({ animatedWidth: v.width + v.left + v.right }), + reset: false, + immediate: props.skipAnimation, + }, + ); + + const clipId = cleanId(`${chartId}-${props.id}`); + return ( + + + {transitionAppear((style) => ( + + ))} + + {props.children} + + ); +}