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) => voidCalled when tags change
suggestionsstring[][]Autocomplete suggestions
maxTagsnumberMaximum number of tags
allowDuplicatesbooleanfalseAllow duplicate tags
delimiterstring | string[]["Enter", ","]Keys that confirm a tag
validate(tag) => booleanCustom validation function
tagVariant"solid" | "subtle" | "outline""solid"Tag chip style
labelstringVisible label
hintstringHelper text below input
errorstringError message (overrides hint)
size"sm" | "md" | "lg""md"Input size
tone"neutral" | "primary" | "success" | "danger""neutral"Color tone
disabledbooleanfalseDisable interaction
maxLengthnumberMax chars per tag
caseSensitivebooleanfalseCase-sensitive duplicate detection
onTagAdd(tag) => voidTag added callback
onTagRemove(tag, index) => voidTag removed callback
renderTag(tag, i, onRemove) => ReactNodeCustom 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) => stringNormalize 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