Skip to content

ConfirmPopover

<ConfirmPopover> anchors a “Are you sure?” mini-popover next to the trigger. Less interruptive than a modal, perfect for row-level operations that still need a beat of confirmation.

import from "@na/ui/components/ConfirmPopover" ▶ Open in Storybook packages/ui/src/components/ConfirmPopover.tsx

When to use

  • Removing a row from a list / table inline.
  • Disconnect / detach actions in a settings list.
  • Any low-stakes destructive verb where a full modal would over-dramatize.

Don’t use ConfirmPopover for: high-stakes destruction (delete an entity completely → ConfirmDialog), publish / unpublish (the gravity warrants a modal).

Destructive

<ConfirmPopover
message="Remove this row?"
confirmLabel="Remove"
variant="destructive"
onConfirm={async () => api.remove(row.id)}
>
<Button variant="ghost" size="sm">Remove</Button>
</ConfirmPopover>

API

Prop Type Default Description
children * ReactNode Trigger. Wrap the visible Button as the popover anchor.
message * string Body question — single sentence.
confirmLabel * string Verb-only confirm-button label.
cancelLabel string "Cancel" Override for i18n.
pendingLabel string "Processing…" Shown while onConfirm pending.
variant "default" | "destructive" "default" Tints the confirm button.
onConfirm * () => unknown | Promise<unknown> Resolved → close. Rejected → stay open with error.
side "top" | "right" | "bottom" | "left" Preferred placement.
align "start" | "center" | "end" "end" Anchor alignment.
formatError (err: unknown) => string Override the inline error message.

Design guidelines

✓ Do

  • Use ConfirmPopover for row-level destructive verbs. The proximity reads as "for this row."
  • Keep the message a single short sentence. The popover is small.
  • Pair a destructive ConfirmPopover with a destructive Button trigger.

✗ Don't

  • Use ConfirmPopover for entity-level destruction. ConfirmDialog's gravity is correct there.
  • Stuff multi-paragraph explanations into the message. If you need that, you need a Dialog.
  • Show ConfirmPopover *and* ConfirmDialog for the same verb. Pick one — usually based on stake.

Accessibility

  • Composes Radix Popover — focus trapped while open, Esc closes.
  • Confirm button is the primary keyboard target after open.

▶ Open ConfirmPopover stories in Storybook