use-confirm-dialog
Promise-based confirm dialog state machine (idle → revealed → idle), independent of any dialog markup.
| Package | @vizejs/composable/use-confirm-dialog |
| Own the source | vize lib pull composable:use-confirm-dialog |
| Runtime exports | useConfirmDialog |
| Gzip budget | 2304 B |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/composable
Import the entry directly. Call lifecycle-bound utilities inside <script setup> so cleanup follows the component scope; consult the runtime contract for this entry's SSR and hydration behavior.
import { useConfirmDialog } from "@vizejs/composable/use-confirm-dialog";
Try it
Confirm before deleting a draft
Await the reader's decision in the middle of an action instead of splitting it across callbacks.
What to observe: Delete draft reveals the confirmation. Keep draft reports Kept the draft; Delete reports Deleted the draft.
reveal() returns a promise for { isCanceled, data }. Render the dialog yourself; the composable only manages its state.
Compare the initial and interacted states


Copy the example
Save this complete SFC in your Vue project. Its public imports and source are the same ones executed in the preview.
<script setup lang="ts">
import { ref } from "vue";
import { useConfirmDialog } from "@vizejs/composable/use-confirm-dialog";
const { isRevealed, reveal, confirm, cancel } = useConfirmDialog();
const message = ref("The draft is saved.");
async function deleteDraft() {
const { isCanceled } = await reveal();
message.value = isCanceled ? "Kept the draft." : "Deleted the draft.";
}
</script>
<template>
<div class="composable-example">
<p>Ask before a destructive action and continue with the reader's answer.</p>
<button type="button" :disabled="isRevealed" @click="deleteDraft">Delete draft</button>
<div v-if="isRevealed" role="alertdialog" aria-label="Delete the draft?">
<p>Delete the draft? This cannot be undone.</p>
<div class="example-actions">
<button type="button" @click="() => confirm()">Delete</button>
<button type="button" @click="() => cancel()">Keep draft</button>
</div>
</div>
<output aria-live="polite">{{ message }}</output>
</div>
</template>
Runtime contract
| Utility | Category | Stability | SSR | Hydration | Cleanup | Targets | Host globals | Uses |
|---|---|---|---|---|---|---|---|---|
useConfirmDialog |
state | experimental | safe | stable | reactive-scope | web, server, worker, native, desktop, terminal | — | createEventHook |
API
useConfirmDialog
Promise-based confirm dialog state machine (idle → revealed → idle), independent of any dialog markup. reveal() resolves with a discriminated result, so if (!result.isCanceled) narrows data to the confirm payload. Payload types are declared as type parameters; void payloads take no argument. Pair it with a native <dialog> or any headless dialog. Synchronous state: SSR-safe; listeners registered inside a scope are removed with it.
function useConfirmDialog< RevealData = void, ConfirmData = void, CancelData = void, >(): ConfirmDialog<RevealData, ConfirmData, CancelData>
const dialog = useConfirmDialog<{ name: string }, "keep" | "delete">();
const result = await dialog.reveal({ name: file.name });
if (!result.isCanceled && result.data === "delete") remove(file);
useConfirmDialog
function useConfirmDialog(): ConfirmDialog<unknown, unknown, unknown>
Types
ConfirmDialog
Dialog state machine returned by useConfirmDialog.
| Member | Type | Description |
|---|---|---|
state |
Readonly<ShallowRef<ConfirmDialogState>> |
"revealed" between reveal() and confirm()/cancel(). |
isRevealed |
Readonly<ShallowRef<boolean>> |
Shorthand for state === "revealed". |
reveal |
( ...payload: ConfirmDialogPayload<RevealData> ) => Promise<ConfirmDialogResult<ConfirmData, CancelData>> |
Open the dialog. While already revealed, returns the pending promise without re-firing onReveal. |
confirm |
(...payload: ConfirmDialogPayload<ConfirmData>) => boolean |
Confirm the revealed dialog. |
cancel |
(...payload: ConfirmDialogPayload<CancelData>) => boolean |
Cancel the revealed dialog. |
onReveal |
( listener: EventHookListener<ConfirmDialogPayload<RevealData>>, ) => EventHookSubscription |
Listen for reveals. |
onConfirm |
( listener: EventHookListener<ConfirmDialogPayload<ConfirmData>>, ) => EventHookSubscription |
Listen for confirmations. |
onCancel |
( listener: EventHookListener<ConfirmDialogPayload<CancelData>>, ) => EventHookSubscription |
Listen for cancellations. |