Components

Chip

Interactive filters, tags, and inputs with UiChip and UiChipGroup.

UiChip renders a single tappable chip. UiChipGroup renders a set of chips from an options array and manages selection with v-model — use it for filters and tag pickers. For static status labels, use UiBadge instead.

Single-select filter chips

In single mode, modelValue is string | null. Clicking the selected chip deselects it.

<script setup lang="ts">
import { ref } from 'vue'

const status = ref<string | null>(null)
const options = [
  { id: 'active', text: 'Active' },
  { id: 'paused', text: 'Paused' },
  { id: 'archived', text: 'Archived' },
]
</script>

<template>
  <UiChipGroup v-model="status" :options="options" aria-label="Filter by status" />
</template>

Multi-select chips

Set multiple to model a string[].

<script setup lang="ts">
import { ref } from 'vue'

const tags = ref<string[]>([])
const options = [
  { id: 'vue', text: 'Vue', iconCode: '&#xe86f;' },
  { id: 'nuxt', text: 'Nuxt' },
  { id: 'ts', text: 'TypeScript' },
]
</script>

<template>
  <UiChipGroup v-model="tags" :options="options" multiple aria-label="Filter by tag" />
</template>

Closable tag list

Set closable on an option to render a trailing remove button. UiChipGroup emits remove with the option id — you own the removal logic.

<script setup lang="ts">
import { ref } from 'vue'

const tags = ref([
  { id: '1', text: 'Design', closable: true },
  { id: '2', text: 'Frontend', closable: true },
])

function onRemove(id: string) {
  tags.value = tags.value.filter(tag => tag.id !== id)
}
</script>

<template>
  <UiChipGroup :options="tags" @remove="onRemove" />
</template>

Use UiChip directly

<template>
  <UiChip text="Filter chip" icon-code="&#xe152;" @click="onClick" />
  <UiChip text="Selected" selected />
  <UiChip text="Disabled" disabled />
  <UiChip text="Removable" closable close-label="Remove tag" @remove="onRemove" />
</template>

UiChip props

PropTypeDefaultDescription
idstring | nullUnique identifier for the chip.
textstring | nullDisplay text label.
iconCodestring | nullLeading Material Symbols code point. Replaced by a check mark while selected.
selectedbooleanfalseRenders the filter-chip active state and swaps the leading icon for a check mark.
disabledbooleanfalseDisables the chip.
closablebooleanfalseRenders a trailing remove button (input-chip behavior).
textOnlybooleanfalseRenders the borderless text-only chip variant.
closeLabelstring'Remove'Accessible label for the remove button.
customClassstring | string[] | Record<string, boolean> | nullExtra classes.

Emits: click (MouseEvent) when the chip body is clicked; remove when the trailing remove button of a closable chip is clicked.

Slots: default renders after the text (e.g. a trailing badge), in addition to text.

UiChipGroup props

PropTypeDefaultDescription
optionsIChipOption[]Chip options: { id, text, iconCode?, disabled?, closable? }.
modelValuestring | string[] | nullSelected id (single) or ids (multiple).
multiplebooleanfalseAllows selecting multiple chips.
ariaLabelstring | nullARIA label describing the group.
customClassstring | string[] | Record<string, boolean> | nullExtra classes for the group container.

Emits: update:modelValue when the selection changes; remove with the option id when a closable option's remove button is clicked.

UiChipGroup renders a role="group" container. In single-select mode, clicking the currently selected chip clears the selection (sets modelValue to null).
Copyright © 2026