ConfirmPopover
Asks "are you sure?" next to the control that triggered it: a non-modal alertdialog anchored to the trigger with a question, an optional consequence and Cancel / confirm buttons.
Status: alpha. Group: overlay. Markdown version: /design-system/components/confirm-popover.md
When to use
Asks "are you sure?" next to the control that triggered it: a non-modal alertdialog anchored to the trigger with a question, an optional consequence and Cancel / confirm buttons.
When not to use
- Do not use it when the action can be undone; offer Undo instead.
- Do not put forms or long explanations inside; use Modal.
Look-alikes
- Modal: Do not put forms or long explanations inside; use Modal.
Props
| Prop | Type | Default | Description | Required |
|---|---|---|---|---|
children | React.ReactElement | none | The control that opens the confirmation, usually a Button. It keeps its own label and styling. | Yes |
title | string | none | The question, for example "Clear the answers in this section?". Names the dialog. With choices, it asks which one, for example "What do you want to clear?". | Yes |
description | string | none | What happens if the person confirms; describes the dialog. | No |
confirmLabel | string | none | Label of the confirming button; repeat the action, for example "Clear answers". Not used with choices, where each choice has its own. | No |
choices | ConfirmPopoverChoice[] | none | Several actions to pick from first; picking one asks "are you sure?" with that choice's question and labels. | No |
cancelLabel | string | translated "Cancel" | Label of the cancelling button. | No |
tone | "error" | "neutral" | neutral | "error" for actions that remove or destroy something. | No |
onConfirm | (choiceId?: string) => void | none | Called when the person confirms, with the picked choice's id when there are choices; the popover then closes. | Yes |
onOpenChange | (open: boolean) => void | none | Called when the popover opens or closes, whichever way. | No |
side | "top" | "right" | "bottom" | "left" | top | Preferred side of the trigger; flips when out of room. | No |
align | "center" | "start" | "end" | start | Alignment along that side. Not used with arrow, which always centres the popover on the trigger. | No |
arrow | boolean | false | Draws a pointer from the middle of the popover's edge to the trigger, like a speech bubble; side picks the edge (top, right, bottom or left) and the popover centres on the trigger. Off by default. | No |
shortcut | string[] | none | Keys that run the action without the popover, one entry per key; shown under the description as keycaps joined by plus signs. | No |
className | string | none | Extra class on the popover surface. | No |
Variants
- Available tones:
neutral,error(defaultneutral). - Allowed
sidevalues:top,right,bottom,left(defaulttop). - Allowed
alignvalues:center,start,end(defaultstart).
Invalid combinations
- SHOULD NOT: When
arrowis set andalignis one ofstart,end, then do not setalign. A speech-bubble pointer sits in the middle of the popover's edge, so the popover centres on the trigger and align is ignored. Drop align, e.g. <ConfirmPopover side="left" arrow />.
Keyboard
| Key | Behaviour |
|---|---|
| Enter / Space | On the trigger opens the popover. |
| General | Focus starts on Cancel, the safe choice; Tab moves between Cancel and confirm. |
| Escape | Cancels and returns focus to the trigger. |
Rules
Every item under When not to use is a MUST NOT. MUST and SHOULD follow RFC 2119.
| Level | Rule | How it is checked |
|---|---|---|
| SHOULD NOT | When arrow is set and align is one of start, end, then do not set align. A speech-bubble pointer sits in the middle of the popover's edge, so the popover centres on the trigger and align is ignored. Drop align, e.g. <ConfirmPopover side="left" arrow />. | Checked by the MCP tool validate_component_usage (rule confirmpopover-arrow-centres). Also enforced in code: ConfirmPopover.tsx development warning (arrow && align !== "center"). |
| MUST | ARIA: The popover is role="alertdialog", named by title and described by description. | Not yet verified: no evidence record. WCAG 4.1.2. |
| MUST | ARIA: The trigger exposes aria-expanded and aria-controls (Radix Popover). | Not yet verified: no evidence record. WCAG 4.1.2. |
| MUST | ARIA: A click outside cancels; focus returns to the trigger. | Not yet verified: no evidence record. WCAG 4.1.2. |
| MUST | Required stories produce no axe violations at the configured severity. | Automated by npm run test:stories:matrix:ci. WCAG 2.5.8. |
| MUST | The accessibility tree (role, name, state) matches the committed snapshot for every required story. | Automated by npm run test:stories:matrix:ci. WCAG 1.3.1, 4.1.2. |
| MUST | The component remains legible and operable under a real browser forced-colors: active pass. | Automated by npm run test:stories:hc. |
| MUST | Every documented keyboard interaction works as specified. | Not yet verified: no evidence record. WCAG 2.1.1, 2.1.2. |
Install and import
- In-repo only. ConfirmPopover is not exported from
@digitaltableteur/react, so there is no public import path. - Alpha components are internal and never exported.
Links
- Machine-readable contract (Design System Contract 1.0)
- Markdown version of this page
- Component index as JSON
- All components
- Source: The implementation lives in a private repository. This page, its Markdown twin and the contract are generated from it at build time and are the public source of truth.