base-ui icon indicating copy to clipboard operation
base-ui copied to clipboard

[dialog] Use html `dialog` element

Open israelKusayev opened this issue 3 years ago • 11 comments

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:

israelKusayev avatar May 15 '22 13:05 israelKusayev

Not sure, I think global usage also matters. We need to wait for atleast 90% global usage. Currently it is 82.98%.

ZeeshanTamboli avatar May 16 '22 09:05 ZeeshanTamboli

What about now? 93%+ as of today.

PinkaminaDianePie avatar May 06 '23 11:05 PinkaminaDianePie

As of today it's 94.18%

I'm willing to implement this myself, are there any blockers/issues?

kosciolek avatar Jun 02 '23 17:06 kosciolek

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:

  1. 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.
  2. 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 is open, for example, when using Intercom, Drift.com, etc.
  3. 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.
  4. Grammarly like extensions needs suggestion popup, they can't render above a <dialog>

oliviertassinari avatar Jul 21 '24 16:07 oliviertassinari

Hi, here are some thoughts

  1. Nesting <dialog> is fine, the most recently opened modal is on top and all other items are inert (including the source modal).
  2. 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.
  3. By having a container div inside 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

Link2Twenty avatar Aug 27 '24 11:08 Link2Twenty

  1. 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)

raythurnvoid avatar Sep 30 '24 23:09 raythurnvoid

any updates on this?

mschwandt98 avatar May 02 '25 17:05 mschwandt98

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).

OliverJAsh avatar May 14 '25 14:05 OliverJAsh

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.

Link2Twenty avatar May 16 '25 19:05 Link2Twenty

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.

atomiks avatar May 16 '25 20:05 atomiks

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.

Link2Twenty avatar May 16 '25 20:05 Link2Twenty

FWIW we have been using native modal

s in production at Unsplash

@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.

oliviertassinari avatar Oct 11 '25 13:10 oliviertassinari

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.

OliverJAsh avatar Oct 11 '25 13:10 OliverJAsh

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). 🤞

OliverJAsh avatar Oct 15 '25 12:10 OliverJAsh