UNPKG

vuetify

Version:

Vue Material Component Framework

166 lines (138 loc) 3.56 kB
// Components import { VTabTransition, VTabReverseTransition, } from '../transitions' // Mixins import { inject as RegistrableInject } from '../../mixins/registrable' // Helpers import { convertToUnit } from '../../util/helpers' // Utilities import mixins from '../../util/mixins' // Types import { VNode, FunctionalComponentOptions, VNodeData } from 'vue' const baseMixins = mixins( RegistrableInject('stepper', 'v-stepper-content', 'v-stepper') ) interface options extends InstanceType<typeof baseMixins> { $refs: { wrapper: HTMLElement } isVerticalProvided: boolean } /* @vue/component */ export default baseMixins.extend<options>().extend({ name: 'v-stepper-content', inject: { isVerticalProvided: { from: 'isVertical', }, }, props: { step: { type: [Number, String], required: true, }, }, data () { return { height: 0 as number | string, // Must be null to allow // previous comparison isActive: null as boolean | null, isReverse: false, isVertical: this.isVerticalProvided, } }, computed: { computedTransition (): FunctionalComponentOptions { // Fix for #8978 const reverse = this.$vuetify.rtl ? !this.isReverse : this.isReverse return reverse ? VTabReverseTransition : VTabTransition }, styles (): object { if (!this.isVertical) return {} return { height: convertToUnit(this.height), } }, }, watch: { isActive (current, previous) { // If active and the previous state // was null, is just booting up if (current && previous == null) { this.height = 'auto' return } if (!this.isVertical) return if (this.isActive) this.enter() else this.leave() }, }, mounted () { this.$refs.wrapper.addEventListener( 'transitionend', this.onTransition, false ) this.stepper && this.stepper.register(this) }, beforeDestroy () { this.$refs.wrapper.removeEventListener( 'transitionend', this.onTransition, false ) this.stepper && this.stepper.unregister(this) }, methods: { onTransition (e: TransitionEvent) { if (!this.isActive || e.propertyName !== 'height' ) return this.height = 'auto' }, enter () { let scrollHeight = 0 // Render bug with height requestAnimationFrame(() => { scrollHeight = this.$refs.wrapper.scrollHeight }) this.height = 0 // Give the collapsing element time to collapse setTimeout(() => this.isActive && (this.height = (scrollHeight || 'auto')), 450) }, leave () { this.height = this.$refs.wrapper.clientHeight setTimeout(() => (this.height = 0), 10) }, toggle (step: string | number, reverse: boolean) { this.isActive = step.toString() === this.step.toString() this.isReverse = reverse }, }, render (h): VNode { const contentData = { staticClass: 'v-stepper__content', } as VNodeData const wrapperData = { staticClass: 'v-stepper__wrapper', style: this.styles, ref: 'wrapper', } if (!this.isVertical) { contentData.directives = [{ name: 'show', value: this.isActive, }] } const wrapper = h('div', wrapperData, [this.$slots.default]) const content = h('div', contentData, [wrapper]) return h(this.computedTransition, { on: this.$listeners, }, [content]) }, })