Skip to content

Popconfirm

Beta
Get Ritla UI

One short question next to the action it protects, for quick choices that are easy to undo.

Preview

Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.

PreviewCode
EnglishMirroredArabic
LTR →

Installation

  1. Add the component

    npx ritla add popconfirm

    Also works with shadcn: npx shadcn@latest add @ritla/popconfirm

  2. Dependencies it brings

    @base-ui/react@phosphor-icons/react

  3. Or copy by hand

    Installing by hand copies the component's source into your project. The source comes with a Ritla UI license, so the CLI is the short way to the same files.

Usage

popconfirm.tsx
import { Button } from "@/components/ui/button";import { Popconfirm, PopconfirmContent, PopconfirmTrigger } from "@/components/ui/popconfirm";<Popconfirm>  <PopconfirmTrigger render={<Button variant="outline" />}>Make default</PopconfirmTrigger>  <PopconfirmContent title="Set as default account?" okText="Set default" onConfirm={setDefault} /></Popconfirm>

Examples

Danger

tone="danger" for removing something that can be added back: Confirm turns red, the icon becomes a warning, and focus starts on Cancel so Enter never removes anything by accident.

EnglishMirroredArabic
LTR →

Placement, without icon or description

placement="bottom" when there is no room above the trigger; it also flips on its own. icon={false} and no description leave the question alone.

EnglishMirroredArabic
LTR →

API reference

Popconfirm

PropTypeDefaultDescription
open / defaultOpenbooleanNoneTo control it from code.
onOpenChange(open, details) => voidNoneWhen it opens or closes.

PopconfirmTrigger

PropTypeDefaultDescription
renderReactElementNoneThe visible control: <Button … />.

PopconfirmContent

PropTypeDefaultDescription
titleReactNodeNoneFigma's Title: the question, short, ending with a question mark. Names the dialog.
descriptionReactNodeNoneFigma's Show description: one line on what happens next.
iconbooleantrueFigma's Show icon: Info for Default, a warning for Danger.
tone"default" | "danger""default"Figma's Tone; Danger turns Confirm red.
placement"top" | "bottom""top"Figma's Placement. Flips when there isn't room.
okTextReactNode"Confirm" / «تأكيد»The Confirm button: name it after the action (Remove, Set default).
cancelTextReactNode"Cancel" / «إلغاء»The Cancel button: closes it and does nothing.
onConfirm() => voidNoneOn Confirm, then it closes.
onCancel() => voidNoneOn Cancel, then it closes. Esc and a click outside close it without calling either.

Accessibility

Keyboard

Keys are written for left-to-right. In right-to-left the arrow keys swap: the one pointing toward the reading direction moves forward.

KeyAction
EnterSpaceOn the trigger: opens it and moves focus to Confirm, or to Cancel when the tone is Danger.
TabShift+TabBetween the two buttons. Tabbing out closes it.
EscCloses it and returns focus to the trigger.

ARIA

  • A non-modal dialog (role="dialog") named by the question and described by its second line.
  • The icon is decorative: the words and the Confirm label carry the tone, never the colour alone.
  • For anything that moves money or cannot be undone, use a Dialog.
  • It needs a pointer and room around the trigger: on phones, use a Drawer with the same question and buttons.

Arabic and RTL notes

Mirrors

  • The icon and the text move to the right.
  • The buttons sit at the inline end: Confirm at the left end, Cancel beside it.

Does not mirror

  • The info and warning icons.
  • The arrow stays centred on the trigger; Top and Bottom don't change.
Numerals
Numbers in the question follow the numerals setting.
Arabic typography
The question body-14 Medium, the description body-14.
Mixed-direction text
It carries the trigger's direction and language into the portal, and the default button labels with them. Isolate names with <bdi>, so a Latin name keeps its order inside an Arabic question.

Checks it passes

The Ritla checks this component satisfies by construction. Used as documented, it does not bring these defects onto your page.

  • R042Clipped text: content wider than its box with overflow hidden and no ellipsis
  • R043Fixed-pixel-width container whose Arabic text exceeds the space
  • R050Arabic text falling back past the declared font family (measured, declared, or a webfont that failed to load)
  • R051letter-spacing applied to Arabic text (breaks the connected script)