elements
Demos UI Feed Discuss Install
Style System
  • Style
  • Themes
  • Behaviors
Forms
  • Button
  • ButtonGroup
  • Checkbox
  • ColorPicker
  • Combobox
  • Field
  • FileUpload
  • Input
  • InputGroup
  • InputOTP
  • Label
  • NativeSelect
  • NumberInput
  • PasswordInput
  • RadioGroup
  • Select
  • Slider
  • Switch
  • TagsInput
  • Textarea
  • Toggle
  • ToggleGroup
Overlays
  • AlertDialog
  • Command
  • ContextMenu
  • Dialog
  • Drawer
  • DropdownMenu
  • HoverCard
  • Menubar
  • NavigationMenu
  • Popover
  • Sheet
  • Toast
  • Tooltip
Display
  • Accordion
  • Alert
  • AspectRatio
  • Avatar
  • Badge
  • Breadcrumb
  • Card
  • Collapsible
  • Empty
  • Item
  • Kbd
  • Pagination
  • Progress
  • Separator
  • Skeleton
  • Spinner
  • Table
  • Tabs
  • Tree
Layout
  • Carousel
  • Resizable
  • ScrollArea
  • Sidebar
Dates
  • Calendar
  • DatePicker
  • DateRangePicker
  • TimePicker
Data
  • AreaChart
  • BarChart
  • Chart
  • DataTable
  • Kanban
  • LineChart
  • PieChart
  • RadarChart
  • RadialChart
  • VirtualList
Chat
  • Attachment
  • Message
  • MessageList
  • PromptInput
Elements UI / Forms / TagsInput

TagsInput

Type a list of tags into one field: add, edit, delete and paste them from the keyboard.

Autofocus

autofocus through attrs puts the cursor in the input when the page loads, ready for the first tag.

urgent
Code
<TagsInput value={state.focusTags} placeholder="Add a label" attrs={{ autofocus: true }} />

Usage

import { TagsInput } from "@elements/ui/tags-input";

<TagsInput value={post.tags} placeholder="Add a tag" attrs={{ "aria-label": "Tags" }} />
<TagsInput value={invite.emails} delimiter={/[,;\s]/} addOnPaste validate={isEmail} max={10} />

Examples

Basic

Enter or a comma adds a tag. Backspace at the start highlights the last tag, a second Backspace deletes it. Arrows move the highlight; Enter or a double click edits.

applepear
tags: apple|pear; draft: ; changes: 0; highlight: ; invalid: ; outside: 0; pressed: 0
Code
<TagsInput value={state.tags} inputValue={state.draft} placeholder="Add a fruit"
           attrs={{ "aria-label": "Fruits" }} />

Emails

A RegExp delimiter (comma, semicolon or space), paste as tags, and validate refusing what is not an email.

ada@example.com
ada@example.com
Code
<TagsInput value={state.emails} delimiter={/[,;\s]/} addOnPaste
           validate={({ inputValue }) => /^\S+@\S+\.\S+$/.test(inputValue)} />

Limits

max refuses a fourth tag and reports onValueInvalid with reason rangeOverflow; allowOverflow takes it and marks the field invalid. maxLength caps each tag.

onetwo
onetwothree
one|two / one|two|three / onValueInvalid: none
Code
<TagsInput value={state.limited} max={3} onValueInvalid={(d) => state.invalid = d.reason} />
<TagsInput value={state.overflow} max={3} allowOverflow />
<TagsInput value={state.short} maxLength={5} />

Disabled, read-only and invalid

Read-only tags can be highlighted but not changed.

designcode
designcode
oops
Code
<TagsInput value={state.locked} disabled />
<TagsInput value={state.fixed} readonly />
<TagsInput value={state.wrong} invalid />

Disabled tags

disabledTags keeps a tag in place: its delete button is disabled, Backspace and Delete skip it, it cannot be edited, and Clear leaves it.

ownerdesigncode
owner|design|code
Code
<TagsInput value={state.team} disabledTags={["owner"]} />

On blur

blurBehavior add turns leftover text into a tag; clear drops it.

/
Code
<TagsInput value={state.added} blurBehavior="add" />
<TagsInput value={state.cleared} blurBehavior="clear" />

Editing and sanitizing

editable={false} turns off edit mode. sanitizeValue lowercases here, with duplicates allowed.

fixedtags
fixed|tags /
Code
<TagsInput value={state.plain} editable={false} />
<TagsInput value={state.lower} sanitizeValue={(v) => v.trim().toLowerCase()} allowDuplicates />

Set from code

value is two-way: push, assign or clear the array.

Changes show in the Basic demo above.
Code
<TagsInput value={state.tags} />
<Button onclick={() => state.tags.push("cherry")}>Add</Button>
<Button onclick={() => state.tags = ["one", "two"]}>Set</Button>
<Button onclick={() => state.tags = []}>Clear</Button>

In a form

name submits the tags joined by commas; required blocks an empty list; reset restores.

writing

Press Enter after each one.

not submitted
Code
<form onsubmit={(e) => save(e)}>
  <Field label="Skills" description="Press Enter after each one.">
    <TagsInput value={state.skills} name="skills" required />
  </Field>
  <Button type="submit" variant="primary">Save</Button>
</form>

With suggestions

suggestions offers options in a listbox under the input, as a combobox. Typing filters them, ArrowDown and ArrowUp highlight with focus kept in the input, Enter or a click adds the option, and chosen options are not offered again. Enter with nothing highlighted still adds the typed text.

Pear
Pear
Code
<TagsInput value={state.suggested}
           suggestions={["Apple", "Lemon", "Pear", "Cherry", ...]}
           placeholder="Add a fruit" attrs={{ "aria-label": "Fruits" }} />

In a field

Field's label names the text input and its helper text and error describe it. A fourth skill sets error, which shows in its reserved line.

writingediting

Add up to three.

Code
<Field label="Skills" description="Add up to three."
       error={state.skills.length > 3 ? "Pick at most three skills." : ""}>
  <TagsInput value={state.skills} invalid={state.skills.length > 3} />
</Field>

Right to left

Under rtl the arrows swap with the layout. translations replace the button labels and the live-region messages.

تصميمبرمجة
Code
<div dir="rtl" lang="ar">
  <TagsInput value={state.tags}
             translations={{ clearTriggerLabel: "مسح كل الوسوم", deleteTagTriggerLabel: (v) => `حذف ${v}` }} />
</div>
Reference TagsInput in the manual Every part, attribute, slot, key and data attribute.
Prev SwitchNext Textarea
Product
Manual Pricing Compare
Company
History Contact
Legal
Privacy Policy Acceptable Use Terms License Agreement
© Elements Dev Corporation 2026