Tags Input

GitHubnpm
Tags input render tags inside an input, followed by an actual text input.
Apple
Banana
<script setup lang="ts">
import { TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from 'akar';
import { ref } from 'vue';

const modelValue = ref(['Apple', 'Banana']);
</script>

<template>
  <div class="akar-demo akar-demo-TagsInput">
    <TagsInputRoot
      v-model="modelValue"
      class="border-blackA7 p-2 border rounded-lg bg-white flex flex-wrap gap-2 w-[380px] w-full items-center"
    >
      <TagsInputItem
        v-for="item in modelValue"
        :key="item"
        :value="item"
        class="bg-green8 aria-[current=true]:bg-green9 color-white p-1 rounded flex gap-2 shadow-md items-center justify-center"
      >
        <TagsInputItemText class="text-sm pl-1" />
        <TagsInputItemDelete class="hover:bg-blackA4 p-0.5 rounded bg-transparent">
          <PIcon name="i-lucide-x" />
        </TagsInputItemDelete>
      </TagsInputItem>

      <TagsInputInput
        placeholder="Fruits..."
        class="color-green9 placeholder:color-mauve9 text-sm px-1 rounded bg-transparent flex-1 focus:outline-none"
      />
    </TagsInputRoot>
  </div>
</template>

Features

  • Can be controlled or uncontrolled.
  • Full keyboard navigation.
  • Limit the number of tags.
  • Accept value from clipboard.
  • Clear button to reset all tags values.

Installation

Install the component from your command line.

pnpm add akar

Anatomy

Import all parts and piece them together.

<script setup>
import { TagsInputClear, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from 'akar';
</script>

<template>
  <TagsInputRoot>
    <TagsInputItem>
      <TagsInputItemText />
      <TagsInputItemDelete />
    </TagsInputItem>

    <TagsInputInput />
    <TagsInputClear />
  </TagsInputRoot>
</template>

API Reference

Root

Contains all the tags input component parts.

PropDefaultType
addOnBlur
boolean

When true allow adding tags blur input

addOnPaste
boolean

When true, allow adding tags on paste. Work in conjunction with delimiter prop.

addOnTab
boolean

When true allow adding tags on tab keydown

as
"div"
AsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

convertValue
((value: string) => T)

Convert the input value to the desired type. Mandatory when using objects as values and using TagsInputInput

defaultValue
[]
T[]

The value of the tags that should be added. Use when you do not need to control the state of the tags input

delimiter
","
string | RegExp

The character or regular expression to trigger the addition of a new tag. Also used to split tags for @paste event

dir
"ltr" | "rtl"

The reading direction of the combobox when applicable.

If omitted, inherits globally from ConfigProvider or assumes LTR (left-to-right) reading mode.

disabled
boolean

When true, prevents the user from interacting with the tags input.

displayValue
value.toString()
((value: T) => string)

Display the value of the tag. Useful when you want to apply modifications to the value like adding a suffix or when using object as values

duplicate
boolean

When true, allow duplicated tags.

id
string
max
0
number

Maximum number of tags.

modelValue
T[] | null

The controlled value of the tags input. Can be bind as v-model.

name
string

The name of the field. Submitted with its owning form as part of a name/value pair.

required
boolean

When true, indicates that the user must set the value before the owning form can be submitted.

EventPayload
addTag
payload: T

Event handler called when tag is added

invalid
payload: T

Event handler called when the value is invalid

removeTag
payload: T

Event handler called when tag is removed

update:modelValue
payload: T[]

Event handler called when the value changes

Slot (default)Payload
modelValue
string | number | bigint | Record<string, any>

Current input values

TagsInputRoot.vue source

Data attribute Value
[data-disabled]
Present when disabled
[data-focused]
Present when focus on input
[data-invalid]
Present when input value is invalid

Item

The component that contains the tag.

PropDefaultType
as
"div"
AsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

disabled
boolean

When true, prevents the user from interacting with the tags input.

value*
string | number | bigint | Record<string, any>

Value associated with the tags

TagsInputItem.vue source

Data attribute Value
[data-state]
"active" | "inactive"
[data-disabled]
Present when disabled

ItemText

The textual part of the tag. Important for accessibility.

PropDefaultType
as
"span"
AsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

TagsInputItemText.vue source

ItemDelete

The button that delete the associate tag.

PropDefaultType
as
"button"
AsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

TagsInputItemDelete.vue source

Data attribute Value
[data-state]
"active" | "inactive"
[data-disabled]
Present when disabled

Input

The input element for the tags input.

PropDefaultType
as
"input"
AsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

autoFocus
boolean

Focus on element when mounted.

maxLength
number

Maximum number of character allowed.

placeholder
string

The placeholder character to use for empty tags input.

TagsInputInput.vue source

Data attribute Value
[data-invalid]
Present when input value is invalid

Clear

The button that remove all tags.

PropDefaultType
as
"button"
AsTag | Component

The element or component this component should render as. Can be overwritten by asChild.

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

TagsInputClear.vue source

Data attribute Value
[data-disabled]
Present when disabled

Examples

Paste behavior

You can automatically add tags on paste by passing the add-on-paste prop.

<script setup lang="ts">
import { TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from 'akar'
</script>

<template>
  <TagsInputRoot
    v-model="modelValue"
    add-on-paste
  >
    …
  </TagsInputRoot>
</template>

Multiple delimiters

You can pass RegExp as delimiter to allow multiple characters to trigger addition of a new tag. When add-on-paste is passed it will be also used to split tags for @paste event.

<script setup lang="ts">
import { TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from 'akar'

// split by space, comma, semicolon, tab, or newline
const delimiter = /[ ,;\t\n\r]+/
</script>

<template>
  <TagsInputRoot
    v-model="modelValue"
    :delimiter="delimiter"
    add-on-paste
  >
    …
  </TagsInputRoot>
</template>

Accessibility

Keyboard Interactions

Key Description
Delete
When tag is active, remove it and set the tag on right active.
Backspace
When tag is active, remove it and set the tag on left active. If there are no tags to the left, either the next tags gets focus, or the input.
ArrowRight
Set the next tag active.
ArrowLeft
Set the previous tag active.
Home
Set the first tag active
End
Set the last tag active