Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Save Draft Dialog Block for React

A publishing editor with its save-draft dialog shown open: a name, a folder, an autosave choice with a sentence that follows it, and a discard that asks again in the same row.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Let someone name a draft and decide how it keeps itself, with this save dialog for React with Base UI. It opens from the editor of Draftwick, a publishing tool: the header holds an outline Save draft Button, and the page is drawn under a soft scrim inside a hairline frame with a plus mark on each corner: a sheet of paper with a toolbar, a chip that says whether the draft is saved, and the first lines of the post. The Dialog holds a Field with an Input for the draft's name, a Segment Group for the autosave (Off, every 30 seconds, every 2 minutes) with one sentence that follows the choice and a typed time of the last autosave, and a Native Select for the folder with the number of earlier drafts in it. Save draft, the one Shine Button, refuses an empty name, and Discard changes asks again in the same row with Yes and No, so there is no dialog on a dialog. Saving puts "Draft: Spring menu, saved" in the toolbar's chip. For preview the dialog is drawn open in place when the page loads; Save draft opens the real Dialog, with the same fields. For editors, composers and any tool that autosaves.

FAQ

Why is the dialog already open, and what do I keep?

So you can see it without a click. On load the dialog is a copy drawn in place over the editor: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. Save draft in the header opens the real Dialog, modal, with its focus trap, Escape and focus on the name, and the copy stays closed until a reload. Both show the same DraftFields 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 Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

How does the autosave sentence work?

Each choice carries its own sentence: "Autosave is off. The draft saves only when you press Save draft", or "Autosaves every 2 minutes", with "Last autosave 10:42" added for the two that run. The time is typed, never the clock, so the preview never ages. The sentence sits in one reserved two-line slot, so changing the choice never moves the buttons. Nothing autosaves here: in your app start a timer from the chosen cadence and show the real time of the last save.

How does Discard changes ask again without a nested dialog?

The ghost button swaps, in a row of fixed height, for the question "Discard? This removes the draft." with Yes and No. Focus goes to No, the safe answer, and back to Discard changes if the person says no. Yes discards the draft, closes the dialog and changes the chip to "Draft discarded". A dialog opened from inside a dialog would trap focus twice and, in the in-place copy, couldn't open at all, so the question stays in the row.

What does Save draft do here, and how do I wire it up?

It checks that the name isn't empty (a field error appears and focus returns to the field), then puts the name in the toolbar's chip, shows the cadence sentence under it and says in a polite status message that nothing was stored in this demo. In your app save to your API in save, keep the dialog open with a busy state until it answers, and show a failure inside the dialog with a retry.

Where does focus go, and how does it close?

The real dialog opens with focus on the name field. Enter in it saves, Escape and Cancel close it and return focus to Save draft, and the values typed stay for the next time it opens while the Discard question resets. The first field takes focus by default. The copy shown on load moves no focus.

How does it look on a phone?

The copy shown on load docks to the foot of the page as a bottom sheet with Cancel and Save draft pinned and the fields scrolling above them. The autosave choice comes second so it is in reach without scrolling, and the three choices share the full width. The real dialog keeps the Dialog's own phone layout, sticking to the bottom edge.

  • Pro

    Unsaved Changes Dialog

    Confirm and consent

    An essay editor with its leave prompt shown open: an alert dialog that lists what changed since the last save and offers Save and leave, Discard changes and Keep editing.

  • Pro

    A docs tool's version history sheet shown open: six versions with authors and times, the diff of the chosen one against the current text marked with underline, strike-through, glyphs and words, and a two-step restore.

  • Pro

    Quick Note Dialog

    Notes and editing

    A sticky-note wall with its dialog shown open: a title, a note of up to 280 characters, an Idea, To-do, Reference or Later label, a reminder day on a calendar and a pin switch, and a new card that lands first on the wall.

  • Pro

    Warning Dialog

    Destructive confirms

    A hosted database's Migrations page with its caution shown open: an alert dialog with a drawn freeze track and a checkbox that must be ticked before the destructive Run anyway turns on.

  • Pro

    Confirm Action Dialog

    Confirm and consent

    A newsletter editor with its publish confirmation shown open: an alert dialog that lists what happens to the issue, a box that remembers the answer, and a foot that gives the question back.

  • Pro

    Success Dialog

    Status and errors

    An invoice page with its payment confirmation shown open: a dialog with a drawn check, a receipt list with a copy button for the reference, and one button that settles the invoice.