select
Select with description text per option
Select with description text per option
Загрузка превью…
src/select/c-select-27.vue
<script setup lang="ts">
import { Field } from "@/components/ui/field"
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
const plans = [
{
value: "startup",
label: "Startup",
description: "For small teams up to 10",
},
{
value: "business",
label: "Business",
description: "For growing companies",
},
{
value: "enterprise",
label: "Enterprise",
description: "Unlimited everything",
},
]
function findPlan(value: unknown) {
return plans.find((plan) => plan.value === value)
}
</script>
<template>
<Field class="max-w-xs">
<Select :default-value="plans[0]!.value">
<SelectTrigger class="w-[240px] [&_span.text-muted-foreground]:hidden">
<!--
reka-ui's SelectValue отдаёт только textContent выбранного
SelectItem, тогда как Radix's Select.Value заново монтирует
children целиком (см. комментарий в c-select-6.vue).
-->
<SelectValue placeholder="Select plan">
<template #default="{ modelValue }">
<div v-if="findPlan(modelValue)" class="flex flex-col items-start gap-px">
<span class="font-medium">{{ findPlan(modelValue)!.label }}</span>
<span class="text-muted-foreground text-xs">
{{ findPlan(modelValue)!.description }}
</span>
</div>
</template>
</SelectValue>
</SelectTrigger>
<SelectContent position="popper">
<SelectGroup>
<SelectItem
v-for="plan in plans"
:key="plan.value"
:value="plan.value"
class="[&_svg]:text-primary"
>
<div class="flex flex-col items-start gap-px">
<span class="font-medium">{{ plan.label }}</span>
<span class="text-muted-foreground text-xs">
{{ plan.description }}
</span>
</div>
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</Field>
</template>