AppConfirmDialog
A focused yes/no step that makes the user pause before a destructive or irreversible action.
<app-confirm-dialog id="del" title="Delete this project?" danger="true" />A confirm dialog is the short pause before something you can't easily undo — deleting a project, cancelling a subscription. <app-confirm-dialog> is the one way to ask "are you sure?": a centred status icon, the question, and two equal-width actions. It's built on the same modal chrome, so it inherits the focus trap, Escape, and focus restore.
Its look comes entirely from the shared @webority/theme, so the Razor <app-confirm-dialog> and the React <AppConfirmDialog> render identically. It's an overlay: open it from a trigger. In Razor that's any element carrying data-bs-toggle="modal" data-bs-target="#id".
Playground
Every attribute, live. Each change re-renders the real tag helper on the server, so the markup underneath is the exact call that produced the dialog above it.
loading="true" on while the dialog is open locks Cancel, the confirm button, and the backdrop/Escape path — the same as production. Toggle it back off (or reload) to get the dialog to release.Destructive confirm
Set danger for anything that removes or destroys data — it turns the icon and the confirm button red so the weight of the action is unmistakable.
Show code
<app-button variant="danger" data-bs-toggle="modal" data-bs-target="#scDeleteConfirm">Delete project</app-button>
<app-confirm-dialog id="scDeleteConfirm"
title="Delete this project?"
message="Assessments and reports attached to it will be removed. This cannot be undone."
confirm-label="Delete"
danger="true" />
danger="true" and label the button with the actual verb. The red styling and the named action are what stop an accidental click.Type to confirm
For the highest-stakes actions — deleting a workspace, wiping an account — confirm-phrase makes the user type an exact string before the confirm button unlocks.
Show code
<app-confirm-dialog id="scWipeConfirm"
title="Delete workspace?"
message='Type "acme-corp" to confirm.'
confirm-phrase="acme-corp"
confirm-label="Delete forever"
danger="true" />
Neutral confirm
Leave danger off for a reversible or benign confirmation — archiving, a one-off action. The icon and confirm button stay in the neutral primary tone.
Show code
<app-confirm-dialog id="scArchiveConfirm"
title="Archive this report?"
message="You can restore it later from the archive tab."
confirm-label="Archive" />
A custom illustration
Point image at your own artwork when the six tone illustrations do not say what this particular confirmation is about — a plan upgrade, an export, an onboarding step. It replaces the tone artwork; danger still decides the confirm button's colour.
image attribute. The first source file is 512px square, the second is 40px — and both land at exactly the size the built-in badge occupies, because the box is the theme's and only the artwork is yours. No resizing and no per-product CSS. When the footprint itself should change, see icon-size below.Show code
<app-confirm-dialog id="scImageBigConfirm"
title="Upgrade to Team?"
message="Everyone in your workspace gets the shared library."
image="/art/upgrade.svg"
confirm-label="Upgrade" />
aria-hidden with an empty alt, exactly like the tone artwork — the title and message carry the meaning for a screen reader. Say what the dialog is about in the title; do not rely on the picture to say it.Icon size
icon-size sets the illustration's width and height in px, for the tone artwork and a custom image alike. Unset, the badge is 120px with a message and 84px without one; set, the given size wins in both cases.
Show code
<app-confirm-dialog id="archive" title="Archive this report?" tone="warning" icon-size="48" /> <app-confirm-dialog id="upgrade" title="Upgrade to Team?" image="/art/upgrade.svg" icon-size="120" />
Loading
Set loading="true" while the confirmed action is in flight — the confirm button shows a spinner and locks, Cancel and any confirm-phrase field lock too, and the dialog stops closing on backdrop click or Escape until the action settles.
Show code
<app-confirm-dialog id="scLoadingConfirm"
title="Delete this project?"
message="Assessments and reports attached to it will be removed. This cannot be undone."
confirm-label="Delete"
danger="true"
loading="true" />
loading="true", Cancel is disabled and the modal carries data-bs-backdrop="static" data-bs-keyboard="false" — the backdrop and Escape no longer close it. Only the async action finishing (by toggling loading off) lets the user out.When to use
Use it when
- A destructive action needs a deliberate second step — delete, remove, cancel.
- An action is irreversible and you want the user to pause before it runs.
- The stakes are high enough to warrant typing an exact phrase to unlock (confirm-phrase).
Reach for something else when
- The dialog holds a form or details, not a yes/no question. → AppModal
- The action is trivial and easily undone. → an inline action + undo toast
- You're confirming across a slide-in panel of options. → AppSidebarMenu
Best practices
Every option
The whole surface of the component, one cell per value — every tone, both danger states, the type-to-confirm gate, custom copy, the busy and static-backdrop states, and both placements.
tone — every value, plus an unrecognized one
tone="success"
tone="error"
tone="warning"
tone="info"
tone="delete"
tone="primary"
tone="nonsense"
image — any source size, one footprint
image (512px source)
image (40px source)
image, no message
image + danger
danger — confirm button tone
danger="false"
danger="true"
confirm-phrase — type-to-confirm gate
confirm-phrase="acme-corp" (locked until typed)
confirm-label / cancel-label — custom copy
confirm-label="Delete forever"
cancel-label="Never mind"
loading, static-backdrop & placement
loading="true" (spinner, everything locked)
static-backdrop="true" (backdrop/Escape blocked, no loading)
placement="top"
size — card width (preset or custom px)
size="sm" (380)
size="md" (440, default)
size="lg" (640)
size="xl" (880)
size="720" (custom px)
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
| id | string | — | The dialog id a trigger points at with data-bs-target. |
| title | string | — | The question — a clear "Delete this project?". |
| message | string | — | The consequence — what happens if the user confirms. Inner content overrides it. |
| confirm-label | string | Confirm | Confirm button label — use the verb (Delete, Archive). |
| cancel-label | string | Cancel | Cancel button label. |
| danger | bool | false | Red styling for destructive actions. |
| confirm-href | string | — | If set, the confirm button is a link to this URL; otherwise a plain button carrying data-app-confirm to wire up. |
| tone | success | error | warning | info | delete | primary | — | Semantic tone for the icon + confirm button (React tone). |
| icon-size | int | — | Width and height of the illustration in px, for the tone artwork and a custom image alike. Unset: 120px with a message, 84px without. |
| image | string | — | URL of a custom illustration, shown in place of the tone artwork. Any source size works — the theme boxes it to the built-in badge's footprint. |
| confirm-phrase | string | — | Require typing this phrase before confirming (React confirmPhrase). |
| loading | bool | false | Busy state — spinner + disabled Confirm, disabled Cancel and confirm-phrase field, and blocks backdrop/Escape dismissal (React loading). |
| static-backdrop | bool | false | Backdrop click and Escape no longer close the dialog. loading already implies this; use it to require the lock independent of the busy state (React staticBackdrop). |
| placement | center | top | center | Vertical placement of the card — centred, or pinned near the top of the viewport (React placement). |
| size | sm | md | lg | xl | number | md | Card width — a preset (sm 380 / md 440 / lg 640 / xl 880) or an exact max-width in px. Resolved to the same width as app-modal (React size). |