-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[charts] Remove react spring #17123
[charts] Remove react spring #17123
Conversation
const time = now() - this.elapsed; | ||
|
||
this.timer = timer((elapsed) => this.timerCallback(elapsed), 0, time); | ||
timerFlush(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without timerFlush()
:
Screen.Recording.2025-03-25.at.08.37.47.mov
With timerFlush()
:
Screen.Recording.2025-03-25.at.08.38.02.mov
4960d5c
to
e95e201
Compare
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
ba4ee01
to
b8c3085
Compare
xOrigin: xScale(0) ?? 0, | ||
yOrigin: yScale(0) ?? 0, | ||
height: verticalLayout ? maxValueCoord - minValueCoord : barWidth, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how to handle this. Technically, defaulting this to 0 is wrong, but it's also wrong to assert as non-undefined because it can be.
To have proper types, I suppose we'd need to change the return value depending on the layout.
Open to suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const xOrigin = xScale(0)
if (!xOrigin) throw 💣
🤷
I think defaulting to 0 is reasonable enough, even though it could create issues, it shouldn't happen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we throw our tests will start failing. The thing is that we don't use the value in the cases where it doesn't make sense, so there's no issue. If we throw, we'll break our tests.
yOrigin, | ||
y, | ||
width, | ||
height: -8, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels a bit hacky because it requires knowledge of the implementation details of useAnimateBarLabel
.
I wonder if we should expose useAnimate
after all (or maybe a higher-level version of it?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's weird. Is it just to specify the initial value that you need this height: -8
If yes it might be easier to let user specify their own initial values.
Wy not having also the default initial height adapting to the layout like you do for x and y.
const initialProps = {
...,
height: props.layout === 'vertical' ? 0 : props.height
And if the -8 is here to hide the element, maybe the opacity
could be an extra label to animate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it just to specify the initial value that you need this height: -8
It's not about the initial value, it's about the end value actually. I've since updated this code, but it's still a bit weird.
By default we render the bar labels in the middle of the bar. In this demo I'm moving them to the top of the bar and keeping the animation, so that's why I need this hack.
If yes it might be easier to let user specify their own initial values.
That's another use case, but yeah, I'm considering exporting a slightly higher level version of useAnimate
.
I'll try to get a grasp of how something like that would look like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got confused because the y-axis goes from top to bottom 🙈
Maybe the solution for now is to not encourage users to create custom animation with those hook.
- User want to create a custom component because they need to add extra element: They can reuse the hook
- User want to customize the animation: They pick their own animation library
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created a higher-level useAnimateRef
hook here.
We might want to expose that one so that users can customize the animations using our "framework".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to expose that one so that users can customize the animations using our "framework".
I agree. My point was more about the timeline. This PR could have a docs with a simpler example. But I struggle to find an interesting one. I thought about a bar label with a rectangle behind it but it does seems as hacky as the current one because the useBarLabelAnimation
will only animate the x and y.
It seems that without hack, those hook are only to reproduce the exact same behavior as default components.
So maybe in this PR just documenting that user can use those hook to create their own version. And in another PR we will discuss the DX and
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So maybe in this PR just documenting that user can use those hook to create their own version. And in another PR we will discuss the DX and
Sure. So you're saying that we should ship this as is and then in a separate PR export a higher-level hook to be customizable by users, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CodSpeed Performance ReportMerging #17123 will improve performances by 58.76%Comparing Summary
Benchmarks breakdown
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. All the comments are more thoughts I got while reading than requests for changes
y={y} | ||
width={width} | ||
height={height} | ||
skipAnimation={skipAnimation ?? false} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
skipAnimation={skipAnimation ?? false} | |
skipAnimation={skipAnimation} |
Usually false has the same behavior as undefined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but the problem is that we're now exposing skipAnimation
through slots, so it might not be clear to users what undefined
means. IMO, we should always return either false
or true
.
Would it make sense to update useSkipAnimation
to reflect that? I think so. If you agree, I'll do that in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check, but IIRC we used undefined|true
because that was the ReactSpring api, now that we got rid of it, we can have undefined | boolean
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I didn't get that. What do you mean by it was the React Spring API? It seems we are the ones setting the type to true | undefined
in line 17 of AnimationProvider.tsx
.
Nevertheless, I wanted to know if we could just return boolean
from useSkipAnimation
, instead of boolean | undefined
. Basically, I need to know: what's the difference between undefined
and false
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum, then I'm not sure why. It could have been different behaviours between false vs undefined.
Returning boolean should be ok
yOrigin, | ||
y, | ||
width, | ||
height: -8, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got confused because the y-axis goes from top to bottom 🙈
Maybe the solution for now is to not encourage users to create custom animation with those hook.
- User want to create a custom component because they need to add extra element: They can reuse the hook
- User want to customize the animation: They pick their own animation library
x: number; | ||
xOrigin: number; | ||
y: number; | ||
yOrigin: number; | ||
width: number; | ||
height: number; | ||
layout: 'horizontal' | 'vertical'; | ||
skipAnimation: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a BarCommonProps
could help to define whihc porps are needed to draw an element (bar, barLabel, barClipPath)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initially this looked like a good idea to me, but the comments on each property are slightly different. BarClipPath
and BarElement
aren't exported, so we don't need to document their properties.
BarProps
and BarLabelProps
are exported, so we should document those. However, the comments aren't the same for properties with the same name:
BarProps
:
/**
* The position of the bar in the x-axis.
*/
x: number;
/**
* The position of the bar in the y-axis.
*/
y: number;
BarLabelProps
:
/**
* Position in the x-axis of the bar this label belongs to.
*/
x: number;
/**
* Position in the y-axis of the bar this label belongs to.
*/
So, I suppose it makes sense that they're duplicated? What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not thougth about JSDocs. Then I'm ok to keep it as it is
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. All the comments are more thoughts I got while reading than requests for changes
1e0a071
to
6d5675e
Compare
Co-authored-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> Signed-off-by: Bernardo Belchior <Bernardo.belchior1@gmail.com>
Co-authored-by: Jose C Quintas Jr <juniorquintas@gmail.com> Signed-off-by: Bernardo Belchior <Bernardo.belchior1@gmail.com>
65e2a55
to
2007381
Compare
It still happens but I just accepted the changes, the benefits are bigger than small text changes. It might be difference in render since we were probably using react:18 on docs prior to this pr. |
Fixes #16281.
Remove react-spring and replace it with CSS transitions or our
useAnimate
hook.Changelog
Removes
react-spring
as a dependency of@mui/x-charts
. A consequence of this change is that the props of some slots have been changed because theSpringValue
wrapper has been removed. The affected slots and props are:x
,y
,width
andheight
props of thebar
slot are nownumber
;startAngle
,endAngle
,innerRadius
,outerRadius
,arcLabelRadius
,cornerRadius
andpaddingAngle
props ofpieArcLabel
slot are nownumber
.