Tags Input
A neo-brutalist style tag entry component built on reka-ui primitives. Commonly used in form scenarios such as article tags, email recipients, and keyword filtering. Supports keyboard shortcuts, delimiter-based auto-add, and multiple color variants.
Demo
默认
主要
次要
强调
危险
成功
自定义 aria-label
Installation
pnpm dlx brutx-vue@latest add tags-inputUsage
<script setup>
import { ref } from 'vue'
import {
TagsInput,
TagsInputInput,
TagsInputItem,
TagsInputItemText,
TagsInputItemDelete
} from 'brutx-ui-vue'
const tags = ref(['vue', 'css'])
</script>
<template>
<TagsInput v-model="tags">
<TagsInputItem v-for="tag in tags" :key="tag" :value="tag">
<TagsInputItemText>{{ tag }}</TagsInputItemText>
<TagsInputItemDelete />
</TagsInputItem>
<TagsInputInput placeholder="Add tag..." />
</TagsInput>
</template>Variants
You can customize the color scheme of individual tags using the variant prop on TagsInputItem:
| Variant | Description |
|---|---|
primary | Default coral background with black bold border |
secondary | Mint green background |
accent | Brutal yellow background |
success | Classic green background |
danger | Classic red background |
default | Plain white background |
<template>
<TagsInputItem value="css" variant="secondary">
<TagsInputItemText>CSS</TagsInputItemText>
<TagsInputItemDelete />
</TagsInputItem>
</template>Sub-components
| Component | Description |
|---|---|
TagsInput | Root component that manages the tag list state |
TagsInputInput | Text input field |
TagsInputItem | Individual tag item container |
TagsInputItemText | Tag text content |
TagsInputItemDelete | Tag delete button |
API Reference
TagsInput
| Name | Type | Default | Description |
|---|---|---|---|
modelValueNullable | AcceptableInputValue[] | null | undefined | — | The controlled list of tag values, synchronized with v-model. Each value may be a string, number, bigint, or object. |
DetailsDeclared typeAcceptableInputValue[] | null | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
defaultValue | AcceptableInputValue[] | undefined | — | The initial tag list for uncontrolled use. Use modelValue when the list must stay synchronized with external state. |
DetailsDeclared typeAcceptableInputValue[] | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
addOnPaste | boolean | undefined | — | Splits pasted text using delimiter and attempts to add the resulting tags, subject to max and duplicate rules. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
addOnTab | boolean | undefined | — | Commits the current input as a tag when the Tab key is pressed. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
addOnBlur | boolean | undefined | — | Commits the current input as a tag when the input loses focus. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
duplicate | boolean | undefined | — | Allows duplicate tag values in the list. When false, a duplicate value is treated as invalid. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
disabled | boolean | undefined | — | Disables user interaction with the tags-input group and its child items. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
delimiter | string | RegExp | undefined | — | The delimiter used to commit typed input and split pasted text. Accepts a string or regular expression. |
DetailsDeclared typestring | RegExp | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
dir | Direction | undefined | — | Sets the reading direction for the combobox. When omitted, it inherits ConfigProvider or defaults to left-to-right. |
DetailsDeclared typeDirection | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
max | number | undefined | — | The maximum number of tags. Further additions are rejected and emit invalid at the limit; 0 means unlimited. |
DetailsDeclared typenumber | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
id | string | undefined | — | The DOM ID passed to the tags-input root primitive to identify this input group. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
convertValue | ((value: string) => AcceptableInputValue) | undefined | — | Converts typed strings into tag values. It is required when using object values with TagsInputInput. |
DetailsDeclared type((value: string) => AcceptableInputValue) | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
displayValue | ((value: AcceptableInputValue) => string) | undefined | — | Converts a tag value to display text, for example when rendering object values or adding a display suffix. |
DetailsDeclared type((value: AcceptableInputValue) => string) | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
asChild | boolean | undefined | — | Merges the component props and interaction behavior into its single child, which replaces the default rendered element. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
as | AsTag | Component | undefined | — | Selects the HTML tag or Vue component rendered for this tags-input part; asChild takes precedence when both are set. |
DetailsDeclared typeAsTag | Component | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
name | string | undefined | — | The form field name used when this tags input is submitted with its owning form. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
required | boolean | undefined | — | Marks the tags input as required before its owning form can be submitted. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
class | string | undefined | — | Additional CSS classes applied to the tags-input root container. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
ariaLabel | string | undefined | — | The accessible name of the tags-input group. When omitted, the localized tagsInput.label text is used. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInput.vue | |||
| Name | Signature or type | Description |
|---|---|---|
@update:modelValue | [payload: AcceptableInputValue[]] | Emits the updated tag array when the list changes so a controlled v-model can be synchronized. |
DetailsDeclared type[payload: AcceptableInputValue[]] Sourcepackages/ui/src/components/tags-input/TagsInput.vue | ||
@invalid | [payload: AcceptableInputValue] | Emits the rejected tag value when an addition is a duplicate or would exceed max. |
DetailsDeclared type[payload: AcceptableInputValue] Sourcepackages/ui/src/components/tags-input/TagsInput.vue | ||
@addTag | [payload: AcceptableInputValue] | Emits the newly added value after a tag is successfully added. |
DetailsDeclared type[payload: AcceptableInputValue] Sourcepackages/ui/src/components/tags-input/TagsInput.vue | ||
@removeTag | [payload: AcceptableInputValue] | Emits the removed value after a tag is successfully removed. |
DetailsDeclared type[payload: AcceptableInputValue] Sourcepackages/ui/src/components/tags-input/TagsInput.vue | ||
| Name | Signature or type | Description |
|---|---|---|
#default | {} | Composes the tag items and input field. The slot scope exposes modelValue; it usually contains TagsInputItem and TagsInputInput. |
DetailsDeclared type{}Sourcepackages/ui/src/components/tags-input/TagsInput.vue | ||
TagsInputInput
| Name | Type | Default | Description |
|---|---|---|---|
placeholder | string | undefined | — | Placeholder text shown while the input is empty. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputInput.vue | |||
autoFocus | boolean | undefined | — | Moves focus to the input when the component mounts. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputInput.vue | |||
maxLength | number | undefined | — | Limits the number of characters that can be entered in the input. |
DetailsDeclared typenumber | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputInput.vue | |||
asChild | boolean | undefined | — | Merges the component props and interaction behavior into its single child, which replaces the default rendered element. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputInput.vue | |||
as | AsTag | Component | undefined | — | Selects the HTML tag or Vue component rendered for this tags-input part; asChild takes precedence when both are set. |
DetailsDeclared typeAsTag | Component | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputInput.vue | |||
class | string | undefined | — | Additional CSS classes applied to the native tags-input field. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputInput.vue | |||
TagsInputItem
| Name | Type | Default | Description |
|---|---|---|---|
variant | "accent" | "danger" | "default" | "primary" | "secondary" | "success" | undefined | "primary" | Sets the color variant for an individual tag. |
DetailsDeclared typeNonNullable<"default" | "primary" | "secondary" | "success" | "danger" | "accent" | null | undefined> | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItem.vue | |||
class | string | undefined | undefined | Additional CSS classes applied to the individual tag container. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItem.vue | |||
valueRequired | AcceptableInputValue | — | The value represented by this tag, which must match an item in the root tag list. |
DetailsDeclared typeAcceptableInputValue Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItem.vue | |||
disabled | boolean | undefined | — | Prevents interaction with this tag. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItem.vue | |||
asChild | boolean | undefined | — | Merges the component props and interaction behavior into its single child, which replaces the default rendered element. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItem.vue | |||
as | AsTag | Component | undefined | — | Selects the HTML tag or Vue component rendered for this tags-input part; asChild takes precedence when both are set. |
DetailsDeclared typeAsTag | Component | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItem.vue | |||
| Name | Signature or type | Description |
|---|---|---|
#default | {} | Renders the tag item content, commonly TagsInputItemText and TagsInputItemDelete. |
DetailsDeclared type{}Sourcepackages/ui/src/components/tags-input/TagsInputItem.vue | ||
TagsInputItemDelete
| Name | Type | Default | Description |
|---|---|---|---|
class | string | undefined | undefined | Additional CSS classes applied to the tag delete button. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItemDelete.vue | |||
ariaLabel | string | undefined | undefined | The delete button’s accessible name. When omitted, the localized default delete text is used. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItemDelete.vue | |||
type | "button" | "submit" | "reset" | undefined | "button" | Sets the native button type. The default button value avoids accidental form submission. |
DetailsDeclared type"button" | "submit" | "reset" | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItemDelete.vue | |||
asChild | boolean | undefined | — | Merges the component props and interaction behavior into its single child, which replaces the default rendered element. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItemDelete.vue | |||
as | AsTag | Component | undefined | — | Selects the HTML tag or Vue component rendered for this tags-input part; asChild takes precedence when both are set. |
DetailsDeclared typeAsTag | Component | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItemDelete.vue | |||
| Name | Signature or type | Description |
|---|---|---|
#default | {} | Customizes the delete button content; an X icon is shown when omitted. |
DetailsDeclared type{}Sourcepackages/ui/src/components/tags-input/TagsInputItemDelete.vue | ||
TagsInputItemText
| Name | Type | Default | Description |
|---|---|---|---|
asChild | boolean | undefined | — | Merges the component props and interaction behavior into its single child, which replaces the default rendered element. |
DetailsDeclared typeboolean | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItemText.vue | |||
as | AsTag | Component | undefined | — | Selects the HTML tag or Vue component rendered for this tags-input part; asChild takes precedence when both are set. |
DetailsDeclared typeAsTag | Component | undefined Literal values
Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItemText.vue | |||
class | string | undefined | — | Additional CSS classes applied to the tag text element. |
DetailsDeclared typestring | undefined Default value details
Sourcepackages/ui/src/components/tags-input/TagsInputItemText.vue | |||
| Name | Signature or type | Description |
|---|---|---|
#default | {} | Renders the text content of the tag. |
DetailsDeclared type{}Sourcepackages/ui/src/components/tags-input/TagsInputItemText.vue | ||
Accessibility
- ARIA Attributes: TagsInput provides
aria-labelvia locale by default (e.g., "Tags Input" in English); falls back tot('tagsInput.label')when not provided - Custom Labels: When a more specific description is needed (e.g., "Article tags", "Recipients"), use the
ariaLabelprop to customize
<script setup>
import { ref } from 'vue'
import {
TagsInput,
TagsInputInput,
TagsInputItem,
TagsInputItemText,
TagsInputItemDelete
} from 'brutx-ui-vue'
const tags = ref(['vue', 'css'])
</script>
<template>
<TagsInput v-model="tags" aria-label="Article tags">
<TagsInputItem v-for="tag in tags" :key="tag" :value="tag">
<TagsInputItemText>{{ tag }}</TagsInputItemText>
<TagsInputItemDelete />
</TagsInputItem>
<TagsInputInput placeholder="Add tag..." />
</TagsInput>
</template>FAQ
Q: How do I use objects as tag values instead of strings?
A: When tag values are objects, you must provide a convertValue function to convert the input string to the target object type. It is also recommended to provide a displayValue function to customize the tag display text. If convertValue is not provided, the component will use strings as tag values.
Q: Why doesn't adding a tag work after setting the max attribute?
A: When the number of tags reaches the max limit, new tags will not be added and the invalid event will be triggered. You can listen to this event to display a message to the user. If max is set to 0, there is no limit on the number of tags.
Q: How do I automatically split multiple tags on paste?
A: Set addOnPaste to true, and text containing delimiters will be automatically split into multiple tags when pasted. The default delimiter is a comma (,), which can be customized via the delimiter prop (supports strings and regular expressions). For example, set delimiter=";" to split by semicolons.