---
title: "Tags Input"
description: "Tags input render tags inside an input, followed by an actual text input."
canonical_url: "https://vinicunca.dev/akar/components/tags-input"
---
# Tags Input

> Tags input render tags inside an input, followed by an actual text input.

```vue [index.vue]
<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="flex gap-2 items-center border p-2 rounded-lg w-full w-[380px] 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">
            <PIcon name="i-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>
  </div>
</template>
```

```css [styles.css]
@import '../_colors/black-alpha.css';
@import '../_colors/green.css';
@import '../_colors/mauve.css';
@import '../_colors/grass.css';

@scope (.akar-demo-TagsInput) {
/* reset */
button,
fieldset,
input {
  all: unset;
}
}
```

## 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 [pnpm]
pnpm add akar
```

```bash [yarn]
yarn add akar
```

```bash [npm]
npm install akar
```

```bash [bun]
bun add akar
```

## Anatomy

Import all parts and piece them together.

```vue
<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.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `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.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/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.<br><br>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. |

**Events**

| Event | Payload | Description |
| --- | --- | --- |
| `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 |

**Slots**

| Slot | Payload | Description |
| --- | --- | --- |
| `modelValue` | `string \| number \| bigint \| Record<string, any>` | Current input values |

[TagsInputRoot.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/TagsInput/TagsInputRoot.vue)

| 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.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `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.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/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](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/TagsInput/TagsInputItem.vue)

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

### ItemText

The textual part of the tag. Important for accessibility.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `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.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |

[TagsInputItemText.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/TagsInput/TagsInputItemText.vue)

### ItemDelete

The button that delete the associate tag.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `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.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |

[TagsInputItemDelete.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/TagsInput/TagsInputItemDelete.vue)

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

### Input

The input element for the tags input.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `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.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/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](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/TagsInput/TagsInputInput.vue)

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

### Clear

The button that remove all tags.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `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.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |

[TagsInputClear.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/TagsInput/TagsInputClear.vue)

| 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.

```vue
<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.

```vue
<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 |
| --- | --- |
| <kbd>Delete</kbd> |  When tag is active, remove it and set the tag on right active. |
| <kbd>Backspace</kbd> |  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. |
| <kbd>ArrowRight</kbd> |  Set the next tag active. |
| <kbd>ArrowLeft</kbd> |  Set the previous tag active. |
| <kbd>Home</kbd> |  Set the first tag active |
| <kbd>End</kbd> |  Set the last tag active |

---

- [GitHub](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/TagsInput)
- [npm](https://www.npmjs.com/package/akar)


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
