Skip to content

Commit e4b54aa

Browse files
authored
feat(material/progress-bar): add default options injection token (#23363)
Adds an injection token that allows for the progress bar defaults to be configured. Fixes #23329.
1 parent 2b81e7c commit e4b54aa

File tree

6 files changed

+95
-16
lines changed

6 files changed

+95
-16
lines changed

src/material-experimental/mdc-progress-bar/progress-bar.spec.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import {TestBed, ComponentFixture} from '@angular/core/testing';
2-
import {Component, DebugElement, Type} from '@angular/core';
2+
import {Component, DebugElement, Provider, Type} from '@angular/core';
33
import {By} from '@angular/platform-browser';
44
import {dispatchFakeEvent} from '../../cdk/testing/private';
5-
import {MatProgressBarModule} from './index';
5+
import {MatProgressBarModule, MAT_PROGRESS_BAR_DEFAULT_OPTIONS} from './index';
66
import {MatProgressBar} from './progress-bar';
77

88

99
describe('MDC-based MatProgressBar', () => {
1010
function createComponent<T>(componentType: Type<T>,
11-
imports?: Type<{}>[]): ComponentFixture<T> {
11+
providers: Provider[] = []): ComponentFixture<T> {
1212
TestBed.configureTestingModule({
13-
imports: imports || [MatProgressBarModule],
14-
declarations: [componentType]
13+
imports: [MatProgressBarModule],
14+
declarations: [componentType],
15+
providers
1516
}).compileComponents();
1617

1718
return TestBed.createComponent<T>(componentType);
@@ -152,6 +153,20 @@ describe('MDC-based MatProgressBar', () => {
152153
.withContext('Expect aria-valuenow to be cleared in query mode.').toBe(false);
153154
});
154155

156+
it('should be able to configure the default progress bar options via DI', () => {
157+
const fixture = createComponent(BasicProgressBar, [{
158+
provide: MAT_PROGRESS_BAR_DEFAULT_OPTIONS,
159+
useValue: {
160+
mode: 'buffer',
161+
color: 'warn'
162+
}
163+
}]);
164+
fixture.detectChanges();
165+
const progressElement = fixture.debugElement.query(By.css('mat-progress-bar'))!;
166+
expect(progressElement.componentInstance.mode).toBe('buffer');
167+
expect(progressElement.componentInstance.color).toBe('warn');
168+
});
169+
155170
});
156171

157172
describe('animation trigger on determinate setting', () => {

src/material-experimental/mdc-progress-bar/progress-bar.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ import {
2222
} from '@angular/core';
2323
import {CanColor, mixinColor} from '@angular/material-experimental/mdc-core';
2424
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
25-
import {ProgressAnimationEnd} from '@angular/material/progress-bar';
25+
import {
26+
MatProgressBarDefaultOptions,
27+
MAT_PROGRESS_BAR_DEFAULT_OPTIONS,
28+
ProgressAnimationEnd,
29+
} from '@angular/material/progress-bar';
2630
import {
2731
MDCLinearProgressAdapter,
2832
MDCLinearProgressFoundation,
@@ -67,7 +71,9 @@ export class MatProgressBar extends _MatProgressBarBase implements AfterViewInit
6771
constructor(elementRef: ElementRef<HTMLElement>,
6872
private _ngZone: NgZone,
6973
@Optional() dir?: Directionality,
70-
@Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string) {
74+
@Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string,
75+
@Optional() @Inject(MAT_PROGRESS_BAR_DEFAULT_OPTIONS)
76+
defaults?: MatProgressBarDefaultOptions) {
7177
super(elementRef);
7278
this._isNoopAnimation = _animationMode === 'NoopAnimations';
7379
if (dir) {
@@ -76,6 +82,14 @@ export class MatProgressBar extends _MatProgressBarBase implements AfterViewInit
7682
this._foundation?.restartAnimation();
7783
});
7884
}
85+
86+
if (defaults) {
87+
if (defaults.color) {
88+
this.color = this.defaultColor = defaults.color;
89+
}
90+
91+
this.mode = defaults.mode || this.mode;
92+
}
7993
}
8094

8195
/** Implements all of the logic of the MDC progress bar. */

src/material-experimental/mdc-progress-bar/public-api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@ export {
1414
MAT_PROGRESS_BAR_LOCATION,
1515
MatProgressBarLocation,
1616
MAT_PROGRESS_BAR_LOCATION_FACTORY,
17+
MAT_PROGRESS_BAR_DEFAULT_OPTIONS,
18+
MatProgressBarDefaultOptions,
1719
} from '@angular/material/progress-bar';

src/material/progress-bar/progress-bar.spec.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
import {TestBed, ComponentFixture} from '@angular/core/testing';
2-
import {Component, DebugElement, Type} from '@angular/core';
2+
import {Component, DebugElement, Provider, Type} from '@angular/core';
33
import {By} from '@angular/platform-browser';
44
import {dispatchFakeEvent} from '../../cdk/testing/private';
55
import {MatProgressBarModule, MAT_PROGRESS_BAR_LOCATION} from './index';
6-
import {MatProgressBar} from './progress-bar';
6+
import {MatProgressBar, MAT_PROGRESS_BAR_DEFAULT_OPTIONS} from './progress-bar';
77

88

99
describe('MatProgressBar', () => {
1010
let fakePath: string;
1111

1212
function createComponent<T>(componentType: Type<T>,
13-
imports?: Type<{}>[]): ComponentFixture<T> {
13+
providers: Provider[] = []): ComponentFixture<T> {
1414
fakePath = '/fake-path';
1515

1616
TestBed.configureTestingModule({
17-
imports: imports || [MatProgressBarModule],
17+
imports: [MatProgressBarModule],
1818
declarations: [componentType],
1919
providers: [{
2020
provide: MAT_PROGRESS_BAR_LOCATION,
2121
useValue: {getPathname: () => fakePath}
22-
}]
22+
}, ...providers]
2323
}).compileComponents();
2424

2525
return TestBed.createComponent<T>(componentType);
@@ -196,6 +196,20 @@ describe('MatProgressBar', () => {
196196
.withContext('Expect aria-valuenow to be cleared in query mode.').toBe(false);
197197
});
198198

199+
it('should be able to configure the default progress bar options via DI', () => {
200+
const fixture = createComponent(BasicProgressBar, [{
201+
provide: MAT_PROGRESS_BAR_DEFAULT_OPTIONS,
202+
useValue: {
203+
mode: 'buffer',
204+
color: 'warn'
205+
}
206+
}]);
207+
fixture.detectChanges();
208+
const progressElement = fixture.debugElement.query(By.css('mat-progress-bar'))!;
209+
expect(progressElement.componentInstance.mode).toBe('buffer');
210+
expect(progressElement.componentInstance.color).toBe('warn');
211+
});
212+
199213
});
200214

201215
describe('animation trigger on determinate setting', () => {

src/material/progress-bar/progress-bar.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
ViewChild,
2525
ViewEncapsulation,
2626
} from '@angular/core';
27-
import {CanColor, mixinColor} from '@angular/material/core';
27+
import {CanColor, mixinColor, ThemePalette} from '@angular/material/core';
2828
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
2929
import {fromEvent, Observable, Subscription} from 'rxjs';
3030
import {filter} from 'rxjs/operators';
@@ -76,6 +76,20 @@ export function MAT_PROGRESS_BAR_LOCATION_FACTORY(): MatProgressBarLocation {
7676

7777
export type ProgressBarMode = 'determinate' | 'indeterminate' | 'buffer' | 'query';
7878

79+
/** Default `mat-progress-bar` options that can be overridden. */
80+
export interface MatProgressBarDefaultOptions {
81+
/** Default color of the progress bar. */
82+
color?: ThemePalette;
83+
84+
/** Default mode of the progress bar. */
85+
mode?: ProgressBarMode;
86+
}
87+
88+
/** Injection token to be used to override the default options for `mat-progress-bar`. */
89+
export const MAT_PROGRESS_BAR_DEFAULT_OPTIONS =
90+
new InjectionToken<MatProgressBarDefaultOptions>('MAT_PROGRESS_BAR_DEFAULT_OPTIONS');
91+
92+
7993
/** Counter used to generate unique IDs for progress bars. */
8094
let progressbarId = 0;
8195

@@ -111,7 +125,9 @@ export class MatProgressBar extends _MatProgressBarBase implements CanColor,
111125
* @deprecated `location` parameter to be made required.
112126
* @breaking-change 8.0.0
113127
*/
114-
@Optional() @Inject(MAT_PROGRESS_BAR_LOCATION) location?: MatProgressBarLocation) {
128+
@Optional() @Inject(MAT_PROGRESS_BAR_LOCATION) location?: MatProgressBarLocation,
129+
@Optional() @Inject(MAT_PROGRESS_BAR_DEFAULT_OPTIONS)
130+
defaults?: MatProgressBarDefaultOptions) {
115131
super(elementRef);
116132

117133
// We need to prefix the SVG reference with the current path, otherwise they won't work
@@ -124,6 +140,14 @@ export class MatProgressBar extends _MatProgressBarBase implements CanColor,
124140
const path = location ? location.getPathname().split('#')[0] : '';
125141
this._rectangleFillValue = `url('${path}#${this.progressbarId}')`;
126142
this._isNoopAnimation = _animationMode === 'NoopAnimations';
143+
144+
if (defaults) {
145+
if (defaults.color) {
146+
this.color = this.defaultColor = defaults.color;
147+
}
148+
149+
this.mode = defaults.mode || this.mode;
150+
}
127151
}
128152

129153
/** Flag that indicates whether NoopAnimations mode is set to true. */

tools/public_api_guard/material/progress-bar.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import { InjectionToken } from '@angular/core';
1717
import { NgZone } from '@angular/core';
1818
import { NumberInput } from '@angular/cdk/coercion';
1919
import { OnDestroy } from '@angular/core';
20+
import { ThemePalette } from '@angular/material/core';
21+
22+
// @public
23+
export const MAT_PROGRESS_BAR_DEFAULT_OPTIONS: InjectionToken<MatProgressBarDefaultOptions>;
2024

2125
// @public
2226
export const MAT_PROGRESS_BAR_LOCATION: InjectionToken<MatProgressBarLocation>;
@@ -27,7 +31,7 @@ export function MAT_PROGRESS_BAR_LOCATION_FACTORY(): MatProgressBarLocation;
2731
// @public
2832
export class MatProgressBar extends _MatProgressBarBase implements CanColor, AfterViewInit, OnDestroy {
2933
constructor(elementRef: ElementRef, _ngZone: NgZone, _animationMode?: string | undefined,
30-
location?: MatProgressBarLocation);
34+
location?: MatProgressBarLocation, defaults?: MatProgressBarDefaultOptions);
3135
readonly animationEnd: EventEmitter<ProgressAnimationEnd>;
3236
// (undocumented)
3337
_animationMode?: string | undefined;
@@ -56,7 +60,13 @@ export class MatProgressBar extends _MatProgressBarBase implements CanColor, Aft
5660
// (undocumented)
5761
static ɵcmp: i0.ɵɵComponentDeclaration<MatProgressBar, "mat-progress-bar", ["matProgressBar"], { "color": "color"; "value": "value"; "bufferValue": "bufferValue"; "mode": "mode"; }, { "animationEnd": "animationEnd"; }, never, never>;
5862
// (undocumented)
59-
static ɵfac: i0.ɵɵFactoryDeclaration<MatProgressBar, [null, null, { optional: true; }, { optional: true; }]>;
63+
static ɵfac: i0.ɵɵFactoryDeclaration<MatProgressBar, [null, null, { optional: true; }, { optional: true; }, { optional: true; }]>;
64+
}
65+
66+
// @public
67+
export interface MatProgressBarDefaultOptions {
68+
color?: ThemePalette;
69+
mode?: ProgressBarMode;
6070
}
6171

6272
// @public

0 commit comments

Comments
 (0)