Tag Input

A text field that turns what's typed into a list of removable tags.

DesignResearch2 tags: Design, Research.

Installation

  1. Add the registryOnce per project
  2. Add tag-input

Usage

TagInput holds the tags as strings and draws the box around them. TagInputList renders a TagInputItem for each tag, or calls its child for each one. Enter adds what's been typed, and so does typing a comma. Pass delimiters to use other characters in its place. Pasted text is split on them too, and on new lines and tabs, so a pasted list becomes a tag per line, and any it turns away stay in the input to fix. Tags are trimmed, with runs of spaces collapsed, and a tag that's already there, ignoring case, is turned away unless you set allowDuplicates.

Backspace with the caret at the start of the input highlights the last tag, and a second Backspace removes it. While a tag is highlighted, the left and right arrows, Home and End move between tags, Delete removes it and Escape lets it go. Each change is announced to screen readers.

To suggest tags as people type, pass suggestions and add a TagInputContent, as below. For a single value, use an Autocomplete, which suggests the same way. To pick several from a short, fixed list, a Combobox with multiple also works.

Composition

Examples

With a label

Put it in a Field, and point a FieldLabel at the input's id.

TypeScriptReact2 tags: TypeScript, React.

Press Enter or type a comma to add one.

Limit

max caps the number of tags. Control the value to show how many are left.

LaunchQ32 tags: Launch, Q3.

2 of 4 labels

Validation

validate decides which tags to take, and onTagReject tells you which it turned away and why: validate returned false, the tag's a duplicate, there were max already, or it's unlisted among the suggestions, as below. Set invalid on the Field to show the error. Here spaces separate addresses as well as commas, and addOnBlur adds an address left in the input when focus leaves it.

ada@example.com1 tag: ada@example.com.

Separate addresses with commas or spaces, or paste a list.

Editable

With editable, double-clicking a tag, or pressing Enter while it's highlighted, edits it in place. Enter or leaving the tag saves it, Escape cancels, and clearing it removes the tag. When the new text is turned away, Enter keeps the tag open to fix it, and leaving it puts the old text back.

OnboardingBillingMobile app3 tags: Onboarding, Billing, Mobile app.

Double-click a tag to rename it.

Suggestions

Pass the tags to suggest as suggestions, and put a TagInputSuggestions in a TagInputContent. The list opens as people type, or on the down arrow, and leaves out the tags already added. The up and down arrows move through it, and Enter or a click adds the highlighted suggestion. With none highlighted, Enter adds what's been typed, so people can still add a tag that isn't suggested, and typing one that matches a suggestion but for its case adds the suggestion's spelling. Set autoHighlight to highlight the first match as people type, so Enter adds it instead.

TypeScript1 tag: TypeScript.

Pick a suggestion, or type any language and press Enter.

Custom suggestions

Pass TagInputSuggestions a function to render each suggestion. suggestionLabel gives the text people's typing matches, here a person's name as well as their email address, and autoHighlight lets Enter add the first person who matches. A TagInputEmpty shows when nothing matches. Without one, the list closes.

APAda Park1 tag: ada@example.com.

Async suggestions

To load suggestions from somewhere else, such as a search endpoint, pass loadSuggestions in place of suggestions. It's called with the typed text once people stop typing for loadDelay milliseconds, 300 by default, and with an AbortSignal that aborts when they type again, so pass it on to fetch. When it reads anything besides the typed text, such as a selected category, list that in loadDeps so suggestions load again when it changes.

The results are shown as given, less the tags already added. A TagInputStatus shows a spinner while they load and a message if loading fails, and screen readers announce both. Until new results arrive, the last ones stay in the list, dimmed. Here a stand-in for the endpoint answers after 600 milliseconds with the libraries that start with what's typed.

Suggestions load as you type, such as "re".

Only suggestions

Set allowCustom={false} to take only tags among the suggestions. Typed text that matches one, ignoring case, adds it with the suggestion's spelling, and autoHighlight is on, so Enter adds the first match. Anything else stays in the input, and onTagReject gets it with the reason unlisted.

Bug1 tag: Bug.

Choose from the project’s labels.

It works with loadSuggestions too, where any result it's returned counts. When Enter comes before the results for what's typed, it waits for them, then adds the first one that isn't already a tag, the same one it would have added had they been there, or turns the text away when there's none:

Custom tags

Pass TagInputList a function to render each tag yourself. A TagInputClear removes them all.

releasechangelogv23 tags: release, changelog, v2.

In a form

Give a Field or the tag input a name, and each tag submits under it in order, so formData.getAll(name) returns them, and a Form's onFormSubmit gets them as an array. Text typed that isn't a tag yet never submits. Pass form with a form's id when the tag input sits outside it. With required, the form won't submit without a tag, which fails as valueMissing. addOnBlur adds text left in the input as focus moves to the submit button. A form reset brings back defaultValue.

MotionTypography2 tags: Motion, Typography.

Each topic submits as its own value.

Sizes

Default1 tag: Default.
Large1 tag: Large.

Disabled and read-only

A read-only tag input shows its tags without remove buttons, and turns away new ones. A disabled Field disables the tag input inside it too.

us-east-1eu-west-12 tags: us-east-1, eu-west-1.
us-east-1eu-west-12 tags: us-east-1, eu-west-1.

Props

The tags keep their order and are strings. To add one from outside the input, control value. To manage loading yourself instead of with loadSuggestions, change suggestions as people type, and pass filter={null} to show them as given. TagInputContent takes side, sideOffset, align, alignOffset and anchor.

The tables leave out className, style and render. Parts built on Base UI take them as its styling and composition guides describe.

TagInput

TagInputList

TagInputItem

TagInputContent

TagInputSuggestions

TagInputSuggestion

TagInputStatus

TagInputClear