Skip to content

Commit

Permalink
fix(transition): respect rules in *-leave-from transition class (#2597)
Browse files Browse the repository at this point in the history
fix #2593
  • Loading branch information
luwuer authored Dec 2, 2020
1 parent 20a704f commit e2618a6
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 18 deletions.
24 changes: 16 additions & 8 deletions packages/runtime-dom/src/components/Transition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ export interface TransitionProps extends BaseTransitionProps<Element> {
leaveToClass?: string
}

export interface ElementWithTransition extends HTMLElement {
// _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>
}

// DOM Transition is a higher-order-component based on the platform-agnostic
// base Transition component, with DOM-specific logic.
export const Transition: FunctionalComponent<TransitionProps> = (
Expand Down Expand Up @@ -149,7 +157,15 @@ export function resolveTransitionProps(
const resolve = () => finishLeave(el, done)
addTransitionClass(el, leaveActiveClass)
addTransitionClass(el, leaveFromClass)
// ref #2531, #2593
// disabling the transition before nextFrame ensures styles from
// *-leave-from and *-enter-from classes are applied instantly before
// the transition starts. This is applied for enter transition as well
// so that it accounts for `visibility: hidden` cases.
const cachedTransition = (el as HTMLElement).style.transitionProperty
;(el as HTMLElement).style.transitionProperty = 'none'
nextFrame(() => {
;(el as HTMLElement).style.transitionProperty = cachedTransition
removeTransitionClass(el, leaveFromClass)
addTransitionClass(el, leaveToClass)
if (!(onLeave && onLeave.length > 1)) {
Expand Down Expand Up @@ -206,14 +222,6 @@ function validateDuration(val: unknown) {
}
}

export interface ElementWithTransition extends HTMLElement {
// _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>
}

export function addTransitionClass(el: Element, cls: string) {
cls.split(/\s+/).forEach(c => c && el.classList.add(c))
;(
Expand Down
3 changes: 2 additions & 1 deletion packages/vue/__tests__/Transition.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1305,9 +1305,10 @@ describe('e2e: Transition', () => {
await classWhenTransitionStart()
await nextFrame()
expect(await html('#container')).toBe(
'<div class="test v-leave-active v-leave-to">one</div>'
'<div class="test v-leave-active v-leave-to" style="">one</div>'
)
await transitionFinish()
await nextFrame()
expect(await html('#container')).toBe(
'<div class="test v-enter-active v-enter-to">two</div>'
)
Expand Down
19 changes: 10 additions & 9 deletions packages/vue/__tests__/TransitionGroup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ describe('e2e: TransitionGroup', () => {

const duration = 50
const buffer = 5
const transitionDisableProp = `style="transition-property: none;"`

const htmlWhenTransitionStart = () =>
page().evaluate(() => {
Expand Down Expand Up @@ -106,15 +107,15 @@ describe('e2e: TransitionGroup', () => {
)

expect(await htmlWhenTransitionStart()).toBe(
`<div class="test test-leave-active test-leave-from">a</div>` +
`<div class="test test-leave-active test-leave-from" ${transitionDisableProp}>a</div>` +
`<div class="test">b</div>` +
`<div class="test test-leave-active test-leave-from">c</div>`
`<div class="test test-leave-active test-leave-from" ${transitionDisableProp}>c</div>`
)
await nextFrame()
expect(await html('#container')).toBe(
`<div class="test test-leave-active test-leave-to">a</div>` +
`<div class="test test-leave-active test-leave-to" style="">a</div>` +
`<div class="test">b</div>` +
`<div class="test test-leave-active test-leave-to">c</div>`
`<div class="test test-leave-active test-leave-to" style="">c</div>`
)
await transitionFinish()
expect(await html('#container')).toBe(`<div class="test">b</div>`)
Expand Down Expand Up @@ -150,14 +151,14 @@ describe('e2e: TransitionGroup', () => {
)

expect(await htmlWhenTransitionStart()).toBe(
`<div class="test test-leave-active test-leave-from">a</div>` +
`<div class="test test-leave-active test-leave-from" ${transitionDisableProp}>a</div>` +
`<div class="test">b</div>` +
`<div class="test">c</div>` +
`<div class="test test-enter-active test-enter-from">d</div>`
)
await nextFrame()
expect(await html('#container')).toBe(
`<div class="test test-leave-active test-leave-to">a</div>` +
`<div class="test test-leave-active test-leave-to" style="">a</div>` +
`<div class="test">b</div>` +
`<div class="test">c</div>` +
`<div class="test test-enter-active test-enter-to">d</div>`
Expand Down Expand Up @@ -278,7 +279,7 @@ describe('e2e: TransitionGroup', () => {
`<div class="test group-enter-active group-enter-from">d</div>` +
`<div class="test">b</div>` +
`<div class="test group-move" style="">a</div>` +
`<div class="test group-leave-active group-leave-from group-move" style="">c</div>`
`<div class="test group-leave-active group-leave-from group-move" ${transitionDisableProp}>c</div>`
)
await nextFrame()
expect(await html('#container')).toBe(
Expand Down Expand Up @@ -461,7 +462,7 @@ describe('e2e: TransitionGroup', () => {

// enter + leave
expect(await htmlWhenTransitionStart()).toBe(
`<div class="test test-leave-active test-leave-from">a</div>` +
`<div class="test test-leave-active test-leave-from" ${transitionDisableProp}>a</div>` +
`<div class="test">b</div>` +
`<div class="test">c</div>` +
`<div class="test test-enter-active test-enter-from">d</div>`
Expand All @@ -474,7 +475,7 @@ describe('e2e: TransitionGroup', () => {
expect(afterEnterSpy).not.toBeCalled()
await nextFrame()
expect(await html('#container')).toBe(
`<div class="test test-leave-active test-leave-to">a</div>` +
`<div class="test test-leave-active test-leave-to" style="">a</div>` +
`<div class="test">b</div>` +
`<div class="test">c</div>` +
`<div class="test test-enter-active test-enter-to">d</div>`
Expand Down

0 comments on commit e2618a6

Please sign in to comment.