ConfirmActionDialog
A confirmation for an action that cannot be undone, with a cancel that is always available and a busy state while the action runs.
Ask for confirmation before an action the reader cannot take back: deleting, publishing,
recalculating. Confirm asks one question with two answers, and stays open, busy,
while your action runs.
Nothing confirmed yet.
// apps/docs/examples/ui/confirm-action-dialog.tsx'use client';
import {useState} from 'react';
import {ConfirmActionDialog} from '@workspace/active-ui/components/composed/confirm-action-dialog';import {Button} from '@workspace/active-ui/components/primitives/button';
/** * Two confirmations. The application owns the open and busy state and runs * the action itself; here the deletion takes two seconds, so the busy state * is visible: a spinner, and both buttons disabled. */export default function ConfirmActionDialogExample() { const [publishOpen, setPublishOpen] = useState(false); const [deleteOpen, setDeleteOpen] = useState(false); const [deleting, setDeleting] = useState(false); const [log, setLog] = useState('Nothing confirmed yet.');
return ( <div className="flex flex-col gap-3"> <div className="flex flex-wrap gap-2"> <Button variant="outline" onClick={() => setPublishOpen(true)}> Publish scheme </Button> <Button variant="destructive" onClick={() => setDeleteOpen(true)}> Delete table </Button> </div> <p role="status" className="text-muted-foreground text-sm"> {log} </p>
<ConfirmActionDialog isOpen={publishOpen} isLoading={false} onClose={() => { setPublishOpen(false); setLog('Publishing cancelled.'); }} onConfirm={() => { setPublishOpen(false); setLog('Scheme published.'); }} title="Publish this scheme?" description="The scheme becomes visible to every employer in this administration." confirmButtonText="Publish" cancelButtonText="Cancel" />
<ConfirmActionDialog isOpen={deleteOpen} isLoading={deleting} onClose={() => { setDeleteOpen(false); setLog('Deletion cancelled.'); }} onConfirm={() => { setDeleting(true); window.setTimeout(() => { setDeleting(false); setDeleteOpen(false); setLog('Table deleted.'); }, 2000); }} title="Delete this lookup table?" description="This cannot be undone. Schemes that refer to the table keep their last calculated values." confirmButtonText="Delete" confirmButtonVariant="destructive" loadingText="Deleting…" cancelButtonText="Cancel" /> </div> );}What the composition adds#
It is the alert dialog primitive, two buttons and a spinner, arranged so that every confirmation behaves the same:
an alert dialog: it must be answered; it is announced as an alert, not as a passing window;
cancel is the easy exit: the cancel button and
Escapecallon; a click outside does not close an alert dialog, so the reader answers it deliberately;Close a busy state: with
is, the confirm button shows a spinner andLoading loading(or its own label), and both buttons are disabled, so the action cannot run twice;Text one colour axis: only the confirm button changes, with
confirm; the dialog itself carries no warning colour.Button Variant
Usage#
import {ConfirmActionDialog} from '@workspace/active-ui/components/composed/confirm-action-dialog';
<ConfirmActionDialog isOpen={open} isLoading={deleting} onClose={() => setOpen(false)} onConfirm={deleteTable} title="Delete this lookup table?" description="This cannot be undone." confirmButtonText="Delete" confirmButtonVariant="destructive" cancelButtonText="Cancel"/>;What your application provides#
The open state (
is,Open on): the dialog has no trigger of its own; open it from your button.Close The action (
on) and its busy state (Confirm is). The dialog does not close itself on confirm: close it when your action has finished, or keep it open to show an error.Loading All text: the title, the description, both button labels and, optionally,
loading. The package supplies no default wording.Text
Accessibility and keyboard#
Opening moves the focus into the dialog;
Tabstays inside it.Escapecancels, and the focus returns to the element that opened it.The title names the dialog and the description is read with it.
While busy, both buttons are disabled; the spinner is decorative because the label already says what happens.
API#
ConfirmActionDialog#
Import from @workspace/
Props
- Type
ReactNode
What will happen, read with the title. Empty ('' or null), the dialog has no description.
- Type
boolean
Whether the action runs. Both buttons are disabled and the confirm button shows a spinner beside loading.
- Type
boolean
Whether the dialog is open. Closed, it renders nothing.
- Type
string
The title of the dialog, which also names it for assistive technology.
- Type
string
A status line below the description, for a dialog that stays open while something happened outside it, such as a confirmation in another step that has just succeeded. Empty, there is no line.
It is a role="status" region beside the description, not part of it: a description that changes while the dialog is open is not announced again, a status line is.
- Type
string
The text of the confirm button while the action runs, such as "Deleting…".
Omitted, confirm stays, with the spinner beside it. There is no English default: this package does not translate, and the spinner already shows the busy state.
Events
Called by the component when something happens.
- Type
() => void
Called when the dialog asks to close: the cancel button or Escape. Set is to false in response.
- Type
() => void
Called when the confirm button is pressed. The dialog stays open: start the action, set is while it runs, and close the dialog when it has finished.
Takes only the props listed.
Types
The props of Confirm, each described in its prop list on this page.
interface ConfirmActionDialogProps {
isOpen: boolean;
onClose: () => void;
onConfirm: () => void;
isLoading: boolean;
title: string;
description: React.ReactNode;
confirmButtonText: string;
confirmButtonVariant?: ButtonVariant;
cancelButtonText: string;
loadingText?: string;
confirmationNotice?: string;
}