GrConfirmDialog
Asks to confirm a potentially important or dangerous action.
Overview
When to take it
- the action is irreversible — deleting, revoking access, cancelling an order: the pause before it is the point of the component;
- the confirmation goes to a server —
confirmLoadingkeeps the window open for the duration of the request,errorshows the refusal; - the button has to look dangerous —
confirmTonecolours the confirmation in the tone of the consequence; - the focus lands on cancel —
focusActionkeeps a dangerous action from being confirmed blindly withEnter.
When to take something else
| Need | Take |
|---|---|
| Ask for a value rather than for consent | GrPromptDialog |
| Call a confirmation from code | GrDialogService |
| A window with arbitrary content | GrDialog |
| A confirmation right at the button, without a window | GrPopover |
| Report a result rather than ask | GrToaster |
Harmless actions do not need confirming: a dialog that is always answered “yes” stops being read and will not stop anyone on the single occasion when it mattered. A reversible action is better covered by an undo in a toast.
Playground controls come from the API, not from hand
The window opens above the page with the props set on the right.
0 changed· state is in the URL
<GrConfirmDialog
title="Delete the report?"
description="The report and its 12 scheduled runs are removed. This cannot be undone."
confirmText="Delete report"
confirmTone="danger"
v-model="value"
/>Examples 3 each with a live demo and its code
Revoking a member's access
The answer is named by the action — «Revoke Grace», «Keep access» — because «OK» does not say what it agrees to, and
confirm-tone="danger"paints it in the tone of the consequence.focus-action="cancel"puts the focus on the safe answer: Enter pressed right after opening must not revoke anything.Workspace members GWGrace WuAccountantOHOmar HaddadSalesINInes NovakOwnerA cancellation the server refuses
close-on-confirm="false"keeps the window while the request runs,confirm-loadingshows the wait in the button, andpersistentturns off Esc and the backdrop meanwhile — the cross and «Keep plan» still work. The first try is refused:errorputs the server’s answer above the buttons, where the decision is made.Business planRenews on 1 November · €240 a month
API generated from the package · cannot drift
Props
| Prop | Type | default | Description |
|---|---|---|---|
title | string | undefined | undefined | The title of the window, which is also its accessible name. Not set — taken from the locale. |
size | "sm" | "md" | "lg" | "xl" | "full" | undefined | undefined | The width of the window on the `GrDialog` scale: from `sm` to `xl`, `full` — the whole screen. `md` by default. |
description | string | undefined | undefined | The text of the question in the body of the window. The `default` slot replaces it. |
closeOnBackdrop | boolean | undefined | true | Close on a click on the backdrop. `true` by default; with `persistent` it is switched off for the duration of `confirmLoading`. |
closeOnEsc | boolean | undefined | true | Close on Esc. `true` by default; with `persistent` it is switched off for the duration of `confirmLoading`. |
showHeader | boolean | undefined | true | Show the header with the title and the close button. `true` by default. |
showCloseButton | boolean | undefined | true | The close button in the header. `true` by default; it stays with `persistent` too. |
headerConfig | GrDialogSectionConfig | undefined | undefined | The paddings and the line of the header: `paddingX`, `paddingY`, `bordered`. |
footerConfig | GrDialogSectionConfig | undefined | undefined | The paddings and the line of the footer with the buttons. |
bodyConfig | GrDialogSectionConfig | undefined | undefined | The paddings of the window body. `bordered` does not apply to the body. |
closeLabel | string | undefined | undefined | The a11y label of the close button (i18n). |
buttonSize | "xs" | "sm" | "md" | "lg" | undefined | undefined | The size of both footer buttons. Not set — the buttons take their size from `GrConfigProvider`. |
confirmText | string | undefined | undefined | The label of the confirm button. Not set — taken from the locale. |
cancelText | string | undefined | undefined | The label of the cancel button. Not set — taken from the locale. |
confirmVariant | GrButtonVariant | undefined | "primary" | The weight of the confirm button. `primary` by default. |
confirmTone |
| "primary" | The tone of the confirm button: `danger` — for an irreversible action. `primary` by default. |
error | ResponseErrorInfo | null | undefined | null | The structure of a server error to show in the body of the dialog (through `GrResponseErrorBanner`). It is used by the imperative `useDialogService` for an async `onConfirm`. `null` — the block is hidden. |
confirmLoading | boolean | undefined | false | The loading state of the Confirm button (an async `onConfirm` in flight). |
confirmDisabled | boolean | undefined | false | Forcibly disables the Confirm button. |
closeOnConfirm | boolean | undefined | true | Whether to close the dialog automatically on a click of Confirm. `true` by default (the historical behaviour). `false` hands the closing outside (needed by `useDialogService`, which waits for the result of an async `onConfirm`). |
focusAction | GrConfirmDialogFocusAction | undefined | "cancel" | Which action gets the focus on opening. "Cancel" by default: a confirmation is sometimes destructive, and `Enter` right after the opening must not run it. `none` leaves the focus on the panel of the window. The name is deliberately not `initialFocus`: in `GrModal`/`GrDrawer` that is the name of the prop carrying an element, while here an action is chosen. |
persistent | boolean | undefined | false | A ban on the "soft" ways of closing (Esc, a click on the backdrop) while the confirmation is running (`confirmLoading`). The close button and "Cancel" remain: a window with no way out is a trap. |
modelValuerequiredv-model | boolean | — | Whether the window is open (`v-model`). Cancelling always closes it, confirming does so with `closeOnConfirm`. |
Slots
| Slot | Type | Description |
|---|---|---|
default | any | The content of the dialog instead of the text from the `description` prop. |
error | { error: ResponseErrorInfo | null; } | Your own presentation of the error instead of the built-in banner. |
footer | any | The buttons of the dialog instead of the "cancel and confirm" pair. |
Events
| Event | Signature | Description |
|---|---|---|
update:modelValue | (event: "update:modelValue", value: boolean): void | — |
confirm | (event: "confirm"): void | — |
cancel | (event: "cancel"): void | — |
Types
Every exported type of the subpath, grouped by the file it lives in. Names, generics and bodies come from the package’s declaration files and cannot drift.
import type { GrConfirmDialogFocusAction, GrConfirmDialogProps, GrConfirmDialogEmits } from '@feugene/granularity/components/GrConfirmDialog'Filedist/types/components/GrConfirmDialog/GrConfirmDialog.vue.d.ts
type GrConfirmDialogFocusAction = 'confirm' | 'cancel' | 'none';interface GrConfirmDialogProps {
modelValue: boolean;
title?: string;
description?: string;
closeOnBackdrop?: boolean;
closeOnEsc?: boolean;
showHeader?: boolean;
showCloseButton?: boolean;
size?: GrDialogSize;
headerConfig?: GrDialogSectionConfig;
footerConfig?: GrDialogSectionConfig;
bodyConfig?: GrDialogSectionConfig;
closeLabel?: string;
buttonSize?: GrButtonSize;
confirmText?: string;
cancelText?: string;
confirmVariant?: GrButtonVariant;
confirmTone?: GrButtonTone;
error?: ResponseErrorInfo | null;
confirmLoading?: boolean;
confirmDisabled?: boolean;
closeOnConfirm?: boolean;
focusAction?: GrConfirmDialogFocusAction;
persistent?: boolean;
}interface GrConfirmDialogEmits {
(e: 'update:modelValue', value: boolean): void;
(e: 'confirm'): void;
(e: 'cancel'): void;
}Filedist/types/components/GrConfirmDialog/config.d.ts
const grConfirmDialogConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrConfirmDialog">;Accessibility
Keys
EscTab / Shift+Tab
Full contract of the package: docs/keyboard.md ↗
Usage from the library prose
The focus on opening
focusAction decides which action gets the focus: 'cancel' (the default),
'confirm' or 'none' — the focus stays on the panel of the window.
The default is 'cancel' precisely because a confirmation window exists for the sake
of a risky action: Enter pressed right after the opening has to cancel, not delete.
'confirm' is appropriate where the confirmation is a routine (“Save before
leaving?”).
The focus is set from the side of the content after rendering rather than with the
initialFocus prop of GrModal: the element is born inside the subtree of the
dialog, and returning it upwards through a prop closes the render into a loop.
The degradation is silent. If the #footer slot has been overridden, the component
does not know your buttons and the focus stays on the panel; the same happens with
focusAction="confirm" and confirmDisabled. This is not a configuration error: a
footer of your own means the consumer disposes of the focus.
Asynchronous confirmation
closeOnConfirm: false hands the closing outside: the component sends confirm and
stays open until the consumer clears v-model. For the duration of the operation
there are confirmLoading (the button shows loading and accepts no clicks) and
error (a banner with the server’s answer in the body of the window, and the
#error slot — if a banner is not enough).
persistent switches off the soft ways of closing for that time — Esc and a
click on the backdrop. The cross and “Cancel” remain: a window with no way out is a
trap, not a protection. The same prop with the same semantics exists in
GrPromptDialog and GrDrawer.
<GrConfirmDialog
v-model="open"
confirm-tone="danger"
:confirm-loading="loading"
:error="error"
:close-on-confirm="false"
persistent
@confirm="submit"
/>useDialogService switches persistent on for all of its windows itself — there
loading means the request has already left.
Props in this example