109 lines
2.7 KiB
Vue
109 lines
2.7 KiB
Vue
<script setup lang="ts">
|
|
import { computed, ref, useSlots } from 'vue';
|
|
|
|
import { VbenTooltip } from '@vben-core/shadcn-ui';
|
|
|
|
import { Code } from 'lucide-vue-next';
|
|
import {
|
|
TabsContent,
|
|
TabsIndicator,
|
|
TabsList,
|
|
TabsRoot,
|
|
TabsTrigger,
|
|
} from 'radix-vue';
|
|
|
|
defineOptions({
|
|
inheritAttrs: false,
|
|
});
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
files?: string[];
|
|
}>(),
|
|
{ files: () => [] },
|
|
);
|
|
|
|
const open = ref(false);
|
|
|
|
const slots = useSlots();
|
|
|
|
const tabs = computed(() => {
|
|
return props.files.map((file) => {
|
|
return {
|
|
component: slots[file],
|
|
label: file,
|
|
};
|
|
});
|
|
});
|
|
|
|
const currentTab = ref('index.vue');
|
|
|
|
const toggleOpen = () => {
|
|
open.value = !open.value;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<TabsRoot
|
|
v-model="currentTab"
|
|
class="bg-background-deep border-border overflow-hidden rounded-b-xl border-t"
|
|
@update:model-value="open = true"
|
|
>
|
|
<div class="border-border bg-background flex border-b-2 pr-2">
|
|
<div class="flex w-full items-center justify-between text-[13px]">
|
|
<TabsList class="relative flex">
|
|
<template v-if="open">
|
|
<TabsIndicator
|
|
class="absolute bottom-0 left-0 h-[2px] w-[--radix-tabs-indicator-size] translate-x-[--radix-tabs-indicator-position] rounded-full transition-[width,transform] duration-300"
|
|
>
|
|
<div class="size-full bg-[var(--vp-c-indigo-1)]"></div>
|
|
</TabsIndicator>
|
|
<TabsTrigger
|
|
v-for="(tab, index) in tabs"
|
|
:key="index"
|
|
:value="tab.label"
|
|
class="border-box text-foreground px-4 py-3 data-[state=active]:text-[var(--vp-c-indigo-1)]"
|
|
tabindex="-1"
|
|
>
|
|
{{ tab.label }}
|
|
</TabsTrigger>
|
|
</template>
|
|
</TabsList>
|
|
|
|
<div
|
|
:class="{
|
|
'py-2': !open,
|
|
}"
|
|
class="flex items-center"
|
|
>
|
|
<VbenTooltip side="top">
|
|
<template #trigger>
|
|
<Code
|
|
class="hover:bg-accent size-7 cursor-pointer rounded-full p-1.5"
|
|
@click="toggleOpen"
|
|
/>
|
|
</template>
|
|
{{ open ? 'Collapse code' : 'Expand code' }}
|
|
</VbenTooltip>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
:class="`${open ? 'h-[unset] max-h-[80vh]' : 'h-0'}`"
|
|
class="block overflow-y-scroll bg-[var(--vp-code-block-bg)] transition-all duration-300"
|
|
>
|
|
<TabsContent
|
|
v-for="tab in tabs"
|
|
:key="tab.label"
|
|
:value="tab.label"
|
|
as-child
|
|
class="rounded-xl"
|
|
>
|
|
<div class="text-foreground relative rounded-xl">
|
|
<component :is="tab.component" class="border-0" />
|
|
</div>
|
|
</TabsContent>
|
|
</div>
|
|
</TabsRoot>
|
|
</template>
|