CodeGroup.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <template>
  2. <TabGroup @change="changeTab" :selectedIndex="selectedTabIndex" as="div" class="not-prose my-6 overflow-hidden rounded-2xl bg-zinc-900 shadow-md ring-1 ring-white/10">
  3. <div ref="positionRef" class="flex min-h-[calc(theme(spacing.12)+1px)] flex-wrap items-start gap-x-4 border-b px-4 border-zinc-800 bg-transparent">
  4. <h3 v-if="title != ''" class="mr-auto pt-3 text-xs font-semibold text-white">
  5. {{ title }}
  6. </h3>
  7. <TabList class="-mb-px flex gap-4 text-xs font-medium">
  8. <Tab v-for="tab in tabs"
  9. :key="'tab-'+tab.key"
  10. class="border-b py-3 transition focus-visible:outline-none focus:[&:not(:focus-visible)]:outline-none"
  11. :class="{
  12. 'border-emerald-500 text-emerald-400': selectedTab == tab.key,
  13. 'border-transparent text-zinc-400 hover:text-zinc-300': selectedTab != tab.key
  14. }">
  15. {{ tab.name }}
  16. </Tab>
  17. </TabList>
  18. </div>
  19. <TabPanels>
  20. <TabPanel as="div" v-for="tab in tabs" :key="'tab-'+tab">
  21. <div class="group bg-white/2.5">
  22. <PanelHeader
  23. :tag="tag"
  24. :label="label"/>
  25. <div class="relative overflow-x-auto p-4 text-xs text-white">
  26. <ContentSlot :use="$slots[tab.key]"/>
  27. <CopyButton :code="$slots[tab.key]()[0].props.code"/>
  28. </div>
  29. </div>
  30. </TabPanel>
  31. </TabPanels>
  32. </TabGroup>
  33. </template>
  34. <script setup>
  35. import {
  36. TabList,
  37. Tab,
  38. TabGroup,
  39. TabPanels,
  40. TabPanel
  41. } from '@headlessui/vue'
  42. const props = defineProps({
  43. title: {
  44. default: ''
  45. },
  46. tabs: {
  47. default(){
  48. return [];
  49. }
  50. },
  51. label: {
  52. default: ''
  53. },
  54. snippets: {
  55. default(){
  56. return [];
  57. }
  58. },
  59. tag: {
  60. return: ''
  61. },
  62. label: {
  63. return: ''
  64. }
  65. })
  66. const preferredProgrammingLanguage = usePreferredProgrammingLanguage();
  67. const selectedTab = computed(() => {
  68. if( preferredProgrammingLanguage.value == '' ){
  69. if( props.tabs.length > 0 ){
  70. return props.tabs[0].key;
  71. }else{
  72. return '';
  73. }
  74. }else{
  75. return preferredProgrammingLanguage.value;
  76. }
  77. })
  78. const selectedTabIndex = computed(() => {
  79. for( let i = 0; i < props.tabs.length; i++ ){
  80. if( props.tabs[ i ].key == preferredProgrammingLanguage.value ){
  81. return i;
  82. }
  83. }
  84. return 0;
  85. });
  86. const positionRef = ref(null);
  87. function changeTab( index ){
  88. let initialTop = positionRef.value.getBoundingClientRect().top
  89. preferredProgrammingLanguage.value = props.tabs[index].key;
  90. window.requestAnimationFrame(() => {
  91. let newTop = positionRef.value.getBoundingClientRect().top
  92. window.scrollBy(0, newTop - initialTop)
  93. })
  94. }
  95. </script>