Input-Tags

Ein Input-Element, das interaktive Tags anzeigt.

Bearbeiten

Verwenden Sie die v-model-Direktive, um den Wert der InputTags zu steuern.

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>

Verwenden Sie die default-value-prop, um den Anfangswert festzulegen, wenn Sie den Zustand nicht steuern müssen.

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

Platzhalter

Verwenden Sie die placeholder-Prop, um einen Platzhaltertext festzulegen.

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

Max Länge

Verwenden Sie die max-length-prop, um die maximale Anzahl von Zeichen in einem Tag festzulegen.

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

Color (englisch)

Verwenden Sie die color-Prop, um die Ringfarbe zu ändern, wenn die InputTags fokussiert sind.

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>
Die highlight-prop wird hier verwendet, um den Fokuszustand anzuzeigen. Es wird intern verwendet, wenn ein Validierungsfehler auftritt.

Varianten

Verwenden Sie die variant-prop, um das Aussehen der InputTags zu ändern.

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>

Größe

Verwenden Sie die size-prop, um die Größe der InputTags anzupassen.

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 (englisch)

Verwenden Sie die icon-Prop, um eine Icon innerhalb der InputTags anzuzeigen.

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>
Verwenden Sie die leading-und trailing-Requisiten, um die Symbolposition festzulegen, oder die leading-icon-und trailing-icon-Requisiten, um für jede Position ein anderes Symbol festzulegen.

Avatar (englisch)

Verwenden Sie die avatar-Prop, um eine Avatar innerhalb der InputTags anzuzeigen.

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 Icon (englisch)

Verwenden Sie die delete-icon-Prop, um das Löschen Icon in den Tags. Defaults auf i-lucide-x anzupassen.

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>
Sie können dieses Symbol global in Ihrem app.config.ts unter ui.icons.close Schlüssel anpassen.
Sie können dieses Symbol global in Ihrem vite.config.ts unter ui.icons.close Schlüssel anpassen.

Loading (nicht verfügbar)

Verwenden Sie die loading-Prop, um ein Ladesymbol auf den InputTags anzuzeigen.

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 (englisch).

Verwenden Sie die loading-icon-Prop, um das Ladesymbol anzupassen. Standardmäßig 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>
Sie können dieses Symbol global in Ihrem app.config.ts unter ui.icons.loading Schlüssel anpassen.
Sie können dieses Symbol global in Ihrem vite.config.ts unter ui.icons.loading Schlüssel anpassen.

Disabled (nicht verfügbar)

Verwenden Sie die disabled-Prop, um die InputTags zu deaktivieren.

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>

Beispiele:

Innerhalb eines Formularfelds

Sie können die InputTags innerhalb einer FormField-Komponente verwenden, um eine Beschriftung, einen Hilfetext, eine erforderliche Anzeige usw. anzuzeigen.

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 ist

Props Bearbeiten

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; }
Diese Komponente unterstützt auch alle nativen <input>-HTML-Attribute.

Slots Bearbeiten

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 (englisch)

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 (englisch)

Beim Zugriff auf die Komponente über eine Template-Referenz können Sie Folgendes verwenden:

VornameTypen
inputRef nichtRef<HTMLInputElement | null> (nicht)

Theme Bearbeiten

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 (englisch)

No recent changes