import Vue from '../../utils/vue'; import idMixin from '../../mixins/id'; import normalizeSlotMixin from '../../mixins/normalize-slot'; import BVTransition from '../../utils/bv-transition'; // @vue/component export var BTab = /*#__PURE__*/ Vue.extend({ name: 'BTab', mixins: [idMixin, normalizeSlotMixin], inject: { bvTabs: { default: function _default() { return {}; } } }, props: { active: { type: Boolean, default: false }, tag: { type: String, default: 'div' }, buttonId: { type: String, default: '' }, title: { type: String, default: '' }, titleItemClass: { // Sniffed by tabs.js and added to nav 'li.nav-item' type: [String, Array, Object], default: null }, titleLinkClass: { // Sniffed by tabs.js and added to nav 'a.nav-link' type: [String, Array, Object], default: null }, disabled: { type: Boolean, default: false }, noBody: { type: Boolean, default: false }, lazy: { type: Boolean, default: false } }, data: function data() { return { localActive: this.active && !this.disabled, show: false }; }, computed: { tabClasses: function tabClasses() { return [{ active: this.localActive, disabled: this.disabled, 'card-body': this.bvTabs.card && !this.noBody }, // Apply `activeTabClass` styles when this tab is active this.localActive ? this.bvTabs.activeTabClass : null]; }, controlledBy: function controlledBy() { return this.buttonId || this.safeId('__BV_tab_button__'); }, computedNoFade: function computedNoFade() { return !(this.bvTabs.fade || false); }, computedLazy: function computedLazy() { return this.bvTabs.lazy || this.lazy; }, _isTab: function _isTab() { // For parent sniffing of child return true; } }, watch: { localActive: function localActive(newVal) { // Make 'active' prop work with `.sync` modifier this.$emit('update:active', newVal); }, active: function active(newVal, oldVal) { if (newVal !== oldVal) { if (newVal) { // If activated post mount this.activate(); } else { /* istanbul ignore next */ if (!this.deactivate()) { // Tab couldn't be deactivated, so we reset the synced active prop // Deactivation will fail if no other tabs to activate this.$emit('update:active', this.localActive); } } } }, disabled: function disabled(newVal, oldVal) { if (newVal !== oldVal) { if (newVal && this.localActive && this.bvTabs.firstTab) { this.localActive = false; this.bvTabs.firstTab(); } } } }, mounted: function mounted() { // Inform b-tabs of our presence this.registerTab(); // Initially show on mount if active and not disabled this.show = this.localActive; }, updated: function updated() { // Force the tab button content to update (since slots are not reactive) // Only done if we have a title slot, as the title prop is reactive if (this.hasNormalizedSlot('title') && this.bvTabs.updateButton) { this.bvTabs.updateButton(this); } }, destroyed: function destroyed() { // inform b-tabs of our departure this.unregisterTab(); }, methods: { // Private methods registerTab: function registerTab() { // Inform `b-tabs` of our presence this.bvTabs.registerTab && this.bvTabs.registerTab(this); }, unregisterTab: function unregisterTab() { // Inform `b-tabs` of our departure this.bvTabs.unregisterTab && this.bvTabs.unregisterTab(this); }, // Public methods activate: function activate() { if (this.bvTabs.activateTab && !this.disabled) { return this.bvTabs.activateTab(this); } else { // Not inside a component or tab is disabled return false; } }, deactivate: function deactivate() { if (this.bvTabs.deactivateTab && this.localActive) { return this.bvTabs.deactivateTab(this); } else { // Not inside a component or not active to begin with return false; } } }, render: function render(h) { var content = h(this.tag, { ref: 'panel', staticClass: 'tab-pane', class: this.tabClasses, directives: [{ name: 'show', rawName: 'v-show', value: this.localActive, expression: 'localActive' }], attrs: { role: 'tabpanel', id: this.safeId(), 'aria-hidden': this.localActive ? 'false' : 'true', 'aria-labelledby': this.controlledBy || null } }, // Render content lazily if requested [this.localActive || !this.computedLazy ? this.normalizeSlot('default') : h()]); return h(BVTransition, { props: { mode: 'out-in', noFade: this.computedNoFade } }, [content]); } });