feat(transition): handle transition classes when patching classes
This commit is contained in:
parent
7859e4bce3
commit
be9b4b2527
@ -64,19 +64,19 @@ function resolveCSSTransitionData({
|
||||
...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)
|
||||
@ -87,17 +87,17 @@ function resolveCSSTransitionData({
|
||||
})
|
||||
},
|
||||
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)
|
||||
@ -143,6 +143,27 @@ function validateDuration(val: unknown) {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -1,7 +1,17 @@
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user