Inspector Tags

Settings block for a list of short strings: tags are typed one after another and wrap under the label, a comma or a paste splits several at once, and Backspace on an empty field reaches back into the list. Collapsible, so a long list folds down to the height of a row with the count still on it.

landing pagesaaspricing

Installation

Adds the component and everything it depends on to your project.

npx shadcn add https://ui.beste.co/component/r-base/inspector-tags

New here? Read the installation guide.

Usage

The import and the props worth knowing about, in one place.

import { InspectorTags } from "@/components/beste/component/inspector-tags";

// Uncontrolled
<InspectorTags label="Keywords" defaultValue={["saas", "pricing"]} placeholder="Add a keyword" />

// Controlled
<InspectorTags label="Keywords" value={keywords} onValueChange={setKeywords} />

// A ceiling, which also puts a count beside the label
<InspectorTags label="Tags" max={6} value={tags} onValueChange={setTags} />

<InspectorTags
  label="Utility classes"
  icon={BracesIcon}       // optional leading icon
  tone="outline"          // "muted" (default) | "outline" | "ghost"
  size="sm"               // "sm" | "default" | "lg"
  maxLength={24}          // longest a single tag may be
  caseSensitive           // "React" and "react" are then two tags
  allowDuplicates         // keep repeats
  value={classes}
  onValueChange={setClasses}
/>

// Each tag submits under the same name, so the list arrives as a list
<InspectorTags label="Keywords" name="keywords" defaultValue={["a", "b"]} />

// Pasting "one, two, three" adds three tags; typing a comma ends the one in progress
<InspectorTags label="Keywords" onValueChange={(value) => console.log(value)} />

// Folded away when it is not being written. Closed, the block measures exactly what
// a row of the family measures, and the header still counts what is in there.
<InspectorTags label="Keywords" collapsible defaultOpen={false} onOpenChange={(open) => console.log("open:", open)} />

Playground

Turn the props on the right; the snippet under them is what you would write to get what you see.

landing pagesaaspricing
Usage
import { InspectorTags } from "@/components/beste/component/inspector-tags";

<InspectorTags
  label="Keywords"
  className="w-72"
  collapsible
  defaultValue={["landing page","saas","pricing"]}
  placeholder="Add a keyword"
/>

Keyboard and gestures

Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.

EnterAdd what is in the field. It does not submit the surrounding form.
Comma, or a pasteSplits into several tags at once, trimmed and deduped against the list.
Backspace on an empty fieldReach back and take the last tag off.

Props

Read from the component's own type, so this cannot drift from what it accepts.

PropTypeDefaultDescription
label*stringLabel rendered above the tags, inside the block.
iconLucideIconOptional leading icon shown before the label.
valuestring[]Controlled value. Pair it with `onValueChange`.
defaultValuestring[]Initial value in uncontrolled mode.
onValueChange(value: string[]) => voidFires whenever a tag is added or removed, never mid-typing.
placeholderstringGhost text shown in the field while there is room for another tag.
maxnumberMost tags the block may hold. Setting it also puts a count beside the label, since a limit nobody can see is a trap.
maxLengthnumberLongest a single tag may be.
collapsiblebooleanLet the block be folded away, leaving its header. A long list of tags takes several rows of a drawer and is usually written once, so the panel around it is otherwise mostly a scroll past something nobody is editing. Folded, the header still counts what is in there.
openbooleanControlled open state. Pair it with `onOpenChange`.
defaultOpenbooleantrueWhether it starts open in uncontrolled mode.
onOpenChange(open: boolean) => void
allowDuplicatesbooleanKeep repeats. By default a tag already in the list is dropped.
caseSensitivebooleanTreat tags differing only in case as different. Off by default, so pasting `React, react` leaves one tag.
disabledbooleanBlock interaction and dim the block.
tone"muted" | "outline" | "ghost""muted"Surface treatment: filled (default), hairline outline, or bare until focus.
size"sm" | "default" | "lg""default"Padding preset.
namestringName the tags submit under. Each tag becomes its own hidden input, which is how a list reaches a server without being flattened into one string first.
idstringId of the field. One is generated when it is left out.
classNamestring
aria-labelstringAccessible name for the field. Falls back to the visible label.

More Inspector components

View all Inspector

Inspector Textarea

The family's block row: the same surface and tones, but the label sits above a multi-line field whose height comes from the text, with a character count whenever there is a limit to see. Collapsible, so a paragraph written once can be folded down to the height of a row without leaving the form.

Inspector Tracks

The columns of a grid as a list of lengths: the row shows the CSS it comes to, the editor holds one length per line with a picture of the shares above them. There is no reordering on purpose, because a track's place in the list is its place in the grid.

Inspector Code

Settings block for a snippet: a monospaced field with a language chip and a line count, Tab indenting instead of leaving, and a fixed height so a pasted stylesheet cannot push the rest of the drawer out of reach. Collapsible, since a snippet is the tallest thing in a drawer and the least often touched; folded, it measures exactly what a row measures and still reports its line count.

Inspector Spacing

Settings row for the four edges of a box: the row carries a CSS-shorthand summary, and opens a cross where each field sits on the edge it sets, tied together or not.

Inspector Combobox

Settings row for a list too long to read: pressing it opens a width-matched list with a search field, the keyboard walking the results while focus stays in the field. Options carry groups, descriptions, swatches and search keywords, and `multiple` turns the row into a counted multi-select.

Inspector Range

Settings row for a span rather than a value: two thumbs on the row itself, the band between them filling it, and both ends of the pair read out on the right. Ticks, tones and thumb states follow inspector-slider exactly, appearing on hover.