Meet Frontfriend.Your brand. Your rules. Your agents, connected.Explore what’s new
DocumentationTagsInput

TagsInput

Interactive preview

Rendered from the shared Frontfriend stories with React Base, the same preview Studio shows. Styling comes from your Design System; the code below is native to Radix UI.

Installation

Complete project setup first. Your configuration must select react/radix and include your Design System ID.

pnpm exec frontfriend download tags-input -f react --primitive radix

Review dependencies reported by the downloader and keep your source changes in version control.

Usage

import {
  TagsInput,
  TagsInputItem,
  TagsInputItemText,
  TagsInputItemDelete,
  TagsInputInput,
} from "@/components/ui/tags-input";
import * as React from "react";
export default function TagsInputExample() {
  const [value, setValue] = React.useState(["react", "vue"]);
  return (
    <TagsInput
      value={value}
      onValueChange={setValue}
      disabled={false}
      className="w-80"
    >
      {value.map((tag) => (
        <TagsInputItem key={tag} value={tag}>
          <TagsInputItemText />
          <TagsInputItemDelete />
        </TagsInputItem>
      ))}
      <TagsInputInput placeholder="Add a tag..." />
    </TagsInput>
  );
}

Examples

Default

import {
  TagsInput,
  TagsInputItem,
  TagsInputItemText,
  TagsInputItemDelete,
  TagsInputInput,
} from "@/components/ui/tags-input";
import * as React from "react";
function TagsField({
  initial,
  disabled,
}: {
  initial: string[];
  disabled?: boolean;
}) {
  const [tags, setTags] = React.useState<string[]>(initial);
  return (
    <div className="w-[320px]">
      <TagsInput value={tags} onValueChange={setTags} disabled={disabled}>
        {tags.map((tag) => (
          <TagsInputItem key={tag} value={tag}>
            <TagsInputItemText />
            <TagsInputItemDelete />
          </TagsInputItem>
        ))}
        <TagsInputInput placeholder="Add tag..." />
      </TagsInput>
    </div>
  );
}
<TagsField initial={["react", "vue"]} />;

Empty

import {
  TagsInput,
  TagsInputItem,
  TagsInputItemText,
  TagsInputItemDelete,
  TagsInputInput,
} from "@/components/ui/tags-input";
import * as React from "react";
function TagsField({
  initial,
  disabled,
}: {
  initial: string[];
  disabled?: boolean;
}) {
  const [tags, setTags] = React.useState<string[]>(initial);
  return (
    <div className="w-[320px]">
      <TagsInput value={tags} onValueChange={setTags} disabled={disabled}>
        {tags.map((tag) => (
          <TagsInputItem key={tag} value={tag}>
            <TagsInputItemText />
            <TagsInputItemDelete />
          </TagsInputItem>
        ))}
        <TagsInputInput placeholder="Add tag..." />
      </TagsInput>
    </div>
  );
}
<TagsField initial={[]} />;

Disabled

import {
  TagsInput,
  TagsInputItem,
  TagsInputItemText,
  TagsInputItemDelete,
  TagsInputInput,
} from "@/components/ui/tags-input";
import * as React from "react";
function TagsField({
  initial,
  disabled,
}: {
  initial: string[];
  disabled?: boolean;
}) {
  const [tags, setTags] = React.useState<string[]>(initial);
  return (
    <div className="w-[320px]">
      <TagsInput value={tags} onValueChange={setTags} disabled={disabled}>
        {tags.map((tag) => (
          <TagsInputItem key={tag} value={tag}>
            <TagsInputItemText />
            <TagsInputItemDelete />
          </TagsInputItem>
        ))}
        <TagsInputInput placeholder="Add tag..." />
      </TagsInput>
    </div>
  );
}
<TagsField initial={["react", "vue"]} disabled />;

API reference

Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Radix UI.

TagsInput

Prop Type Default Description
addOnBlur boolean false
addOnPaste boolean false
addOnTab boolean false
convertValue (value: string) => string (nextValue) => nextValue.trim()
defaultValue string[] []
delimiter string ","
disabled boolean false
displayValue (value: string) => string (nextValue) => nextValue
duplicate boolean false
id string —
max number 0
onAddTag (value: string) => void —
onInvalid (value: string, reason: TagsInputInvalidReason) => void —
onRemoveTag (value: string) => void —
onValueChange (value: string[]) => void —
value string[] —

TagsInputInput

Prop Type Default Description
autoFocus boolean —
maxLength number —
placeholder string —

TagsInputItem

Prop Type Default Description
addOnBlur boolean —
addOnPaste boolean —
addOnTab boolean —
autoFocus boolean —
convertValue (value: string) => string —
defaultValue string[] —
delimiter string —
disabled boolean false
displayValue (value: string) => string —
duplicate boolean —
max number —
maxLength number —
onAddTag (value: string) => void —
onInvalid (value: string, reason: TagsInputInvalidReason) => void —
onRemoveTag (value: string) => void —
onValueChange (value: string[]) => void —
placeholder string —
value string —

Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.