npx shadcn@latest add https://sdk-components.thesqd.com/r/confirm-popover.jsonimport { ConfirmPopover } from "@/components/ui/confirm-popover";const [anchor, setAnchor] = React.useState<Element | null>(null);
<Button onClick={(e) => setAnchor(e.currentTarget)}>Delete</Button>
<ConfirmPopover
open={anchor !== null}
onOpenChange={(open) => !open && setAnchor(null)}
anchor={anchor}
title="Delete this step?"
description="Its connections go with it."
onConfirm={deleteStep}
/>ConfirmPopover (flat — no slots to compose)
├── anchor (the element that asked; the popover sits beside it)
├── title / description (PopoverHeader → PopoverTitle + PopoverDescription)
└── one destructive Button (actionLabel; runs onConfirm, then closes)
No Cancel button: clicking away or Esc cancels.| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Whether the popover is showing. |
onOpenChange | (open: boolean) => void | — | Called on click-away, Esc, and after the button runs. |
anchor | Element | null | — | The element that asked; the popover is positioned beside it. |
title | ReactNode | — | The question, e.g. "Delete 2 steps?". |
description | ReactNode | — | Optional line under the title. |
actionLabel | ReactNode | "Delete" | The red button's label. |
onConfirm | () => void | — | Runs on the button. The popover closes itself afterwards. |
side | "top" | "right" | "bottom" | "left" | "bottom" | Side of the anchor to sit on. |
align | "start" | "center" | "end" | "start" | Alignment along that side. |