1// This code come from https://github.com/BinarCode/vue2-transitions 2// Updated for Vue 3 compatibility 3 4const BaseTransitionMixin = { 5 inheritAttrs: false, 6 props: { 7 /** 8 * Transition duration. Number for specifying the same duration for enter/leave transitions 9 * Object style {enter: 300, leave: 300} for specifying explicit durations for enter/leave 10 */ 11 duration: { 12 type: [Number, Object], 13 default: 200, 14 }, 15 /** 16 * Transition delay. Number for specifying the same delay for enter/leave transitions 17 * Object style {enter: 300, leave: 300} for specifying explicit durations for enter/leave 18 */ 19 delay: { 20 type: [Number, Object], 21 default: 0, 22 }, 23 /** 24 * Whether the component should be a `transition-group` component. 25 */ 26 group: Boolean, 27 /** 28 * Transition tag, in case the component is a `transition-group` 29 */ 30 tag: { 31 type: String, 32 default: 'span', 33 }, 34 /** 35 * Transform origin property https://tympanus.net/codrops/css_reference/transform-origin/. 36 * Can be specified with styles as well but it's shorter with this prop 37 */ 38 origin: { 39 type: String, 40 default: '', 41 }, 42 /** 43 * Element styles that are applied during transition. These styles are applied on @beforeEnter and @beforeLeave hooks 44 */ 45 styles: { 46 type: Object, 47 default: () => ({ 48 animationFillMode: 'both', 49 animationTimingFunction: 'ease-out', 50 }), 51 }, 52 }, 53 emits: [ 54 'before-enter', 55 'after-enter', 56 'before-leave', 57 'leave', 58 'after-leave', 59 ], 60 computed: { 61 componentType() { 62 return this.group ? 'transition-group' : 'transition' 63 }, 64 hooks() { 65 // In Vue 3, $listeners is merged into $attrs 66 return { 67 ...this.$attrs, 68 beforeEnter: this.beforeEnter, 69 afterEnter: (el) => { 70 this.cleanUpStyles(el) 71 this.$emit('after-enter', el) 72 }, 73 beforeLeave: this.beforeLeave, 74 leave: this.leave, 75 afterLeave: (el) => { 76 this.cleanUpStyles(el) 77 this.$emit('after-leave', el) 78 }, 79 } 80 }, 81 }, 82 methods: { 83 beforeEnter(el) { 84 const enterDuration = this.duration.enter 85 ? this.duration.enter 86 : this.duration 87 el.style.animationDuration = `${enterDuration}ms` 88 89 const enterDelay = this.delay.enter ? this.delay.enter : this.delay 90 el.style.animationDelay = `${enterDelay}ms` 91 92 this.setStyles(el) 93 this.$emit('before-enter', el) 94 }, 95 cleanUpStyles(el) { 96 Object.keys(this.styles).forEach((key) => { 97 const styleValue = this.styles[key] 98 if (styleValue) { 99 el.style[key] = '' 100 } 101 }) 102 el.style.animationDuration = '' 103 el.style.animationDelay = '' 104 }, 105 beforeLeave(el) { 106 const leaveDuration = this.duration.leave 107 ? this.duration.leave 108 : this.duration 109 el.style.animationDuration = `${leaveDuration}ms` 110 111 const leaveDelay = this.delay.leave ? this.delay.leave : this.delay 112 el.style.animationDelay = `${leaveDelay}ms` 113 114 this.setStyles(el) 115 this.$emit('before-leave', el) 116 }, 117 leave(el, done) { 118 this.setAbsolutePosition(el) 119 this.$emit('leave', el, done) 120 }, 121 setStyles(el) { 122 this.setTransformOrigin(el) 123 Object.keys(this.styles).forEach((key) => { 124 const styleValue = this.styles[key] 125 if (styleValue) { 126 el.style[key] = styleValue 127 } 128 }) 129 }, 130 setAbsolutePosition(el) { 131 if (this.group) { 132 el.style.position = 'absolute' 133 } 134 return this 135 }, 136 setTransformOrigin(el) { 137 if (this.origin) { 138 el.style.transformOrigin = this.origin 139 } 140 return this 141 }, 142 }, 143} 144 145export default { 146 name: 'collapse-transition', 147 mixins: [BaseTransitionMixin], 148 methods: { 149 transitionStyle(duration = 300) { 150 const durationInSeconds = duration / 1000 151 const style = `${durationInSeconds}s height ease-in-out, ${durationInSeconds}s padding-top ease-in-out, ${durationInSeconds}s padding-bottom ease-in-out` 152 return style 153 }, 154 beforeEnter(el) { 155 const enterDuration = this.duration.enter 156 ? this.duration.enter 157 : this.duration 158 el.style.transition = this.transitionStyle(enterDuration) 159 if (!el.dataset) el.dataset = {} 160 161 el.dataset.oldPaddingTop = el.style.paddingTop 162 el.dataset.oldPaddingBottom = el.style.paddingBottom 163 164 el.style.height = '0' 165 el.style.paddingTop = 0 166 el.style.paddingBottom = 0 167 this.setStyles(el) 168 }, 169 170 enter(el) { 171 el.dataset.oldOverflow = el.style.overflow 172 if (el.scrollHeight !== 0) { 173 el.style.height = `${el.scrollHeight}px` 174 el.style.paddingTop = el.dataset.oldPaddingTop 175 el.style.paddingBottom = el.dataset.oldPaddingBottom 176 } else { 177 el.style.height = '' 178 el.style.paddingTop = el.dataset.oldPaddingTop 179 el.style.paddingBottom = el.dataset.oldPaddingBottom 180 } 181 182 el.style.overflow = 'hidden' 183 }, 184 185 afterEnter(el) { 186 // for safari: remove class then reset height is necessary 187 el.style.transition = '' 188 el.style.height = '' 189 el.style.overflow = el.dataset.oldOverflow 190 }, 191 192 beforeLeave(el) { 193 if (!el.dataset) el.dataset = {} 194 el.dataset.oldPaddingTop = el.style.paddingTop 195 el.dataset.oldPaddingBottom = el.style.paddingBottom 196 el.dataset.oldOverflow = el.style.overflow 197 198 el.style.height = `${el.scrollHeight}px` 199 el.style.overflow = 'hidden' 200 this.setStyles(el) 201 }, 202 203 leave(el) { 204 const leaveDuration = this.duration.leave 205 ? this.duration.leave 206 : this.duration 207 if (el.scrollHeight !== 0) { 208 // for safari: add class after set height, or it will jump to zero height suddenly, weired 209 el.style.transition = this.transitionStyle(leaveDuration) 210 el.style.height = 0 211 el.style.paddingTop = 0 212 el.style.paddingBottom = 0 213 } 214 // necessary for transition-group 215 this.setAbsolutePosition(el) 216 }, 217 218 afterLeave(el) { 219 el.style.transition = '' 220 el.style.height = '' 221 el.style.overflow = el.dataset.oldOverflow 222 el.style.paddingTop = el.dataset.oldPaddingTop 223 el.style.paddingBottom = el.dataset.oldPaddingBottom 224 }, 225 }, 226 template: ` 227 <component :is="componentType" 228 :tag="tag" 229 v-bind="$attrs" 230 @before-enter="beforeEnter" 231 @after-enter="afterEnter" 232 @enter="enter" 233 @before-leave="beforeLeave" 234 @leave="leave" 235 @after-leave="afterLeave" 236 move-class="collapse-move"> 237 <slot></slot> 238 </component>`, 239}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.