-
-
Notifications
You must be signed in to change notification settings - Fork 32.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
[Accordion] Add Joy UI Accordion components #38164
Conversation
Netlify deploy preview@mui/joy: parsed: +2.08% , gzip: +2.01% Bundle size reportDetails of bundle changes (Toolpad) |
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.
Great to see movement on the accordion 👍
I wonder about the order we create this vs. the one in Base UI.
More ideas to push it further:
- For the animation duration, I think that
getAutoHeightDuration
could make a difference in how great it feels, Material UI is following this duration curve based on the height, to control the transition px/s
- We will likely need
overflowAnchor
- I think that we will need to consider the performance implication of mounting the whole accordion details list.
- This makes me think that we could start to support Support for prefers-reduced-motion #16367
adding @DiegoAndai to the loop, as the owner of the Accordion component (we are in draft mode now, so no need to review, I came here from https://twitter.com/siriwatknp/status/1684042706849505280).
> | ||
<Radio value="0.3s linear" label="Linear" /> | ||
<Radio value="0.4s ease" label="Easing" /> | ||
<Radio value="0.8s cubic-bezier(0.68, -0.6, 0.32, 1.6)" label="Bouncy" /> |
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.
It takes 277ms for the accordion to start moving, I don't think that we can't have this transition curve, per https://web.dev/fid/#what-is-a-good-fid-score. For comparison, with Easing, I measure this at 27ms.
<Radio value="0.8s cubic-bezier(0.68, -0.6, 0.32, 1.6)" label="Bouncy" /> |
Instead, I think that we could have a small bounce at the end of the animation like https://dribbble.com/shots/20711653-Side-panel-framework-for-Opkey-s-no-code-automation-tool?
<Radio value="mix" label="Mix" /> | ||
</RadioGroup> | ||
<AccordionGroup | ||
transition={ |
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.
Would it be clearer if this was customized with CSS and the sx prop? Developer would have direct access to their CSS animation design tokens, like duration, easing, etc.
What problem does the transition
prop solve better?
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 thought about it as well. With transition
prop, developers don't have to remember and specify both properties grid-template-rows
and padding
.
Also, if you want to customize the transition for both initial and expanded state in CSS, you will need to do this:
<AccordionGroup
sx={{
// actually you don't need to use CSS variables here but the amount of code to write is likely the same.
'--AccordionDetails-transition': `grid-template-rows 0.2s, padding-block 0.2s`,
[`& .${accordionDetailsClasses.root}.${accordionDetailsClasses.expanded}`]: {
'--AccordionDetails-transition': `grid-template-rows 0.3s, padding-block 0.3s`,
},
}}
/>
whereas with transition prop:
<AccordionGroup
transition={{
initial: '0.2s',
expanded: '0.3s',
}}
/>
<ToggleButtonGroup | ||
size="sm" | ||
buttonFlex={1} | ||
value={size} | ||
onChange={(event, newValue) => setSize(newValue)} |
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.
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.
How to reproduce 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.
Screen.Recording.2023-08-05.at.19.16.24.mov
https://deploy-preview-38164--material-ui.netlify.app/joy-ui/react-accordion/#sizes
Oh, actually https://mui.com/material-ui/react-toggle-button/#exclusive-selection and https://mui.com/joy-ui/react-toggle-button-group/#editor-toolbar has the same bug? One of the text alignments must be active at all times. It's covered in https://mui.com/material-ui/react-toggle-button/#enforce-value-set. Maybe we need a prop for 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.
Hmm, I don't think so. We should let developers handle by themselve.
setTransition(event.target.value); | ||
}} | ||
> | ||
<Radio value="0.3s linear" label="Linear" /> |
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 easing makes me feel uncomfortable. What if instead, we were slowing the default animation (for illustration)? And/Or have it to be instant to illustrate prefers-reduced-motion
?
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 think the default animation/transition is out of scope from this PR that's why the demo illustrates how to add transitions.
@zanivan mentioned the default transition for Joy as well and I think it should be done separately so that each component does not need to wait to roll out.
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 think adding default animations/transitions to Joy UI would be really helpful. It could improve the microinteractions on components and potentially become a standout feature that sets Joy UI apart from competitors. Also, if we incorporate the Joy UI design language into Base UI, it would further differentiate the two products.
All in all, I think we can polish out a bit these animations, the easing is indeed a bit off, mostly on the bouncing demo—at least for me. Are there any workarounds to improve these animations before coming up with the default transition?
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 think the default animation/transition is out of scope from this PR that's why the demo illustrates how to add transitions.
@siriwatknp Ah sorry, I used the wrong terminology. By "default animation", I meant the one applied on the demo. I didn't consider the animation of the component bare.
But actually, this connects well to point 1. in #38164 (review). This feels OK, maybe a 10% faster would be good (to move to great, I think it would take a different easing IMHO):
Screen.Recording.2023-08-05.at.19.23.16.mov
and this feels too fast; 40% slower would be good (to move to great, I think it would take a different easing IMHO):
Screen.Recording.2023-08-05.at.19.25.07.mov
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 think we can also see this bug in this animation: the children isn't stable, "The Accordion Group supports the…" moves during the transition. So to start reading the content, you have to wait for the whole transition to finish
Screen.Recording.2023-08-05.at.19.31.20.mov
To compare with how it feels stable, e.g. https://ui.shadcn.com/docs/components/accordion. I feel stable is better UX.
…accordion-component
For the Accordion to match WAI ARIA guide, using an internal hook from
Got it.
Why? I think there will be a rare case to think in terms of performance which I think we can leave to the developer to decide. |
@siriwatknp I think it's the same problem as in #21250. I think that the default of mounting everything is best, agree. The point I lead to is: How can developers unmount what's not visible with Joy UI without breaking animations? Radix UI has the forceMount prop, by default it unmounts, and when applied to mounts: https://www.radix-ui.com/docs/primitives/components/accordion & https://codesandbox.io/p/sandbox/wizardly-zeh-dp5ng6?file=%2FApp.jsx%3A13%2C1.
It fixed this strange bug: #22152.
I was thinking of it in terms of priority. The alternative route would be to open this PR on Base UI first, and then Joy UI. |
@zanivan Updates:
|
|
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.
A quick review:
- We could add the playground back, at least, why not.
- In the size demo, I was a bit surprised to see the typography change as well, I don't know, I feel should we want to control spacing and typography size independently.
- Rebasing on HEAD could be nice, to pull in the latest changes
- https://github.com/mui/material-ui/issues/38037#issuecomment-1678190180
- I linked this PR to the Base UI issue, so that the community, if they decide to take on Base UI accordion can more easily find the work we did here.
- I wish we had more demo previews. Maybe 3 accordion isn't compatible with this (too much vertical space), but it would work with 2.
- We could add
ComponentLinkHeader
- https://github.com/mui/material-ui/issues/38037#issuecomment-1678200974
component = 'div', | ||
color = 'neutral', | ||
children, | ||
indicator = <KeyboardArrowDown />, |
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 React element could be hoisted.
/** Class name applied when the accordion is disabled. */ | ||
disabled: string; | ||
/** Class name applied when the accordion is expanded. */ | ||
expanded: string; |
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.
The disabled
and expanded
classes are Accordion
classes, why add them here as well?
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.
For styling purposes, without these classes, you will have to theme the AccordionSummary
like this:
extendTheme({
components: {
JoyAccordion: {
styleOverrides: {
root: {
[`.${accordionClasses.root}.${accordionClasses.expanded} &`]: {
…styles
}
}
}
}
}
})
whereas
extendTheme({
components: {
JoyAccordion: {
styleOverrides: {
root: {
[`&.${accordionSummaryClasses.expanded}`]: {
…styles
}
}
}
}
}
})
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 agree it's easier, but if we do it for the AccordionSummary
component, shouldn't we do it for the other accordion components as well?
AccordionDetails
hasexpanded
but notdisabled
AccordionGroup
has neither
We should either add the classes to all or none. Otherwise, it might be confusing.
I would only have these on the root, I think the following is not a bad API:
extendTheme({
components: {
JoyAccordion: {
styleOverrides: {
root: {
[`.${accordionClasses.expanded} &.${accordionSummaryClasses.root}`]: {
…styles
}
}
}
}
}
})
I brought back the Usage demo and apply the variant to other components when it is solid. Also, fix the demo you mentioned. |
5bbe4bf
to
db26aa1
Compare
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.
Added some small tweaks to a demo, but it looks good to me! 🚀
Preview: https://deploy-preview-38164--material-ui.netlify.app/joy-ui/react-accordion/
closes #36281. We have to roll a custom implementation as Base UI isn't available mui/base-ui#25 yet.
The Accordion family reuses styles from the List family.
Joy UI Accordion uses CSS Grid for the accordion detail to let developers use CSS transition to animate the open/closed state.