入力タグ

インタラクティブタグを表示するinput要素。

使用法

v-modelディレクティブを使用してInputTagsの値を制御します。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" />
</template>

状態を制御する必要がない場合は、default-valueプロパティを使用して初期値を設定します。

Vue
<template>
  <UInputTags :default-value="['Vue']" />
</template>

Placeholder

placeholderプロパティを使用してプレースホルダーテキストを設定します。

<template>
  <UInputTags placeholder="Enter tags..." />
</template>

Max長さ

max-lengthプロパティを使用して、タグで許可される最大文字数を設定します。

<template>
  <UInputTags :max-length="4" />
</template>

Color

InputTagsがフォーカスされたときにリングの色を変更するには、colorプロパティを使用します。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" color="neutral" highlight />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" color="neutral" highlight />
</template>
highlightプロパティはフォーカスの状態を示すために使用されます。バリデーションエラーが発生したときに内部で使用されます。

バリアント

variantプロパティを使用して、InputTagsの外観を変更します。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" variant="subtle" color="neutral" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" variant="subtle" color="neutral" />
</template>

サイズ

sizeプロパティを使用して、InputTagsのサイズを調整します。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" size="xl" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" size="xl" />
</template>

Icon

iconプロパティを使用して、InputTags内にIconを表示します。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" icon="i-lucide-search" size="md" variant="outline" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" icon="i-lucide-search" size="md" variant="outline" />
</template>
アイコンの位置を設定するにはleadingとtrailingのプロップを使用し、位置ごとに異なるアイコンを設定するにはleading-iconとtrailing-iconのプロップを使用します。

アバター

avatarプロパティを使用して、AvatarをInputTags内に表示します。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags
    v-model="value"
    :avatar="{
      src: 'https://github.com/vuejs.png',
      loading: 'lazy'
    }"
    size="md"
    variant="outline"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags
    v-model="value"
    :avatar="{
      src: 'https://github.com/vuejs.png',
      loading: 'lazy'
    }"
    size="md"
    variant="outline"
  />
</template>

Deleteアイコン

delete-iconプロパティを使用して、タグ内の削除Iconをカスタマイズします。デフォルトはi-lucide-xです。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" delete-icon="i-lucide-trash" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" delete-icon="i-lucide-trash" />
</template>
このアイコンはapp.config.tsのui.icons.closeキーでグローバルにカスタマイズできます。
このアイコンは、vite.config.tsのui.icons.closeキーでグローバルにカスタマイズできます。

Loading

loadingプロパティを使用して、InputTagsにロードアイコンを表示します。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" loading />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" loading />
</template>

Loading Icon

loading-iconプロパティを使用してロードアイコンをカスタマイズします。デフォルトはi-lucide-loader-circleです。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" loading loading-icon="i-lucide-loader" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" loading loading-icon="i-lucide-loader" />
</template>
このアイコンはapp.config.tsのui.icons.loadingキーでグローバルにカスタマイズできます。
このアイコンはvite.config.tsのui.icons.loadingキーでグローバルにカスタマイズできます。

無効

disabledプロパティを使用してInputTagsを無効にします。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" disabled />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" disabled />
</template>

例

FormField内

FormFieldコンポーネント内のInputTagsを使用して、ラベル、ヘルプテキスト、必須インジケータなどを表示できます。

Vue
<script setup lang="ts">
const tags = ref(['Vue'])
</script>

<template>
  <UFormField label="Tags" required>
    <UInputTags v-model="tags" placeholder="Enter tags..." />
  </UFormField>
</template>
<script setup lang="ts">
import { ref } from 'vue'

const tags = ref(['Vue'])
</script>

<template>
  <UFormField label="Tags" required>
    <UInputTags v-model="tags" placeholder="Enter tags..." />
  </UFormField>
</template>

API

Props

Prop Default Type
as
'div'
any

The element or component this component should render as.

placeholder
string

The placeholder text when the input is empty.

maxLength
number

The maximum number of character allowed.

color
'primary'
"primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral"
variant
'outline'
"outline" | "soft" | "subtle" | "ghost" | "none"
size
'md'
"xs" | "sm" | "md" | "lg" | "xl"
autofocus
boolean
autofocusDelay
0
number
deleteIcon
appConfig.ui.icons.close
any

The icon displayed to delete a tag.

highlight
boolean

Highlight the ring color like a focus state.

fixed
boolean

Keep the mobile text size on all breakpoints.

modelValue
null | T[]

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

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

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

addOnBlur
boolean

When true allow adding tags blur input

duplicate
boolean

When true, allow duplicated tags.

disabled
boolean

When true, prevents the user from interacting with 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

max
number

Maximum number of tags.

id
string
convertValue
(value: string): T

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

displayValue
(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

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.

icon
any

Display an icon based on the leading and trailing props.

avatar
AvatarProps

Display an avatar on the left side.

leading
boolean

When true, the icon will be displayed on the left side.

leadingIcon
any

Display an icon on the left side.

trailing
boolean

When true, the icon will be displayed on the right side.

trailingIcon
any

Display an icon on the right side.

loading
boolean

When true, the loading icon will be displayed.

loadingIcon
appConfig.ui.icons.loading
any

The icon when the loading prop is true.

list
string
readonly
false | true | "true" | "false"
autocomplete
"on" | "off" | string
ui
{ root?: SlotClass; base?: SlotClass; leading?: SlotClass; leadingIcon?: SlotClass; leadingAvatar?: SlotClass; leadingAvatarSize?: SlotClass; trailing?: SlotClass; trailingIcon?: SlotClass; item?: SlotClass; itemText?: SlotClass; itemDelete?: SlotClass; itemDeleteIcon?: SlotClass; input?: SlotClass; }
このコンポーネントはすべてのネイティブ<input> HTML属性もサポートします。

スロット

Slot Type
leading
{ ui: object; }
default
{ ui: object; }
trailing
{ ui: object; }
item-text
{ item: T; index: number; ui: object; }
item-delete
{ item: T; index: number; ui: object; }

Emits

Event Type
change
[event: Event]
blur
[event: FocusEvent]
focus
[event: FocusEvent]
update:modelValue
[payload: T[]]
invalid
[payload: T]
addTag
[payload: T]
removeTag
[payload: T]

Expose

テンプレート参照を介してコンポーネントにアクセスする場合、以下を使用できます:

名前タイプ
inputRefRef<HTMLInputElement | null>

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    inputTags: {
      slots: {
        root: [
          'relative inline-flex items-center',
          'flex-wrap'
        ],
        base: [
          'rounded-md',
          'transition-colors'
        ],
        leading: 'absolute inset-y-0 start-0 flex items-center',
        leadingIcon: 'shrink-0 text-dimmed',
        leadingAvatar: 'shrink-0',
        leadingAvatarSize: '',
        trailing: 'absolute inset-y-0 end-0 flex items-center',
        trailingIcon: 'shrink-0 text-dimmed',
        item: 'px-1.5 py-0.5 rounded-sm font-medium inline-flex items-center gap-0.5 ring ring-inset ring-accented bg-elevated text-default data-disabled:cursor-not-allowed data-disabled:opacity-75 wrap-anywhere data-[state="active"]:bg-accented',
        itemText: '',
        itemDelete: [
          'inline-flex items-center rounded-xs text-dimmed hover:text-default hover:bg-accented/75 disabled:pointer-events-none',
          'transition-colors'
        ],
        itemDeleteIcon: 'shrink-0',
        input: 'flex-1 border-0 bg-transparent placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75'
      },
      variants: {
        fieldGroup: {
          horizontal: 'not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none focus-visible:z-[1]',
          vertical: 'not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none focus-visible:z-[1]'
        },
        size: {
          xs: {
            base: 'px-2 py-1 text-sm/4 gap-1',
            leading: 'ps-2',
            trailing: 'pe-2',
            leadingIcon: 'size-4',
            leadingAvatarSize: '3xs',
            trailingIcon: 'size-4',
            item: 'text-[10px]/3',
            itemDeleteIcon: 'size-3'
          },
          sm: {
            base: 'px-2.5 py-1.5 text-sm/4 gap-1.5',
            leading: 'ps-2.5',
            trailing: 'pe-2.5',
            leadingIcon: 'size-4',
            leadingAvatarSize: '3xs',
            trailingIcon: 'size-4',
            item: 'text-[10px]/3',
            itemDeleteIcon: 'size-3'
          },
          md: {
            base: 'px-2.5 py-1.5 text-base/5 gap-1.5',
            leading: 'ps-2.5',
            trailing: 'pe-2.5',
            leadingIcon: 'size-5',
            leadingAvatarSize: '2xs',
            trailingIcon: 'size-5',
            item: 'text-xs',
            itemDeleteIcon: 'size-3.5'
          },
          lg: {
            base: 'px-3 py-2 text-base/5 gap-2',
            leading: 'ps-3',
            trailing: 'pe-3',
            leadingIcon: 'size-5',
            leadingAvatarSize: '2xs',
            trailingIcon: 'size-5',
            item: 'text-xs',
            itemDeleteIcon: 'size-3.5'
          },
          xl: {
            base: 'px-3 py-2 text-base gap-2',
            leading: 'ps-3',
            trailing: 'pe-3',
            leadingIcon: 'size-6',
            leadingAvatarSize: 'xs',
            trailingIcon: 'size-6',
            item: 'text-sm',
            itemDeleteIcon: 'size-4'
          }
        },
        variant: {
          outline: 'text-highlighted bg-default ring ring-inset ring-accented',
          soft: 'text-highlighted bg-elevated/50 hover:bg-elevated has-focus:bg-elevated disabled:bg-elevated/50',
          subtle: 'text-highlighted bg-elevated ring ring-inset ring-accented',
          ghost: 'text-highlighted bg-transparent hover:bg-elevated has-focus:bg-elevated disabled:bg-transparent dark:disabled:bg-transparent',
          none: 'text-highlighted bg-transparent has-focus:outline-none'
        },
        color: {
          primary: '',
          secondary: '',
          success: '',
          info: '',
          warning: '',
          error: '',
          neutral: ''
        },
        leading: {
          true: ''
        },
        trailing: {
          true: ''
        },
        loading: {
          true: ''
        },
        highlight: {
          true: ''
        },
        fixed: {
          false: ''
        },
        type: {
          file: 'file:me-1.5 file:font-medium file:text-muted file:outline-none'
        }
      },
      compoundVariants: [
        {
          color: 'primary',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'outline-primary/25 has-focus-visible:outline-3 has-focus-visible:ring-primary'
        },
        {
          color: 'primary',
          variant: [
            'soft',
            'ghost'
          ],
          class: 'outline-primary/25 has-focus-visible:outline-3'
        },
        {
          color: 'primary',
          highlight: true,
          class: 'ring ring-inset ring-primary'
        },
        {
          color: 'neutral',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'outline-inverted/25 has-focus-visible:outline-3 has-focus-visible:ring-inverted'
        },
        {
          color: 'neutral',
          variant: [
            'soft',
            'ghost'
          ],
          class: 'outline-inverted/25 has-focus-visible:outline-3'
        },
        {
          color: 'neutral',
          highlight: true,
          class: 'ring ring-inset ring-inverted'
        },
        {
          leading: true,
          size: 'xs',
          class: 'ps-7'
        },
        {
          leading: true,
          size: 'sm',
          class: 'ps-8'
        },
        {
          leading: true,
          size: 'md',
          class: 'ps-9'
        },
        {
          leading: true,
          size: 'lg',
          class: 'ps-10'
        },
        {
          leading: true,
          size: 'xl',
          class: 'ps-11'
        },
        {
          trailing: true,
          size: 'xs',
          class: 'pe-7'
        },
        {
          trailing: true,
          size: 'sm',
          class: 'pe-8'
        },
        {
          trailing: true,
          size: 'md',
          class: 'pe-9'
        },
        {
          trailing: true,
          size: 'lg',
          class: 'pe-10'
        },
        {
          trailing: true,
          size: 'xl',
          class: 'pe-11'
        },
        {
          loading: true,
          leading: true,
          class: {
            leadingIcon: 'animate-spin'
          }
        },
        {
          loading: true,
          leading: false,
          trailing: true,
          class: {
            trailingIcon: 'animate-spin'
          }
        },
        {
          fixed: false,
          size: 'xs',
          class: 'md:text-xs'
        },
        {
          fixed: false,
          size: 'sm',
          class: 'md:text-xs'
        },
        {
          fixed: false,
          size: 'md',
          class: 'md:text-sm'
        },
        {
          fixed: false,
          size: 'lg',
          class: 'md:text-sm'
        }
      ],
      defaultVariants: {
        size: 'md',
        color: 'primary',
        variant: 'outline'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        inputTags: {
          slots: {
            root: [
              'relative inline-flex items-center',
              'flex-wrap'
            ],
            base: [
              'rounded-md',
              'transition-colors'
            ],
            leading: 'absolute inset-y-0 start-0 flex items-center',
            leadingIcon: 'shrink-0 text-dimmed',
            leadingAvatar: 'shrink-0',
            leadingAvatarSize: '',
            trailing: 'absolute inset-y-0 end-0 flex items-center',
            trailingIcon: 'shrink-0 text-dimmed',
            item: 'px-1.5 py-0.5 rounded-sm font-medium inline-flex items-center gap-0.5 ring ring-inset ring-accented bg-elevated text-default data-disabled:cursor-not-allowed data-disabled:opacity-75 wrap-anywhere data-[state="active"]:bg-accented',
            itemText: '',
            itemDelete: [
              'inline-flex items-center rounded-xs text-dimmed hover:text-default hover:bg-accented/75 disabled:pointer-events-none',
              'transition-colors'
            ],
            itemDeleteIcon: 'shrink-0',
            input: 'flex-1 border-0 bg-transparent placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75'
          },
          variants: {
            fieldGroup: {
              horizontal: 'not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none focus-visible:z-[1]',
              vertical: 'not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none focus-visible:z-[1]'
            },
            size: {
              xs: {
                base: 'px-2 py-1 text-sm/4 gap-1',
                leading: 'ps-2',
                trailing: 'pe-2',
                leadingIcon: 'size-4',
                leadingAvatarSize: '3xs',
                trailingIcon: 'size-4',
                item: 'text-[10px]/3',
                itemDeleteIcon: 'size-3'
              },
              sm: {
                base: 'px-2.5 py-1.5 text-sm/4 gap-1.5',
                leading: 'ps-2.5',
                trailing: 'pe-2.5',
                leadingIcon: 'size-4',
                leadingAvatarSize: '3xs',
                trailingIcon: 'size-4',
                item: 'text-[10px]/3',
                itemDeleteIcon: 'size-3'
              },
              md: {
                base: 'px-2.5 py-1.5 text-base/5 gap-1.5',
                leading: 'ps-2.5',
                trailing: 'pe-2.5',
                leadingIcon: 'size-5',
                leadingAvatarSize: '2xs',
                trailingIcon: 'size-5',
                item: 'text-xs',
                itemDeleteIcon: 'size-3.5'
              },
              lg: {
                base: 'px-3 py-2 text-base/5 gap-2',
                leading: 'ps-3',
                trailing: 'pe-3',
                leadingIcon: 'size-5',
                leadingAvatarSize: '2xs',
                trailingIcon: 'size-5',
                item: 'text-xs',
                itemDeleteIcon: 'size-3.5'
              },
              xl: {
                base: 'px-3 py-2 text-base gap-2',
                leading: 'ps-3',
                trailing: 'pe-3',
                leadingIcon: 'size-6',
                leadingAvatarSize: 'xs',
                trailingIcon: 'size-6',
                item: 'text-sm',
                itemDeleteIcon: 'size-4'
              }
            },
            variant: {
              outline: 'text-highlighted bg-default ring ring-inset ring-accented',
              soft: 'text-highlighted bg-elevated/50 hover:bg-elevated has-focus:bg-elevated disabled:bg-elevated/50',
              subtle: 'text-highlighted bg-elevated ring ring-inset ring-accented',
              ghost: 'text-highlighted bg-transparent hover:bg-elevated has-focus:bg-elevated disabled:bg-transparent dark:disabled:bg-transparent',
              none: 'text-highlighted bg-transparent has-focus:outline-none'
            },
            color: {
              primary: '',
              secondary: '',
              success: '',
              info: '',
              warning: '',
              error: '',
              neutral: ''
            },
            leading: {
              true: ''
            },
            trailing: {
              true: ''
            },
            loading: {
              true: ''
            },
            highlight: {
              true: ''
            },
            fixed: {
              false: ''
            },
            type: {
              file: 'file:me-1.5 file:font-medium file:text-muted file:outline-none'
            }
          },
          compoundVariants: [
            {
              color: 'primary',
              variant: [
                'outline',
                'subtle'
              ],
              class: 'outline-primary/25 has-focus-visible:outline-3 has-focus-visible:ring-primary'
            },
            {
              color: 'primary',
              variant: [
                'soft',
                'ghost'
              ],
              class: 'outline-primary/25 has-focus-visible:outline-3'
            },
            {
              color: 'primary',
              highlight: true,
              class: 'ring ring-inset ring-primary'
            },
            {
              color: 'neutral',
              variant: [
                'outline',
                'subtle'
              ],
              class: 'outline-inverted/25 has-focus-visible:outline-3 has-focus-visible:ring-inverted'
            },
            {
              color: 'neutral',
              variant: [
                'soft',
                'ghost'
              ],
              class: 'outline-inverted/25 has-focus-visible:outline-3'
            },
            {
              color: 'neutral',
              highlight: true,
              class: 'ring ring-inset ring-inverted'
            },
            {
              leading: true,
              size: 'xs',
              class: 'ps-7'
            },
            {
              leading: true,
              size: 'sm',
              class: 'ps-8'
            },
            {
              leading: true,
              size: 'md',
              class: 'ps-9'
            },
            {
              leading: true,
              size: 'lg',
              class: 'ps-10'
            },
            {
              leading: true,
              size: 'xl',
              class: 'ps-11'
            },
            {
              trailing: true,
              size: 'xs',
              class: 'pe-7'
            },
            {
              trailing: true,
              size: 'sm',
              class: 'pe-8'
            },
            {
              trailing: true,
              size: 'md',
              class: 'pe-9'
            },
            {
              trailing: true,
              size: 'lg',
              class: 'pe-10'
            },
            {
              trailing: true,
              size: 'xl',
              class: 'pe-11'
            },
            {
              loading: true,
              leading: true,
              class: {
                leadingIcon: 'animate-spin'
              }
            },
            {
              loading: true,
              leading: false,
              trailing: true,
              class: {
                trailingIcon: 'animate-spin'
              }
            },
            {
              fixed: false,
              size: 'xs',
              class: 'md:text-xs'
            },
            {
              fixed: false,
              size: 'sm',
              class: 'md:text-xs'
            },
            {
              fixed: false,
              size: 'md',
              class: 'md:text-sm'
            },
            {
              fixed: false,
              size: 'lg',
              class: 'md:text-sm'
            }
          ],
          defaultVariants: {
            size: 'md',
            color: 'primary',
            variant: 'outline'
          }
        }
      }
    })
  ]
})
Some colors in compoundVariants are omitted for readability. Check out the source code on GitHub.

Changelog

No recent changes