36 lines
1.3 KiB
Vue
36 lines
1.3 KiB
Vue
<script setup lang="ts">
|
|
import { TabsContent, TabsList, TabsRoot, TabsTrigger } from 'reka-ui';
|
|
|
|
defineProps<{
|
|
/** `{ value, label, icon? }` for each tab; panels are named slots keyed by value. */
|
|
tabs: Array<{ value: string; label: string; icon?: string }>;
|
|
}>();
|
|
|
|
const active = defineModel<string>({ required: true });
|
|
</script>
|
|
|
|
<template>
|
|
<TabsRoot v-model="active">
|
|
<TabsList class="mb-4 flex gap-1 border-b border-slate-200">
|
|
<TabsTrigger
|
|
v-for="tab in tabs"
|
|
:key="tab.value"
|
|
:value="tab.value"
|
|
class="data-[state=active]:border-primary-600 data-[state=active]:text-primary-600 -mb-px cursor-pointer border-b-2 border-transparent px-4 py-2 font-medium text-slate-500 transition-colors hover:text-slate-700 focus-visible:outline-none"
|
|
>
|
|
<i v-if="tab.icon" :class="tab.icon" class="mr-2" aria-hidden="true" />
|
|
{{ tab.label }}
|
|
</TabsTrigger>
|
|
</TabsList>
|
|
|
|
<TabsContent
|
|
v-for="tab in tabs"
|
|
:key="tab.value"
|
|
:value="tab.value"
|
|
class="focus-visible:outline-none"
|
|
>
|
|
<slot :name="tab.value" />
|
|
</TabsContent>
|
|
</TabsRoot>
|
|
</template>
|