Closed SaFrMo closed 5 years ago
Super useful component, but now that we're using Velocity a bit less, it adds a good amount of weight. I started this but haven't had time to finish yet:
<template> <transition @enter="enter" @leave="leave" :css="false"> <slot /> </transition> </template> <script> import Vue from 'vue' import { tween } from 'shifty' export default { data() { return { targetHeight: 0, tween: null, displayHeight: 0 } }, props: { speed: { type: Number, default: 400 } // easing: { // type: String, // default: 'swing' // } }, methods: { calculateHeight() { // save old style values const old = { position: this.$el.style['position'], visiblity: this.$el.style['visibility'] } // hide element and remove from flow to measure height this.$el.style['position'] = 'absolute' this.$el.style['visibility'] = 'hidden' // save target height const height = this.$el.offsetHeight this.$el.style['position'] = old.position this.$el.style['visibility'] = old.visibility || 'visible' return height }, async enter(el, done) { // wait for slot to exist in DOM await Vue.nextTick() // calculate target height const height = this.calculateHeight() await tween({ from: { h: 0 }, to: { h: height }, step: state => { this.displayHeight = state.h const elem = _get(this, '$slots.default[0].elm', { style: {} }) elem.style.height = `${state.h}px` } }) // proxy event this.$emit('enter', ...arguments) done() }, async leave(el, done) { console.log(this) const elem = _get(this, '$slots.default[0].elm') await tween({ from: { h: elem.offsetHeight }, to: { h: 0 }, step: state => { const elem = _get(this, '$slots.default[0].elm', { style: {} }) el.style.height = `${state.h}px` } }) done() // proxy event this.$emit('leave', ...arguments) } } } </script> <style lang="scss"> </style>
Closing since this is a pretty specific solution to a problem that doesn't crop up that much any more.
Super useful component, but now that we're using Velocity a bit less, it adds a good amount of weight. I started this but haven't had time to finish yet: