shadcn.io is not affiliated with official shadcn/ui
Version History Command Menu Block for React
A design editor's command menu shown open at the end of the editor: twelve things done in four time buckets, type chips that filter them, choosing an entry reverts it and the drawn layer list follows, and Clear history asks before it clears.
Installation
Overview
Take any step back with this version history command menu for React with Base UI. It opens from the Version history page of Stitchback, a design editor, whose header holds an outline field with its ⌘ K cap, and the editor is drawn under a soft scrim inside a hairline frame with a plus mark on each corner, its layer list at the start and the menu docked at the end. The menu is the catalog Command over twelve things done to the file, Renamed, Deleted, Moved and Published, in Just now, Earlier today, Yesterday and This week, each with a time. A row of chips, a Toggle Group that allows several, shows or hides a type and carries how many entries it holds. Choosing an entry reverts it: the row reads Reverted with its text struck through, the menu stays open, and the drawn layer list behind it gets the old name back, the layer that was deleted, or its old place; the badge in the bar goes from Published to Draft when the last publish is taken back. Choosing it again redoes it. The last row, Clear history, turns into a confirm row that says "Clear 12 entries?" with ↵ yes and Esc no. For preview the menu is drawn open in place when the page loads; the field, or Ctrl or ⌘ K while focus is in the block, opens the real command dialog with the same history, filters and reverts. For editors, design tools, document apps and any product with a trail worth searching.
FAQ
Why is the menu already open, and what do I keep?
So you can see it without a click. On load the menu is the Command drawn inline over a picture of the editor, in a plain shell that is not modal, so nothing is trapped, hidden or focused and the page around the preview keeps working. The header's field opens the real command dialog, modal, with its focus trap, Escape and focus return, and the inline copy stays closed until a reload. Both show the same Palette and share the block's state, so the filters, the reverts and the text you typed in the copy are in the real dialog. In your app keep the dialog and drop the copy: the "in-place" state, the scrim with its shell and the Escape and blur effects.
What does reverting an entry do, and how do I wire it up?
Each entry carries a small patch, the name, the place or the visibility its layer had before it, and layersFor applies the patches of the entries you reverted to the layer list, so the drawing is always a function of the list of reverts. The entry itself stays in the history, struck through, and choosing it again removes it from that list. Here nothing is saved. In your app, pick is where you call your undo, or apply the inverse change, and mark the entry.
How does Clear history ask first?
Choosing the last row does not clear anything: the row turns into "Clear 12 entries?" with the keys that answer it, and Enter on it (it is still the highlighted row) clears the history. Escape answers no: in the copy and in the real dialog the first Escape, and a click away, only cancel the question and say "Kept the history."; the next one closes the menu. Choosing any other row or typing also cancels it. Clearing empties the list and leaves the editor as it is, as the status line says.
How do the type chips work?
They are a multiple-choice group where at least one chip stays pressed, so the list is never empty because of them; each is named with its count ("Moved, 3"). They sit above the input and outside the command, because the command's own keys (Enter, the arrows) would take the keys from them. The count in the foot says how many of the twelve are shown, and is spoken when you press a chip or pause typing. On a phone the chips scroll sideways.
Is it accessible from the keyboard?
Yes. Type to search, the arrow keys move through the entries, Enter reverts or redoes the highlighted one, and Escape closes the menu and puts focus on the field; Ctrl or ⌘ K opens the dialog while focus is inside the block, and only then. The rows are options of a cmdk listbox; the block turns off its own fuzzy filter and lists the rows itself. The real dialog is named by its title and described by its sentence.
Related
- Pro
Recent Items Command Menu
Search everythingA project hub's command menu shown open on what you opened lately: Today, Yesterday and Earlier buckets before you type, recent matches first when you do, opening a row moves it to the top, and a last row clears the list.
- Pro
Actions Command Menu
Actions and keysA signing tool's document with its actions menu shown open: nine actions in four groups, a key on the five that change the document that runs them while the menu is open, and a drawn lease whose badge and signature follow.
- Pro
Basic Command Menu
Search everythingA team workspace's home page with its command menu shown open: eleven pages in three groups, a shortcut on the five most used, matches marked, an empty state that says what to try and a foot with the key hints and a spoken count.
- Pro
An invoicing app's quick-actions dialog shown open: eight action tiles in two columns, a star on each that pins it into one of four slots at the top, arrow keys across the tiles and a letter that runs an action.
- Pro
Navigation Command Menu
Pages and docsA bank back office's navigation menu shown open: 24 pages in three levels, each row the name over its whole path, a search that reads the path by the start of each word, and a tick on the page you are on.
- 333Pro
Global Search Command Menu
Search everythingA company intranet's command menu shown open: one input searches pages, docs, people and tags at once, each type is a group of three matches with a row that opens it in place, and the foot counts the results by type.