Skip to content

Commit 6b079aa

Browse files
Louw Swarthenetiriki
authored andcommitted
chore(accordion): adds disabled property to CDK accordion-item (#8141)
Adds a disabled property to Accordion Item in the CDK. Closes #8141
1 parent dbd64b6 commit 6b079aa

File tree

7 files changed

+123
-73
lines changed

7 files changed

+123
-73
lines changed

src/cdk/accordion/accordion-item.spec.ts

Lines changed: 102 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -31,45 +31,96 @@ describe('CdkAccordionItem', () => {
3131
.injector.get(CdkAccordionItem);
3232
});
3333

34-
it('should toggle its expanded state', () => {
35-
expect(item.expanded).toBeFalsy();
36-
item.toggle();
37-
expect(item.expanded).toBeTruthy();
38-
item.toggle();
39-
expect(item.expanded).toBeFalsy();
34+
describe('that is not disabled', () => {
35+
beforeEach(() => {
36+
item.disabled = false;
37+
});
38+
39+
it('should toggle its expanded state', () => {
40+
expect(item.expanded).toBeFalsy();
41+
item.toggle();
42+
expect(item.expanded).toBeTruthy();
43+
item.toggle();
44+
expect(item.expanded).toBeFalsy();
45+
});
46+
47+
it('should set its expanded state to expanded', () => {
48+
item.expanded = false;
49+
item.open();
50+
expect(item.expanded).toBeTruthy();
51+
});
52+
53+
it('should set its expanded state to closed', () => {
54+
item.expanded = true;
55+
item.close();
56+
expect(item.expanded).toBeFalsy();
57+
});
58+
59+
it('should emit a closed event', () => {
60+
spyOn(item.closed, 'emit');
61+
item.close();
62+
fixture.detectChanges();
63+
expect(item.closed.emit).toHaveBeenCalledWith();
64+
});
65+
66+
it('should emit an opened event', () => {
67+
spyOn(item.opened, 'emit');
68+
item.open();
69+
fixture.detectChanges();
70+
expect(item.opened.emit).toHaveBeenCalledWith();
71+
});
72+
73+
it('should emit a destroyed event', () => {
74+
spyOn(item.destroyed, 'emit');
75+
item.ngOnDestroy();
76+
fixture.detectChanges();
77+
expect(item.destroyed.emit).toHaveBeenCalledWith();
78+
});
4079
});
4180

42-
it('should set its expanded state to expanded', () => {
43-
item.expanded = false;
44-
item.open();
45-
expect(item.expanded).toBeTruthy();
46-
});
47-
48-
it('should set its expanded state to closed', () => {
49-
item.expanded = true;
50-
item.close();
51-
expect(item.expanded).toBeFalsy();
52-
});
53-
54-
it('should emit a closed event', () => {
55-
spyOn(item.closed, 'emit');
56-
item.close();
57-
fixture.detectChanges();
58-
expect(item.closed.emit).toHaveBeenCalledWith();
59-
});
60-
61-
it('should emit an opened event', () => {
62-
spyOn(item.opened, 'emit');
63-
item.open();
64-
fixture.detectChanges();
65-
expect(item.opened.emit).toHaveBeenCalledWith();
66-
});
67-
68-
it('should emit an destroyed event', () => {
69-
spyOn(item.destroyed, 'emit');
70-
item.ngOnDestroy();
71-
fixture.detectChanges();
72-
expect(item.destroyed.emit).toHaveBeenCalledWith();
81+
describe('that is disabled', () => {
82+
beforeEach(() => {
83+
item.disabled = true;
84+
});
85+
86+
it('should not toggle its expanded state', () => {
87+
expect(item.expanded).toBeFalsy();
88+
item.toggle();
89+
expect(item.expanded).toBeFalsy();
90+
});
91+
92+
it('should not set its expanded state to expanded', () => {
93+
item.expanded = false;
94+
item.open();
95+
expect(item.expanded).toBeFalsy();
96+
});
97+
98+
it('should not set its expanded state to closed', () => {
99+
item.expanded = true;
100+
item.close();
101+
expect(item.expanded).toBeTruthy();
102+
});
103+
104+
it('should not emit a closed event', () => {
105+
spyOn(item.closed, 'emit');
106+
item.close();
107+
fixture.detectChanges();
108+
expect(item.closed.emit).not.toHaveBeenCalled();
109+
});
110+
111+
it('should not emit an opened event', () => {
112+
spyOn(item.opened, 'emit');
113+
item.open();
114+
fixture.detectChanges();
115+
expect(item.opened.emit).not.toHaveBeenCalled();
116+
});
117+
118+
it('should emit a destroyed event', () => {
119+
spyOn(item.destroyed, 'emit');
120+
item.ngOnDestroy();
121+
fixture.detectChanges();
122+
expect(item.destroyed.emit).toHaveBeenCalledWith();
123+
});
73124
});
74125
});
75126

@@ -99,6 +150,20 @@ describe('CdkAccordionItem', () => {
99150
expect(firstItem.expanded).toBeTruthy();
100151
expect(secondItem.expanded).toBeTruthy();
101152
});
153+
154+
it('should not change expanded state for disabled items', () => {
155+
firstItem.disabled = true;
156+
expect(firstItem.expanded).toBeFalsy();
157+
expect(secondItem.expanded).toBeFalsy();
158+
firstItem.open();
159+
fixture.detectChanges();
160+
expect(firstItem.expanded).toBeFalsy();
161+
expect(secondItem.expanded).toBeFalsy();
162+
secondItem.open();
163+
fixture.detectChanges();
164+
expect(firstItem.expanded).toBeFalsy();
165+
expect(secondItem.expanded).toBeTruthy();
166+
});
102167
});
103168

104169

src/cdk/accordion/accordion-item.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
Optional,
1616
ChangeDetectorRef,
1717
} from '@angular/core';
18+
import {coerceBooleanProperty} from '@angular/cdk/coercion';
1819
import {UniqueSelectionDispatcher} from '@angular/cdk/collections';
1920
import {CdkAccordion} from './accordion';
2021

@@ -65,6 +66,12 @@ export class CdkAccordionItem implements OnDestroy {
6566
}
6667
private _expanded: boolean;
6768

69+
/** Whether the AccordionItem is disabled. */
70+
@Input()
71+
get disabled() { return this._disabled; }
72+
set disabled(disabled: boolean) { this._disabled = coerceBooleanProperty(disabled); }
73+
private _disabled: boolean = false;
74+
6875
/** Unregister function for _expansionDispatcher. */
6976
private _removeUniqueSelectionListener: () => void = () => {};
7077

@@ -88,16 +95,22 @@ export class CdkAccordionItem implements OnDestroy {
8895

8996
/** Toggles the expanded state of the accordion item. */
9097
toggle(): void {
91-
this.expanded = !this.expanded;
98+
if (!this.disabled) {
99+
this.expanded = !this.expanded;
100+
}
92101
}
93102

94103
/** Sets the expanded state of the accordion item to false. */
95104
close(): void {
96-
this.expanded = false;
105+
if (!this.disabled) {
106+
this.expanded = false;
107+
}
97108
}
98109

99110
/** Sets the expanded state of the accordion item to true. */
100111
open(): void {
101-
this.expanded = true;
112+
if (!this.disabled) {
113+
this.expanded = true;
114+
}
102115
}
103116
}

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/cdk/accordion/public-api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
export {CdkAccordionItem} from './accordion-item';
9+
export {CdkAccordionItem} from './accordion-item';
1010
export {CdkAccordion} from './accordion';
1111
export * from './accordion-module';

src/lib/expansion/expansion-module.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ import {A11yModule} from '@angular/cdk/a11y';
1414
import {MatAccordion} from './accordion';
1515
import {
1616
MatExpansionPanel,
17-
MatExpansionPanelActionRow,
18-
MatExpansionPanelBase
17+
MatExpansionPanelActionRow
1918
} from './expansion-panel';
2019
import {
2120
MatExpansionPanelDescription,
@@ -35,7 +34,6 @@ import {
3534
MatExpansionPanelDescription
3635
],
3736
declarations: [
38-
MatExpansionPanelBase,
3937
MatAccordion,
4038
MatExpansionPanel,
4139
MatExpansionPanelActionRow,

src/lib/expansion/expansion-panel-header.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,7 @@ export class MatExpansionPanelHeader implements OnDestroy {
111111

112112
/** Toggles the expanded state of the panel. */
113113
_toggle(): void {
114-
if (!this.panel.disabled) {
115-
this.panel.toggle();
116-
}
114+
this.panel.toggle();
117115
}
118116

119117
/** Gets whether the panel is expanded. */

src/lib/expansion/expansion-panel.ts

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
ChangeDetectorRef,
1313
Component,
1414
Directive,
15-
forwardRef,
1615
Host,
1716
Input,
1817
OnChanges,
@@ -23,7 +22,6 @@ import {
2322
} from '@angular/core';
2423
import {CdkAccordionItem} from '@angular/cdk/accordion';
2524
import {UniqueSelectionDispatcher} from '@angular/cdk/collections';
26-
import {CanDisable, mixinDisabled} from '@angular/material/core';
2725
import {Subject} from 'rxjs/Subject';
2826
import {MatAccordion} from './accordion';
2927

@@ -33,24 +31,6 @@ export const _CdkAccordionItem = CdkAccordionItem;
3331
/** Time and timing curve for expansion panel animations. */
3432
export const EXPANSION_PANEL_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2,1)';
3533

36-
// Boilerplate for applying mixins to MatExpansionPanel.
37-
/** @docs-private */
38-
@Component({
39-
template: '',
40-
moduleId: module.id,
41-
encapsulation: ViewEncapsulation.None,
42-
preserveWhitespaces: false,
43-
changeDetection: ChangeDetectionStrategy.OnPush,
44-
})
45-
export class MatExpansionPanelBase extends _CdkAccordionItem {
46-
constructor(accordion: MatAccordion,
47-
_changeDetectorRef: ChangeDetectorRef,
48-
_uniqueSelectionDispatcher: UniqueSelectionDispatcher) {
49-
super(accordion, _changeDetectorRef, _uniqueSelectionDispatcher);
50-
}
51-
}
52-
export const _MatExpansionPanelMixinBase = mixinDisabled(MatExpansionPanelBase);
53-
5434
/** MatExpansionPanel's states. */
5535
export type MatExpansionPanelState = 'expanded' | 'collapsed';
5636

@@ -78,9 +58,6 @@ export type MatExpansionPanelState = 'expanded' | 'collapsed';
7858
'[class.mat-expanded]': 'expanded',
7959
'[class.mat-expansion-panel-spacing]': '_hasSpacing()',
8060
},
81-
providers: [
82-
{provide: _MatExpansionPanelMixinBase, useExisting: forwardRef(() => MatExpansionPanel)}
83-
],
8461
animations: [
8562
trigger('bodyExpansion', [
8663
state('collapsed', style({height: '0px', visibility: 'hidden'})),
@@ -89,8 +66,7 @@ export type MatExpansionPanelState = 'expanded' | 'collapsed';
8966
]),
9067
],
9168
})
92-
export class MatExpansionPanel extends _MatExpansionPanelMixinBase
93-
implements CanDisable, OnChanges, OnDestroy {
69+
export class MatExpansionPanel extends _CdkAccordionItem implements OnChanges, OnDestroy {
9470
/** Whether the toggle indicator should be hidden. */
9571
@Input() hideToggle: boolean = false;
9672

0 commit comments

Comments
 (0)