...baseProps,
onBeforeEnter(el) {
onBeforeEnter && onBeforeEnter(el)
- el.classList.add(enterActiveClass)
- el.classList.add(enterFromClass)
+ addTransitionClass(el, enterActiveClass)
+ addTransitionClass(el, enterFromClass)
},
onEnter(el, done) {
nextFrame(() => {
const resolve = () => {
- el.classList.remove(enterToClass)
- el.classList.remove(enterActiveClass)
+ removeTransitionClass(el, enterToClass)
+ removeTransitionClass(el, enterActiveClass)
done()
}
onEnter && onEnter(el, resolve)
- el.classList.remove(enterFromClass)
- el.classList.add(enterToClass)
+ removeTransitionClass(el, enterFromClass)
+ addTransitionClass(el, enterToClass)
if (!(onEnter && onEnter.length > 1)) {
if (enterDuration) {
setTimeout(resolve, enterDuration)
})
},
onLeave(el, done) {
- el.classList.add(leaveActiveClass)
- el.classList.add(leaveFromClass)
+ addTransitionClass(el, leaveActiveClass)
+ addTransitionClass(el, leaveFromClass)
nextFrame(() => {
const resolve = () => {
- el.classList.remove(leaveToClass)
- el.classList.remove(leaveActiveClass)
+ removeTransitionClass(el, leaveToClass)
+ removeTransitionClass(el, leaveActiveClass)
done()
}
onLeave && onLeave(el, resolve)
- el.classList.remove(leaveFromClass)
- el.classList.add(leaveToClass)
+ removeTransitionClass(el, leaveFromClass)
+ addTransitionClass(el, leaveToClass)
if (!(onLeave && onLeave.length > 1)) {
if (leaveDuration) {
setTimeout(resolve, leaveDuration)
}
}
+export interface ElementWithTransition extends Element {
+ // _vtc = Vue Transition Classes.
+ // Store the temporarily-added transition classes on the element
+ // so that we can avoid overwriting them if the element's class is patched
+ // during the transition.
+ _vtc?: Set<string>
+}
+
+function addTransitionClass(el: ElementWithTransition, cls: string) {
+ el.classList.add(cls)
+ ;(el._vtc || (el._vtc = new Set())).add(cls)
+}
+
+function removeTransitionClass(el: ElementWithTransition, cls: string) {
+ el.classList.remove(cls)
+ el._vtc!.delete(cls)
+ if (!el._vtc!.size) {
+ el._vtc = undefined
+ }
+}
+
function nextFrame(cb: () => void) {
requestAnimationFrame(() => {
requestAnimationFrame(cb)
+import { ElementWithTransition } from '../components/CSSTransition'
+
// compiler should normalize class + :class bindings on the same element
// into a single binding ['staticClass', dynamic]
-
-export function patchClass(el: Element, value: string, isSVG: boolean) {
+export function patchClass(
+ el: ElementWithTransition,
+ value: string,
+ isSVG: boolean
+) {
+ // if this is an element during a transition, take the temporary transition
+ // classes into account.
+ if (el._vtc) {
+ value = [value, ...el._vtc].join(' ')
+ }
// directly setting className should be faster than setAttribute in theory
if (isSVG) {
el.setAttribute('class', value)