-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
[ShadCN] Migrate Modal component to ShadCN/Tailwind #14163
Conversation
✅ Deploy Preview for ethereumorg ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
f5592cd
to
0003319
Compare
ab4905e
to
3c246ef
Compare
Currently trying to leverage |
Great! thanks for the update @TylerAPfledderer. I'll have a closer look tomorrow. |
@pettinarip I've noticed an error in my approach that I'll have corrected soon. I should allow disclosure control to come purely from a parent of the modal, and consider including the dialog trigger in the renders if they aren't being used already. |
src/components/ui/dialog-modal.tsx
Outdated
<Center className="absolute end-0 top-0" asChild> | ||
<DialogPrimitive.Close className={close()}> | ||
<MdClose /> | ||
<span className="sr-only">Close</span> | ||
</DialogPrimitive.Close> | ||
</Center> |
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.
To give full control, perhaps we could avoid forcing this and declare it as part of the DialogClose
button.
Then, we could be more opinionated in the Modal structure and declare it as part of the header.
<DialogHeader>
<DialogTitle>{title}</DialogTitle>
<Center className="absolute end-0 top-0" asChild>
<DialogClose />
</Center>
</DialogHeader>
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 could use our Button
to wrap the close button to inherit the styles, right?
<DialogPrimitive.Close asChild>
<Button ...>...
</DialogPrimitive.Close>
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.
To give full control, perhaps we could avoid forcing this and declare it as part of the DialogClose button.
Can you clarify what you mean here? Are you referring specifically to DialogTitle
?
Hmmm I'm not sure either way about the use of Button
component. Best would be
<Button variant="ghost" isSecondary size="sm">
though here the size might be too small, but size="md"
is too tall compared to the figma file, and you would have to force overrides in the size.
contentProps?: DialogContentProps | ||
} | ||
|
||
const Modal = ({ |
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.
Nice. So, this export is to be backwards compatible with the previous instances, right?
Anyway, I think this abstraction makes sense to avoid repeating this code and have more consistency.
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.
Was thinking if this was the correct place to put it or in src/components/Modal.tsx
.
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.
Yea. Prop naming has changed slightly.
I currently have it here just to keep this isolated from the existing Modal
file along with having all of this isolated from the existing dialog
file while I try to figure out how all of it should be merged together.
src/components/ui/dialog-modal.tsx
Outdated
const dialogVariant = tv({ | ||
slots: { | ||
content: | ||
"data-[state=open]:animate-contentShow w-full fixed left-1/2 top-1/2 grid -translate-x-1/2 -translate-y-1/2 gap-4 rounded-md bg-white p-8 shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] focus:outline-none", |
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.
contentShow
? is that a built-in animation in TW?
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 is a utility that came from Radix as I was copy/pasting some default code. I'll review this.
@pettinarip Not sure what should be done here using this new modal for the wallet simulators. Per how logic works in radix between I could try and keep the current way the simulator modals are triggered, but could be become async with the intended approach in using this modal in other areas. Would at least keep this temporary At the time of this comment, I have not viewed other renders that are currently using the existing |
This component seems to require in its pattern to have the I could for now ignore this and maintain the controlled logic currently present. Not sure if there will be unintended results. |
Hey @TylerAPfledderer not sure if I follow you 100% on all you described but you can have a controlled Dialog without a DialogTrigger, its optional. At least in my tests, I didn't get any warnings or errors by doing that and having a fully controlled dialog. So, for the Simulator, this is how I see it // current layout
<grid>
<buttons>
<simulatormodal>
<template ...>
</simulatormodal>
</grid>
// new layout
<Dialog open={..}>
<grid>
<buttons />
<DialogContent>
<template ...>
</DialogContent>
</grid>
</Dialog> And if you were talking about keeping the same API as the SimulatorModal, then yes, I think we will have to adapt in each case. And I agree with you that this "adaptation work" might be better addressed in another PR. |
@pettinarip noting that I do not have any objection to your response, and currently addressing the areas using the current custom I would still consider revisiting this in a future PR in improving disclosure. |
@pettinarip I believe I am at a point for a proper review. I'm thinking that it should be left as a separate And aside from that, I think there still might be a benefit to using |
Cool, got it. I think we will need to leave both, the dialog and dialog-modal. The only chakra modal still pending would be the
Sounds good, are you planning on doing that in a different 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.
@TylerAPfledderer gj, this looks solid. I'll see if I can get a review from designers but looks ready to me.
I believe I didn't touch it because it was not connected to the original custom modal. (The modal is a direct import from Chakra) For how old this PR is now, I would look at that in a separate PR to not let this one linger for any longer than needed. And I would like to address the use of |
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.
@TylerAPfledderer on desktop it looks like everything is working fine but in mobile there are a few things left.
- You can't scroll if the content it too large. In some cases, even the close button is not visible.
- We had a margin before wrapping the modal container and you could see a bit of the dark overlay, do you think it is possible to replicate?
This happens in the quizzes page or in the simulator
PR
Minor request: could it be possible to make the close button icon a bit bigger? as we have in prod? is 32px in prod, in this PR is 16px.
Hey @pettinarip! My apologies in delay with in responding to your latest review. I will be taking a look at these two items right now. I do not expect any issue, but will notify you immediately if I run into a problem I cannot find a quick solution for. I will also review the design in Figma. I'll let you know if I happen to see any discrepancy there vs. prod |
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.
@pettinarip I made updates with comments provided. The comment regarding scroll needs a recommendation, as this PR is not complete at this point.
src/components/ui/dialog-modal.tsx
Outdated
/** | ||
* `size-[calc(-2rem_+_100%)]` provides 16px x- and y-spacing | ||
* around the container instead of using `margin` to | ||
* avoid positioning side-effects. | ||
* (The container is fixed-positioned) | ||
* | ||
* Credit: Chakra v2 takes a similar approach for modal | ||
*/ |
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.
Comment regarding using of calc
with height and width instead of margin
to have spacing around the container when the viewport gets too small.
src/components/ui/dialog-modal.tsx
Outdated
* | ||
* Credit: Chakra v2 takes a similar approach for modal | ||
*/ | ||
"data-[state=open]:animate-contentShow size-[calc(-2rem_+_100%)] fixed left-1/2 top-1/2 grid -translate-x-1/2 -translate-y-1/2 gap-4 rounded-md bg-background p-8 shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] focus:outline-none z-modal overflow-auto", |
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.
Note that I add overflow-auto
here in conjunction to setting height
(see above comment) to allow for scroll when the container has a lot of content.
I'm torn here. When applying this quick fix, this creates space on the top and bottom around the container to prevent the container from hitting the edge of the screen. Prod does not have bottom spacing because the container is allowed to expand below the fold, and you are actually scrolling the rest of the container into view and not only the content.
The prod version allows for scrolling from below the fold into view because there is a wrapper around the container which is not present in the current usage of the radix component. I would have to create this wrapper manually and wrap DialogPrimitive.Content
. This would also need to update where the styling is assigned to here.
I prefer the UX of prod, but wanted to show you what my quick fix looks like. If you are in agreement to maintain what is in prod, should I address it here or in a separate PR? I do not see this as a big fix, but I don't want to bloat or extend the life of this PR any more than necessary.
Update: I saw in Chromatic that my approach resulted in a side-effect of expanding the height without a max. (you'll see this when you review) This is correct behavior, but should not be employed unless there is a max-height that should be defined from the design. I think this further justifies addressing how to approach adding the content wrapper I described above.
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.
Looking at this, I think this effect will be easier if we make the Overlay wrap the Content (right now it is a sibling which make it hard to place it).
Following this guide, we could do
// this
const DialogContent = () => {
return (
<DialogPortal>
<DialogOverlay>
<DialogPrimitive.Content>
{children}
</DialogPrimitive.Content>
</DialogOverlay>
</DialogPortal>
)
})
// instead of
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content />
</DialogPortal>
and then,
overlay => fixed inset-0 overflow-y-auto p-4
content => free, no positioning
Of course, this would be only for mobile screens, the previous styles should still apply to desktop resolutions.
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.
Ah I missed that. No problem!
{children} | ||
<Center className={close()} asChild> | ||
<DialogPrimitive.Close> | ||
<MdClose size="20" /> |
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 close button is different from prod, because the prod version comes from Chakra, which has it's own close icon, and different than MdClose
. Therefore, I chose to use react-icons size
prop to set a different value to match prod.
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!
No worries. This is a pretty heavy task. I left a comment about the mobile version. LMK if you agree on that. I think we are very close on this one. |
@pettinarip alright, that wrapping approach is better. Looks like Also made a comment in Chromatic regarding padding for the quiz modal (unless I ended up addressing it before you see it) |
@pettinarip Applied a missing style. Need the Quiz Modal snapshot reviewed. |
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.
Awesome @TylerAPfledderer! gj
Description
Migrate
Modal
component to ShadCN to build off of theDialog
component.Replaces only the instances of the
Modal
currently in prod.