Skip to content

Dialog

A modal dialog. Zag handles the focus trap, scroll lock, and dismissal (escape / click-outside).

html
<div data-controller="zag-dialog">
  <button
    data-part="trigger"
    class="bg-destructive hover:bg-destructive/90 focus-visible:ring-destructive rounded-lg px-4 py-2 text-sm font-medium text-white shadow-sm transition focus:outline-none focus-visible:ring-2"
  >
    Delete account
  </button>

  <!-- `hidden` keeps the dialog shut before the controller connects; Zag clears it on open. -->
  <div data-part="backdrop" hidden class="fixed inset-0 z-50 bg-black/50 transition-opacity"></div>
  <div data-part="positioner" hidden class="fixed inset-0 z-50 grid place-items-center p-4">
    <div
      data-part="content"
      hidden
      class="bg-popover w-full max-w-md rounded-xl p-6 shadow-xl focus:outline-none"
    >
      <h2 data-part="title" class="text-foreground text-lg font-semibold">Delete account?</h2>
      <p data-part="description" class="text-muted-foreground mt-2 text-sm">
        This permanently removes your account and all its data. This action can’t be undone.
      </p>
      <div class="mt-6 flex justify-end gap-2">
        <button
          data-part="close-trigger"
          class="border-input text-foreground hover:bg-accent rounded-lg border px-4 py-2 text-sm font-medium"
        >
          Cancel
        </button>
        <button
          class="bg-destructive hover:bg-destructive/90 rounded-lg px-4 py-2 text-sm font-medium text-white"
        >
          Delete
        </button>
      </div>
    </div>
  </div>
</div>

TIP

Author hidden on backdrop, positioner, and content so the dialog stays shut before the controller connects — Zag clears it on open. Pair it with the global [hidden] { display: none !important; } rule (see Styling).

Parts

trigger, backdrop, positioner, content, title, description, close-trigger.

Values

AttributeTypeDefaultDescription
data-zag-dialog-open-valueBooleanfalseOpen by default.
data-zag-dialog-role-valueString"dialog""dialog" or "alertdialog".
data-zag-dialog-modal-valueBooleantrueTrap focus and mark the rest inert.
data-zag-dialog-close-on-escape-valueBooleantrueClose on the Escape key.
data-zag-dialog-close-on-interact-outside-valueBooleantrueClose when clicking outside the content.
data-zag-dialog-prevent-scroll-valueBooleantrueLock body scroll while open.
data-zag-dialog-trap-focus-valueBooleantrueKeep focus within the dialog.

Events

Emits zag-dialog:changedetail is { open }.

Programmatic control

open(), close(), isOpen.