ConfirmProvider
One app-wide confirm dialog you can await from any handler, so `if (!(await confirm({ title }))) return;` replaces window.confirm with a styled, localised AlertDialog.
Code
import { Button, ConfirmProvider, NasaqProvider, useConfirm } from "@fadymondy/nasaq/web";declare function deleteProject(id: string): Promise<void>;function DeleteProject({ id, name }: { id: string; name: string }) { const confirm = useConfirm(); async function onDelete() { if (!(await confirm({ title: `Delete ${name}?`, description: "Its tasks and files are deleted too. This can't be undone.", confirmLabel: "Delete" }))) return; await deleteProject(id); } return <Button variant="danger" onClick={onDelete}>Delete</Button>;}export function App() { return ( <NasaqProvider> <ConfirmProvider> <DeleteProject id="p1" name="Billing" /> </ConfirmProvider> </NasaqProvider> );}Overlays · beta
Live examples and controls: ConfirmProvider in the lab.
Install
npx shadcn@latest add https://docs.nasaqui.com/r/confirm-provider.jsonMount it once, then call useConfirm() anywhere. confirm(options) opens an AlertDialog and resolves
true or false, so the code that deletes stays in one handler.
When to use
- Handlers that need a "yes" first: delete from a menu, leave with unsaved changes, bulk actions.
- When the trigger is not a button you render (a keyboard shortcut, a context menu, a table action).
When not to use
- One button that confirms before it acts: use
ConfirmButtonfromAlertDialog. - Undoable actions: act at once and offer Undo in a
Toast. - Dialogs with fields: use
Dialog.
Import
import { ConfirmProvider, useConfirm } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"Quick start
import { Button, ConfirmProvider, NasaqProvider, useConfirm } from "@fadymondy/nasaq/web";
declare function deleteProject(id: string): Promise<void>;
function DeleteProject({ id, name }: { id: string; name: string }) {
const confirm = useConfirm();
async function onDelete() {
if (!(await confirm({ title: `Delete ${name}?`, description: "Its tasks and files are deleted too. This can't be undone.", confirmLabel: "Delete" }))) return;
await deleteProject(id);
}
return <Button variant="danger" onClick={onDelete}>Delete</Button>;
}
export function App() {
return (
<NasaqProvider>
<ConfirmProvider>
<DeleteProject id="p1" name="Billing" />
</ConfirmProvider>
</NasaqProvider>
);
}Anatomy
ConfirmProvider
├─ children
└─ AlertDialog data-slot="confirm-dialog"
├─ title, description
└─ Cancel, Confirm Confirm is danger unless `danger: false`API
ConfirmProvider: { children }. Place it inside NasaqProvider.
useConfirm(): ConfirmFn: throws when there is no provider above.
ConfirmOptions
| Option | Type | Default | Description |
|---|---|---|---|
title | ReactNode | required | The question. Name what is affected. |
description | ReactNode | What happens, and whether it can be undone. | |
confirmLabel | ReactNode | "Confirm" | Use the verb: "Delete", "Leave". |
cancelLabel | ReactNode | "Cancel" | |
danger | boolean | true | false styles Confirm as primary. |
The promise resolves false on Cancel, Escape or a click outside. A new confirm() while one is open
resolves the first with false.
Accessibility
- It is an
AlertDialog: focus moves into it, starts on Cancel, and returns to the trigger on close. - The title and description name the dialog.
RTL & i18n
- Default button labels follow the Nasaq locale (English and Arabic). Pass localised
titleanddescription.
Styling & tokens
- Inherits
AlertDialogandButton. Target[data-slot="confirm-dialog"].
Do / Don't
- Do write the consequence in
description. - Do label Confirm with the verb, not "OK".
- Don't confirm things that can be undone; that teaches people to click through.
Related
Lab
https://docs.nasaqui.com/?path=/docs/components-overlays-confirm-provider--docs
AlertDialog
Modal that interrupts to ask for an explicit answer before a consequential action, plus a ConfirmButton shorthand. Wraps Base UI AlertDialog.
ContextMenu
Right-click (or long-press) menu for a region, with items, checkbox and radio items, groups, shortcuts and submenus. Wraps Base UI ContextMenu and shares DropdownMenu styling.