Components
Tags input

Tags Input

Tag inputs render tags inside an input, followed by an actual text input. By default, tags are added when text is typed in the input field and the Enter or Comma key is pressed. Throughout the interaction, DOM focus remains on the input element.

React
Solid
Vue

Import

import {
  Tag,
  TagDeleteTrigger,
  TagInput,
  TagsInput,
  TagsInputClearTrigger,
  TagsInputControl,
  TagsInputInput,
  TagsInputLabel,
} from '@ark-ui/react'

Usage

The TagsInput component consists of the Tag, TagInput, TagsInputControl, TagsInputInput, TagsInputClearTrigger, TagDeleteTrigger and TagsInputLabel components. Combine them as desired to fit your design system.

Note that the TagsInputClearTrigger and TagDeleteTrigger components accept a single JSX element which will receive all necessary props to add the event listeners and attributes to ensure the desired accessibility.

<TagsInput>
  {({ value }) => (
    <>
      <TagsInputLabel>Label</TagsInputLabel>
      <TagsInputControl>
        {(value ?? []).map((value, index) => (
          <Fragment key={index}>
            <Tag index={index} value={value}>
              <span>{value}</span>
              <TagDeleteTrigger index={index} value={value}>
                x
              </TagDeleteTrigger>
            </Tag>
            <TagInput index={index} value={value} />
          </Fragment>
        ))}
        <TagsInputInput placeholder="Add tag" />
        <TagsInputClearTrigger>Clear all</TagsInputClearTrigger>
      </TagsInputControl>
    </>
  )}
</TagsInput>

When the input has an empty value or the caret is at the start position, the tags can be selected by using the arrow left and arrow right keys. When “visual” focus in on any tag:

  • Pressing Enter or double-clicking on the tag will put it in edit mode, allowing the user change its value and press Enter to commit the changes.
  • Pressing Delete or Backspace will delete the tag that has visual focus.

Setting the initial tags

To set the initial tag values, set the defaultValue prop.

<TagsInput defaultValue={['foo', 'bar']}>{/*...*/}</TagsInput>

Limiting the number of tags

To limit the number of tags within the component, you can set the max property to the limit you want. The default value is Infinity.

When the tag reaches the limit, new tags cannot be added except the allowOverflow prop is set to true.

<TagsInput max={3} allowOverflow>
  {/*...*/}
</TagsInput>

Validating Tags

Before a tag is added, the validate function is called to determine whether to accept or reject a tag.

A common use-case for validating tags is preventing duplicates or validating the data type.

<TagsInput
  validate={(details) => {
    return !details.values.includes(details.inputValue)
  }}
>
  {/*...*/}
</TagsInput>

Blur behavior

When the tags input is blurred, you can configure the action the component should take by passing the blurBehavior prop.

  • add — Adds the tag to the list of tags.
  • clear — Clears the tags input value.
<TagsInput blurBehavior="add">{/*...*/}</TagsInput>

Paste behavior

To add a tag when a arbitrary value is pasted in the input element, pass the addOnPaste prop.

When a value is pasted, the component will:

  • check if the value is a valid tag based on the validate option
  • split the value by the delimiter option passed
<TagsInput addOnPaste delimiter=",">
  {/*...*/}
</TagsInput>

Disable tag editing

by default the tags can be edited by double-clicking on the tag or focusing on them and pressing Enter. To disable this behavior, pass allowEditTag={false}

<TagsInput allowEditTag={false}>{/*...*/}</TagsInput>

Events

During the lifetime of the tags input interaction, here’s a list of events we emit:

  • onChange — invoked when the tag value changes.
  • onHighlight — invoked when a tag has visual focus.
  • onInvalid — invoked when the max tag count is reached or the validate function returns false.
<TagsInput
  onChange={(details) => {
    console.log('tags changed to:', details.values)
  }}
  onHighlight={(details) => {
    console.log('highlighted tag:', details.value)
  }}
  onInvalid={(details) => {
    console.log('Invalid!', details.reason)
  }}
>
  {/*...*/}
</TagsInput>

Previous

Tabs

Next

Toast