preview-group.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <script setup lang="ts">
  2. import { computed, ref, useSlots } from 'vue';
  3. import { VbenTooltip } from '@vben-core/shadcn-ui';
  4. import { Code } from 'lucide-vue-next';
  5. import {
  6. TabsContent,
  7. TabsIndicator,
  8. TabsList,
  9. TabsRoot,
  10. TabsTrigger,
  11. } from 'radix-vue';
  12. defineOptions({
  13. inheritAttrs: false,
  14. });
  15. const props = withDefaults(
  16. defineProps<{
  17. files?: string[];
  18. }>(),
  19. { files: () => [] },
  20. );
  21. const open = ref(false);
  22. const slots = useSlots();
  23. const tabs = computed(() => {
  24. return props.files.map((file) => {
  25. return {
  26. component: slots[file],
  27. label: file,
  28. };
  29. });
  30. });
  31. const currentTab = ref('index.vue');
  32. const toggleOpen = () => {
  33. open.value = !open.value;
  34. };
  35. </script>
  36. <template>
  37. <TabsRoot
  38. v-model="currentTab"
  39. class="bg-background-deep border-border overflow-hidden rounded-b-xl border-t"
  40. @update:model-value="open = true"
  41. >
  42. <div class="border-border bg-background flex border-b-2 pr-2">
  43. <div class="flex w-full items-center justify-between text-[13px]">
  44. <TabsList class="relative flex">
  45. <template v-if="open">
  46. <TabsIndicator
  47. 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"
  48. >
  49. <div class="size-full bg-[var(--vp-c-indigo-1)]"></div>
  50. </TabsIndicator>
  51. <TabsTrigger
  52. v-for="(tab, index) in tabs"
  53. :key="index"
  54. :value="tab.label"
  55. class="border-box text-foreground px-4 py-3 data-[state=active]:text-[var(--vp-c-indigo-1)]"
  56. tabindex="-1"
  57. >
  58. {{ tab.label }}
  59. </TabsTrigger>
  60. </template>
  61. </TabsList>
  62. <div
  63. :class="{
  64. 'py-2': !open,
  65. }"
  66. class="flex items-center"
  67. >
  68. <VbenTooltip side="top">
  69. <template #trigger>
  70. <Code
  71. class="hover:bg-accent size-7 cursor-pointer rounded-full p-1.5"
  72. @click="toggleOpen"
  73. />
  74. </template>
  75. {{ open ? 'Collapse code' : 'Expand code' }}
  76. </VbenTooltip>
  77. </div>
  78. </div>
  79. </div>
  80. <div
  81. :class="`${open ? 'h-[unset] max-h-[80vh]' : 'h-0'}`"
  82. class="block overflow-y-scroll bg-[var(--vp-code-block-bg)] transition-all duration-300"
  83. >
  84. <TabsContent
  85. v-for="tab in tabs"
  86. :key="tab.label"
  87. :value="tab.label"
  88. as-child
  89. class="rounded-xl"
  90. >
  91. <div class="text-foreground relative rounded-xl">
  92. <component :is="tab.component" class="border-0" />
  93. </div>
  94. </TabsContent>
  95. </div>
  96. </TabsRoot>
  97. </template>