2019-11-16 10:21:14 +03:00

169 lines
3.5 KiB
Vue

<template>
<div>
<div
:class="[
{ 'col-md-4': vertical && !tabNavWrapperClasses },
{ 'col-12': centered && !tabNavWrapperClasses },
tabNavWrapperClasses
]"
>
<ul
class="nav nav-pills"
role="tablist"
:class="[
`nav-pills-${type}`,
{ 'flex-column': vertical },
{ 'justify-content-center': centered },
tabNavClasses
]"
>
<li
v-for="tab in tabs"
class="nav-item active"
data-toggle="tab"
role="tablist"
aria-expanded="true"
:key="tab.id"
>
<a
data-toggle="tab"
role="tablist"
:href="`#${tab.id}`"
@click.prevent="activateTab(tab)"
:aria-expanded="tab.active"
class="nav-link"
:class="{ active: tab.active }"
>
<tab-item-content :tab="tab"> </tab-item-content>
</a>
</li>
</ul>
</div>
<div
class="tab-content"
:class="[
{ 'tab-space': !vertical },
{ 'col-md-8': vertical && !tabContentClasses },
tabContentClasses
]"
>
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: 'tabs',
components: {
TabItemContent: {
props: ['tab'],
render(h) {
return h('div', [this.tab.$slots.title || this.tab.title]);
}
}
},
provide() {
return {
addTab: this.addTab,
removeTab: this.removeTab
};
},
props: {
type: {
type: String,
default: 'primary',
validator: value => {
let acceptedValues = [
'primary',
'info',
'success',
'warning',
'danger'
];
return acceptedValues.indexOf(value) !== -1;
}
},
activeTab: {
type: String,
default: '',
description: 'Active tab name'
},
tabNavWrapperClasses: {
type: [String, Object],
default: '',
description: 'ul wrapper css classes'
},
tabNavClasses: {
type: [String, Object],
default: '',
description: 'ul css classes'
},
tabContentClasses: {
type: [String, Object],
default: '',
description: 'tab content css classes'
},
vertical: Boolean,
centered: Boolean,
value: String
},
data() {
return {
tabs: []
};
},
methods: {
findAndActivateTab(title) {
let tabToActivate = this.tabs.find(t => t.title === title);
if (tabToActivate) {
this.activateTab(tabToActivate);
}
},
activateTab(tab) {
if (this.handleClick) {
this.handleClick(tab);
}
this.deactivateTabs();
tab.active = true;
},
deactivateTabs() {
this.tabs.forEach(tab => {
tab.active = false;
});
},
addTab(tab) {
const index = this.$slots.default.indexOf(tab.$vnode);
if (!this.activeTab && index === 0) {
tab.active = true;
}
if (this.activeTab === tab.name) {
tab.active = true;
}
this.tabs.splice(index, 0, tab);
},
removeTab(tab) {
const tabs = this.tabs;
const index = tabs.indexOf(tab);
if (index > -1) {
tabs.splice(index, 1);
}
}
},
mounted() {
this.$nextTick(() => {
if (this.value) {
this.findAndActivateTab(this.value);
}
});
},
watch: {
value(newVal) {
this.findAndActivateTab(newVal);
}
}
};
</script>
<style scoped></style>