Zephora UI

Overlay

Dialog

Accessible modal dialog rendered in a portal with backdrop, focus trap, Escape handling and body scroll lock. Composes with DialogHeader/Body/Footer, DialogTitle/Description and DialogClose.

Import

import { Dialog, DialogHeader, DialogBody, DialogFooter, DialogTitle, DialogDescription, DialogClose } from "@zephora/react";

Examples

Basic dialog

Control the open state with useState and `onOpenChange`.

Sizes

`size` scales the panel width: sm, md, lg, xl or full.

Blocking dialog

Disable outside-press and Escape dismissal for flows that need an explicit choice.

API

Dialog props

PropTypeDefaultDescription
openbooleanControlled open state.
defaultOpenbooleanfalseInitial open state (uncontrolled).
onOpenChange(open: boolean) => voidCalled whenever the dialog requests an open state change.
onClose(reason: "escape" | "overlay" | "close-button") => boolean | voidCalled before the dialog closes itself (Escape, backdrop press or DialogClose). Return false to cancel the close and keep it open.
size"sm" | "md" | "lg" | "xl" | "full""md"Panel width scale.
closeOnOverlayClickbooleantrueClicking the backdrop closes the dialog.
closeOnEscapebooleantruePressing Escape closes the dialog.
initialFocusRefRefObject<HTMLElement | null>Element focused when the dialog opens (defaults to the first focusable).
classNamesPartial<Record<DialogSlot, string>>Per-slot class overrides set once on the root: "root" (fixed positioner) | "backdrop" | "panel" (where className also lands) | "header" | "body" | "footer" | "title" | "description" | "close". Appended after the module classes and also applied in unstyled mode.
unstyledbooleanfalseHeadless mode — skips Zephora styling.

DialogHeader / DialogBody / DialogFooter props

PropTypeDefaultDescription
unstyledbooleanfalseHeadless mode for the layout region.
…restHTMLAttributes<HTMLDivElement>Native div props are forwarded.

DialogTitle / DialogDescription props

PropTypeDefaultDescription
unstyledbooleanfalseHeadless mode.
idstringOptional id; auto-generated otherwise and wired to the panel via aria-labelledby / aria-describedby.

DialogClose props

PropTypeDefaultDescription
childrenReactNodeCustom close glyph; defaults to an X icon.
aria-labelstring"Close"Accessible name of the close button.
unstyledbooleanfalseHeadless mode.

Keyboard

KeyAction
EscapeCloses the dialog (unless closeOnEscape is false).
Tab / Shift+TabCycles focus inside the panel — focus is trapped while open.