// eslint-disable-next-line no-unused import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome' import { mapState } from 'pinia' import { Fragment, h } from 'vue' import './tab_switcher.scss' import { useInterfaceStore } from 'src/stores/interface' const findFirstUsable = (slots) => slots.findIndex((_) => _.props) export default { name: 'TabSwitcher', props: { renderOnlyFocused: { required: false, type: Boolean, default: false, }, onSwitch: { required: false, type: Function, default: undefined, }, activeTab: { required: false, type: String, default: undefined, }, scrollableTabs: { required: false, type: Boolean, default: false, }, bodyScrollLock: { required: false, type: Boolean, default: false, }, }, data() { return { active: findFirstUsable(this.slots()), } }, computed: { activeIndex() { // In case of controlled component if (this.activeTab) { return this.slots().findIndex( (slot) => slot && slot.props && this.activeTab === slot.props.key, ) } else { return this.active } }, isActive() { return (tabName) => { const isWanted = (slot) => slot.props && slot.props['data-tab-name'] === tabName return this.$slots.default().findIndex(isWanted) === this.activeIndex } }, }, beforeUpdate() { const currentSlot = this.slots()[this.active] if (!currentSlot.props) { this.active = findFirstUsable(this.slots()) } }, methods: { clickTab(index) { return (e) => { e.preventDefault() this.setTab(index) } }, // DO NOT put it to computed, it doesn't work (caching?) slots() { if (this.$slots.default()[0].type === Fragment) { return this.$slots.default()[0].children } return this.$slots.default() }, setTab(index) { if (typeof this.onSwitch === 'function') { this.onSwitch.call(null, this.slots()[index].key) } this.active = index if (this.scrollableTabs) { this.$refs.contents.scrollTop = 0 } }, }, render() { const tabs = this.slots().map((slot, index) => { const props = slot.props if (!props) return const classesTab = ['tab'] const classesWrapper = ['tab-wrapper'] if (this.activeIndex === index) { classesTab.push('active') classesWrapper.push('active') } if (props.image) { return (
) } return (
) }) const contents = this.slots().map((slot, index) => { const props = slot.props if (!props) return const active = this.activeIndex === index const classes = [active ? 'active' : 'hidden'] if (props.fullHeight || props['full-height']) { classes.push('-full-height') } if (props.fullWidth || props['full-width']) { classes.push('-full-width') } let delayRender = slot.props['delay-render'] if (delayRender && active) { slot.props['delay-render'] = false delayRender = false } const renderSlot = !delayRender && (!this.renderOnlyFocused || active) ? slot : '' return
{renderSlot}
}) return (
{tabs}
{contents}
) }, }