Skip to content

Commit

Permalink
fix(carousel): update active class when the content changes
Browse files Browse the repository at this point in the history
  • Loading branch information
fbasso committed Jan 12, 2021
1 parent acae6c2 commit 15ad374
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/carousel/carousel.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ describe('ngb-carousel', () => {
fixture.componentInstance.slides = ['c', 'd'];
fixture.detectChanges();
expect(getSlidesText(fixture.nativeElement)).toEqual(['c', 'd']);
expectActiveSlides(fixture.nativeElement, [true, false]);
});

it('should change slide on indicator click', fakeAsync(() => {
Expand Down
22 changes: 20 additions & 2 deletions src/carousel/carousel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {NgbCarouselConfig} from './carousel-config';

import {BehaviorSubject, combineLatest, NEVER, Observable, Subject, timer, zip} from 'rxjs';
import {distinctUntilChanged, map, startWith, switchMap, take, takeUntil} from 'rxjs/operators';
import {ngbRunTransition, NgbTransitionOptions} from '../util/transition/ngbTransition';
import {ngbCompleteTransition, ngbRunTransition, NgbTransitionOptions} from '../util/transition/ngbTransition';
import {
ngbCarouselTransitionIn,
ngbCarouselTransitionOut,
Expand Down Expand Up @@ -280,7 +280,25 @@ export class NgbCarousel implements AfterContentChecked,
});
}

this.slides.changes.pipe(takeUntil(this._destroy$)).subscribe(() => this._cd.markForCheck());
this.slides.changes.pipe(takeUntil(this._destroy$)).subscribe(() => {
this._transitionIds ?.forEach(id => ngbCompleteTransition(this._getSlideElement(id)));
this._transitionIds = null;

this._cd.markForCheck();

// The following code need to be done asynchronously, after the dom becomes stable,
// otherwise all changes will be undone.
this._ngZone.onStable.pipe(take(1)).subscribe(() => {
for (const { id } of this.slides) {
const element = this._getSlideElement(id);
if (id === this.activeId) {
element.classList.add('active');
} else {
element.classList.remove('active');
}
}
});
});
}

ngAfterContentChecked() {
Expand Down
1 change: 1 addition & 0 deletions src/test/test-styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@

.ngb-test-after {
opacity: 0;
transition: none;
}

.ngb-test-hide-outer {
Expand Down
2 changes: 1 addition & 1 deletion src/util/transition/ngbTransition.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ if (isBrowserVisible('ngbRunTransition')) {
expect(completeSpy1).toHaveBeenCalled();
expect(element.classList.contains('ngb-test-during')).toBe(false);
expect(element.classList.contains('ngb-test-after')).toBe(true);
expect(window.getComputedStyle(element).opacity).toBe('0');
expectOpacity(element, '0');
});

it(`should create and allow modifying context when running a new transition`, (done) => {
Expand Down
6 changes: 3 additions & 3 deletions src/util/transition/ngbTransition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface NgbTransitionOptions<T> {

export interface NgbTransitionCtx<T> {
transition$: Subject<any>;
stop: () => void;
complete: () => void;
context: T;
}

Expand Down Expand Up @@ -70,7 +70,7 @@ export const ngbRunTransition =
const stop$ = transition$.pipe(endWith(true));
runningTransitions.set(element, {
transition$,
stop: () => {
complete: () => {
finishTransition$.next();
finishTransition$.complete();
},
Expand Down Expand Up @@ -100,5 +100,5 @@ export const ngbRunTransition =
};

export const ngbCompleteTransition = (element: HTMLElement) => {
runningTransitions.get(element) ?.stop();
runningTransitions.get(element) ?.complete();
};

0 comments on commit 15ad374

Please sign in to comment.