select
Select component with a subscription plan style
Select component with a subscription plan style
Загрузка превью…
src/select/c-select-6.vue
<script setup lang="ts">
import { Field } from "@/components/ui/field"
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Item, ItemContent, ItemDescription, ItemTitle } from "@/components/ui/item"
const plans = [
{
name: "Starter",
description: "Perfect for individuals getting started.",
},
{
name: "Professional",
description: "Ideal for growing teams and businesses.",
},
{
name: "Enterprise",
description: "Advanced features for large organizations.",
},
]
function findPlan(name: unknown) {
return plans.find((plan) => plan.name === name)
}
</script>
<template>
<Field class="max-w-xs">
<Select default-value="Starter">
<SelectTrigger class="h-auto! w-full">
<!--
reka-ui's SelectValue отдаёт только textContent выбранного
SelectItem (см. reka-ui/dist/Select/SelectValue.js), тогда как
Radix's Select.Value заново монтирует children выбранного
SelectItem целиком (включая вложенный `Item`). Тот же приём
дублирования разметки уже используется у `SelectItem` ниже:
воспроизводим оригинал через доступный SelectValue's default
scoped slot (`modelValue`), не трогая сам примитив.
-->
<SelectValue placeholder="Select plan">
<template #default="{ modelValue }">
<Item v-if="findPlan(modelValue)" size="xs" class="w-full p-0">
<ItemContent class="gap-0">
<ItemTitle>{{ findPlan(modelValue)!.name }}</ItemTitle>
<ItemDescription class="text-xs">
{{ findPlan(modelValue)!.description }}
</ItemDescription>
</ItemContent>
</Item>
</template>
</SelectValue>
</SelectTrigger>
<SelectContent position="popper">
<SelectGroup>
<SelectItem v-for="plan in plans" :key="plan.name" :value="plan.name">
<Item size="xs" class="w-full p-0">
<ItemContent class="gap-0">
<ItemTitle>{{ plan.name }}</ItemTitle>
<ItemDescription class="text-xs">
{{ plan.description }}
</ItemDescription>
</ItemContent>
</Item>
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</Field>
</template>