<script setup lang="ts">
import { ref } from 'vue'
import { Chip, Inline } from '@hina-ui/vue'
const genres = ['Sci-fi', 'Fantasy', 'Slice of life', 'Mystery', 'Romance']
const picked = ref(['Sci-fi', 'Slice of life'])
function toggle(genre: string, on: boolean) {
picked.value = on ? [...picked.value, genre] : picked.value.filter(item => item !== genre)
}
</script>
<template>
<Inline>
<Chip
v-for="genre in genres"
:key="genre"
selectable
:selected="picked.includes(genre)"
@update:selected="toggle(genre, $event)"
>
{{ genre }}
</Chip>
</Inline>
</template>
Usage
import { Chip } from '@hina-ui/vue'
A chip is used in one of two ways: selectable makes it selectable, removable gives it a remove button, and the two are exclusive. A short label with no interaction is a Tag.
<script setup lang="ts">
import { ref } from 'vue'
import { Chip, Inline } from '@hina-ui/vue'
const finished = ref(true)
const kept = ref(true)
</script>
<template>
<Inline>
<Chip v-model:selected="finished" selectable>Finished</Chip>
<Chip v-if="kept" removable @remove="kept = false">Sci-fi</Chip>
</Inline>
</template>
Examples
Selectable
With selectable set the chip renders as a button and v-model:selected binds its selected state. A selected chip takes the accent colour and shows a check icon before its text.
<script setup lang="ts">
import { ref } from 'vue'
import { Chip, Inline } from '@hina-ui/vue'
const finished = ref(true)
const translated = ref(false)
</script>
<template>
<Inline>
<Chip v-model:selected="finished" selectable>Finished</Chip>
<Chip v-model:selected="translated" selectable>Translated</Chip>
</Inline>
</template>
Removable
With removable set a remove button sits at the end of the chip and emits remove when clicked; the chip itself is not clickable.
<script setup lang="ts">
import { ref } from 'vue'
import { Chip, Inline } from '@hina-ui/vue'
const tags = ref(['Sci-fi', 'School', 'Romance', 'Ensemble'])
</script>
<template>
<Inline>
<Chip
v-for="tag in tags"
:key="tag"
removable
@remove="tags = tags.filter(item => item !== tag)"
>
{{ tag }}
</Chip>
</Inline>
</template>
Variants and tones
soft has a tinted background and outline only a border; the default is soft. The tones are neutral and accent, with neutral as the default.
<script setup lang="ts">
import { Chip, Inline } from '@hina-ui/vue'
</script>
<template>
<Inline>
<Chip selectable>soft</Chip>
<Chip selectable tone="accent">soft accent</Chip>
<Chip selectable variant="outline">outline</Chip>
<Chip selectable variant="outline" tone="accent">outline accent</Chip>
</Inline>
</template>
Sizes
md matches the height of a small button; sm is for inputs and dense lists.
<script setup lang="ts">
import { Chip, Inline } from '@hina-ui/vue'
</script>
<template>
<Inline align="center">
<Chip size="sm" selectable selected>Small</Chip>
<Chip size="sm" removable>Small</Chip>
<Chip selectable selected>Medium</Chip>
<Chip removable>Medium</Chip>
</Inline>
</template>
With an icon
Put the icon in the icon slot. On a selectable chip the icon gives way to the check icon once selected.
<script setup lang="ts">
import { ref } from 'vue'
import { Chip, Inline } from '@hina-ui/vue'
import { Flame, Star } from '@lucide/vue'
const hot = ref(true)
const starred = ref(false)
</script>
<template>
<Inline>
<Chip v-model:selected="hot" selectable>
<template #icon><Flame /></template>
Trending
</Chip>
<Chip v-model:selected="starred" selectable>
<template #icon><Star /></template>
Starred
</Chip>
<Chip removable>
<template #icon><Star /></template>
Starred
</Chip>
</Inline>
</template>
Disabled
A disabled chip ignores clicks, and its remove button is disabled as well.
<script setup lang="ts">
import { Chip, Inline } from '@hina-ui/vue'
</script>
<template>
<Inline>
<Chip selectable disabled>Unselected</Chip>
<Chip selectable selected disabled>Selected</Chip>
<Chip removable disabled>Locked</Chip>
</Inline>
</template>
As a link
With as set to a and an href, the chip becomes a link with hover and press feedback. To use application routing, pass href and navigate from the custom slot of RouterLink or NuxtLink, preserving link semantics and SPA navigation.
<script setup lang="ts">
import { Chip, Inline } from '@hina-ui/vue'
const localePath = useLocalePath()
</script>
<template>
<NuxtLink v-slot="{ href, navigate }" :to="localePath('/components/tag')" custom>
<Inline>
<Chip as="a" :href="href" @click="navigate">Sci-fi</Chip>
<Chip as="a" :href="href" @click="navigate">School</Chip>
<Chip as="a" :href="href" variant="outline" @click="navigate">Romance</Chip>
</Inline>
</NuxtLink>
</template>
Behaviour
- A selectable chip is a native button: click, Enter and Space all toggle it.
- Once selected a check icon appears before the text; with an
iconslot, the icon gives way to the check. - With the remove button focused, Enter, Space, Backspace and Delete all emit
remove; clicking the remove button does not trigger a click on the chip. - Setting both
selectableandremovablewarns in development and ignoresremovable. - A disabled chip ignores clicks and leaves the keyboard focus order.
Accessibility
- A selectable chip carries
aria-pressed, so screen readers announce it as a toggle button. - The remove button is named “Remove”, taken from
chip.removein the locale. - A removable chip is not focusable itself; keyboard focus lands on the remove button directly.
API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
selectable | boolean | false | Whether the chip can be selected |
selected | boolean | false | Selected state, supports v-model:selected |
removable | boolean | false | Whether the chip has a remove button |
variant | 'soft' | 'outline' | 'soft' | Visual style |
tone | 'neutral' | 'accent' | 'neutral' | Tone |
size | 'sm' | 'md' | 'md' | Size |
disabled | boolean | false | Whether the chip is disabled |
ripple | boolean | true | Whether pressing shows a ripple |
as | string | — | The rendered tag: button when selectable, otherwise span |
class | string | — | Classes appended to the root element |
Events
| Event | Payload | Description |
|---|---|---|
update:selected | selected: boolean | The selected state changed |
remove | — | The remove button was clicked |
Slots
| Slot | Description |
|---|---|
default | The chip’s text |
icon | An icon before the text |