Dialog
A popup that opens on top of the entire page.
API reference
Import the component and place its parts the following way:
import { Dialog } from '@base-ui-components/react/dialog';
<Dialog.Root>
<Dialog.Trigger />
<Dialog.Portal>
<Dialog.Backdrop />
<Dialog.Popup>
<Dialog.Title />
<Dialog.Description />
<Dialog.Close />
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
Root
Groups all parts of the dialog. Doesn’t render its own HTML element.
Prop | Type | Default | |
---|---|---|---|
defaultOpen | boolean | false | |
dismissible | boolean | true | |
modal | boolean | true | |
onOpenChange | (open, event) => void | undefined | |
open | boolean | undefined |
Trigger
A button that opens the dialog.
Renders a <button>
element.
Prop | Type | Default | |
---|---|---|---|
className | string | (state) => string | undefined | |
render | | React.ReactElement | undefined |
Attribute | Description | |
---|---|---|
data-popup-open | Present when the corresponding dialog is open. |
Portal
A portal element that moves the popup to a different part of the DOM.
By default, the portal element is appended to <body>
.
Prop | Type | Default | |
---|---|---|---|
container | React.Ref | HTMLElement | null | undefined | |
keepMounted | boolean | false |
Backdrop
An overlay displayed beneath the popup.
Renders a <div>
element.
Prop | Type | Default | |
---|---|---|---|
className | string | (state) => string | undefined | |
keepMounted | boolean | false | |
render | | React.ReactElement | undefined |
Attribute | Description | |
---|---|---|
data-closed | Present when the dialog is closed. | |
data-ending-style | Present when the dialog is animating out. | |
data-open | Present when the dialog is open. | |
data-starting-style | Present when the dialog is animating in. |
Popup
A container for the dialog contents.
Renders a <div>
element.
Prop | Type | Default | |
---|---|---|---|
className | string | (state) => string | undefined | |
finalFocus | React.Ref | undefined | |
initialFocus | | React.Ref | undefined | |
keepMounted | boolean | false | |
render | | React.ReactElement | undefined |
Attribute | Description | |
---|---|---|
data-closed | Present when the dialog is closed. | |
data-ending-style | Present when the dialog is animating out. | |
data-nested-dialogs | Indicates how many dialogs are nested within. | |
data-open | Present when the dialog is open. | |
data-starting-style | Present when the dialog is animating in. |
CSS Variable | Description | |
---|---|---|
--nested-dialogs | Indicates how many dialogs are nested within. |
Title
A heading that labels the dialog.
Renders an <h2>
element.
Prop | Type | Default | |
---|---|---|---|
className | string | (state) => string | undefined | |
render | | React.ReactElement | undefined |
Description
A paragraph with additional information about the dialog.
Renders a <p>
element.
Prop | Type | Default | |
---|---|---|---|
className | string | (state) => string | undefined | |
render | | React.ReactElement | undefined |
Close
A button that closes the dialog.
Renders a <button>
element.
Prop | Type | Default | |
---|---|---|---|
className | string | (state) => string | undefined | |
render | | React.ReactElement | undefined |
Examples
State
By default, Dialog is an uncontrolled component that manages its own state.
<Dialog.Root>
<Dialog.Trigger>Open</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup>
<Dialog.Title>Example dialog</Dialog.Title>
<Dialog.Close>Close</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
Use open
and onOpenChange
props if you need to access or control the state of the dialog.
const [open, setOpen] = React.useState(false);
return (
<Dialog.Root open={open} onOpenChange={setOpen}>
<Dialog.Trigger>Open</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Popup>
<form
// Close the dialog once the form data is submitted
onSubmit={async () => {
await submitData();
setOpen(false);
}}
>
...
</form>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
);
It’s also common to use onOpenChange
if your app needs to do something when the dialog is closed or opened. This is recommended over React.useEffect
when reacting to state changes.
<Dialog.Root
open={open}
onOpenChange={(open) => {
// Do stuff when the dialog is closed
if (!open) {
doStuff();
}
// Set the new state
setOpen(open);
}}
>