v2 first commit
This commit is contained in:
33
resources/assets/js/components/Tabs/Tab.vue
Normal file
33
resources/assets/js/components/Tabs/Tab.vue
Normal file
@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div
|
||||
class="tab-pane"
|
||||
v-show="active"
|
||||
:id="id || title"
|
||||
:class="{ active: active }"
|
||||
:aria-expanded="active"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'tab-pane',
|
||||
props: ['title', 'id'],
|
||||
inject: ['addTab', 'removeTab'],
|
||||
data() {
|
||||
return {
|
||||
active: false
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.addTab(this);
|
||||
},
|
||||
destroyed() {
|
||||
if (this.$el && this.$el.parentNode) {
|
||||
this.$el.parentNode.removeChild(this.$el);
|
||||
}
|
||||
this.removeTab(this);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style></style>
|
168
resources/assets/js/components/Tabs/Tabs.vue
Normal file
168
resources/assets/js/components/Tabs/Tabs.vue
Normal file
@ -0,0 +1,168 @@
|
||||
<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>
|
Reference in New Issue
Block a user