/// Overlay
Popconfirm
A small confirm bubble anchored to its trigger — a title plus confirm/cancel — for low-stakes actions that still deserve a second tap.
import { Popconfirm } from "@protocore/pds";Basics
Wrap the control that triggers the action. The bubble opens anchored to it with a title, an optional description, and confirm/cancel buttons. Confirming or cancelling closes the bubble and leaves the trigger in place.
Placement
side (top default, right, bottom, left) and align position the bubble against the trigger; placement is collision-aware and flips to stay on screen.
When to use it
A Popconfirm is the inline gut-check for a reversible or low-consequence action — remove a filter, revoke a dev key, discard a draft — where a full modal would be too heavy but a bare click is too easy to trigger by accident. It keeps the user in context, right next to the button they pressed.
Escalate to an [AlertDialog](/overlay/alert-dialog) or [ModalsProvider](/overlay/modals-provider) openConfirm when the action is genuinely destructive and irreversible — a centered, backdropped prompt commands more attention than a bubble. Use a plain [Popover](/overlay/popover) when you need arbitrary anchored content rather than a yes/no decision.
Usage
Do
- Use it for low-stakes, reversible actions next to their trigger.
- Set tone="danger" for removals so the confirm button reads as destructive.
- Keep the title to a single question; add one line of description if needed.
- Wrap the real trigger control as the child — it becomes the anchor.
Don't
- Use a bubble for irreversible, high-blast-radius actions — reach for AlertDialog.
- Cram a form into it; it's a yes/no decision, not a panel.
- Stack a Popconfirm on top of another overlay.
- Write a paragraph in the title — that's what description is for.
Accessibility
| Keys | Action |
|---|---|
| Enter / Space | On the trigger, opens the bubble. |
| Tab | Moves between the cancel and confirm buttons. |
| Esc | Closes the bubble without confirming. |
- The bubble is role=alertdialog, labelled by its title and described by its description.
- Built on Radix Popover: focus moves into the bubble and returns to the trigger on close.
- Both actions are real buttons — keyboard-reachable and screen-reader friendly.
Popconfirm props
| Prop | Type | Default | Description |
|---|---|---|---|
align | enum | center | Alignment along that side. |
cancelLabel | string | Cancel | Label for the cancel action. |
children * | ReactNode | — | The control that opens the bubble — rendered via `asChild`. |
className | string | — | Extra class on the bubble panel. |
confirmLabel | string | Confirm | Label for the confirm action. |
defaultOpen | boolean | — | Uncontrolled initial open state. |
description | ReactNode | — | Optional supporting copy explaining the consequence. |
onCancel | (() => void) | — | Called when the user cancels (button or dismissal). |
onConfirm | (() => void) | — | Called when the user confirms. |
onOpenChange | ((open: boolean) => void) | — | Fires when the open state changes. |
open | boolean | — | Controlled open state. |
side | enum | top | Side of the trigger to render on. |
title * | ReactNode | — | Heading of the confirmation. |
tone | enum | danger | Severity of the confirm action — danger renders the destructive button. |