Dialog
A modal window that overlays the page for focused tasks and content.
Usage
Dialog is a compound component built on Base UI's Dialog. The root holds the open state; the parts compose the trigger and the portalled, centered popup. By default it's modal (focus trapped, page behind blocked) and dismissible (an outside click or Escape closes it), and it draws a close button in the corner:
DialogTrigger— the button that opens the dialog. Userenderto project it onto your ownButton(or any element).DialogContent— the portalled, centered popup. It draws the card, backdrop, focus trap, and corner close button, and accepts the shared modal props below.DialogHeader— groups the title and description with consistent spacing.DialogTitle— an<h2>that labels the popup (aria-labelledby).DialogDescription— a<p>that describes it (aria-describedby).DialogBody— the main content region. It doesn't scroll on its own — for content taller than the viewport, wrap it in aScrollArea.DialogFooter— the actions; stacks on small screens and right-aligns in a row fromsmup.DialogClose— a button that dismisses the dialog; project it onto your ownButtonwithrender.
Use a Dialog for a focused task or piece of content that should interrupt the page — a form, a confirmation with detail, a media viewer. When the action is a high-stakes confirmation, reach for an Alert Dialog; when the overlay should slide in from an edge (or be swipeable on touch), use a Drawer; for a small, non-blocking panel anchored to a control, use a Popover.
Examples
Form dialog
The most common shape: a header, a body of Fields, and a footer of actions. Lay the form out in DialogBody and dismiss with DialogClose projected onto your buttons.
Sizing
DialogContent is w-150 (600px) by default. Override the width with a className — a responsive sm:w-100 / sm:w-200, a max-w-* cap, or a fixed w-*. Every dialog also carries max-w-full, so any width you set still shrinks to fit narrow screens. For height, the popup grows with its content up to the viewport; give it a fixed h-* only when you want a scrollable body that doesn't resize as content changes.
Scrollable content
For content taller than the viewport, give DialogContent a fixed height and let a ScrollArea own the overflow between a pinned header and footer. The header and footer stay put while the body scrolls.
Nested dialogs
A dialog can open another dialog. When the child opens, the parent retracts with the same animation as a close and the child takes its place as a fresh dialog — keeping its frosted frame over the original backdrop — so the two never have to line up in size. Closing the child brings the parent back. Each dialog keeps its own state; just nest the markup.
Controlled
Drive the open state yourself with open + onOpenChange (or stay uncontrolled with defaultOpen). Owning the state is what makes a multi-step flow work — this create-project wizard tracks the current step, gates Next until the name is filled, resets itself when the dialog closes (via onOpenChange), and closes programmatically from Create rather than a DialogClose. The result is handed back to the page, which swaps the trigger for a project card; delete it to start over.
RTL
Every Appica UI component supports right-to-left layouts out of the box. Set the dir attribute on a container (commonly your <html> element) so CSS logical properties resolve correctly, and wrap your tree in DirectionProvider so direction-aware behavior follows the same direction.
The header, body, and footer flip to read right-to-left, the footer's actions mirror to the leading edge, and the corner close button moves to the opposite corner. The popup portals to <body>, so it follows the document direction — when you scope RTL to a subtree of an LTR page, set dir="rtl" on DialogContent so the popup mirrors too. For setup details and caveats, see the RTL guide.
API reference
Dialog wraps Base UI's Dialog. Each part forwards every remaining prop to the matching Base UI primitive, so anything it accepts works here — the tables below list the Appica additions and the most common props. See the Base UI docs for the complete API.
Dialog
The root. Holds the open state; renders no DOM of its own.
DialogTrigger
The button that opens the dialog. Forwards Base UI's Dialog.Trigger; use render to project it onto your own element.
DialogContent
The portalled, centered popup. Draws the card, backdrop, focus trap, and corner close button, and maps the underlying Base UI Portal / Backdrop / Viewport so you don't have to reach into them. Shared with Alert Dialog and Drawer through the modal props. Defaults to a w-150 (600px) width — override with a className.
DialogHeader
A layout wrapper that groups the title and description with consistent padding and spacing.
DialogTitle
An <h2> that labels the popup. Rendering one sets the popup's aria-labelledby.
DialogDescription
A <p> that describes the popup. Rendering one sets the popup's aria-describedby.
DialogBody
The main content region between the header and footer. Flexes to fill the available height; it doesn't scroll on its own — wrap it in a ScrollArea for content taller than the viewport.
DialogFooter
A layout wrapper for the actions. Stacks them vertically on small screens and lays them out in a right-aligned row from sm up.
DialogClose
A button that closes the dialog. Forwards Base UI's Dialog.Close; project it onto your own element with render.
Accessibility
- The popup has
role="dialog"witharia-modal, andaria-labelledby/aria-describedbywired automatically fromDialogTitleandDialogDescription— always render a title. - Opening traps focus inside the popup; Escape and an outside click close it (set
disablePointerDismissalto keep it open on a backdrop click), and focus returns to the trigger. - With
modal(the default), scroll and interaction with the rest of the page are blocked while the dialog is open. Setmodal={false}for a non-blocking dialog that leaves the page interactive. - The corner close button carries an accessible label (
closeLabel, default"Close"); set it when your dialog needs more specific wording. - Popup enter/exit transitions are skipped when the user prefers reduced motion.