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>

Установка

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

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

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