2018-08-27 12:22:25 -07:00
|
|
|
import Vue from 'vue'
|
|
|
|
|
|
|
|
import './tab_switcher.scss'
|
|
|
|
|
|
|
|
export default Vue.component('tab-switcher', {
|
|
|
|
name: 'TabSwitcher',
|
2019-07-15 09:42:27 -07:00
|
|
|
props: ['renderOnlyFocused', 'onSwitch', 'customActive'],
|
2018-08-27 12:22:25 -07:00
|
|
|
data () {
|
|
|
|
return {
|
2019-01-17 11:25:50 -08:00
|
|
|
active: this.$slots.default.findIndex(_ => _.tag)
|
2018-08-27 12:22:25 -07:00
|
|
|
}
|
|
|
|
},
|
2019-07-05 00:02:14 -07:00
|
|
|
beforeUpdate () {
|
|
|
|
const currentSlot = this.$slots.default[this.active]
|
|
|
|
if (!currentSlot.tag) {
|
|
|
|
this.active = this.$slots.default.findIndex(_ => _.tag)
|
|
|
|
}
|
|
|
|
},
|
2018-08-27 12:22:25 -07:00
|
|
|
methods: {
|
2019-08-09 20:48:33 -07:00
|
|
|
activateTab (index) {
|
2019-01-17 11:25:50 -08:00
|
|
|
return () => {
|
2019-05-14 12:38:16 -07:00
|
|
|
if (typeof this.onSwitch === 'function') {
|
2019-08-09 20:48:08 -07:00
|
|
|
this.onSwitch.call(null, this.$slots.default[index].key)
|
2019-05-14 12:38:16 -07:00
|
|
|
}
|
2019-01-17 11:25:50 -08:00
|
|
|
this.active = index
|
|
|
|
}
|
2019-07-15 09:42:27 -07:00
|
|
|
},
|
|
|
|
isActiveTab (index) {
|
|
|
|
const customActiveIndex = this.$slots.default.findIndex(slot => {
|
|
|
|
const dataFilter = slot.data && slot.data.attrs && slot.data.attrs['data-filter']
|
|
|
|
return this.customActive && this.customActive === dataFilter
|
|
|
|
})
|
|
|
|
|
|
|
|
return customActiveIndex > -1 ? customActiveIndex === index : index === this.active
|
2019-01-17 11:25:50 -08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
render (h) {
|
2018-08-27 12:22:25 -07:00
|
|
|
const tabs = this.$slots.default
|
2019-07-05 00:02:14 -07:00
|
|
|
.map((slot, index) => {
|
|
|
|
if (!slot.tag) return
|
|
|
|
const classesTab = ['tab']
|
|
|
|
const classesWrapper = ['tab-wrapper']
|
2018-08-27 12:22:25 -07:00
|
|
|
|
2019-07-15 09:42:27 -07:00
|
|
|
if (this.isActiveTab(index)) {
|
2019-07-05 00:02:14 -07:00
|
|
|
classesTab.push('active')
|
|
|
|
classesWrapper.push('active')
|
|
|
|
}
|
2019-07-24 12:35:52 -07:00
|
|
|
if (slot.data.attrs.image) {
|
|
|
|
return (
|
|
|
|
<div class={ classesWrapper.join(' ')}>
|
|
|
|
<button
|
|
|
|
disabled={slot.data.attrs.disabled}
|
|
|
|
onClick={this.activateTab(index)}
|
|
|
|
class={classesTab.join(' ')}>
|
|
|
|
<img src={slot.data.attrs.image} title={slot.data.attrs['image-tooltip']}/>
|
|
|
|
{slot.data.attrs.label ? '' : slot.data.attrs.label}
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
2019-07-05 00:02:14 -07:00
|
|
|
return (
|
|
|
|
<div class={ classesWrapper.join(' ')}>
|
|
|
|
<button
|
|
|
|
disabled={slot.data.attrs.disabled}
|
|
|
|
onClick={this.activateTab(index)}
|
|
|
|
class={classesTab.join(' ')}>
|
|
|
|
{slot.data.attrs.label}</button>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
})
|
2019-01-17 11:25:50 -08:00
|
|
|
|
|
|
|
const contents = this.$slots.default.map((slot, index) => {
|
|
|
|
if (!slot.tag) return
|
2018-11-20 20:38:00 -08:00
|
|
|
const active = index === this.active
|
2019-01-31 07:00:31 -08:00
|
|
|
if (this.renderOnlyFocused) {
|
|
|
|
return active
|
|
|
|
? <div class="active">{slot}</div>
|
|
|
|
: <div class="hidden"></div>
|
|
|
|
}
|
|
|
|
return <div class={active ? 'active' : 'hidden' }>{slot}</div>
|
2019-01-17 11:25:50 -08:00
|
|
|
})
|
|
|
|
|
2018-08-27 12:22:25 -07:00
|
|
|
return (
|
|
|
|
<div class="tab-switcher">
|
2019-01-17 12:05:58 -08:00
|
|
|
<div class="tabs">
|
|
|
|
{tabs}
|
|
|
|
</div>
|
|
|
|
<div class="contents">
|
|
|
|
{contents}
|
|
|
|
</div>
|
2018-11-21 11:08:27 -08:00
|
|
|
</div>
|
|
|
|
)
|
2018-08-27 12:22:25 -07:00
|
|
|
}
|
|
|
|
})
|