react ~8 KB 0 deps v1.3.0 ↗ GitHub ↗

@mshafiqyajid/react-tag-input

Headless tag input hook and styled component. Chip-style tags, autocomplete dropdown, keyboard navigation, validation, max tags.

Playground #

ReactTypeScript
Paste multiple tags split by comma / newline / tab / semicolon.
Props
TSX
import { TagInputStyled } from "@mshafiqyajid/react-tag-input/styled";
import "@mshafiqyajid/react-tag-input/styles.css";

<TagInputStyled
  value={tags}
  onChange={setTags}
/>

Install #

npm install @mshafiqyajid/react-tag-input

Quick start #

import { TagInputStyled } from "@mshafiqyajid/react-tag-input/styled";
import "@mshafiqyajid/react-tag-input/styles.css";

const [tags, setTags] = useState<string[]>([]);
<TagInputStyled
  value={tags}
  onChange={setTags}
  suggestions={["React", "TypeScript", "Node.js"]}
  maxTags={5}
  label="Technologies"
  tone="primary"
/>

Headless #

import { useTagInput } from "@mshafiqyajid/react-tag-input";

const { tags, inputProps, removeTag } = useTagInput({
  defaultValue: ["react", "ts"],
  maxTags: 5,
});

return (
  <div className="tags">
    {tags.map((tag, i) => (
      <span key={i} className="tag">
        {tag}
        <button onClick={() => removeTag(i)}>×</button>
      </span>
    ))}
    <input {...inputProps} placeholder="Add tag..." />
  </div>
);

API #

PropTypeDefaultDescription
valuestring[]—Controlled tags array
defaultValuestring[][]Uncontrolled initial tags
onChange(tags) => void—Called when tags change
suggestionsstring[][]Autocomplete suggestions
maxTagsnumber—Maximum number of tags
allowDuplicatesbooleanfalseAllow duplicate tags
delimiterstring | string[]["Enter", ","]Keys that confirm a tag
validate(tag) => boolean—Custom validation function
tagVariant"solid" | "subtle" | "outline""solid"Tag chip style
labelstring—Visible label
hintstring—Helper text below input
errorstring—Error message (overrides hint)
size"sm" | "md" | "lg""md"Input size
tone"neutral" | "primary" | "success" | "danger""neutral"Color tone
disabledbooleanfalseDisable interaction
maxLengthnumber—Max chars per tag
caseSensitivebooleanfalseCase-sensitive duplicate detection
onTagAdd(tag) => void—Tag added callback
onTagRemove(tag, index) => void—Tag removed callback
renderTag(tag, i, onRemove) => ReactNode—Custom chip renderer
sortablebooleanfalseDrag-to-reorder tags
pasteDelimiters(string | RegExp)[] | null[",", ";", /\s*\n\s*/, /\s*\t\s*/]Split pasted text into multiple tags. Pass null to disable.
transform(tag) => string—Normalize each tag before insertion (e.g. lowercase, trim).
backspaceEditsLastTagbooleanfalseWhen the input is empty, Backspace pops the last tag back into the input for editing instead of deleting it.
Edit this page on GitHub