Skip to content

Commit 6317583

Browse files
committed
fix(progress-spinner): coerce string values
Coerces any string values that are passed to `value`, `diameter` and `strokeWidth` to numbers. Fixes #7790.
1 parent 9673f63 commit 6317583

File tree

2 files changed

+43
-14
lines changed

2 files changed

+43
-14
lines changed

src/lib/progress-spinner/progress-spinner.spec.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {TestBed, async} from '@angular/core/testing';
22
import {Component} from '@angular/core';
33
import {By} from '@angular/platform-browser';
4-
import {MatProgressSpinnerModule} from './index';
4+
import {MatProgressSpinnerModule, MatProgressSpinner} from './index';
55

66

77
describe('MatProgressSpinner', () => {
@@ -17,6 +17,7 @@ describe('MatProgressSpinner', () => {
1717
ProgressSpinnerCustomStrokeWidth,
1818
ProgressSpinnerCustomDiameter,
1919
SpinnerWithColor,
20+
ProgressSpinnerWithStringValues,
2021
],
2122
}).compileComponents();
2223
}));
@@ -174,6 +175,24 @@ describe('MatProgressSpinner', () => {
174175
expect(fixture.nativeElement.querySelector('svg').getAttribute('focusable')).toBe('false');
175176
});
176177

178+
it('should handle the number inputs being passed in as strings', () => {
179+
const fixture = TestBed.createComponent(ProgressSpinnerWithStringValues);
180+
const spinner = fixture.debugElement.query(By.directive(MatProgressSpinner));
181+
const svgElement = spinner.nativeElement.querySelector('svg');
182+
183+
fixture.detectChanges();
184+
185+
expect(spinner.componentInstance.diameter).toBe(37);
186+
expect(spinner.componentInstance.strokeWidth).toBe(11);
187+
expect(spinner.componentInstance.value).toBe(25);
188+
189+
expect(spinner.nativeElement.style.width).toBe('38px');
190+
expect(spinner.nativeElement.style.height).toBe('38px');
191+
expect(svgElement.style.width).toBe('38px');
192+
expect(svgElement.style.height).toBe('38px');
193+
expect(svgElement.getAttribute('viewBox')).toBe('0 0 38 38');
194+
});
195+
177196
});
178197

179198

@@ -201,3 +220,10 @@ class SpinnerWithColor { color: string = 'primary'; }
201220

202221
@Component({template: `<mat-progress-spinner value="50" [color]="color"></mat-progress-spinner>`})
203222
class ProgressSpinnerWithColor { color: string = 'primary'; }
223+
224+
@Component({
225+
template: `
226+
<mat-progress-spinner value="25" diameter="37" strokeWidth="11"></mat-progress-spinner>
227+
`
228+
})
229+
class ProgressSpinnerWithStringValues { }

src/lib/progress-spinner/progress-spinner.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
import {CanColor, mixinColor} from '@angular/material/core';
2222
import {Platform} from '@angular/cdk/platform';
2323
import {DOCUMENT} from '@angular/common';
24+
import {coerceNumberProperty} from '@angular/cdk/coercion';
2425

2526
/** Possible mode for a progress spinner. */
2627
export type ProgressSpinnerMode = 'determinate' | 'indeterminate';
@@ -86,6 +87,7 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements
8687
private _value: number;
8788
private readonly _baseSize = 100;
8889
private readonly _baseStrokeWidth = 10;
90+
private _strokeWidth = 10;
8991
private _fallbackAnimation = false;
9092

9193
/** The width and height of the host element. Will grow with stroke width. **/
@@ -102,14 +104,23 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements
102104
get diameter(): number {
103105
return this._diameter;
104106
}
105-
106107
set diameter(size: number) {
107-
this._setDiameterAndInitStyles(size);
108+
this._diameter = coerceNumberProperty(size);
109+
110+
if (!this._fallbackAnimation && !MatProgressSpinner.diameters.has(this._diameter)) {
111+
this._attachStyleNode();
112+
}
108113
}
109-
_diameter = this._baseSize;
114+
private _diameter = this._baseSize;
110115

111116
/** Stroke width of the progress spinner. */
112-
@Input() strokeWidth: number = 10;
117+
@Input()
118+
get strokeWidth(): number {
119+
return this._strokeWidth;
120+
}
121+
set strokeWidth(value: number) {
122+
this._strokeWidth = coerceNumberProperty(value);
123+
}
113124

114125
/** Mode of the progress circle */
115126
@Input() mode: ProgressSpinnerMode = 'determinate';
@@ -121,7 +132,7 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements
121132
}
122133
set value(newValue: number) {
123134
if (newValue != null && this.mode === 'determinate') {
124-
this._value = Math.max(0, Math.min(100, newValue));
135+
this._value = Math.max(0, Math.min(100, coerceNumberProperty(newValue)));
125136
}
126137
}
127138

@@ -181,14 +192,6 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements
181192
return this.strokeWidth / this._elementSize * 100;
182193
}
183194

184-
/** Sets the diameter and adds diameter-specific styles if necessary. */
185-
private _setDiameterAndInitStyles(size: number): void {
186-
this._diameter = size;
187-
if (!MatProgressSpinner.diameters.has(this.diameter) && !this._fallbackAnimation) {
188-
this._attachStyleNode();
189-
}
190-
}
191-
192195
/** Dynamically generates a style tag containing the correct animation for this diameter. */
193196
private _attachStyleNode(): void {
194197
let styleTag = MatProgressSpinner.styleTag;

0 commit comments

Comments
 (0)