shadcn.io is not affiliated with official shadcn/ui
Confirm Delete Dialog Block for React Aria
A planner's project list with its delete confirmation shown open: an alert dialog that lists what goes with the project, asks for its name to be typed exactly, and keeps Delete off until it matches.
Installation
Overview
Make the last click on something irreversible a deliberate one, with this delete confirmation for React with React Aria. It opens from the Projects page of Plankline, a planner for small workshops: the header holds an outline Delete Button named for the selected project, and the project list itself is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Alert Dialog names Orchard Redesign and lists what goes with it in a Data List: its tasks, the collaborators who lose access and its files. A Field with an Input asks for the project's name, a polite line under it says Matches or Does not match as you type, and the Delete project button, the catalog Button in its destructive variant, stays off until the name is exact. Cancel has focus when it opens. Confirming folds the project's row out of the drawn list and turns the header's button into Restore. For preview the alert is drawn open in place when the page loads; the header button opens the real Alert Dialog, with the same list and the same field. For projects, workspaces, repositories and anything a person can't get back.
FAQ
Why is the alert already open, and what do I keep?
So you can see it without a click. On load the alert is a copy drawn in place over the project list: a native dialog element with the alertdialog role that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Delete button in the header opens the real Alert Dialog, modal, with its focus trap, Escape and focus on Cancel, and the copy stays closed until a reload. Both show the same ConfirmFields component and share the block's state, so a name typed in the copy is there in the real one. In your app keep the Alert Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.
How does the typed name keep Delete off?
PROJECT holds the exact name, and Delete is enabled only when what was typed equals it, capitals included. The line under the field is a polite live region in one reserved slot, so "Matches." and "Does not match." are read out without moving the buttons, and the field is named by a label that says what to type. Pressing Enter in the field confirms only when it matches. Typing the name is the friction on purpose: use it for what can't be undone, and a plain two-button alert for what can.
What does Delete do here, and how do I wire it up?
Here it folds the project's row out of the drawn list, turns the header's button into Restore, and says in a polite status message that nothing was deleted in this demo. Restore brings the row back. In your app delete on your server in confirm, keep the alert open with its busy state until the server answers, fold the row only on success, and show a failure in the field's line with a retry. Offer Restore only if your server really keeps the project for a while.
Where does focus go, and how does it close?
The real alert is named by its title and described by its sentence, and it opens with focus on Cancel, never on Delete, so a stray Enter backs out. Escape and Cancel close it and return focus to the Delete button; clicking outside does not close it, since an alert has to be answered. React Aria focuses the dialog itself, so a frame later focus is moved to Cancel, and the title is a level 2 heading. After a confirmed delete the button that opened the alert is gone, so about 300 ms later focus moves to Restore, the button that took its place. The copy shown on load moves no focus; Escape inside it, Cancel and Delete close it the same way.
Why isn't the action a Shine Button?
An alert's confirm that deletes uses the catalog Button in its destructive variant, and the block has no Shine Button: the Shine Button is the one primary for actions that move something forward, and this one ends something. The destructive colour is on that button only. The rest, including the list, the field and the lines, stays in the theme's neutral tones.
How does it look on a phone?
The copy shown on load docks to the foot of the page as a bottom sheet, its actions pinned at the bottom with Cancel under Delete project, and the list and the field scroll above them. The real alert keeps the Alert Dialog's own layout: a centred card that is as wide as the screen allows.