nori-ui

Dialog

Modal dialog with focus trap, scroll lock, escape-to-close, and click-outside.

5.2 kBgzipped

At a glance

  • Compose: Dialog, DialogTrigger, DialogContent, DialogTitle, DialogDescription, DialogClose, DialogFooter. Triggers and closes use asChild by default — wrap any element (Button, Link, custom Pressable) and it becomes the activator.
  • Cross-platform: uses RN <Modal> as the visibility primitive on every target. On web, additional effects layer on: focus trap, body scroll lock, Escape-to-close, click-outside-to-close, and focus restored to the trigger on close.
  • Accessibility: role="dialog" with aria-modal, aria-labelledby on the title, aria-describedby on the description.

Preview

Direction:
Locale:

Open state — open, defaultOpen, onOpenChange

open (controlled) + onOpenChange is the parent-driven shape; pass defaultOpen instead for uncontrolled mode when the Dialog should manage its own open state. Mixing the two prefers controlled and ignores defaultOpen. The Trigger and Close subcomponents flip the state for you, so most use sites don't need either prop.

// Uncontrolled — Trigger / Close manage open state.
<Dialog>
    <Dialog.Trigger><Button>Open</Button></Dialog.Trigger>
    <Dialog.Content>...</Dialog.Content>
</Dialog>
 
// Controlled — parent owns the state, useful for closing the dialog
// after an async save completes.
const [open, setOpen] = useState(false);
<Dialog open={open} onOpenChange={setOpen}>
    <Dialog.Trigger><Button>Open</Button></Dialog.Trigger>
    <Dialog.Content>...</Dialog.Content>
</Dialog>

Anatomy

SubcomponentRole
DialogRoot — owns open state (controlled or uncontrolled).
DialogTriggerElement that opens the dialog. asChild by default.
DialogContentThe visible surface. Renders only while open.
DialogTitleHeading. Wires aria-labelledby.
DialogDescriptionBody subtitle. Wires aria-describedby.
DialogCloseElement that closes the dialog. asChild by default; without children renders the canonical top-right ✕.
DialogFooterRight-aligned row for action buttons.

Props

Dialog

PropTypeDefaultDescription
defaultOpenbooleanfalseUncontrolled initial open state. @defaultValue false
onOpenChange(open: boolean) => voidFires with the new open state.
openbooleanControlled open state.

DialogTrigger

PropTypeDefaultDescription
asChildbooleantrueRender the child as the trigger (Slot pattern). Default true — pass `false` for an inline button.
classNamestring
testIDstring

DialogContent

PropTypeDefaultDescription
classNamestring
testIDstring

DialogClose

PropTypeDefaultDescription
accessibilityLabelstringClose
asChildbooleantrueRender the child as the close button (Slot pattern). Default true.
classNamestring
testIDstring

On this page

Preview theme