select
Select with avatar items for team member assignment
Select with avatar items for team member assignment
Загрузка превью…
src/select/c-select-29.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 members = [
{ value: "sarah", label: "Sarah Chen", initials: "SC", avatar: PIXEL },
{ value: "alex", label: "Alex Kim", initials: "AK", avatar: PIXEL },
{ value: "maria", label: "Maria Garcia", initials: "MG", avatar: PIXEL },
{ value: "james", label: "James Wilson", initials: "JW", avatar: PIXEL },
]
function findMember(value: unknown) {
return members.find((member) => member.value === value)
}
</script>
<template>
<Field class="max-w-xs">
<Select :default-value="members[0]!.value">
<SelectTrigger>
<!--
reka-ui's SelectValue отдаёт только textContent выбранного
SelectItem, тогда как Radix's Select.Value заново монтирует
children целиком (см. комментарий в c-select-6.vue).
-->
<SelectValue placeholder="Select member">
<template #default="{ modelValue }">
<span v-if="findMember(modelValue)" class="flex items-center gap-2">
<Avatar class="size-6">
<AvatarImage :src="findMember(modelValue)!.avatar" :alt="findMember(modelValue)!.label" />
<AvatarFallback class="text-xs">
{{ findMember(modelValue)!.initials }}
</AvatarFallback>
</Avatar>
<span>{{ findMember(modelValue)!.label }}</span>
</span>
</template>
</SelectValue>
</SelectTrigger>
<SelectContent position="popper">
<SelectGroup>
<SelectLabel>Assign to</SelectLabel>
<SelectItem v-for="member in members" :key="member.value" :value="member.value">
<span class="flex items-center gap-2">
<Avatar class="size-6">
<AvatarImage :src="member.avatar" :alt="member.label" />
<AvatarFallback class="text-xs">
{{ member.initials }}
</AvatarFallback>
</Avatar>
<span>{{ member.label }}</span>
</span>
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</Field>
</template>