combobox
Invisible combobox with member tags
Invisible combobox with member tags
Загрузка превью…
src/combobox/c-combobox-20.vue
<!--
Unsplash-URL заменены локальным 1x1 data-URI (см. `c-combobox-10.vue`).
-->
<script setup lang="ts">
import { ref } from "vue"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxContent, ComboboxEmpty, ComboboxItem, ComboboxList, ComboboxValue, useComboboxAnchor } from "@/components/ui/combobox"
import { Field } from "@/components/ui/field"
import { Item, ItemContent, ItemDescription, ItemTitle } from "@/components/ui/item"
const PIXEL =
"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAUwAOw=="
const users = [
{ id: "1", name: "Alex Johnson", email: "alex@example.com", initials: "AJ" },
{ id: "2", name: "Sarah Chen", email: "sarah@example.com", initials: "SC" },
{ id: "3", name: "Michael Rodriguez", email: "michael@example.com", initials: "MR" },
{ id: "4", name: "Emma Wilson", email: "emma@example.com", initials: "EW" },
{ id: "5", name: "David Kim", email: "david@example.com", initials: "DK" },
{ id: "6", name: "Aron Thompson", email: "lisa@example.com", initials: "LT" },
{ id: "7", name: "James Brown", email: "james@example.com", initials: "JB" },
{ id: "8", name: "Maria Garcia", email: "maria@example.com", initials: "MG" },
{ id: "9", name: "Nick Johnson", email: "nick@example.com", initials: "NJ" },
{ id: "10", name: "Liam Thompson", email: "liam@example.com", initials: "LT" },
]
const members = users.map((user, index) => ({
...user,
avatar: PIXEL,
position: ["Software Engineer", "Product Manager", "UX Designer", "Technical Lead", "CTO"][
index % 5
],
}))
type Member = (typeof members)[number]
const anchor = useComboboxAnchor()
const selected = ref<Member[]>([members[5]!, members[9]!, members[3]!])
function handleRemove(id: string) {
selected.value = selected.value.filter((m) => m.id !== id)
}
</script>
<template>
<Field class="max-w-xs">
<Combobox
multiple
:by="(a, b) => (a as Member).id === (b as Member).id"
:model-value="selected"
@update:model-value="(v) => (selected = v as unknown as Member[])"
>
<ComboboxChips class="border-none bg-transparent p-0 shadow-none ring-0 focus-within:ring-0">
<ComboboxValue v-slot="{ value }">
<ComboboxChip
v-for="member in (value as Member[]) ?? []"
:key="member.id"
:show-remove="true"
class="bg-background rounded-full inline-flex h-auto items-center gap-1.5 border py-0.5 pl-2 shadow-xs **:data-[slot=combobox-chip-remove]:mr-0.5 **:data-[slot=combobox-chip-remove]:bg-transparent"
@remove="handleRemove(member.id)"
>
<Avatar class="size-4">
<AvatarImage :src="member.avatar" :alt="member.name" />
<AvatarFallback class="text-[8px]">{{ member.initials }}</AvatarFallback>
</Avatar>
{{ member.name }}
</ComboboxChip>
<ComboboxChipsInput placeholder="Add members..." class="bg-transparent" />
</ComboboxValue>
</ComboboxChips>
<ComboboxContent :anchor="anchor" class="max-w-(--anchor-width) min-w-(--anchor-width)">
<ComboboxEmpty>No members found.</ComboboxEmpty>
<ComboboxList>
<ComboboxItem v-for="member in members" :key="member.id" :value="member">
<Item size="xs" class="p-0">
<Avatar class="size-6">
<AvatarImage :src="member.avatar" :alt="member.name" />
<AvatarFallback>{{ member.initials }}</AvatarFallback>
</Avatar>
<ItemContent>
<ItemTitle class="whitespace-nowrap">{{ member.name }}</ItemTitle>
<ItemDescription>{{ member.position }}</ItemDescription>
</ItemContent>
</Item>
</ComboboxItem>
</ComboboxList>
</ComboboxContent>
</Combobox>
</Field>
</template>