Skip to content

Commit e4dca02

Browse files
henetirikiLouw Swart
authored andcommitted
feat(expansion): add accordion expand/collapse all (#6929)
Refactors expand/collapse all after accordion item moved to CDK. Closes #6929
1 parent 903c04a commit e4dca02

File tree

6 files changed

+53
-10
lines changed

6 files changed

+53
-10
lines changed

src/cdk/accordion/accordion-item.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,12 @@ export class CdkAccordionItem implements OnDestroy {
7272
private _changeDetectorRef: ChangeDetectorRef,
7373
protected _expansionDispatcher: UniqueSelectionDispatcher) {
7474
this._removeUniqueSelectionListener =
75-
_expansionDispatcher.listen((id: string, accordionId: string) => {
76-
if (this.accordion && !this.accordion.multi &&
77-
this.accordion.id === accordionId && this.id !== id) {
78-
this.expanded = false;
79-
}
80-
});
75+
_expansionDispatcher.listen((id: string, accordionId: string) => {
76+
if (this.accordion && !this.accordion.multi &&
77+
this.accordion.id === accordionId && this.id !== id) {
78+
this.expanded = false;
79+
}
80+
});
8181
}
8282

8383
/** Emits an event for the accordion item being destroyed. */

src/cdk/accordion/accordion.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class CdkAccordion {
2323
/** A readonly id value to use for unique selection coordination. */
2424
readonly id = `cdk-accordion-${nextId++}`;
2525

26-
/** Whether the accordion should allow multiple expanded accordion items simulateously. */
26+
/** Whether the accordion should allow multiple expanded accordion items simultaneously. */
2727
@Input() get multi(): boolean { return this._multi; }
2828
set multi(multi: boolean) { this._multi = coerceBooleanProperty(multi); }
2929
private _multi: boolean = false;

src/demo-app/expansion/expansion-demo.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ <h1>matAccordion</h1>
4141
</mat-radio-group>
4242
<p>Accordion Actions <sup>('Multi Expansion' mode only)</sup></p>
4343
<div>
44-
<button mat-button (click)="accordion.expandAll()" [disabled]="!multi">Expand All</button>&nbsp;
44+
<button mat-button (click)="accordion.expandAll()" [disabled]="!multi">Expand All</button>
4545
<button mat-button (click)="accordion.collapseAll()" [disabled]="!multi">Collapse All</button>
4646
</div>
4747
<p>Accordion Panel(s)</p>

src/lib/expansion/accordion.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import {Directive, Input} from '@angular/core';
1010
import {coerceBooleanProperty} from '@angular/cdk/coercion';
1111
import {CdkAccordion} from '@angular/cdk/accordion';
12+
import {Subject} from 'rxjs/Subject';
1213

1314
/** Workaround for https://github.com/angular/angular/issues/17849 */
1415
export const _CdkAccordion = CdkAccordion;
@@ -27,6 +28,9 @@ export type MatAccordionDisplayMode = 'default' | 'flat';
2728
}
2829
})
2930
export class MatAccordion extends _CdkAccordion {
31+
/** Stream that emits true/false when expandAll/collapseAll is triggered. */
32+
readonly _expandCollapseAllActions: Subject<boolean> = new Subject<boolean>();
33+
3034
/** Whether the expansion indicator should be hidden. */
3135
@Input() get hideToggle(): boolean { return this._hideToggle; }
3236
set hideToggle(show: boolean) { this._hideToggle = coerceBooleanProperty(show); }
@@ -35,10 +39,30 @@ export class MatAccordion extends _CdkAccordion {
3539
/**
3640
* The display mode used for all expansion panels in the accordion. Currently two display
3741
* modes exist:
38-
* default - a gutter-like spacing is placed around any expanded panel, placing the expanded
42+
* default - a gutter-like spacing is placed around any expanded panel, placing the expanded
3943
* panel at a different elevation from the reset of the accordion.
4044
* flat - no spacing is placed around expanded panels, showing all panels at the same
4145
* elevation.
4246
*/
4347
@Input() displayMode: MatAccordionDisplayMode = 'default';
48+
49+
/**
50+
* Expands all enabled expansion panels in an accordion where multi is enabled.
51+
*/
52+
expandAll(): void {
53+
this._expandCollapseAll(true);
54+
}
55+
56+
/**
57+
* Collapses all enabled expansion panels in an accordion where multi is enabled.
58+
*/
59+
collapseAll(): void {
60+
this._expandCollapseAll(false);
61+
}
62+
63+
_expandCollapseAll(expanded: boolean): void {
64+
if (this.multi) {
65+
this._expandCollapseAllActions.next(expanded);
66+
}
67+
}
4468
}

src/lib/expansion/expansion-panel.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {CdkAccordionItem} from '@angular/cdk/accordion';
2525
import {UniqueSelectionDispatcher} from '@angular/cdk/collections';
2626
import {CanDisable, mixinDisabled} from '@angular/material/core';
2727
import {Subject} from 'rxjs/Subject';
28+
import {Subscription} from 'rxjs/Subscription';
2829
import {MatAccordion} from './accordion';
2930

3031
/** Workaround for https://github.com/angular/angular/issues/17849 */
@@ -90,6 +91,8 @@ export const EXPANSION_PANEL_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2,
9091
})
9192
export class MatExpansionPanel extends _MatExpansionPanelMixinBase
9293
implements CanDisable, OnChanges, OnDestroy {
94+
private _expandCollapseAllSubscription = Subscription.EMPTY;
95+
9396
/** Whether the toggle indicator should be hidden. */
9497
@Input() hideToggle: boolean = false;
9598

@@ -104,6 +107,11 @@ export class MatExpansionPanel extends _MatExpansionPanelMixinBase
104107
_uniqueSelectionDispatcher: UniqueSelectionDispatcher) {
105108
super(accordion, _changeDetectorRef, _uniqueSelectionDispatcher);
106109
this.accordion = accordion;
110+
111+
// When an expansion panel is hosted in an accordion, subscribe to the expand/collapse subject.
112+
if (this.accordion) {
113+
this._expandCollapseAllSubscription = this._subscribeToExpandCollapseAllActions();
114+
}
107115
}
108116

109117
/** Whether the expansion indicator should be hidden. */
@@ -133,6 +141,17 @@ export class MatExpansionPanel extends _MatExpansionPanelMixinBase
133141

134142
ngOnDestroy() {
135143
this._inputChanges.complete();
144+
this._expandCollapseAllSubscription.unsubscribe();
145+
}
146+
147+
_subscribeToExpandCollapseAllActions(): Subscription {
148+
return this.accordion._expandCollapseAllActions
149+
.subscribe(expanded => {
150+
// Only change state if item is enabled
151+
if (!this.disabled) {
152+
this.expanded = expanded;
153+
}
154+
});
136155
}
137156
}
138157

src/material-examples/example-module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ export const EXAMPLE_COMPONENTS = {
521521
selectorName: null
522522
},
523523
'select-no-ripple': {
524-
title: 'Select with cno option ripple ',
524+
title: 'Select with no option ripple ',
525525
component: SelectNoRippleExample,
526526
additionalFiles: null,
527527
selectorName: null

0 commit comments

Comments
 (0)