Skip to content

Commit

Permalink
fix: prevent nested expansion panels from registering to the same acc…
Browse files Browse the repository at this point in the history
…ordion (#11342)
  • Loading branch information
josephperrott authored and mmalerba committed May 24, 2018
1 parent e592615 commit 9bf720a
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 6 deletions.
8 changes: 7 additions & 1 deletion src/cdk/accordion/accordion-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
OnDestroy,
Optional,
ChangeDetectorRef,
SkipSelf,
} from '@angular/core';
import {UniqueSelectionDispatcher} from '@angular/cdk/collections';
import {CdkAccordion} from './accordion';
Expand All @@ -30,6 +31,11 @@ let nextId = 0;
@Directive({
selector: 'cdk-accordion-item, [cdkAccordionItem]',
exportAs: 'cdkAccordionItem',
providers: [
// Provide CdkAccordion as undefined to prevent nested accordion items from registering
// to the same accordion.
{provide: CdkAccordion, useValue: undefined},
],
})
export class CdkAccordionItem implements OnDestroy {
/** Subscription to openAll/closeAll events. */
Expand Down Expand Up @@ -90,7 +96,7 @@ export class CdkAccordionItem implements OnDestroy {
/** Unregister function for _expansionDispatcher. */
private _removeUniqueSelectionListener: () => void = () => {};

constructor(@Optional() public accordion: CdkAccordion,
constructor(@Optional() @SkipSelf() public accordion: CdkAccordion,
private _changeDetectorRef: ChangeDetectorRef,
protected _expansionDispatcher: UniqueSelectionDispatcher) {
this._removeUniqueSelectionListener =
Expand Down
23 changes: 22 additions & 1 deletion src/cdk/accordion/accordion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ describe('CdkAccordion', () => {
CdkAccordionModule
],
declarations: [
SetOfItems
SetOfItems,
NestedItems,
],
});
TestBed.compileComponents();
Expand Down Expand Up @@ -53,6 +54,14 @@ describe('CdkAccordion', () => {
expect(firstPanel.expanded).toBeTruthy();
expect(secondPanel.expanded).toBeTruthy();
});

it('should not register nested items to the same accordion', () => {
const fixture = TestBed.createComponent(NestedItems);
const innerItem = fixture.componentInstance.innerItem;
const outerItem = fixture.componentInstance.outerItem;

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

@Component({template: `
Expand All @@ -65,3 +74,15 @@ class SetOfItems {
@ViewChild('item2') item2;
multi: boolean = false;
}


@Component({template: `
<cdk-accordion>
<cdk-accordion-item #outerItem="cdkAccordionItem">
<cdk-accordion-item #innerItem="cdkAccordionItem"></cdk-accordion-item>
</cdk-accordion-item>
</cdk-accordion>`})
class NestedItems {
@ViewChild('outerItem') outerItem: CdkAccordionItem;
@ViewChild('innerItem') innerItem: CdkAccordionItem;
}
30 changes: 27 additions & 3 deletions src/lib/expansion/accordion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ import {async, TestBed} from '@angular/core/testing';
import {Component, ViewChild} from '@angular/core';
import {By} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {MatExpansionModule, MatAccordion} from './index';
import {MatExpansionModule, MatAccordion, MatExpansionPanel} from './index';


describe('CdkAccordion', () => {
describe('MatAccordion', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
BrowserAnimationsModule,
MatExpansionModule
],
declarations: [
SetOfItems
NestedPanel,
SetOfItems,
],
});
TestBed.compileComponents();
Expand Down Expand Up @@ -84,6 +85,14 @@ describe('CdkAccordion', () => {
expect(panels[0].classes['mat-expanded']).toBeFalsy();
expect(panels[1].classes['mat-expanded']).toBeFalsy();
});

it('should not register nested panels to the same accordion', () => {
const fixture = TestBed.createComponent(NestedPanel);
const innerPanel = fixture.componentInstance.innerPanel;
const outerPanel = fixture.componentInstance.outerPanel;

expect(innerPanel.accordion).not.toBe(outerPanel.accordion);
});
});


Expand All @@ -106,3 +115,18 @@ class SetOfItems {
secondPanelExpanded: boolean = false;
secondPanelDisabled: boolean = false;
}

@Component({template: `
<mat-accordion>
<mat-expansion-panel #outerPanel="matExpansionPanel">
<mat-expansion-panel-header>Outer Panel</mat-expansion-panel-header>
<mat-expansion-panel #innerPanel="matExpansionPanel">
<mat-expansion-panel-header>Inner Panel</mat-expansion-panel-header>
<p>Content</p>
</mat-expansion-panel>
</mat-expansion-panel>
</mat-accordion>`})
class NestedPanel {
@ViewChild('outerPanel') outerPanel: MatExpansionPanel;
@ViewChild('innerPanel') innerPanel: MatExpansionPanel;
}
8 changes: 7 additions & 1 deletion src/lib/expansion/expansion-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
OnDestroy,
Optional,
SimpleChanges,
SkipSelf,
ViewContainerRef,
ViewEncapsulation,
} from '@angular/core';
Expand Down Expand Up @@ -56,6 +57,11 @@ let uniqueId = 0;
inputs: ['disabled', 'expanded'],
outputs: ['opened', 'closed', 'expandedChange'],
animations: [matExpansionAnimations.bodyExpansion],
providers: [
// Provide MatAccordion as undefined to prevent nested expansion panels from registering
// to the same accordion.
{provide: MatAccordion, useValue: undefined},
],
host: {
'class': 'mat-expansion-panel',
'[class.mat-expanded]': 'expanded',
Expand Down Expand Up @@ -87,7 +93,7 @@ export class MatExpansionPanel extends CdkAccordionItem
/** ID for the associated header element. Used for a11y labelling. */
_headerId = `mat-expansion-panel-header-${uniqueId++}`;

constructor(@Optional() accordion: MatAccordion,
constructor(@Optional() @SkipSelf() accordion: MatAccordion,
_changeDetectorRef: ChangeDetectorRef,
_uniqueSelectionDispatcher: UniqueSelectionDispatcher,
private _viewContainerRef: ViewContainerRef) {
Expand Down

0 comments on commit 9bf720a

Please sign in to comment.