Dialog
SourceModal surfaces on base-ui. A blurred backdrop, a centered popup, a close button in the corner.
Overview
Compose the parts. Dialog holds state, DialogTrigger opens it, DialogContent renders the backdrop and the popup into a portal.
DialogHeader stacks the title and description, centered on phones and left-aligned from sm up. DialogFooter reverses its column on phones so the primary action sits on top, then rows the actions to the right from sm up.
The trigger and close parts render a native button with no face of its own. Put a Box inside for the visual, or pass render to swap the element.
Basic
Uncontrolled. The trigger opens, any DialogClose or the corner button closes, and Escape or a click on the backdrop closes too.
<Dialog>
<DialogTrigger>Open dialog</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Withdraw collateral</DialogTitle>
<DialogDescription>The position stays healthy after this.</DialogDescription>
</DialogHeader>
<Text variant="body">1.25 SOL leaves the vault.</Text>
<DialogFooter>
<DialogClose>Cancel</DialogClose>
<DialogClose>Withdraw</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>Controlled
Own the open state when something outside the dialog needs to close it, like a confirm handler.
Nothing confirmed yet
const [open, setOpen] = useState(false);
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger>Confirm something</DialogTrigger>
<DialogContent>
<DialogTitle>Sure?</DialogTitle>
<DialogFooter>
<DialogClose>Not now</DialogClose>
<button type="button" onClick={() => setOpen(false)}>Confirm</button>
</DialogFooter>
</DialogContent>
</Dialog>Backdrop content
overlayChildren renders inside the backdrop, behind the popup. overlayClassName and overlayStyle reach the same element.
<DialogContent
overlayChildren={<Text color="inverse">Rendered inside the backdrop</Text>}
>
...
</DialogContent>Dialog props
The root is base-ui's Dialog.Root. The common props are listed.
Controlled open state. Pair with onOpenChange.
Open on first render, uncontrolled.
Fires on open and close, with the reason.
Whether the page behind is inert. trap-focus keeps focus in without blocking pointer events outside.
DialogContent props
The popup body. The close button is appended after it.
Rendered inside the backdrop, behind the popup.
Bridge className for the backdrop. Tailwind product code only.
Inline style for the backdrop.
Bridge className for the popup. Tailwind product code only, it dies with the bridge.
Inline style for the popup, merged after the lens styles.
Where focus lands on open. Default is the first tabbable element.
Where focus returns on close. Default is the trigger.
DialogTitle props
The heading. Renders an h2 wired to the dialog's aria-labelledby.
Bridge className, appended after the lens styles.
DialogDescription props
One line under the title. Renders a p wired to aria-describedby.
Bridge className, appended after the lens styles.