-
Couldn't load subscription status.
- Fork 5.3k
Migrate ExpandableInfo to Chakra
#8224
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
Migrate ExpandableInfo to Chakra
#8224
Conversation
ExpandableInfo to Chakra
src/components/ExpandableInfo.tsx
Outdated
| transition: { | ||
| when: "beforeChildren", | ||
| }, | ||
| const ExpandableInfo = forwardRef<IProps, "div">( |
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.
Wrapped component in the Chakra forwardRef to allow Chakra props to be used on this component at the parent level.
See run-a-node page when migrating the styled component to Chakra.
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.
Perfect. This could be something that we should enforce more on all of our components. To guarantee that we are forwarding the refs accordingly. 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'm sorry @pettinarip . I made a grave error in my explanation and needed to review forwardRef!! 😅
So yes, the forwardRef from Chakra is an enhanced version of React's forwardRef (Check out the source code)
However, the primary purpose of this version of forwardRef is to ensure the as prop is passed in at the parent level without type error should the given component need to be a different html element or consume a different component on a particular instance.
For example, if this component normally renders a div wrapping the contents but one of the parent components needs it to be an article in a given instance.
So doing this:
<ExpandableInfo as="article">Will not generate a type error.
See the extended documentation regarding the "as" prop
I now believe this is actually unnecessary here, because there is no negative impact to passing props at the parent level without forwardRef so long as the component props are typed correctly, no need for the as prop, and no need to pass reference at the parent level.
To go along with this topic, I'm aware of discussions regarding not to use React.FC because of the implicit typing, and I'm curious about your thoughts on this! 😄
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.
Cool, thanks for the explanation & resource links again.
When we did the TS migration, I didn't know about that discussion about React.FC. Later, I saw that CRA was removing the usage of it and it grab my attention. I'm not super deep into the details but I can say that I don't see too much value on using it tbh and totally agree that the implicit children prop is not desired.
This is something we could discuss in a GH issue if you have a strong opinion about it and you feel that we should change 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.
Thanks @pettinarip! I do not have a strong preference either way.
In fact current version of the FC does not type the children, so you have to explicitly type it either way!
The discussion is indeed old, and React 18 has helped out with this. The implementation of it for the purposes of these components has no impact either way, whether you do this:
const someComponent: React.FC<Type> = (props) =>or this:
const someComponent = (props: Type) =>But you would still have trouble using generic typing with it though, if any of the components were to use it.
I'm not aware if any of the components actually need that! 😄
I will revert back to React.FC from forwardRef as it is not needed here and the component will still accept incoming Chakra Props.
src/components/ExpandableInfo.tsx
Outdated
| duration: 0.1, | ||
| ref | ||
| ) => { | ||
| const { isOpen, getButtonProps, getDisclosureProps } = useDisclosure({ |
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 is used to provide accessibility for this component, should toggling expansion be used (forceOpen = false). getButtonProps holds all the necessary aria-* attributes for toggling, including aria-expanded and aria-controls.
getDisclosureProps Provides id prop for aria-controls and the hidden attribute, which is needed in conjunction with the accordion pattern from the WAI-Aria Authoring Practices
This of course is on contingent on if accordion behavior should still exist.
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 is great! thanks for the detailed explanation. Didn't know useDisclosure exported all those props for you, thats awesome 💪🏼
✅ ethereum-org-website-dev deploy preview ready
|
src/components/ExpandableInfo.tsx
Outdated
| </Center> | ||
| )} | ||
| </Stack> | ||
| <Collapse |
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.
Transition effect simplified to the single Collapse component, as all the fade-in/out effects are apart of the collapse 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.
This looks great @TylerAPfledderer nice job 💪🏼
I haven't tested the collapsing feature yet but one thing I've noticed is that in the https://ethereum.org/en/run-a-node/ page we have a width=90% that is not being applied now. Would suggest replacing the emotion component that is wrapping this component in that page with a chakra approach.
// current run-a-node.tsx page implementation
const StyledExpandableInfo = styled(ExpandableInfo)`
width: 90%;
align-self: center;
@media (max-width: ${({ theme }) => theme.breakpoints.m}) {
margin: 0;
width: 100%;
}
`
// migrate this to chakra as well
// now it would be something like
<ExpandableInfo
...
width="90%"
>
src/components/ExpandableInfo.tsx
Outdated
| duration: 0.1, | ||
| ref | ||
| ) => { | ||
| const { isOpen, getButtonProps, getDisclosureProps } = useDisclosure({ |
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 is great! thanks for the detailed explanation. Didn't know useDisclosure exported all those props for you, thats awesome 💪🏼
src/components/ExpandableInfo.tsx
Outdated
| transition: { | ||
| when: "beforeChildren", | ||
| }, | ||
| const ExpandableInfo = forwardRef<IProps, "div">( |
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.
Perfect. This could be something that we should enforce more on all of our components. To guarantee that we are forwarding the refs accordingly. What do you think?
| background: string | ||
| forceOpen: boolean | ||
| background: BackgroundProps["background"] | ||
| forceOpen?: 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.
👍🏼
src/components/ExpandableInfo.tsx
Outdated
| p="1.5rem" | ||
| mb="1rem" |
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.
In general, lets try to use as much as we can the Chakra scale system (for font sizes & spacing). To keep it consistent with the rest of the codebase and future design system.
| p="1.5rem" | |
| mb="1rem" | |
| p={6} | |
| mb={4} |
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 bad habit of mine. I'll be sure to keep this in mind for future changes and any other existing PRs! 😄
|
As to the width issue, I will go ahead an migrate the instance over in the |
|
@pettinarip to add to the issue with the styling from the There is also a There are a couple of [cleaner] approaches to ensure this is rendered properly and not lose the
// Somewhere before the return
const mdBelowQuery = useQuery({ below: 'md' })
//Then on the component
<ExpandableInfo
sx={{
[`@media ${mdBelowQuery}`] : {
mb: 0
}
>Which under the hood will render: @media (max-width: 48em) {
margin-bottom: 0
}The current problem I see is that the string from Let me know what you think about this! |
src/components/ExpandableInfo.tsx
Outdated
| <Heading | ||
| mt="0" | ||
| mb={1} | ||
| fontSize={{ base: "2xl", md: "2rem" }} |
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 you replaced md: "2rem" with md: 8 here, it will render 8px because the fontSize prop does not like 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.
Oh got it. My bad haha thought it was a spacing prop 🤪
|
@TylerAPfledderer thanks for the explanation. I think I prefer the most common approach for now ( |
I agree! 😅 |
|
@pettinarip should be good to go now with all changes! |
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.
lgtm! thanks @TylerAPfledderer
Description
This migrates the ExpandableInfo
Per discussion in Discord, there was the question about using the
Accordionprop for this component, but did not make sense to do so for accessibility because of it's current usage as only a forced-open iteration on a single page. So going by the existing functionality was considered the best course of action.See comments below for explanation on certain Chakra additions.
Related Issue
#6374