Skip to content

Commit

Permalink
fix(cdk/accordion): allow for closeAll to be used when multiple mode …
Browse files Browse the repository at this point in the history
…is disabled (#22055)

Currently `CdkAccordion.closeAll` only works if `multi` is set to false, however it makes
sense when a single item is expanded as well.

These changes also fix that `_openCloseAllActions` wasn't being completed and they
include more unit tests.

Fixes #22003.

(cherry picked from commit a41fb6e)
  • Loading branch information
crisbeto authored and wagnermaciel committed Mar 2, 2021
1 parent 92de837 commit 02fcebe
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 10 deletions.
63 changes: 61 additions & 2 deletions src/cdk/accordion/accordion.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {waitForAsync, TestBed} from '@angular/core/testing';
import {Component, ViewChild} from '@angular/core';
import {Component, QueryList, ViewChild, ViewChildren} from '@angular/core';
import {By} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {CdkAccordionModule, CdkAccordionItem} from './public-api';
import {CdkAccordion} from './accordion';
import {CdkAccordionItem} from './accordion-item';
import {CdkAccordionModule} from './accordion-module';

describe('CdkAccordion', () => {
beforeEach(waitForAsync(() => {
Expand Down Expand Up @@ -59,6 +61,61 @@ describe('CdkAccordion', () => {

expect(innerItem.accordion).not.toBe(outerItem.accordion);
});

it('should be able to expand and collapse all items in multiple mode', () => {
const fixture = TestBed.createComponent(SetOfItems);
fixture.componentInstance.multi = true;
fixture.detectChanges();
fixture.componentInstance.accordion.openAll();
fixture.detectChanges();

expect(fixture.componentInstance.items.toArray().every(item => item.expanded)).toBe(true);

fixture.componentInstance.accordion.closeAll();
fixture.detectChanges();

expect(fixture.componentInstance.items.toArray().some(item => item.expanded)).toBe(false);
});

it('should not be able to expand all items if multiple mode is off', () => {
const fixture = TestBed.createComponent(SetOfItems);
fixture.componentInstance.multi = false;
fixture.detectChanges();
fixture.componentInstance.accordion.openAll();
fixture.detectChanges();

expect(fixture.componentInstance.items.toArray().some(item => item.expanded)).toBe(false);
});

it('should be able to use closeAll even if multiple mode is disabled', () => {
const fixture = TestBed.createComponent(SetOfItems);
fixture.componentInstance.multi = false;
fixture.detectChanges();
const item = fixture.componentInstance.items.first;

item.expanded = true;
fixture.detectChanges();

fixture.componentInstance.accordion.closeAll();
fixture.detectChanges();

expect(item.expanded).toBe(false);
});

it('should complete the accordion observables on destroy', () => {
const fixture = TestBed.createComponent(SetOfItems);
fixture.detectChanges();
const stateSpy = jasmine.createSpy('stateChanges complete spy');
const openCloseSpy = jasmine.createSpy('openCloseAllActions complete spy');

fixture.componentInstance.accordion._stateChanges.subscribe({complete: stateSpy});
fixture.componentInstance.accordion._openCloseAllActions.subscribe({complete: openCloseSpy});
fixture.destroy();

expect(stateSpy).toHaveBeenCalled();
expect(openCloseSpy).toHaveBeenCalled();
});

});

@Component({template: `
Expand All @@ -67,6 +124,8 @@ describe('CdkAccordion', () => {
<cdk-accordion-item></cdk-accordion-item>
</cdk-accordion>`})
class SetOfItems {
@ViewChild(CdkAccordion) accordion: CdkAccordion;
@ViewChildren(CdkAccordionItem) items: QueryList<CdkAccordionItem>;
multi: boolean = false;
}

Expand Down
13 changes: 5 additions & 8 deletions src/cdk/accordion/accordion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ export class CdkAccordion implements OnDestroy, OnChanges {

/** Opens all enabled accordion items in an accordion where multi is enabled. */
openAll(): void {
this._openCloseAll(true);
if (this._multi) {
this._openCloseAllActions.next(true);
}
}

/** Closes all enabled accordion items in an accordion where multi is enabled. */
closeAll(): void {
this._openCloseAll(false);
this._openCloseAllActions.next(false);
}

ngOnChanges(changes: SimpleChanges) {
Expand All @@ -60,12 +62,7 @@ export class CdkAccordion implements OnDestroy, OnChanges {

ngOnDestroy() {
this._stateChanges.complete();
}

private _openCloseAll(expanded: boolean): void {
if (this.multi) {
this._openCloseAllActions.next(expanded);
}
this._openCloseAllActions.complete();
}

static ngAcceptInputType_multi: BooleanInput;
Expand Down

0 comments on commit 02fcebe

Please sign in to comment.