button-group
Button group with select controls
Button group with select controls
Загрузка превью…
src/button-group/c-button-group-33.vue
<script setup lang="ts">
import { ref } from "vue"
import { ButtonGroup } from "@/components/ui/button-group"
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue } from "@/components/ui/select"
const environments = [
{ value: "production", label: "Production", icon: "globe" },
{ value: "staging", label: "Staging", icon: "layers" },
{ value: "development", label: "Development", icon: "terminal" },
]
const timeRanges = [
{ value: "1h", label: "Last hour", category: "recent" },
{ value: "6h", label: "Last 6 hours", category: "recent" },
{ value: "12h", label: "Last 12 hours", category: "recent" },
{ value: "24h", label: "Last 24 hours", category: "recent" },
{ value: "3d", label: "Last 3 days", category: "plus" },
{ value: "7d", label: "Last 7 days", category: "plus" },
{ value: "14d", label: "Last 14 days", category: "plus" },
{ value: "30d", label: "Last 30 days", category: "plus" },
]
const env = ref("development")
const range = ref("12h")
function findEnv(value: unknown) {
return environments.find((item) => item.value === value)
}
</script>
<template>
<ButtonGroup>
<Select v-model="env">
<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 environment">
<template #default="{ modelValue }">
<div v-if="findEnv(modelValue)" class="flex items-center gap-2">
<svg
v-if="findEnv(modelValue)!.icon === 'globe'"
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-globe size-3.5 opacity-60"
>
<circle cx="12" cy="12" r="10" />
<path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" />
<path d="M2 12h20" />
</svg>
<svg
v-else-if="findEnv(modelValue)!.icon === 'layers'"
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-layers size-3.5 opacity-60"
>
<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z" />
<path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12" />
<path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17" />
</svg>
<svg
v-else
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-terminal size-3.5 opacity-60"
>
<path d="M12 19h8" />
<path d="m4 17 6-6-6-6" />
</svg>
<span>{{ findEnv(modelValue)!.label }}</span>
</div>
</template>
</SelectValue>
</SelectTrigger>
<SelectContent position="popper" align="start">
<SelectGroup>
<SelectItem
v-for="item in environments"
:key="item.value"
:value="item.value"
>
<div class="flex items-center gap-2">
<svg
v-if="item.icon === 'globe'"
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-globe size-3.5 opacity-60"
>
<circle cx="12" cy="12" r="10" />
<path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" />
<path d="M2 12h20" />
</svg>
<svg
v-else-if="item.icon === 'layers'"
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-layers size-3.5 opacity-60"
>
<path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z" />
<path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12" />
<path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17" />
</svg>
<svg
v-else
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-terminal size-3.5 opacity-60"
>
<path d="M12 19h8" />
<path d="m4 17 6-6-6-6" />
</svg>
<span>{{ item.label }}</span>
</div>
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<Select v-model="range">
<SelectTrigger class="w-40">
<SelectValue placeholder="Select range" />
</SelectTrigger>
<SelectContent position="popper">
<SelectGroup>
<SelectItem
v-for="item in timeRanges.filter((r) => r.category === 'recent')"
:key="item.value"
:value="item.value"
>
{{ item.label }}
</SelectItem>
</SelectGroup>
<SelectSeparator />
<SelectGroup>
<SelectLabel>Observability Plus</SelectLabel>
<SelectItem
v-for="item in timeRanges.filter((r) => r.category === 'plus')"
:key="item.value"
:value="item.value"
>
{{ item.label }}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</ButtonGroup>
</template>
Установка
npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-button-group-33.jsonЗависимости реестра
Источник: порт из ReUI (Keenthemes, MIT)