Inspector Tags

landing pagesaaspricing
About this component

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.

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)} />

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*string—Label rendered above the tags, inside the block.
iconLucideIcon—Optional leading icon shown before the label.
valuestring[]—Controlled value. Pair it with `onValueChange`.
defaultValuestring[]—Initial value in uncontrolled mode.
onValueChange(value: string[]) => void—Fires whenever a tag is added or removed, never mid-typing.
placeholderstring—Ghost text shown in the field while there is room for another tag.
maxnumber—Most tags the block may hold. Setting it also puts a count beside the label, since a limit nobody can see is a trap.
maxLengthnumber—Longest a single tag may be.
collapsibleboolean—Let 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.
openboolean—Controlled open state. Pair it with `onOpenChange`.
defaultOpenbooleantrueWhether it starts open in uncontrolled mode.
onOpenChange(open: boolean) => void—
allowDuplicatesboolean—Keep repeats. By default a tag already in the list is dropped.
caseSensitiveboolean—Treat tags differing only in case as different. Off by default, so pasting `React, react` leaves one tag.
disabledboolean—Block 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.
namestring—Name 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.
idstring—Id of the field. One is generated when it is left out.
classNamestring—
aria-labelstring—Accessible name for the field. Falls back to the visible label.

More Inspector components

View all Inspector