Skip to content

Commit

Permalink
fix(animations): duration should be computed after 'startFn' execution
Browse files Browse the repository at this point in the history
  • Loading branch information
maxokorokov committed May 18, 2020
1 parent a8546b6 commit 4efea05
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/test/test-styles.css
Expand Up @@ -34,3 +34,8 @@
.ngb-test-fade:not(.ngb-test-show) {
opacity: 0;
}

.ngb-test-long-duration {
opacity: 0;
transition: opacity 1s linear;
}
21 changes: 21 additions & 0 deletions src/util/transition/ngbTransition.spec.ts
Expand Up @@ -146,6 +146,27 @@ if (isBrowserVisible('ngbRunTransition')) {
expect(window.getComputedStyle(element).opacity).toBe('1');
element.parentElement !.removeChild(element);
});

it(`should read duration after the start function was executed`, (done) => {
const startFn = ({classList}: HTMLElement) => classList.add('ngb-test-long-duration');

const nextSpy = createSpy();
const errorSpy = createSpy();

ngbRunTransition(element, startFn, {animation: true, runningTransition: 'continue'})
.subscribe(nextSpy, errorSpy, async() => {
// if duration is read before the 'startFn' is executed, it will be read as 0
expect(component.componentInstance.onTransitionEnd).toHaveBeenCalledTimes(1);
expect(nextSpy).toHaveBeenCalledWith(undefined);
expect(element.classList.contains('ngb-test-long-duration')).toBe(true);
expect(await getComputedStyleAsync(element, 'opacity')).toBe('0');
expect(errorSpy).not.toHaveBeenCalled();
done();
});

expect(window.getComputedStyle(element).opacity).toBe('1');
expect(element.classList.contains('ngb-test-long-duration')).toBe(true);
});
});
}

Expand Down
4 changes: 2 additions & 2 deletions src/util/transition/ngbTransition.ts
Expand Up @@ -44,10 +44,10 @@ export const ngbRunTransition =
const transition$ = new Subject<any>();
runningTransitions.set(element, transition$);

const transitionDurationMs = getTransitionDurationMs(element);

startFn(element);

const transitionDurationMs = getTransitionDurationMs(element);

// We have to both listen for the 'transitionend' event and have a 'just-in-case' timer,
// because 'transitionend' event might not be fired in some browsers, if the transitioning
// element becomes invisible (ex. when scrolling, making browser tab inactive, etc.). The timer
Expand Down

0 comments on commit 4efea05

Please sign in to comment.