Skip to content

Modal

A dialog that overlays the page for focused tasks — confirmations, forms, or detail views. It traps focus while open, locks page scroll, closes on backdrop click or Escape (unless made persistent), and wires up aria-labelledby / aria-describedby from its title and description.

Unlike the menu overlays, a Modal has no trigger sub-component — you control it with v-model. Open it by setting the bound value to true (typically from a button), and it closes itself via the close button, backdrop, or Escape.

Anatomy

Modal ← the dialog; controlled by v-model, sets size/persistence
├── ModalHeader ← title area (position the close button here)
│ ├── ModalTitle ← the heading (wires aria-labelledby)
│ ├── ModalDescription ← supporting text (wires aria-describedby)
│ └── ModalClose ← the × dismiss button
├── ModalContent ← the body
└── ModalFooter ← action buttons (Cancel / Confirm)

Every part is optional except Modal itself — include only what you need. The default slot exposes a close function for wiring footer actions.

Usage

Drive the modal with v-model; open it from a button.

BasicA modal with a header, body, and close button.

Use ModalFooter for actions, and the close slot prop to dismiss the modal from a button.

Footer actionsCancel and confirm buttons.

Sizes

The size prop controls the max width — sm through 5xl, plus full.

Sizessm, lg, and 2xl.

Persistent

Set persistent to prevent closing via backdrop click or Escape — the user must take an explicit action. Use sparingly, for cases where dismissing accidentally would lose work or skip a required choice.

PersistentCan

Props

PropTypeDefaultDescription
modelValuebooleanOpen state. Use with v-model. Required.
size"sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "full""md"Max width of the dialog.
closeOnBackdropbooleantrueWhether clicking the backdrop closes the modal.
persistentbooleanfalsePrevents closing via backdrop or Escape (the close button still works).
classstringClasses merged onto the dialog.

Emits update:modelValue and close. The default slot exposes close.

Sub-components

ComponentPurpose
ModalHeaderTitle-area container; position ModalClose inside it.
ModalTitleThe heading. Registers aria-labelledby on the dialog.
ModalDescriptionSupporting text. Registers aria-describedby.
ModalContentThe scrollable body.
ModalFooterRight-aligned action row.
ModalCloseThe × button (an icon Button). Dismisses via the modal context.

All sub-components accept class.

Accessibility

  • The dialog has role="dialog" and aria-modal="true". ModalTitle and ModalDescription automatically register aria-labelledby / aria-describedby, so include a ModalTitle for an accessible name.
  • Focus is trapped within the dialog while open and restored when it closes.
  • Page scroll is locked while open.
  • Escape closes the modal (unless persistent); ModalClose always works.