Popconfirm
Inline, anchored confirmation built on Popover with async confirm handling.
|
|
| Package |
@vizejs/ui/popconfirm |
| Maturity |
stable |
| Own the source |
vize lib pull popconfirm |
| Requires |
context, controllable-state, id, popover, positioner |
| Aliases |
popconfirm, inline confirm, confirm popover, are you sure |
| Covers |
Ant Design Popconfirm, Element Plus Popconfirm, WAI-ARIA alertdialog |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/ui
Add the public import below to <script setup lang="ts">. Components provide behavior without styles; the preview uses optional Paper styles.
import { Popconfirm, PopconfirmRoot, PopconfirmCancel, PopconfirmConfirm, PopconfirmContent, PopconfirmTrigger } from "@vizejs/ui/popconfirm";
Or copy the source into your project with vize lib pull popconfirm (see Source Distribution).
Try it
This is the basic example maintained with the component source, using the public package imports. The preview adds the optional Paper styles.
Open the interactive example · Styling these components
Copy the example
<!-- Delete button guarded by an anchored confirmation that runs an async handler before closing. -->
<script setup lang="ts">
import { ref } from "vue";
import {
Popconfirm,
PopconfirmCancel,
PopconfirmConfirm,
PopconfirmContent,
PopconfirmTrigger,
} from "@vizejs/ui/popconfirm";
const deleted = ref(false);
async function deleteDraft(): Promise<void> {
await Promise.resolve();
deleted.value = true;
}
</script>
<template>
<div>
<Popconfirm :on-confirm="deleteDraft">
<PopconfirmTrigger :disabled="deleted">Delete draft</PopconfirmTrigger>
<PopconfirmContent
title="Delete this draft?"
description="The draft and its attachments are removed permanently."
>
<PopconfirmCancel>Keep draft</PopconfirmCancel>
<PopconfirmConfirm>Delete</PopconfirmConfirm>
</PopconfirmContent>
</Popconfirm>
<output>{{ deleted ? "Draft deleted" : "Draft saved" }}</output>
</div>
</template>
API
Popconfirm
Source: src/families/overlays/popconfirm/popconfirm-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id. null and undefined select a deterministic fallback. |
open |
boolean |
undefined |
Controlled open state. undefined selects uncontrolled behavior. |
defaultOpen |
boolean |
false |
Initial open state for uncontrolled use. |
disabled |
boolean |
false |
Disable the trigger and close an open confirmation. |
onConfirm |
PopconfirmConfirmHandler |
undefined |
Confirmation handler (bind with @confirm). A returned promise keeps the confirmation open and pending; it closes on resolve and stays open on reject. |
Events
| Event |
Payload |
Description |
update:open |
[value: boolean] |
Fired when the Popconfirm requests a controlled open value. |
open-change |
[value: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request. |
confirmed |
[nativeEvent: Event | null] |
Fired after the confirmation handler succeeded and the popover closed. |
cancel |
[reason: PopconfirmCancelReason, nativeEvent: Event | null] |
Fired when the confirmation closed without confirming. |
error |
[reason: unknown] |
Fired when the confirmation handler threw or rejected; the popover stays open. |
Slots
| Slot |
Slot props |
Description |
default |
PopconfirmSlotState |
Trigger and content children. Receives the confirmation state. |
Exposed
| Member |
Type |
Description |
cancel |
— |
|
confirm |
— |
|
descriptionId |
— |
|
error |
— |
|
id |
— |
|
open |
— |
|
pending |
— |
|
setOpen |
— |
|
state |
— |
|
titleId |
— |
|
PopconfirmRoot
Source: src/families/overlays/popconfirm/popconfirm-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id. null and undefined select a deterministic fallback. |
open |
boolean |
undefined |
Controlled open state. undefined selects uncontrolled behavior. |
defaultOpen |
boolean |
false |
Initial open state for uncontrolled use. |
disabled |
boolean |
false |
Disable the trigger and close an open confirmation. |
onConfirm |
PopconfirmConfirmHandler |
undefined |
Confirmation handler (bind with @confirm). A returned promise keeps the confirmation open and pending; it closes on resolve and stays open on reject. |
Events
| Event |
Payload |
Description |
update:open |
[value: boolean] |
Fired when the Popconfirm requests a controlled open value. |
open-change |
[value: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request. |
confirmed |
[nativeEvent: Event | null] |
Fired after the confirmation handler succeeded and the popover closed. |
cancel |
[reason: PopconfirmCancelReason, nativeEvent: Event | null] |
Fired when the confirmation closed without confirming. |
error |
[reason: unknown] |
Fired when the confirmation handler threw or rejected; the popover stays open. |
Slots
| Slot |
Slot props |
Description |
default |
PopconfirmSlotState |
Trigger and content children. Receives the confirmation state. |
Exposed
| Member |
Type |
Description |
open |
boolean |
Whether the confirmation is open. |
state |
PopconfirmState |
Request lifecycle. |
pending |
boolean |
Whether an asynchronous confirmation is running. |
error |
unknown |
Rejection reason of the latest failed confirmation, or null. |
id |
string |
Root-owned base id. |
titleId |
string |
Id of the rendered title. |
descriptionId |
string |
Id of the rendered description. |
setOpen |
(value: boolean, event?: Event | null) => boolean |
Request an open value. Closing is refused while pending. |
confirm |
(event?: Event | null) => Promise<boolean> |
Run the confirmation handler. Resolves true when it succeeded and closed. |
cancel |
(event?: Event | null) => boolean |
Close without confirming. Refused while pending. |
PopconfirmCancel
Source: src/families/overlays/popconfirm/popconfirm-cancel.vue
Props
| Prop |
Type |
Default |
Description |
disabled |
boolean |
false |
Disable this action in addition to the pending state. |
Events
| Event |
Payload |
Description |
click |
[nativeEvent: MouseEvent] |
Fired before the action runs. Call preventDefault() to skip it. |
Slots
| Slot |
Slot props |
Description |
default |
PopconfirmSlotState |
Close without confirming. Disabled while a confirmation is pending. |
Exposed
| Member |
Type |
Description |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
focus |
— |
|
PopconfirmConfirm
Source: src/families/overlays/popconfirm/popconfirm-confirm.vue
Props
| Prop |
Type |
Default |
Description |
disabled |
boolean |
false |
Disable this action in addition to the pending state. |
Events
| Event |
Payload |
Description |
click |
[nativeEvent: MouseEvent] |
Fired before the action runs. Call preventDefault() to skip it. |
Slots
| Slot |
Slot props |
Description |
default |
PopconfirmSlotState |
Run the confirmation handler. Busy and disabled while it is pending. |
Exposed
| Member |
Type |
Description |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
focus |
— |
|
PopconfirmContent
Source: src/families/overlays/popconfirm/popconfirm-content.vue
Props
| Prop |
Type |
Default |
Description |
title |
string |
undefined |
Visible question used as the accessible name. The title slot overrides it. |
description |
string |
undefined |
Visible consequence text used as the accessible description. The description slot overrides it. |
initialFocus |
PopconfirmInitialFocus |
"cancel" |
Action focused when the confirmation opens. Cancel is the safe default for destructive confirmations. |
placement |
PopconfirmPlacement |
"top" |
Preferred placement relative to the trigger. |
to |
string | HTMLElement |
"body" |
CSS selector or element the layer is moved into. |
portalDisabled |
boolean |
false |
Render in place instead of teleporting. |
Slots
| Slot |
Slot props |
Description |
title |
PopconfirmSlotState |
Visible title. Receives the confirmation state. |
description |
PopconfirmSlotState |
Visible description. Receives the confirmation state. |
default |
PopconfirmSlotState |
Actions, normally PopconfirmCancel and PopconfirmConfirm. |
Exposed
| Member |
Type |
Description |
open |
boolean |
Whether the confirmation is open. |
state |
PopconfirmState |
Request lifecycle. |
pending |
boolean |
Whether an asynchronous confirmation is running. |
error |
unknown |
Rejection reason of the latest failed confirmation, or null. |
element |
HTMLDivElement | null |
Rendered popover element carrying role="alertdialog". |
PopconfirmTrigger
Source: src/families/overlays/popconfirm/popconfirm-trigger.vue
Props
| Prop |
Type |
Default |
Description |
disabled |
boolean |
false |
Remove the trigger from activation and sequential keyboard focus. |
ariaLabel |
string |
undefined |
Accessible name when no visible label supplies one. |
Slots
| Slot |
Slot props |
Description |
default |
PopconfirmSlotState |
Trigger contents. Receives the confirmation state. |
Exposed
| Member |
Type |
Description |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
focus |
— |
|
Behavior
Normative behavior for the @vizejs/ui/popconfirm compound primitive: an inline,
anchored confirmation built on the Popover family (root, trigger, positioned content,
dismissable layer, focus scope). Every row is proven by the named test.
| State x input |
Observable outcome |
Proven by |
| closed, trigger click |
The popover opens as role="alertdialog" labelled by the title and described by the description; Cancel receives focus. |
opens an alertdialog labelled by title and description with cancel focused |
initialFocus="confirm" |
The Confirm action receives initial focus ("none" leaves focus to the popover). |
initialFocus can target confirm or leave focus to the popover |
| open, Confirm with a synchronous handler |
The handler runs once, the popover closes, and confirmed plus update:open fire. |
synchronous confirm closes and emits confirmed |
| open, Confirm with a promise |
State becomes pending: both actions are disabled, Confirm and content report aria-busy, Escape cannot cancel; resolve closes and confirms. |
async confirm stays open and busy until the promise resolves |
| pending promise rejects, or the handler throws |
The popover stays open, actions re-enable, error fires with the reason, and content publishes data-error. |
rejected confirm stays open, exposes the error, and emits error |
| open, Cancel / Escape / outside pointer-down |
The popover closes without confirming and cancel reports cancel-button or dismiss. |
cancel button, Escape, and outside pointer-down cancel with a reason |
controlled open; root expose |
Requests emit update:open until the parent accepts; setOpen, confirm, cancel, ids, state, and error are exposed. |
controlled open and root expose drive the confirmation |
disabled root |
The trigger cannot open the confirmation. |
disabled roots keep the trigger inert |
| parts outside the root |
Mounting throws VIZE_UI_CONTEXT_MISSING. |
parts require a Popconfirm root |
| SSR |
Closed markup is byte-identical across requests and contains no content. |
renders byte-identical closed popconfirm markup across isolated requests |
hydration with defaultOpen |
Server markup already renders role="alertdialog" through PopoverContent's role prop; hydration emits no warnings. |
renders default-open alertdialog markup and hydrates without diagnostics |
| public types |
Handlers resolve to nothing; state, focus target, and cancel reason are closed unions. |
src/families/overlays/popconfirm/popconfirm.types.test-d.ts |
Components
| Component |
State x input |
Outcome |
popconfirm-root.vue |
open requests, confirm handler |
Wraps PopoverRoot, owns idle/pending state and the last error, refuses to close while pending. |
popconfirm-trigger.vue |
click |
Renders PopoverTrigger with data-vize-ui="popconfirm-trigger". |
popconfirm-content.vue |
open, pending |
Renders PopoverContent with title/description ids, initial focus, and alertdialog role. |
popconfirm-confirm.vue |
click |
Runs the handler; disabled and aria-busy while pending. |
popconfirm-cancel.vue |
click |
Cancels with reason cancel-button; disabled while pending. |
Parts And Data
| Target |
Public contract |
| Root |
data-vize-ui="popconfirm-root", part="root", data-popconfirm-state, plus Popover data-state |
| Trigger |
data-vize-ui="popconfirm-trigger", part="trigger", data-popconfirm-state |
| Content |
data-vize-ui="popconfirm-content", part="content", data-state, data-error, aria-busy; title/description parts |
| Actions |
data-vize-ui="popconfirm-confirm" / "popconfirm-cancel", part, data-state |
Popconfirm ships no stylesheet.