shadcn.io is not affiliated with official shadcn/ui
Tag Manager Dialog Block for React
An expense tracker's tag dialog shown open: a search, a create row with five swatches, a list of eight tags you rename in place, merge or delete after a confirm, an always-there Undo, and the drawn transactions following.
Installation
Overview
Keep a set of tags tidy without leaving the page that uses them, with this tag dialog for React with Base UI. It opens from the Transactions page of Thriftbarrow, an expense tracker: the page's header holds an outline Manage tags Button, and the list, a top bar and seven rows of bars each with a tag chip, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog has a search Input, a create row with a name field, five swatches and an Add button, and a list of eight tags, each with a swatch dot, its name, how many transactions carry it, and three actions. The pencil turns the name into an Editable: Enter saves, Escape cancels, and an empty or duplicate name is refused in words. Merge asks which tag to fold it into, then confirms; Delete asks in the row, "Delete Travel? It is removed from 12 transactions", with Cancel focused. Every change goes on an Undo stack, with no toast and no timer, and the only Shine Button, Done, closes. The drawn chips follow renames, merges and deletions. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog, with the same list. For expenses, tickets, notes, files and anything that carries tags.
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 list: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Manage tags button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same TagBody component and share the block's state, so what you did 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 Undo work, and why is there no toast?
Every change, adding, renaming, merging or deleting, puts the state before it on a stack of ten, and Undo takes the latest one back and says so: "Undid merging Travel into Dining." The button is always in the dialog and quiet when the stack is empty, and its name says what it would undo. A toast that times out would take the chance away from anyone who is slow, so nothing here is timed and the last change is written beside the button.
How does renaming work, and what is refused?
The pencil, or a click on the name, turns it into a field; Enter saves it, Escape or the cross puts the old name back. A blank name, or one another tag already has, ignoring case and accents, is refused in a polite message and the old name stays. The same check guards the create row, where the reason shows under the field. Renaming changes the chips on the drawn transactions at once.
What do Merge and Delete do?
Both ask in the row, in the same fixed height, so the list never moves. Merge lists the other tags and folds the row's tag into the one you choose: its count is added to the target's and its transactions take the target's name. Delete says what it removes, with Cancel focused and a destructive button for the confirm, and the transactions it was on show an empty chip. Escape on an asking row cancels the question first and only a second Escape closes the dialog.
Why are the swatches coloured, and does the colour carry meaning?
They stand for the colours of a person's own tags, so they are the theme's five chart tokens, a declared exception to using no hue in a block. They are never the only sign: every tag is shown by its name, the chosen swatch is ringed and ticked, and the dot beside a tag is decoration.
What stays local in the demo, and how do I wire it up?
All of it. The eight tags and their counts are typed and every change lives in this tab. In your app post each change from commit, let the server return the new counts, and keep Undo as a request that reverses the last one; the rows, the confirms and the keys stay as they are.
Is it accessible from the keyboard?
Yes. The real dialog is named by its title and described by its sentence, focus starts on the search field and stays inside until the dialog closes, and Escape, Done and the close button return focus to Manage tags. Every button names its tag, "Rename Travel", "Merge Travel into another tag", "Delete Travel", and each change is said in a polite message. The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange. The copy shown on load moves no focus; Escape inside it and its close button close it and put focus on the button.
Related
- Pro
Inline Cell Editing Table
Edit in placeA shop price list whose price and stock cells turn into a field in place, with Save, Cancel, Escape, a reserved line for the reason a value is refused and Undo.
- Pro
Editable Cells Grid Table
Edit in placeA sales forecast grid where every number is a field, with live row and column totals, a dot on each changed cell, arrow keys and Enter between regions, Undo and Reset.
- 12Pro
Sort Options Dialog
Notes and editingA data-grid tool's sort dialog shown open: up to three rules with a field and a direction each, Move up, Move down and Remove, a sorted five-row preview with the sorted columns numbered, and the table re-sorting on apply.
- Pro
Reorder Items Dialog
Notes and editingA landing-page builder's reorder dialog shown open: five page sections with grips you lift with Space and move with the arrow keys, Move up and down buttons, a spoken position, and the page behind it rearranging on save.
- Pro
Address Autocomplete Dialog
Pickers and searchA meal-kit delivery page with its address dialog shown open: typing filters eight addresses of an invented town into an inline list you can arrow through, a choice fills four editable fields, and Enter it manually offers the same four, empty.
- Pro
Command Palette Dialog
Pickers and searchA docs workspace's command palette shown open over its page: Recent and Pages when the field is empty, and a typed greater-than, at or hash turns it to Actions, People or Pages, each with its own groups and count, and each choice edits the drawn page.