Skip to content

AlertDialog ​

An alert dialog interrupts to ask a question with consequences — delete this, discard that. It is a Modal with its defaults turned around: clicking away does not dismiss it, because dismissing would answer the question by accident.

ts
import {
  AlertDialog,
  AlertDialogBackdrop,
  AlertDialogContainer,
  AlertDialogDialog,
  AlertDialogHeading,
  AlertDialogIcon,
} from "ropav";
alert-dialog-basic.vue
vue
<script setup lang="ts">
import {
  AlertDialog,
  AlertDialogBackdrop,
  AlertDialogBody,
  AlertDialogClose,
  AlertDialogContainer,
  AlertDialogDialog,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogHeading,
  AlertDialogIcon,
  Button,
} from "ropav";
</script>

<template>
  <AlertDialog>
    <Button variant="danger">Delete project</Button>

    <AlertDialogBackdrop>
      <AlertDialogContainer>
        <AlertDialogDialog class="dialog">
          <AlertDialogHeader>
            <AlertDialogIcon status="danger" />
            <AlertDialogHeading>Delete this project?</AlertDialogHeading>
          </AlertDialogHeader>

          <AlertDialogBody>
            <p class="note">Everything in it goes with it. This cannot be undone.</p>
          </AlertDialogBody>

          <AlertDialogFooter>
            <AlertDialogClose><Button variant="tertiary">Cancel</Button></AlertDialogClose>
            <AlertDialogClose><Button variant="danger">Delete</Button></AlertDialogClose>
          </AlertDialogFooter>
        </AlertDialogDialog>
      </AlertDialogContainer>
    </AlertDialogBackdrop>
  </AlertDialog>
</template>

<style scoped>
.dialog {
  @media (width >= 40rem) {
    max-width: 400px;
  }
}

.note {
  color: var(--rp-muted);
  font-size: var(--rp-text-sm);
  line-height: var(--rp-text-sm--line-height);
}
</style>

AlertDialogIcon takes a status and picks its own glyph and colours from it, so a destructive question does not need an icon chosen by hand.

The defaults that differ ​

is-dismissable is false and is-keyboard-dismiss-disabled is true. That is the whole point of reaching for this over a modal: both ways of leaving without answering are closed, so the reader has to choose one of the buttons.

Turn them back on only when there is a genuine cancel among the choices and losing the dialog costs nothing. If you find yourself doing that, a modal is probably the component you wanted.

Accessibility ​

  • Every alert dialog needs both buttons to say what they do. "OK" and "Cancel" on a delete confirmation put the decision in the heading and leave the buttons ambiguous; "Delete" and "Keep" carry it themselves.
  • AlertDialogHeading labels the dialog, and it should be the question. A reader hearing the heading alone should know what they are being asked.
  • The icon is decoration and carries no meaning of its own — a red glyph says nothing to a reader who cannot see it, so the words have to say "permanently".
  • With dismissal closed off, the buttons are the only way out. Make sure one of them is safe, and that it is the one focus lands on.

API ​

AlertDialog

PropTypeDefaultDescription
defaultOpenboolean—
isDisabledboolean—
isOpenboolean—
stateOverlayTriggerState—An open state held outside the dialog, for a caller driving several overlays from one place. Equivalent to passing isOpen and listening to openChange, and takes precedence over both.

Slots: default.

EventPayload
openChangeboolean
update:isOpenboolean

AlertDialogBackdrop

PropTypeDefaultDescription
isDismissablebooleanfalseWhether an interaction outside the dialog closes it. An alert dialog asks for a decision, so the default is the opposite of a modal's: dismissing it by clicking away would answer the question by accident.
isEnteringboolean—Forces the entry state on both elements, for a caller driving the animation itself.
isExitingboolean—Forces the exit state on both elements.
isKeyboardDismissDisabledbooleantrueWhether Escape leaves the question unanswered.
portalContainerstring | HTMLElementdocument.bodyWhere the dialog is rendered.
shouldCloseOnInteractOutside((element: Element) => boolean)—Filters which outside elements dismiss the dialog.
stylestring | CSSProperties—Inline style for the backdrop. Declared rather than left to fallthrough because the viewport custom properties are merged over it: the stylesheet sizes the dialog from them, and a caller's own style winning would leave it with no height at all.
variant"blur" | "opaque" | "transparent""opaque"How the page behind the dialog is treated.

Slots: default.

AlertDialogBody

Slots: default.

AlertDialogClose

Slots: default.

AlertDialogCloseTrigger

AlertDialogCloseTrigger takes nothing but class.

AlertDialogContainer

PropTypeDefaultDescription
placement"auto" | "bottom" | "center" | "top""auto"
size"xs" | "sm" | "md" | "lg" | "cover""md"

Slots: default.

AlertDialogDialog

The default slot receives:

Slot propType
close() => void

AlertDialogFooter

Slots: default.

AlertDialogHeader

Slots: default.

AlertDialogHeading

PropTypeDefaultDescription
levelnumber2Heading level.

Slots: default.

AlertDialogIcon

PropTypeDefaultDescription
status"default" | "accent" | "success" | "warning" | "danger""danger"The meaning the icon carries, which picks both its colours and its default glyph. Read per icon rather than from the dialog, so two icons in one dialog can say different things.

Slots: default.

AlertDialogTrigger

Slots: default.