Skip to content

Commit

Permalink
fix(expansion): unable to toggle disabled panel via methods (#18181)
Browse files Browse the repository at this point in the history
In our expansion panel readme we state that a disabled panel can still be toggled and this is partially true, because it works only for toggling through the `expanded` property, but not via the `open`, `close` and `toggle` methods since they're inherited from the CDK `AccordionItem`. These changes override the methods so that we can allow them to work on disabled panels. We can't make this change safely for the CDK accordion item, because it doesn't have a panel header which means that we have to assume that all calls to the methods are user-generated.

Fixes #18171.

(cherry picked from commit 3a6c16f)
  • Loading branch information
crisbeto authored and jelbourn committed Jan 22, 2020
1 parent 9086a4b commit 796db4d
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/material/expansion/expansion-panel-header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ export class MatExpansionPanelHeader implements OnDestroy, FocusableOption {

/** Toggles the expanded state of the panel. */
_toggle(): void {
this.panel.toggle();
if (!this.disabled) {
this.panel.toggle();
}
}

/** Gets whether the panel is expanded. */
Expand Down
15 changes: 15 additions & 0 deletions src/material/expansion/expansion-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,21 @@ export class MatExpansionPanel extends CdkAccordionItem implements AfterContentI
return this.expanded ? 'expanded' : 'collapsed';
}

/** Toggles the expanded state of the expansion panel. */
toggle(): void {
this.expanded = !this.expanded;
}

/** Sets the expanded state of the expansion panel to false. */
close(): void {
this.expanded = false;
}

/** Sets the expanded state of the expansion panel to true. */
open(): void {
this.expanded = true;
}

ngAfterContentInit() {
if (this._lazyContent) {
// Render the content as soon as the panel becomes open.
Expand Down
46 changes: 46 additions & 0 deletions src/material/expansion/expansion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,52 @@ describe('MatExpansionPanel', () => {
expect(header.classList).toContain('mat-expanded');
});

it('should be able to toggle a disabled expansion panel programmatically via the ' +
'open/close methods', () => {
const panelInstance = fixture.componentInstance.panel;

expect(panelInstance.expanded).toBe(false);
expect(header.classList).not.toContain('mat-expanded');

fixture.componentInstance.disabled = true;
fixture.detectChanges();

panelInstance.open();
fixture.detectChanges();

expect(panelInstance.expanded).toBe(true);
expect(header.classList).toContain('mat-expanded');

panelInstance.close();
fixture.detectChanges();

expect(panelInstance.expanded).toBe(false);
expect(header.classList).not.toContain('mat-expanded');
});

it('should be able to toggle a disabled expansion panel programmatically via the ' +
'toggle method', () => {
const panelInstance = fixture.componentInstance.panel;

expect(panelInstance.expanded).toBe(false);
expect(header.classList).not.toContain('mat-expanded');

fixture.componentInstance.disabled = true;
fixture.detectChanges();

panelInstance.toggle();
fixture.detectChanges();

expect(panelInstance.expanded).toBe(true);
expect(header.classList).toContain('mat-expanded');

panelInstance.toggle();
fixture.detectChanges();

expect(panelInstance.expanded).toBe(false);
expect(header.classList).not.toContain('mat-expanded');
});

});
});

Expand Down
3 changes: 3 additions & 0 deletions tools/public_api_guard/material/expansion.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,12 @@ export declare class MatExpansionPanel extends CdkAccordionItem implements After
_containsFocus(): boolean;
_getExpandedState(): MatExpansionPanelState;
_hasSpacing(): boolean;
close(): void;
ngAfterContentInit(): void;
ngOnChanges(changes: SimpleChanges): void;
ngOnDestroy(): void;
open(): void;
toggle(): void;
static ngAcceptInputType_disabled: BooleanInput;
static ngAcceptInputType_expanded: BooleanInput;
static ngAcceptInputType_hideToggle: BooleanInput;
Expand Down

0 comments on commit 796db4d

Please sign in to comment.