Skip to the content
BooleanPress UI

Overlay

Dialog

A window above the page for a focused task, such as editing a record. The page waits until it closes.

Import

import { Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from "@booleanpress/ui/dialog"

Usage

A dialog has a trigger, a title, and its content. DialogTitle names the dialog and DialogDescription describes it; both are read when it opens. DialogBody scrolls when the content is taller than the window, while the header and the footer stay in place.

import { Button } from "@booleanpress/ui/button"
import {
  Dialog,
  DialogBody,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@booleanpress/ui/dialog"

export function EditMailer() {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button>Edit mailer</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Edit mailer</DialogTitle>
          <DialogDescription>Change the name and the sender address.</DialogDescription>
        </DialogHeader>
        <DialogBody>…</DialogBody>
        <DialogFooter>
          <DialogClose asChild>
            <Button variant="outline">Cancel</Button>
          </DialogClose>
          <Button>Save</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}

size sets the width: sm (384 px), md (512 px, the default) or lg (672 px). To open it from code, control it with open and onOpenChange and leave out the trigger; focus then returns to the element that had it when the dialog opened.

Examples

Basic

A form in a dialog, with Cancel and Save.

Sizes

The three widths.

Long content

Content taller than the window scrolls inside DialogBody; the title and the actions stay visible.

Opened from code

No trigger: open and onOpenChange control it, and focus returns to the button that opened it.

Accessibility

Semantics
A div with role="dialog" and aria-modal="true", named by DialogTitle and described by DialogDescription. The rest of the page is hidden from assistive technology while it is open.
Labels
Every dialog needs a DialogTitle. If the design has no visible title, keep one for screen readers with className="sr-only". The × button's name comes from the provider's close string.
Focus
Focus moves into the dialog when it opens, Tab and Shift+Tab stay inside, and focus returns to the trigger when it closes. Without a trigger, it returns to the element that had focus when the dialog opened, or to returnFocusTo when that element is gone.
Known limits
  • One dialog at a time. A dialog can open a select or a popover, not a second dialog.

Keyboard

Keyboard
KeyBehaviour
EscapeCloses the dialog.
TabMoves to the next focusable element inside the dialog, wrapping from the last to the first.
ShiftTabMoves to the previous focusable element inside the dialog, wrapping from the first to the last.

API

Dialog

Renders Radix Dialog.Root and passes it every other prop.

Dialog props
PropTypeDefaultDescription
defaultOpenbooleanWhether it starts open, when it controls itself.
modalbooleanKeep it modal: the rest of the page cannot be reached while it is open. Leave it on.
onOpenChange((open: boolean) => void)Called with true or false when it opens or closes.
openbooleanWhether it is open, when you control it. Pair it with onOpenChange.

DialogBody

Renders a div and passes it every other prop.

DialogClose

Renders Radix Dialog.Close and passes it every other prop.

DialogClose props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.

DialogContent

Renders Radix Dialog.Content and passes it every other prop.

DialogContent props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.
deferPointerDownOutsidebooleanWhen true, a 'pointerdown' event outside of the layered element will wait for the interaction's click event before dispatching, allowing third-party code to stop propagation of later events and cancel dismissal.
forceMounttrueUsed to force mounting when more control is needed. Useful when controlling animation with React animation libraries.
onCloseAutoFocus((event: Event) => void)Event handler called when auto-focusing on close. Can be prevented.
onEscapeKeyDown((event: KeyboardEvent) => void)Event handler called when the escape key is down. Can be prevented.
onFocusOutside((event: FocusOutsideEvent) => void)Event handler called when the focus moves outside of the DismissableLayer. Can be prevented.
onInteractOutside((event: FocusOutsideEvent | PointerDownOutsideEvent) => void)Event handler called when an interaction happens outside the DismissableLayer. Specifically, when a pointerdown event happens outside or focus moves outside of it. Can be prevented.
onOpenAutoFocus((event: Event) => void)Event handler called when auto-focusing on open. Can be prevented.
onPointerDownOutside((event: PointerDownOutsideEvent) => void)Event handler called when the a pointerdown event happens outside of the DismissableLayer. Can be prevented.
returnFocusToReturnFocusTargetWhere focus goes on close when the element that opened the overlay no longer exists — for example after the confirmed action deleted the row it sat in.
showCloseButtonbooleantrueRender the × button.
size"sm" | "lg" | "md"mdMaximum width: 384, 512 or 672 px.

DialogDescription

Renders Radix Dialog.Description and passes it every other prop.

DialogDescription props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.

DialogFooter

Renders a div and passes it every other prop.

DialogFooter props
PropTypeDefaultDescription
showCloseButtonbooleanfalse

DialogHeader

Renders a div and passes it every other prop.

DialogOverlay

Renders Radix Dialog.Overlay and passes it every other prop.

DialogOverlay props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.
forceMounttrueUsed to force mounting when more control is needed. Useful when controlling animation with React animation libraries.

DialogPortal

Renders Radix Dialog.Portal and passes it every other prop.

DialogPortal props
PropTypeDefaultDescription
containerElement | DocumentFragment | nullSpecify a container element to portal the content into.
forceMounttrueUsed to force mounting when more control is needed. Useful when controlling animation with React animation libraries.

DialogTitle

Renders Radix Dialog.Title and passes it every other prop.

DialogTitle props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.

DialogTrigger

Renders Radix Dialog.Trigger and passes it every other prop.

DialogTrigger props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.

Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.

Data attributes: data-slot="dialog" (Dialog), data-slot="dialog-body" (DialogBody), data-slot="dialog-close" (DialogClose), data-slot="dialog-portal" (DialogContent), data-slot="dialog-description" (DialogDescription), data-slot="dialog-footer" (DialogFooter), data-slot="dialog-header" (DialogHeader), data-slot="dialog-overlay" (DialogOverlay), data-slot="dialog-portal" (DialogPortal), data-slot="dialog-title" (DialogTitle), data-slot="dialog-trigger" (DialogTrigger), and data-size.

Provider strings: close (BooleanUIProvider's strings).

Theming

The panel is a floating surface, like menus and popovers: --popover and --popover-foreground. Its height stops below the WordPress admin bar (--wp-admin--admin-bar--height).

The tokens its classes read. Change their values in your theme, and it follows.

Theme tokens
TokenUsed for
--backgroundbackground
--foregroundtext
--muted-foregroundtext
--popoverbackground
--popover-foregroundtext