funkwhale/front/src/components/ui/Tabs.vue

60 lines
1.5 KiB
Vue

<script setup lang="ts">
import { TABS_INJECTION_KEY } from '~/injection-keys'
import { computed, provide, reactive, ref, watch } from 'vue'
import { type Props as TabProps } from '~/components/ui/Tab.vue'
import Button from "~/components/ui/Button.vue";
import Link from "~/components/ui/Link.vue";
const currentTitle = ref<TabProps['title']>('')
const tabs = reactive<TabProps[]>([])
provide(TABS_INJECTION_KEY, {
currentTitle: currentTitle,
tabs: tabs,
})
const currentTab = computed(() =>
tabs.find(({title}) => title === currentTitle.value)
)
const currentIndex = computed(() =>
tabs.findIndex(({title}) => title === currentTitle.value)
)
watch(() => tabs.length, (_, from) => {
if (from === 0) {
currentTitle.value = tabs[0].title
}
})
</script>
<template>
<div class="funkwhale tabs">
<div class="tabs-header">
<component ghost :is="tab.to ? Link : Button"
v-for="(tab, _) in tabs" :class="{ 'is-active': currentTitle === tab.title }"
v-bind="tab"
:onClick="() => { currentTitle = tab.title }"
@keydown.left="currentTitle = tabs[(currentIndex - 1 + tabs.length) % tabs.length]"
@keydown.right="currentTitle = tabs[(currentIndex + 1) % tabs.length]"
class="tabs-item"
>
<div class="is-spacing">{{ tab.title }}</div>
<label>{{ tab.title }}</label>
</component>
<div class="tabs-right">
<slot name="tabs-right" />
</div>
</div>
<slot />
</div>
</template>
<style lang="scss">
@import './tabs.scss'
</style>