# Tag manager

A React block (a whole screen) in [Beamline](https://beamline.io/)'s [Manufacturing](https://beamline.io/components/apps/manufacturing) app. Live demo: https://beamline.io/components/tag-manager

Tags for one or several items at once (sounds, photos, documents). Nested tag groups are edited in place (rename, new tag), and a folded group still says how many of its tags are on the selection. Built-in tags can be assigned but not renamed, automatic ones are set by the app; both carry a lock and their origin in words. A tag on part of the selection reads "2 of 3" with Add to all; every change is listed with the items it touches before saving ("Add #vintage to Dusty Rhodes chords and Felt piano bed"); a partial save names the one tag that didn't stick and keeps it for Retry.

## Use it for

- Tagging one or many items in a library, with tags in groups and some set by the app.
- Any bulk edit where the person must see which items each change touches before saving.

## Not for

- Typing tags into one form field ([tag-input](https://beamline.io/components/tag-input)).
- Finding items by their tags ([sound-library](https://beamline.io/components/sound-library)).

## Anatomy

- header: the product's mark and the title
- items: select all with the count, each item with its detail and tag count
- tree: groups that fold and say how many of their tags are on the selection; each tag with its tick (on all, some or none), "2 of 3" with Add to all, rename or its lock and origin; New tag at the end of a group
- changes: each change with the items it touches, Discard and Save; the outcome with Retry

## States

- selection: none (ticks off, said), one, several
- a tag on all, some (2 of 3) or none of the selection
- built-in (assignable, not renamable), automatic (locked, says what sets it)
- renaming and creating in place: empty or taken name said; a failure puts the old name back and says why
- saving, saved, partly saved (the tag that didn't stick named, kept for Retry), nothing saved
- phone: items above the tags
- right to left: mirrors

## Keyboard

- Tab through select all, each item, each group's fold, each tag's tick, Add to all, rename and New tag, then Discard and Save; Enter commits a name, Escape cancels

## Motion

The fold's chevron turns.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `items` (required) | `TaggedItem[]` | — |  |
| `groups` (required) | `TagGroup[]` | — |  |
| `defaultSelected` | `string[]` | — | Items selected at first. |
| `defaultOpen` | `string[]` | — | Groups open at first; the rest start folded. |
| `defaultChanges` | `TagChange[]` | — | Changes already made but not saved, as if the person had ticked them. |
| `onSave` | `((changes: TagChange[]) => Promise<void \| TagSaveResult>)` | — | Save the changes; resolve with what didn't stick (named, kept for retry), reject when nothing was saved. |
| `onRename` | `((tagId: string, name: string) => Promise<void>)` | — |  |
| `onCreate` | `((groupId: string, name: string) => Promise<string>)` | — | Create a tag in a group; resolve with its id. |
| `product` | `string` | — |  |
| `className` | `string` | — | Classes on the documented visual root; no override by default. |
| `ref` | `Ref<HTMLDivElement>` | — | Receives the documented native target or imperative handle; omitted by default. |

## Built from

- [Avatar](https://beamline.io/components/avatar.md)
- [Button](https://beamline.io/components/button.md)
- [Checkbox](https://beamline.io/components/checkbox.md)
- [Empty state](https://beamline.io/components/empty-state.md)
- [Input](https://beamline.io/components/input.md)
- [Label](https://beamline.io/components/label.md)
- [Spinner](https://beamline.io/components/spinner.md)

## Dependencies

`lucide-react`

## Import

```tsx
import { TagManager } from "@beamline/tag-manager";
```

## Get it

Tag manager is part of Beamline UI. Install the parts you need in your React app as compiled packages or editable source. [Get Beamline](https://beamline.io/checkout?pack=complete) · [Connect your agent](https://beamline.io/connect)

## More in Manufacturing

- [Shop floor](https://beamline.io/components/shop-floor): A workshop's shop floor at one workstation: each job is a card at its work centre with why it isn't ready said in words (parts short, or the previous…
- [Production plan](https://beamline.io/components/production-plan): A production plan by month: each product's starting stock, forecast demand, replenishment and ending stock, every ending rolling into the next month's…
- [Production and lots](https://beamline.io/components/production-lots): Stock made and stored, with every movement traceable. A batch of a recipe, read as a batch sheet: the recipe, batches (in halves) and day as one sentence…
- [Print scheduler](https://beamline.io/components/print-scheduler): A print shop's production schedule. The week by station: each station's day holds its runs, with a load bar and minutes used against the station's…
- [Plan readiness](https://beamline.io/components/plan-readiness): A solar plan on its way to a permit. The design checks (fire setback from the ridge, string voltage in the cold, roof load, eave and rake setbacks, the…
- [Design inputs](https://beamline.io/components/design-inputs): What a solar design is checked against, and what the home really uses. Code standards and site conditions (building, electrical and fire codes, wind…
- [Solar quote](https://beamline.io/components/solar-quote): A residential solar quote. The system's price at its rate per watt with adders, discounts and incentives each switched on or off: discounts come off one…
- [Roof layout](https://beamline.io/components/roof-layout): The roof of a solar design. The roof in plan with every face's panels drawn as they lie under its roof type's rules (projected from the slope), each…
- [Electrical design](https://beamline.io/components/electrical-design): The electrical side of a solar design. The existing service set up from a named way of connecting to it (a load-side breaker or a supply-side tap), the…
- [Battery sizing](https://beamline.io/components/battery-sizing): A home battery sized beside its solar. The model and how many with capacity, power and installed price; how it runs (kept full for an outage, storing…
- [Field conditions](https://beamline.io/components/field-conditions): A farm's fields and what each one's conditions are. The fields as a searchable list (each with its outline, crop, area and the layer's value, or Not…
- [Grazing plan](https://beamline.io/components/grazing-plan): Mobs on a grazing rotation, on the farm's map: with a map base, its parcels are the paddocks, each filled by where it stands in the chosen mob's plan (on…
- [Run of show](https://beamline.io/components/run-of-show): One service or event plan's order, run more than once: sections and items with each occurrence's start time in its own column, each item's length dragged…
- [Sound library](https://beamline.io/components/sound-library): A library of sounds (or any media a person auditions before using): a search by words and #tags with facets as filters, a live "3 filters · 12 results"…

Part of [Beamline UI: polished, editable React components and complete screens for custom applications](https://beamline.io/). [Build your own style from any look; tokens, fonts, radii, motion; not only colours](https://beamline.io/docs/customize).
