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>

Установка

npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-select-29.json

Зависимости реестра

Источник: порт из ReUI (Keenthemes, MIT)