1
0
mirror of https://gitlab.com/bramw/baserow.git synced 2024-11-21 23:37:55 +00:00
bramw_baserow/web-frontend/modules/core/components/Tabs.vue
2024-05-24 18:18:11 +00:00

148 lines
3.4 KiB
Vue

<template>
<div
class="tabs"
:class="{
'tabs--full-height': fullHeight,
'tabs--large-offset': largeOffset,
'tabs--nopadding': noPadding,
'tabs--grow-items': growItems,
}"
>
<ul class="tabs__header">
<li
v-for="(tab, index) in tabs"
:key="`${tab.title} ${tab.tooltip}`"
v-tooltip="tab.tooltip"
class="tabs__item"
:class="{
'tabs__item--active': isActive(index),
'tabs__item--disabled': tab.disabled,
}"
@click="
tab.disabled ? $emit('click-disabled', index) : selectTab(index)
"
>
<a
:href="getHref(index)"
class="tabs__link"
:class="{ 'tabs__link--disabled': tab.disabled }"
@click.prevent
>
<i v-if="tab.icon" :class="tab.icon"></i>
{{ tab.title }}
</a>
</li>
</ul>
<slot></slot>
</div>
</template>
<script>
export default {
name: 'Tabs',
props: {
/**
* The index of the selected tab.
*/
selectedIndex: {
type: Number,
required: false,
default: 0,
},
/**
* Whether the tabs should take the full height of the parent.
*/
fullHeight: {
type: Boolean,
required: false,
default: false,
},
/**
* The Vue route object. If provided the tabs will be used for navigation.
* and the active tab will be set according to the current route.
* The child Tab components should have a `to` prop set.
*/
route: {
type: Object,
required: false,
default: null,
},
/**
* Whether the tabs container should add some extra space to the left.
*/
largeOffset: {
type: Boolean,
required: false,
default: false,
},
/**
* Removes the padding from the tabs container and header.
*/
noPadding: {
type: Boolean,
required: false,
default: false,
},
/**
* Whether the tabs header items should grow to use all the available space.
*/
growItems: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
internalSelectedIndex: 0, // In case the prop isn't used by a parent
tabs: [], // all the tabs
}
},
watch: {
selectedIndex: {
handler(i) {
if (!this.route && i !== undefined) {
this.internalSelectedIndex = i
}
},
immediate: true,
},
},
created() {
this.tabs = this.$children
},
mounted() {
if (this.route) {
this.tabs.forEach((tab) => {
tab.isActive = this.route.name === tab.to.name
})
} else this.selectTab(this.internalSelectedIndex)
},
methods: {
isActive(i) {
if (this.route) return this.route.name === this.tabs[i].to.name
else return this.internalSelectedIndex === i
},
getHref(i) {
if (this.route) {
const tab = this.tabs[i]
return !tab.disabled ? this.$router.match(tab.to).path : null
}
return null
},
selectTab(i) {
if (this.route) {
this.$emit('update:selectedIndex', i)
this.$router.push(this.tabs[i].to)
} else {
this.$emit('update:selectedIndex', i)
this.internalSelectedIndex = i
}
this.tabs.forEach((tab, index) => {
tab.isActive = index === i
})
},
},
}
</script>