Skip to content

Commit a389704

Browse files
crisbetojelbourn
authored andcommitted
feat(expansion-panel): add injection token for configuring the default options (#14384)
Adds a new injection token to allow people to configure the default options for the expansion panel component. Fixes #14383.
1 parent 14b90db commit a389704

File tree

3 files changed

+79
-4
lines changed

3 files changed

+79
-4
lines changed

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,17 @@ import {
1818
Input,
1919
OnDestroy,
2020
ViewEncapsulation,
21+
Optional,
22+
Inject,
2123
} from '@angular/core';
2224
import {merge, Subscription, EMPTY} from 'rxjs';
2325
import {filter} from 'rxjs/operators';
2426
import {matExpansionAnimations} from './expansion-animations';
25-
import {MatExpansionPanel} from './expansion-panel';
27+
import {
28+
MatExpansionPanel,
29+
MatExpansionPanelDefaultOptions,
30+
MAT_EXPANSION_PANEL_DEFAULT_OPTIONS,
31+
} from './expansion-panel';
2632

2733

2834
/**
@@ -68,7 +74,9 @@ export class MatExpansionPanelHeader implements OnDestroy, FocusableOption {
6874
@Host() public panel: MatExpansionPanel,
6975
private _element: ElementRef,
7076
private _focusMonitor: FocusMonitor,
71-
private _changeDetectorRef: ChangeDetectorRef) {
77+
private _changeDetectorRef: ChangeDetectorRef,
78+
@Inject(MAT_EXPANSION_PANEL_DEFAULT_OPTIONS) @Optional()
79+
defaultOptions?: MatExpansionPanelDefaultOptions) {
7280

7381
const accordionHideToggleChange = panel.accordion ?
7482
panel.accordion._stateChanges.pipe(filter(changes => !!changes.hideToggle)) : EMPTY;
@@ -93,6 +101,11 @@ export class MatExpansionPanelHeader implements OnDestroy, FocusableOption {
93101
panel.accordion._handleHeaderFocus(this);
94102
}
95103
});
104+
105+
if (defaultOptions) {
106+
this.expandedHeight = defaultOptions.expandedHeight;
107+
this.collapsedHeight = defaultOptions.collapsedHeight;
108+
}
96109
}
97110

98111
/** Height of the header while the panel is expanded. */

src/lib/expansion/expansion-panel.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
ViewContainerRef,
3232
ViewEncapsulation,
3333
ViewChild,
34+
InjectionToken,
3435
} from '@angular/core';
3536
import {DOCUMENT} from '@angular/common';
3637
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
@@ -46,6 +47,28 @@ export type MatExpansionPanelState = 'expanded' | 'collapsed';
4647
/** Counter for generating unique element ids. */
4748
let uniqueId = 0;
4849

50+
/**
51+
* Object that can be used to override the default options
52+
* for all of the expansion panels in a module.
53+
*/
54+
export interface MatExpansionPanelDefaultOptions {
55+
/** Height of the header while the panel is expanded. */
56+
expandedHeight: string;
57+
58+
/** Height of the header while the panel is collapsed. */
59+
collapsedHeight: string;
60+
61+
/** Whether the toggle indicator should be hidden. */
62+
hideToggle: boolean;
63+
}
64+
65+
/**
66+
* Injection token that can be used to configure the defalt
67+
* options for the expansion panel component.
68+
*/
69+
export const MAT_EXPANSION_PANEL_DEFAULT_OPTIONS =
70+
new InjectionToken<MatExpansionPanelDefaultOptions>('MAT_EXPANSION_PANEL_DEFAULT_OPTIONS');
71+
4972
/**
5073
* `<mat-expansion-panel>`
5174
*
@@ -125,7 +148,9 @@ export class MatExpansionPanel extends CdkAccordionItem implements AfterContentI
125148
private _viewContainerRef: ViewContainerRef,
126149
// @breaking-change 8.0.0 _document and _animationMode to be made required
127150
@Inject(DOCUMENT) _document?: any,
128-
@Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string) {
151+
@Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string,
152+
@Inject(MAT_EXPANSION_PANEL_DEFAULT_OPTIONS) @Optional()
153+
defaultOptions?: MatExpansionPanelDefaultOptions) {
129154
super(accordion, _changeDetectorRef, _uniqueSelectionDispatcher);
130155
this.accordion = accordion;
131156
this._document = _document;
@@ -143,6 +168,10 @@ export class MatExpansionPanel extends CdkAccordionItem implements AfterContentI
143168
}
144169
}
145170
});
171+
172+
if (defaultOptions) {
173+
this.hideToggle = defaultOptions.hideToggle;
174+
}
146175
}
147176

148177
/** Determines whether the expansion panel should have spacing between it and its siblings. */

src/lib/expansion/expansion.spec.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import {async, TestBed, fakeAsync, tick, ComponentFixture, flush} from '@angular
22
import {Component, ViewChild} from '@angular/core';
33
import {By} from '@angular/platform-browser';
44
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
5-
import {MatExpansionModule, MatExpansionPanel} from './index';
5+
import {
6+
MatExpansionModule,
7+
MatExpansionPanel,
8+
MatExpansionPanelHeader,
9+
MAT_EXPANSION_PANEL_DEFAULT_OPTIONS,
10+
} from './index';
611
import {SPACE, ENTER} from '@angular/cdk/keycodes';
712
import {dispatchKeyboardEvent, createKeyboardEvent, dispatchEvent} from '@angular/cdk/testing';
813

@@ -305,6 +310,34 @@ describe('MatExpansionPanel', () => {
305310
expect(afterCollapse).toBe(1);
306311
}));
307312

313+
it('should be able to set the default options through the injection token', () => {
314+
TestBed
315+
.resetTestingModule()
316+
.configureTestingModule({
317+
imports: [MatExpansionModule, NoopAnimationsModule],
318+
declarations: [PanelWithTwoWayBinding],
319+
providers: [{
320+
provide: MAT_EXPANSION_PANEL_DEFAULT_OPTIONS,
321+
useValue: {
322+
hideToggle: true,
323+
expandedHeight: '10px',
324+
collapsedHeight: '16px'
325+
}
326+
}]
327+
})
328+
.compileComponents();
329+
330+
const fixture = TestBed.createComponent(PanelWithTwoWayBinding);
331+
fixture.detectChanges();
332+
333+
const panel = fixture.debugElement.query(By.directive(MatExpansionPanel));
334+
const header = fixture.debugElement.query(By.directive(MatExpansionPanelHeader));
335+
336+
expect(panel.componentInstance.hideToggle).toBe(true);
337+
expect(header.componentInstance.expandedHeight).toBe('10px');
338+
expect(header.componentInstance.collapsedHeight).toBe('16px');
339+
});
340+
308341
describe('disabled state', () => {
309342
let fixture: ComponentFixture<PanelWithContent>;
310343
let panel: HTMLElement;

0 commit comments

Comments
 (0)