button-group

Button group with user selection select

Button group with user selection select

Загрузка превью…

src/button-group/c-button-group-26.vue

<script setup lang="ts">
import { ref } from "vue"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import { ButtonGroup } from "@/components/ui/button-group"
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", avatar: PIXEL, initials: "AJ" },
  { id: "2", name: "Sarah Chen", avatar: PIXEL, initials: "SC" },
  { id: "3", name: "Michael Rodriguez", avatar: PIXEL, initials: "MR" },
  { id: "4", name: "Emma Wilson", avatar: PIXEL, initials: "EW" },
]

const selectedUserId = ref("3")

function findUser(value: unknown) {
  return users.find((user) => user.id === value)
}
</script>

<template>
  <ButtonGroup>
    <Select v-model="selectedUserId">
      <SelectTrigger class="w-40">
        <!--
          reka-ui's SelectValue отдаёт только textContent выбранного
          SelectItem, тогда как Radix's Select.Value заново монтирует
          children целиком (см. docs/PORTING.md §5, packages/blocks/src/
          select/c-select-6.vue) — аватар пропадал бы молча.
        -->
        <SelectValue placeholder="Select user">
          <template #default="{ modelValue }">
            <span v-if="findUser(modelValue)" class="flex items-center gap-2">
              <Avatar class="size-5">
                <AvatarImage :src="findUser(modelValue)!.avatar" :alt="findUser(modelValue)!.name" />
                <AvatarFallback class="text-[10px]">
                  {{ findUser(modelValue)!.initials }}
                </AvatarFallback>
              </Avatar>
              <span class="truncate">{{ findUser(modelValue)!.name }}</span>
            </span>
          </template>
        </SelectValue>
      </SelectTrigger>
      <SelectContent position="popper" class="min-w-[200px]">
        <SelectGroup>
          <SelectLabel>Team Members</SelectLabel>
          <SelectItem v-for="user in users" :key="user.id" :value="user.id">
            <span class="flex items-center gap-2">
              <Avatar class="size-5">
                <AvatarImage :src="user.avatar" :alt="user.name" />
                <AvatarFallback class="text-[10px]">
                  {{ user.initials }}
                </AvatarFallback>
              </Avatar>
              <span class="truncate">{{ user.name }}</span>
            </span>
          </SelectItem>
        </SelectGroup>
      </SelectContent>
    </Select>
    <Button variant="outline" size="icon" aria-label="Add Tag">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="24"
        height="24"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        stroke-width="2"
        stroke-linecap="round"
        stroke-linejoin="round"
        aria-hidden="true"
        class="lucide lucide-plus"
      >
        <path d="M5 12h14" />
        <path d="M12 5v14" />
      </svg>
    </Button>
    <Button variant="outline" size="icon" aria-label="Settings">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="24"
        height="24"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        stroke-width="2"
        stroke-linecap="round"
        stroke-linejoin="round"
        aria-hidden="true"
        class="lucide lucide-settings-2"
      >
        <path d="M14 17H5" />
        <path d="M19 7h-9" />
        <circle cx="17" cy="17" r="3" />
        <circle cx="7" cy="7" r="3" />
      </svg>
    </Button>
  </ButtonGroup>
</template>

Установка

npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-button-group-26.json

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

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