base-ui
base-ui copied to clipboard
[dialog] Use html `dialog` element
Summary 💡
Since dialog element is supported across all browsers maybe it's time to refactor dialog to use the native <dialog/> tag?
Examples 🌈
👀
Motivation 🔦
https://caniuse.com/dialog
Search keywords:
Not sure, I think global usage also matters. We need to wait for atleast 90% global usage. Currently it is 82.98%.
What about now? 93%+ as of today.
As of today it's 94.18%
I'm willing to implement this myself, are there any blockers/issues?
We looked into this for https://github.com/mui/base-ui/pull/372. However, it looks to me that the <dialog> native primitive is not usable, not for a general purpose component design system.
The issues that seems to have no user land solutions, so deal breakers:
- I can't find content that proves that we can nest when using
<dialog>. It's an important use case in my experience for a library like Base UI https://github.com/whatwg/html/issues/9936. - Similar to 1. but without nesting. I can't find content on how to not make some part of the UI inert when a modal
- From https://2023.stateofhtml.com/en-US/usage/#html_functionality_features data, one data point I found valuable: "auto-focusing the first input works poorly when the first input is typically the 'close' button". Especially on mobile, it messes up the scroll. A bit related to https://github.com/whatwg/html/issues/1929. Adam shared this same point in https://youtu.be/XYjH_oQ3llg?si=zR8PgY9jeN8-WXHg&t=4568.
- Grammarly like extensions needs suggestion popup, they can't render above a
<dialog>
Hi, here are some thoughts
- Nesting
<dialog>is fine, the most recently opened modal is on top and all other items are inert (including the source modal). - It is possible to move elements that shouldn't be inert into the topmost modal using portals, here's an example: https://codesandbox.io/p/sandbox/modal-change-xpskc7.
- By having a container
divinside the modal with tabIndex -1 and outline:none you can force that div to be the focuses on modal open but not selectable with tab, (this is a trick we use a lot).
Related Issues:
- https://github.com/whatwg/html/issues/9075
- https://github.com/whatwg/html/issues/10370
- https://github.com/fkhadra/react-toastify/issues/959
- It is possible to move elements that shouldn't be inert into the topmost modal using portals, here's an example
This should be a no-go, the vendors have to make a change in their API, all that shady code to make something that is very simple (just show something on top of everything else even if it appeared earlier)
any updates on this?
FWIW we have been using native modal <dialog>s in production at Unsplash for over a year now, including nested dialogs. It works! We're also using Base UI components inside, e.g. popovers, menus, and tooltips (using portals to ensure they appear above/inside the top layer).
I thought I'd make a quick comparison between native dialog and base-ui dialog. I've used states but I don't think it would be too hard to plumb it into context.
Here's the demo: https://codesandbox.io/p/sandbox/native-dialog-9mqcp9.
Even if the native dialog worked correctly in most ways, we can't use it because 3rd party extension elements appear underneath it (e.g. Grammarly popups) and are inaccessible.
The dialog component needs to be fully general in that it interops with everything correctly. Unless all extension elements also use top-layer, it's not a viable solution for real world usage.
There was an issue https://github.com/whatwg/html/issues/9936 looking at helping alleviate some of the top-layers teething issues, I guess the more people that show interest in that the more likely there'll be some movement on it.
It feels a shame to have so much stuff done for us in the platform and not being able to implement it but I take your point.
FWIW we have been using native modal
@OliverJAsh The experience with Grammarly is broken on Unsplash:
https://github.com/user-attachments/assets/4252ee22-29be-489a-b304-4b2752a03805
Maybe to revert back to <div role="dialog"> 😁. It reported the issue to https://chromewebstore.google.com/reviews/9c74943a-2ebb-4f73-af5f-2b2945c97349.
Thanks for the report. I could be wrong but I believe it should be possible for Grammarly and other extensions to support native modal dialogs? If they insert their popups into the top layer (e.g. by monitoring the DOM for changes), they will appear on the top layer.
Native modal dialogs have been supported in browsers for a long time now. Grammarly needs to catch up.
Update: we (Unsplash) migrated to Base UI Dialog. Not because of Grammarly but we were tired of fighting with portals. I still hope one day Base UI will use native functionality under-the-hood (also for popovers). 🤞