Ariakit
/

Radix Dialog

Creating a modal dialog primitive offering the same API as Radix UI but using the Ariakit Dialog component instead.

Open preview in a new tab
Edit withViteNext.js
import "./style.css";
import * as Dialog from "./dialog.jsx";
export default function Example() {
return (
<Dialog.Root>
<Dialog.Trigger asChild>
<button className="Button violet">Edit profile</button>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay className="DialogOverlay" />
<Dialog.Content className="DialogContent">
<Dialog.Title className="DialogTitle">Edit profile</Dialog.Title>
<Dialog.Description className="DialogDescription">
Make changes to your profile here. Click save when you&apos;re done.
<fieldset className="Fieldset">
<label className="Label" htmlFor="name">
Name
</label>
<input className="Input" id="name" defaultValue="Pedro Duarte" />
</fieldset>
<fieldset className="Fieldset">
<label className="Label" htmlFor="username">
Username
</label>
<input className="Input" id="username" defaultValue="@peduarte" />
</fieldset>
<div
style={{
display: "flex",
marginTop: 25,
justifyContent: "flex-end",
}}
>
<Dialog.Close asChild>
<button className="Button green">Save changes</button>
</Dialog.Close>
</div>
<Dialog.Close asChild>
<button className="IconButton" aria-label="Close">
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
strokeWidth={1.5}
width={24}
height={24}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</Dialog.Close>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
}

Components

Browser extensions and third-party dialogs

Ariakit Dialog inspired by Radix UI with keyboard focus on the username input showing the 1Password popup Ariakit Dialog inspired by Radix UI with part of the text selected showing the Google Translate popup

The Ariakit Dialog component seamlessly integrates with browser extensions that open popups, such as 1Password, Grammarly, Google Translate, and many others. This ensures that users can interact with the extension while keeping the modal dialog open, using both keyboard and mouse inputs. The same is true for third-party libraries that open dialogs.

For elements that are already in the DOM, the getPersisentElements prop can be used to specify which elements should remain accessible when the modal dialog is open. This is useful to integrate with chat widgets like Intercom, toast libraries like react-toastify and react-hot-toast, and more. See the Dialog with React-Toastify example for a practical use case.

Focus trap elements

Most component libraries render visually hidden elements around the modal dialog to prevent users from tabbing to elements outside. The Ariakit Dialog component follows a different approach: there are no focus trap elements. Instead, the elements that are not part of the modal context are given the inert attribute on browsers that support it. An alternative method is used on older browsers, but the result is the same.

This allows keyboard and screen reader users to Tab to the browser chrome, where they can interact with the URL address bar, or leave an iframe, which mouse users could do already.

This approach results in a behavior that is more consistent with the native dialog element. Unfortunately, the native dialog element still doesn't work with browser extensions when opened as a modal.

Scrollable backdrop

The Ariakit Dialog component automatically closes when users click outside the dialog. This behavior is controlled by the hideOnInteractOutside prop, which is enabled by default.

However, Ariakit will make sure the dialog is not closed when users interact with the scrollbar on a backdrop container. See the Dialog with scrollable backdrop example for a practical use case.

Follow updates

Join 1,000+ subscribers and receive monthly updates with the latest improvements on Examples.

Read latest issue

No Spam. Unsubscribe at any time.