tabs-view.vue 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <script setup lang="ts">
  2. import type { TabsEmits, TabsProps } from './types';
  3. import { useForwardPropsEmits } from '@vben-core/composables';
  4. import { ChevronLeft, ChevronRight } from '@vben-core/icons';
  5. import { VbenScrollbar } from '@vben-core/shadcn-ui';
  6. import { Tabs, TabsChrome } from './components';
  7. import { useTabsDrag } from './use-tabs-drag';
  8. import { useTabsViewScroll } from './use-tabs-view-scroll';
  9. interface Props extends TabsProps {}
  10. defineOptions({
  11. name: 'TabsView',
  12. });
  13. const props = withDefaults(defineProps<Props>(), {
  14. contentClass: 'vben-tabs-content',
  15. draggable: true,
  16. styleType: 'chrome',
  17. });
  18. const emit = defineEmits<TabsEmits>();
  19. const forward = useForwardPropsEmits(props, emit);
  20. const {
  21. handleScrollAt,
  22. scrollbarRef,
  23. scrollDirection,
  24. scrollIsAtLeft,
  25. scrollIsAtRight,
  26. showScrollButton,
  27. } = useTabsViewScroll(props);
  28. useTabsDrag(props, emit);
  29. </script>
  30. <template>
  31. <div class="flex h-full flex-1 overflow-hidden">
  32. <!-- 左侧滚动按钮 -->
  33. <span
  34. v-show="showScrollButton"
  35. :class="{
  36. 'hover:bg-muted text-muted-foreground cursor-pointer': !scrollIsAtLeft,
  37. 'pointer-events-none opacity-30': scrollIsAtLeft,
  38. }"
  39. class="border-r px-2"
  40. @click="scrollDirection('left')"
  41. >
  42. <ChevronLeft class="size-4 h-full" />
  43. </span>
  44. <div
  45. :class="{
  46. 'pt-[3px]': styleType === 'chrome',
  47. }"
  48. class="size-full flex-1 overflow-hidden"
  49. >
  50. <VbenScrollbar
  51. ref="scrollbarRef"
  52. :shadow-bottom="false"
  53. :shadow-top="false"
  54. class="h-full"
  55. horizontal
  56. scroll-bar-class="z-10 hidden "
  57. shadow
  58. shadow-left
  59. shadow-right
  60. @scroll-at="handleScrollAt"
  61. >
  62. <TabsChrome
  63. v-if="styleType === 'chrome'"
  64. v-bind="{ ...forward, ...$attrs, ...$props }"
  65. />
  66. <Tabs v-else v-bind="{ ...forward, ...$attrs, ...$props }" />
  67. </VbenScrollbar>
  68. </div>
  69. <!-- 右侧滚动按钮 -->
  70. <span
  71. v-show="showScrollButton"
  72. :class="{
  73. 'hover:bg-muted text-muted-foreground cursor-pointer': !scrollIsAtRight,
  74. 'pointer-events-none opacity-30': scrollIsAtRight,
  75. }"
  76. class="hover:bg-muted text-muted-foreground cursor-pointer border-l px-2"
  77. @click="scrollDirection('right')"
  78. >
  79. <ChevronRight class="size-4 h-full" />
  80. </span>
  81. </div>
  82. </template>