Confirm dialog
Ask the user to confirm a destructive action before it runs. Returns a boolean to the caller.
→ awaiting click…
The Callable
declared once, mounted in the React treeimport { createCallable } from 'react-call'
interface Props { message: string}type Response = boolean
export const Confirm = createCallable<Props, Response>(({ call, message }) => ( <div role="dialog" aria-modal="true" className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm" > <div className="w-full max-w-sm rounded-lg border border-[var(--color-border)] bg-[var(--color-bg)] p-6 shadow-2xl"> <p className="text-base text-[var(--color-fg)]">{message}</p> <div className="mt-6 flex items-center justify-end gap-3"> <button type="button" onClick={() => call.end(false)} className="rounded-md border border-[var(--color-border)] px-4 py-2 text-sm font-medium text-[var(--color-fg-muted)] transition-colors hover:text-[var(--color-fg)]" > Cancel </button> <button type="button" onClick={() => call.end(true)} className="rounded-md bg-[var(--color-accent)] px-4 py-2 text-sm font-medium text-[var(--color-accent-fg)] transition-colors hover:bg-[var(--color-accent-hover)]" > Continue </button> </div> </div> </div>))Confirm.displayName = 'Confirm'The Root
mounted in your app tree, onceimport { Confirm } from './Confirm'import { DeleteButton } from './DeleteButton'
export default function App() { return ( <> <Confirm /> <DeleteButton /> </> )}The caller
anywhere in your app, imperativeimport { useState } from 'react'import { Confirm } from './Confirm'
export const DeleteButton = () => { const [status, setStatus] = useState<'idle' | 'deleted' | 'cancelled'>('idle')
const handleClick = async () => { const accepted = await Confirm.call({ message: 'Delete this item? This action cannot be undone.', }) setStatus(accepted ? 'deleted' : 'cancelled') }
return ( <div className="flex flex-col items-center gap-3"> <button type="button" onClick={handleClick} className="rounded-md bg-red-600 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-red-700" > Delete item </button> <span className="font-mono text-xs text-[var(--color-fg-subtle)]"> {status === 'idle' && '→ awaiting click…'} {status === 'deleted' && ( <span className="text-[var(--color-accent)]">→ deleted</span> )} {status === 'cancelled' && '→ cancelled'} </span> </div> )}A boolean is the whole answer
A boolean response is the right model when the user’s answer is the whole point. Delete confirmations, “discard unsaved changes?”, “do you accept?” — the caller doesn’t need a payload back, just a yes-or-no.
If the dialog has fields, return the form data directly (see Prompt for input or Save form) instead of a boolean plus a side-channel.