Skip to content

Commit a72085b

Browse files
crisbetojelbourn
authored andcommitted
feat(expansion-panel): support two-way binding for the expanded property (#9327)
* Supports two-way binding to the `expanded` property on the expansion panel. * Fixes som wrong indentation in the tests. Fixes #9311.
1 parent 6f7332b commit a72085b

File tree

3 files changed

+48
-10
lines changed

3 files changed

+48
-10
lines changed

src/cdk/accordion/accordion-item.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ export class CdkAccordionItem implements OnDestroy {
3737
@Output() opened: EventEmitter<void> = new EventEmitter<void>();
3838
/** Event emitted when the AccordionItem is destroyed. */
3939
@Output() destroyed: EventEmitter<void> = new EventEmitter<void>();
40+
41+
/**
42+
* Emits whenever the expanded state of the accordion changes.
43+
* Primarily used to facilitate two-way binding.
44+
* @docs-private
45+
*/
46+
@Output() expandedChange: EventEmitter<boolean> = new EventEmitter<boolean>();
47+
4048
/** The unique AccordionItem id. */
4149
readonly id: string = `cdk-accordion-child-${nextId++}`;
4250

@@ -49,6 +57,8 @@ export class CdkAccordionItem implements OnDestroy {
4957
// Only emit events and update the internal value if the value changes.
5058
if (this._expanded !== expanded) {
5159
this._expanded = expanded;
60+
this.expandedChange.emit(expanded);
61+
5262
if (expanded) {
5363
this.opened.emit();
5464
/**

src/lib/expansion/expansion-panel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export type MatExpansionPanelState = 'expanded' | 'collapsed';
7373
preserveWhitespaces: false,
7474
changeDetection: ChangeDetectionStrategy.OnPush,
7575
inputs: ['disabled', 'expanded'],
76-
outputs: ['opened', 'closed'],
76+
outputs: ['opened', 'closed', 'expandedChange'],
7777
animations: [matExpansionAnimations.bodyExpansion],
7878
host: {
7979
'class': 'mat-expansion-panel',

src/lib/expansion/expansion.spec.ts

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ describe('MatExpansionPanel', () => {
1818
PanelWithCustomMargin,
1919
LazyPanelWithContent,
2020
LazyPanelOpenOnLoad,
21+
PanelWithTwoWayBinding,
2122
],
2223
});
2324
TestBed.compileComponents();
@@ -165,15 +166,31 @@ describe('MatExpansionPanel', () => {
165166
expect(arrow.style.transform).toBe('rotate(180deg)', 'Expected 180 degree rotation.');
166167
}));
167168

168-
it('make sure accordion item runs ngOnDestroy when expansion panel is destroyed', () => {
169-
let fixture = TestBed.createComponent(PanelWithContentInNgIf);
170-
fixture.detectChanges();
171-
let destroyedOk = false;
172-
fixture.componentInstance.panel.destroyed.subscribe(() => destroyedOk = true);
173-
fixture.componentInstance.expansionShown = false;
174-
fixture.detectChanges();
175-
expect(destroyedOk).toBe(true);
176-
});
169+
it('should make sure accordion item runs ngOnDestroy when expansion panel is destroyed', () => {
170+
let fixture = TestBed.createComponent(PanelWithContentInNgIf);
171+
fixture.detectChanges();
172+
let destroyedOk = false;
173+
fixture.componentInstance.panel.destroyed.subscribe(() => destroyedOk = true);
174+
fixture.componentInstance.expansionShown = false;
175+
fixture.detectChanges();
176+
expect(destroyedOk).toBe(true);
177+
});
178+
179+
it('should support two-way binding of the `expanded` property', () => {
180+
const fixture = TestBed.createComponent(PanelWithTwoWayBinding);
181+
const header = fixture.debugElement.query(By.css('mat-expansion-panel-header')).nativeElement;
182+
183+
fixture.detectChanges();
184+
expect(fixture.componentInstance.expanded).toBe(false);
185+
186+
header.click();
187+
fixture.detectChanges();
188+
expect(fixture.componentInstance.expanded).toBe(true);
189+
190+
header.click();
191+
fixture.detectChanges();
192+
expect(fixture.componentInstance.expanded).toBe(false);
193+
});
177194

178195
describe('disabled state', () => {
179196
let fixture: ComponentFixture<PanelWithContent>;
@@ -313,3 +330,14 @@ class LazyPanelWithContent {
313330
</mat-expansion-panel>`
314331
})
315332
class LazyPanelOpenOnLoad {}
333+
334+
335+
@Component({
336+
template: `
337+
<mat-expansion-panel [(expanded)]="expanded">
338+
<mat-expansion-panel-header>Panel Title</mat-expansion-panel-header>
339+
</mat-expansion-panel>`
340+
})
341+
class PanelWithTwoWayBinding {
342+
expanded = false;
343+
}

0 commit comments

Comments
 (0)