From c3899cfce1ad5bbd77b57e542ccb334a9e3210f0 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 25 May 2018 19:30:24 +0200 Subject: [PATCH] feat(progress-spinner): add injection token for configuring the diameter and stroke globally (#11493) Adds the `MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS` injection token that can be used to globally configure the diameter and stroke (and any other options we decide to add) for all progress spinners. Fixes #11490. --- .../progress-spinner/progress-spinner.spec.ts | 47 ++++++++++++++++++- src/lib/progress-spinner/progress-spinner.ts | 39 ++++++++++++--- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/src/lib/progress-spinner/progress-spinner.spec.ts b/src/lib/progress-spinner/progress-spinner.spec.ts index e5edabe4d41..6e180707267 100644 --- a/src/lib/progress-spinner/progress-spinner.spec.ts +++ b/src/lib/progress-spinner/progress-spinner.spec.ts @@ -1,7 +1,11 @@ import {TestBed, async} from '@angular/core/testing'; import {Component} from '@angular/core'; import {By} from '@angular/platform-browser'; -import {MatProgressSpinnerModule, MatProgressSpinner} from './index'; +import { + MatProgressSpinnerModule, + MatProgressSpinner, + MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS, +} from './index'; describe('MatProgressSpinner', () => { @@ -232,6 +236,47 @@ describe('MatProgressSpinner', () => { expect(spinner.nativeElement.style.width).toBe('32px'); expect(spinner.nativeElement.style.height).toBe('32px'); }); + + it('should be able to set a default diameter', () => { + TestBed + .resetTestingModule() + .configureTestingModule({ + imports: [MatProgressSpinnerModule], + declarations: [BasicProgressSpinner], + providers: [{ + provide: MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS, + useValue: {diameter: 23} + }] + }) + .compileComponents(); + + const fixture = TestBed.createComponent(BasicProgressSpinner); + fixture.detectChanges(); + + const progressElement = fixture.debugElement.query(By.css('mat-progress-spinner')); + expect(progressElement.componentInstance.diameter).toBe(23); + }); + + it('should be able to set a default stroke width', () => { + TestBed + .resetTestingModule() + .configureTestingModule({ + imports: [MatProgressSpinnerModule], + declarations: [BasicProgressSpinner], + providers: [{ + provide: MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS, + useValue: {strokeWidth: 7} + }] + }) + .compileComponents(); + + const fixture = TestBed.createComponent(BasicProgressSpinner); + fixture.detectChanges(); + + const progressElement = fixture.debugElement.query(By.css('mat-progress-spinner')); + expect(progressElement.componentInstance.strokeWidth).toBe(7); + }); + }); diff --git a/src/lib/progress-spinner/progress-spinner.ts b/src/lib/progress-spinner/progress-spinner.ts index 7d4bb6abaae..d6a28b9d3d6 100644 --- a/src/lib/progress-spinner/progress-spinner.ts +++ b/src/lib/progress-spinner/progress-spinner.ts @@ -14,6 +14,7 @@ import { ElementRef, ViewEncapsulation, Optional, + InjectionToken, } from '@angular/core'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; import {CanColor, mixinColor} from '@angular/material/core'; @@ -43,6 +44,26 @@ export class MatProgressSpinnerBase { } export const _MatProgressSpinnerMixinBase = mixinColor(MatProgressSpinnerBase, 'primary'); +/** Default `mat-progress-spinner` options that can be overridden. */ +export interface MatProgressSpinnerDefaultOptions { + /** Diameter of the spinner. */ + diameter?: number; + /** Width of the spinner's stroke. */ + strokeWidth?: number; +} + +/** Injection token to be used to override the default options for `mat-progress-spinner`. */ +export const MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS = + new InjectionToken('mat-progress-spinner-default-options', { + providedIn: 'root', + factory: MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS_FACTORY, + }); + +/** @docs-private */ +export function MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS_FACTORY(): MatProgressSpinnerDefaultOptions { + return {diameter: BASE_SIZE}; +} + // .0001 percentage difference is necessary in order to avoid unwanted animation frames // for example because the animation duration is 4 seconds, .1% accounts to 4ms // which are enough to see the flicker described in @@ -98,7 +119,7 @@ const INDETERMINATE_ANIMATION_TEMPLATE = ` export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements CanColor { private _value = 0; - private _strokeWidth: number; + private _strokeWidth = this._defaults ? this._defaults.strokeWidth : undefined; private _fallbackAnimation = false; /** Tracks diameters of existing instances to de-dupe generated styles (default d = 100) */ @@ -120,7 +141,8 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements this._attachStyleNode(); } } - private _diameter = BASE_SIZE; + private _diameter = this._defaults && this._defaults.diameter ? + this._defaults.diameter : BASE_SIZE; /** Stroke width of the progress spinner. */ @Input() @@ -131,7 +153,6 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements this._strokeWidth = coerceNumberProperty(value); } - /** Mode of the progress circle */ @Input() mode: ProgressSpinnerMode = 'determinate'; @@ -147,7 +168,10 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements constructor(public _elementRef: ElementRef, platform: Platform, @Optional() @Inject(DOCUMENT) private _document: any, - @Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string) { + // @deletion-target 7.0.0 _animationMode and _defaults parameters to be made required. + @Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string, + @Inject(MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS) + private _defaults?: MatProgressSpinnerDefaultOptions) { super(_elementRef); this._fallbackAnimation = platform.EDGE || platform.TRIDENT; @@ -249,8 +273,11 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements export class MatSpinner extends MatProgressSpinner { constructor(elementRef: ElementRef, platform: Platform, @Optional() @Inject(DOCUMENT) document: any, - @Optional() @Inject(ANIMATION_MODULE_TYPE) _animationMode?: string) { - super(elementRef, platform, document, _animationMode); + // @deletion-targets 7.0.0 animationMode and defaults parameters to be made required. + @Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string, + @Inject(MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS) + defaults?: MatProgressSpinnerDefaultOptions) { + super(elementRef, platform, document, animationMode, defaults); this.mode = 'indeterminate'; } }