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);
}}
>