select
Select with user avatars
Select with user avatars
Загрузка превью…
src/select/c-select-18.vue
<script setup lang="ts">
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Field } from "@/components/ui/field"
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select"
const PIXEL =
"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAUwAOw=="
const users = [
{ id: "1", name: "Alex Johnson", initials: "AJ" },
{ id: "2", name: "Sarah Chen", initials: "SC" },
{ id: "3", name: "Michael Rodriguez", initials: "MR" },
{ id: "4", name: "Emma Wilson", initials: "EW" },
{ id: "5", name: "David Kim", initials: "DK" },
{ id: "6", name: "Aron Thompson", initials: "LT" },
{ id: "7", name: "James Brown", initials: "JB" },
{ id: "8", name: "Maria Garcia", initials: "MG" },
{ id: "9", name: "Nick Johnson", initials: "NJ" },
{ id: "10", name: "Liam Thompson", initials: "LT" },
]
const mappedUsers = users.map((user) => ({
value: user.id,
label: user.name,
avatar: PIXEL,
initials: user.initials,
}))
function findUser(value: unknown) {
return mappedUsers.find((user) => user.value === value)
}
</script>
<template>
<Field class="max-w-xs">
<Select :default-value="mappedUsers[2]!.value">
<SelectTrigger>
<!--
reka-ui's SelectValue отдаёт только textContent выбранного
SelectItem, тогда как Radix's Select.Value заново монтирует
children целиком (см. комментарий в c-select-6.vue).
-->
<SelectValue placeholder="Select a user">
<template #default="{ modelValue }">
<span v-if="findUser(modelValue)" class="flex items-center gap-2">
<Avatar class="size-6">
<AvatarImage :src="findUser(modelValue)!.avatar" :alt="findUser(modelValue)!.label" />
<AvatarFallback>{{ findUser(modelValue)!.initials }}</AvatarFallback>
</Avatar>
<span>{{ findUser(modelValue)!.label }}</span>
</span>
</template>
</SelectValue>
</SelectTrigger>
<SelectContent position="popper">
<SelectGroup>
<SelectLabel>Select a user</SelectLabel>
<SelectItem v-for="user in mappedUsers" :key="user.value" :value="user.value">
<span class="flex items-center gap-2">
<Avatar class="size-6">
<AvatarImage :src="user.avatar" :alt="user.label" />
<AvatarFallback>{{ user.initials }}</AvatarFallback>
</Avatar>
<span>{{ user.label }}</span>
</span>
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</Field>
</template>