Tags Input 
 Tag inputs render tags inside an input, followed by an actual text input. 
Apple
Banana
vue
<script setup lang="ts">
import { ref } from 'vue'
import { TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from 'radix-vue'
import { Icon } from '@iconify/vue'
const modelValue = ref(['Apple', 'Banana'])
</script>
<template>
  <TagsInputRoot
    v-model="modelValue"
    class="flex gap-2 items-center border p-2 rounded-lg w-full max-w-[480px] flex-wrap border-blackA7 bg-white"
  >
    <TagsInputItem v-for="item in modelValue" :key="item" :value="item" class="text-white flex shadow-md items-center justify-center gap-2 bg-green8 aria-[current=true]:bg-green9 rounded p-1">
      <TagsInputItemText class="text-sm pl-1" />
      <TagsInputItemDelete class="p-0.5 rounded bg-transparent hover:bg-blackA4">
        <Icon icon="lucide:x" />
      </TagsInputItemDelete>
    </TagsInputItem>
    <TagsInputInput placeholder="Fruits..." class="text-sm focus:outline-none flex-1 rounded text-green9 bg-transparent placeholder:text-mauve9 px-1" />
  </TagsInputRoot>
</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.
bash
npm install radix-vueAnatomy 
Import all parts and piece them together.
vue
<script setup>
import { TagsInputClear, TagsInputDelete, TagsInputInput, TagsInputItem, TagsInputRoot, TagsInputText } from 'radix-vue'
</script>
<template>
  <TagsInputRoot>
    <TagsInputItem>
      <TagsInputItemText />
      <TagsInputItemDelete />
    </TagsInputItem>
    <TagsInputInput />
    <TagsInputClear />
  </TagsInputRoot>
</template>API Reference 
Root 
Contains all the tags input component parts.
| Prop | Type | Default | 
|---|---|---|
| defaultValue | string | |
| modelValue | string | |
| addOnPaste | boolean | |
| delimiter | string | , (comma) | 
| duplicate | boolean | false | 
| dir | enum | |
| disabled | boolean | false | 
| max | number | |
| required | boolean | |
| name | string | |
| as | string | Component | div | 
| asChild | boolean | false | 
| Emit | Type | 
|---|---|
| @update:modelValue | (value: string) => void | 
| @invalid | (value: string) => void | 
| 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.
| Prop | Type | Default | 
|---|---|---|
| as | string | Component | div | 
| asChild | boolean | false | 
| disabled | boolean | false | 
| value | string | 
| Data Attribute | Value | 
|---|---|
| [data-state] | "active" | "inactive" | 
| [data-disabled] | Present when disabled | 
ItemText 
The textual part of the tag. Important for accessibility.
| Prop | Type | Default | 
|---|---|---|
| as | string | Component | span | 
| asChild | boolean | false | 
ItemDelete 
The button that delete the associate tag.
| Prop | Type | Default | 
|---|---|---|
| as | string | Component | button | 
| asChild | boolean | false | 
| Data Attribute | Value | 
|---|---|
| [data-state] | "active" | "inactive" | 
| [data-disabled] | Present when disabled | 
Input 
The input element for the tags input.
| Prop | Type | Default | 
|---|---|---|
| as | string | Component | input | 
| asChild | boolean | false | 
| placeholder | string | |
| autoFocus | boolean | |
| maxLength | number | 
| Data Attribute | Value | 
|---|---|
| [data-invalid] | Present when input value is invalid | 
Clear 
The button that remove all tags.
| Prop | Type | Default | 
|---|---|---|
| as | string | Component | button | 
| asChild | boolean | false | 
| Data Attribute | Value | 
|---|---|
| [data-disabled] | Present when disabled | 
Examples 
With Combobox 
You can compose Tags input together with Combobox.
Apple
vue
<script setup lang="ts">
import { ref, watch } from 'vue'
import { ComboboxAnchor, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxLabel, ComboboxRoot, ComboboxTrigger, ComboboxViewport, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from 'radix-vue'
import { Icon } from '@iconify/vue'
const searchTerm = ref('')
const values = ref(['Apple'])
const options = ['Apple', 'Banana', 'Blueberry', 'Grapes', 'Pineapple']
watch(values, () => {
  searchTerm.value = ''
}, { deep: true })
</script>
<template>
  <ComboboxRoot
    v-model="values"
    v-model:search-term="searchTerm"
    multiple
    class="my-4 mx-auto relative"
  >
    <ComboboxAnchor class="w-[400px] inline-flex items-center justify-between rounded-lg p-2 text-[13px] leading-none  gap-[5px] bg-white text-grass11 shadow-[0_2px_10px] shadow-black/10 hover:bg-mauve3 focus:shadow-[0_0_0_2px] focus:shadow-black data-[placeholder]:text-grass9 outline-none">
      <TagsInputRoot
        v-slot="{ values: tags }"
        :model-value="values"
        delimiter=""
        class="flex gap-2 items-center rounded-lg flex-wrap"
      >
        <TagsInputItem
          v-for="item in tags" :key="item"
          :value="item"
          class="flex items-center justify-center gap-2 text-white bg-grass8 aria-[current=true]:bg-grass9 rounded px-2 py-1"
        >
          <TagsInputItemText class="text-sm" />
          <TagsInputItemDelete>
            <Icon icon="lucide:x" />
          </TagsInputItemDelete>
        </TagsInputItem>
        <ComboboxInput as-child>
          <TagsInputInput
            placeholder="Fruits..."
            class="focus:outline-none flex-1 rounded !bg-transparent  placeholder:text-mauve10 px-1"
            @keydown.enter.prevent
          />
        </ComboboxInput>
      </TagsInputRoot>
      <ComboboxTrigger>
        <Icon icon="radix-icons:chevron-down" class="h-4 w-4 text-grass11" />
      </ComboboxTrigger>
    </ComboboxAnchor>
    <ComboboxContent class="absolute z-10 w-full mt-2 bg-white overflow-hidden rounded shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade">
      <ComboboxViewport class="p-[5px]">
        <ComboboxEmpty class="text-gray-400  text-xs font-medium text-center py-2" />
        <ComboboxGroup>
          <ComboboxLabel class="px-[25px] text-xs leading-[25px] text-mauve11">
            Fruits
          </ComboboxLabel>
          <ComboboxItem
            v-for="(option, index) in options" :key="index"
            class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] pr-[35px] pl-[25px] relative select-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:outline-none data-[highlighted]:bg-grass8 data-[highlighted]:text-grass1"
            :value="option"
          >
            <ComboboxItemIndicator
              class="absolute left-0 w-[25px] inline-flex items-center justify-center"
            >
              <Icon icon="radix-icons:check" />
            </ComboboxItemIndicator>
            <span>
              {{ option }}
            </span>
          </ComboboxItem>
        </ComboboxGroup>
      </ComboboxViewport>
    </ComboboxContent>
  </ComboboxRoot>
</template>Paste behavior 
You can automatically add tags on paste by passing the add-on-paste prop.
vue
<script setup lang="ts">
import { TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from 'radix-vue'
</script>
<template>
  <TagsInputRoot v-model="modelValue" 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 |