Dialog

A popup that opens on top of the page and blocks interaction with it while modal.

WAI-ARIA pattern

Installation

npx nuecrea-ui add dialog

Usage

import { Button } from '@/components/ui/button';
import * as Dialog from '@/components/ui/dialog';

export default function DialogStory() {
  return (
    <main>
      <Dialog.Root>
        <Dialog.Trigger render={<Button variant="outline" />}>
          Delete project
        </Dialog.Trigger>
        <Dialog.Portal>
          <Dialog.Backdrop />
          <Dialog.Viewport>
            <Dialog.Popup>
              <Dialog.Title>Delete project?</Dialog.Title>
              <Dialog.Description>
                This permanently deletes the project and its files. This cannot be undone.
              </Dialog.Description>
              <div className="flex justify-end gap-2">
                <Dialog.Close render={<Button variant="outline" />}>
                  Cancel
                </Dialog.Close>
                <Dialog.Close render={<Button variant="destructive" />}>
                  Delete
                </Dialog.Close>
              </div>
            </Dialog.Popup>
          </Dialog.Viewport>
        </Dialog.Portal>
      </Dialog.Root>
    </main>
  );
}

API reference

Dialog.Root

Groups all parts and owns the open state.

PropTypeDefaultDescription
openboolean—Controlled open state.
defaultOpenbooleanfalseInitial open state when uncontrolled.
modalboolean | 'trap-focus'truetrue: traps focus, locks page scroll, blocks outside pointer interaction. 'trap-focus': traps focus only. false: none.
disablePointerDismissalbooleanfalsePrevents closing on outside press.
EventPayloadDescription
onOpenChangebooleanFired when the dialog requests to open or close. Angular: the `open` model's change event, so `[(open)]` works. React additionally passes eventDetails with the reason.
onOpenChangeCompletebooleanFired after the open or close animation finishes.

Dialog.Trigger

A button that opens the dialog. Renders <button>.

Data attributePresent when
data-popup-openthe dialog is open
data-disableddisabled

Dialog.Portal

Moves the backdrop and popup to the end of <body>. Renders <div>.

PropTypeDefaultDescription
keepMountedbooleanfalseKeeps the portal in the DOM while the dialog is closed.

Dialog.Backdrop

An overlay beneath the popup. Renders <div>.

Data attributePresent when
data-openopen
data-closedclosed
data-starting-styleanimating in
data-ending-styleanimating out

Dialog.Viewport

Positioning container for the popup; can be made scrollable. Renders <div>.

Data attributePresent when
data-openopen
data-closedclosed
data-nestednested in another dialog
data-nested-dialog-opena nested dialog is open
data-starting-styleanimating in
data-ending-styleanimating out

Dialog.Title

Heading that labels the popup (aria-labelledby). Renders <h2>.

Dialog.Description

Paragraph that describes the popup (aria-describedby). Renders <p>.

Dialog.Close

A button that closes the dialog. Renders <button>.

Data attributePresent when
data-disableddisabled

Keyboard

KeyAction
EscapeCloses the dialog.
TabMoves focus to the next tabbable element in the popup, wrapping.
Shift+TabMoves focus to the previous tabbable element in the popup, wrapping.