Dialog
A modal surface that blocks the page until it is dismissed.
Dialog is the modal counterpart to Popover: it dims and blocks interaction with the rest of the page, traps focus, and returns focus to its trigger on close. Use it for a required step, a form, or anything the reader should not be able to dismiss by accident.
DialogTrigger pairs the trigger with the Dialog; the dialog opens on press
and closes on Escape or its own DialogCloseButton. An outside press does not
close it unless you pass isDismissable.
import { DialogTrigger, Heading } from 'react-aria-components';
import { Button } from '@base-org/bds-web/product/button';
import { Dialog, DialogCloseButton } from '@base-org/bds-web/product/dialog';DialogTrigger and Heading come from react-aria-components; BDS does not
re-export them.
<DialogTrigger>
<Button variant="primary">Open Dialog</Button>
<Dialog>
<div className="flex items-start justify-between gap-4">
<Heading slot="title" className="text-headline text-bds-gray-100">
Dialog title
</Heading>
<DialogCloseButton />
</div>
<p className="text-body text-bds-gray-60">Dialog content goes here.</p>
</Dialog>
</DialogTrigger>A Heading with slot="title" gives the dialog its accessible name
automatically; pass aria-label instead when there is no visible heading.
When to use
Use Dialog for a required step, a form, or a confirmation the reader must complete or dismiss on purpose.
Use something else when:
- The content is optional context to glance at. Use Popover.
- It only names a control. Use Tooltip.
- The message can sit in the page without blocking it. Use Banner.
Usage
Do
Reach for Dialog when the content blocks a flow the reader must complete or acknowledge — a form, a confirmation, a required choice.
Don't
Use a Dialog for content that is optional context the reader can glance at and dismiss. That belongs in a Popover, which does not block the rest of the page.
Content taller than the viewport scrolls inside the dialog without a scrollbar: the top or bottom edge fades while more content sits past it.
Props
| Prop | Type | Default |
|---|---|---|
classNameThe CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the | TypeClassNameOrFunction<ModalRenderProps> | Default— |
defaultOpenWhether the overlay is open by default (uncontrolled). | Typeboolean | Default— |
isDismissableWhether to close the modal when the user interacts outside it. | Typeboolean | Defaultfalse |
isEnteringWhether the modal is currently performing an entry animation. | Typeboolean | Default— |
isExitingWhether the modal is currently performing an exit animation. | Typeboolean | Default— |
isKeyboardDismissDisabledWhether pressing the escape key to close the modal should be disabled. | Typeboolean | Defaultfalse |
isOpenWhether the overlay is open by default (controlled). | Typeboolean | Default— |
roleThe accessibility role for the dialog. | Type"dialog" | "alertdialog" | Default'dialog' |
shouldCloseOnInteractOutsideWhen user interacts with the argument element outside of the overlay ref, | Type((element: Element) => boolean) | Default— |
UNSTABLE_portalContainerThe container element in which the overlay portal will be placed. This may have unknown | TypeElement | Defaultdocument.body |
DialogCloseButton
An icon button pre-wired to close the nearest Dialog or Popover. It reads the
open state from context, so it works without an explicit onPress. Its
accessible name defaults to "Close".
| Prop | Type | Default |
|---|---|---|
arrowAppends an animated chevron in place of `endIcon`. Its shaft draws in and | Typeboolean | Default— |
classNameThe CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the | TypeClassNameOrFunction<ButtonRenderProps> | Default— |
endIcon | TypeReactNode | ((renderProps: ButtonRenderProps) => ReactNode) | Default— |
externalArrowAppends a small ↗ in place of `endIcon` for links that leave the site, and | Typeboolean | Default— |
isDisabledWhether the button is disabled. | Typeboolean | Default— |
size | Type"sm" | "md" | "lg" | null | Defaultmd |
startIcon | TypeReactNode | ((renderProps: ButtonRenderProps) => ReactNode) | Default— |
status | Type"idle" | "pending" | "success" | Default— |
successIcon | TypeReactNode | Default— |
title | Typestring | Default— |
typeThe behavior of the button when used in an HTML form. | Type"button" | "submit" | "reset" | Default'button' |
variant | Type"outline" | "outline-negative" | "secondary" | "primary" | "negative" | "ghost" | "bare" | null | Defaultbare |
Accessibility
Dialog wraps React Aria's Modal and Dialog: it traps focus while open,
restores focus to the trigger on close, and dismisses on Escape unless
isKeyboardDismissDisabled is set. Outside presses dismiss it only when
isDismissable is set — leave it off for a required step.
Give it an accessible name via a slot="title" heading or an aria-label.
The panel scales up from 95% as it opens and leaves with a shorter, smaller fade. When the reader prefers reduced motion, it opens and closes without animating.