Skip to content

Commit 46b0cb1

Browse files
committed
fix(progress-spinner): unable to change mode on spinner directive
Currently we have the `mat-spinner` directive which is a shortcut to a `mat-progress-spinner` with `mode="indeterminate"`. Since the spinner inherits all of the inputs from the progress spinner, there's nothing stoping people from changing the mode back to `determinate`, however the element will look half-broken because the host bindings assume that the mode won't change. These changes update the host bindings to allow switching between modes. Fixes #14511.
1 parent 473d4c6 commit 46b0cb1

File tree

5 files changed

+33
-45
lines changed

5 files changed

+33
-45
lines changed

src/material/progress-spinner/progress-spinner-module.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,17 @@
88
import {NgModule} from '@angular/core';
99
import {CommonModule} from '@angular/common';
1010
import {MatCommonModule} from '@angular/material/core';
11-
import {MatProgressSpinner, MatSpinner} from './progress-spinner';
11+
import {MatProgressSpinner} from './progress-spinner';
1212

1313

1414
@NgModule({
1515
imports: [MatCommonModule, CommonModule],
1616
exports: [
1717
MatProgressSpinner,
18-
MatSpinner,
1918
MatCommonModule
2019
],
2120
declarations: [
2221
MatProgressSpinner,
23-
MatSpinner
2422
],
2523
})
2624
class MatProgressSpinnerModule {}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ describe('MatProgressSpinner', () => {
2727
ProgressSpinnerWithStringValues,
2828
IndeterminateSpinnerInShadowDom,
2929
IndeterminateSpinnerInShadowDomWithNgIf,
30+
SpinnerWithMode,
3031
],
3132
}).compileComponents();
3233
}));
@@ -428,6 +429,14 @@ describe('MatProgressSpinner', () => {
428429
expect(shadowRoot.querySelector('style[mat-spinner-animation="27"]')).toBeTruthy();
429430
});
430431

432+
it('should be able to change the mode on a mat-spinner', () => {
433+
const fixture = TestBed.createComponent(SpinnerWithMode);
434+
fixture.detectChanges();
435+
436+
const progressElement = fixture.debugElement.query(By.css('mat-spinner')).nativeElement;
437+
expect(progressElement.getAttribute('mode')).toBe('determinate');
438+
});
439+
431440
});
432441

433442

@@ -494,3 +503,7 @@ class IndeterminateSpinnerInShadowDomWithNgIf {
494503
diameter: number;
495504
}
496505

506+
507+
@Component({template: '<mat-spinner mode="determinate"></mat-spinner>'})
508+
class SpinnerWithMode { }
509+

src/material/progress-spinner/progress-spinner.ts

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,12 @@ const INDETERMINATE_ANIMATION_TEMPLATE = `
105105
*/
106106
@Component({
107107
moduleId: module.id,
108-
selector: 'mat-progress-spinner',
108+
selector: 'mat-progress-spinner, mat-spinner',
109109
exportAs: 'matProgressSpinner',
110110
host: {
111111
'role': 'progressbar',
112-
'class': 'mat-progress-spinner',
112+
// `mat-spinner` is here for backward compatibility.
113+
'class': 'mat-progress-spinner mat-spinner',
113114
'[class._mat-animation-noopable]': `_noopAnimations`,
114115
'[style.width.px]': 'diameter',
115116
'[style.height.px]': 'diameter',
@@ -202,6 +203,10 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements
202203
this._noopAnimations = animationMode === 'NoopAnimations' &&
203204
(!!defaults && !defaults._forceAnimations);
204205

206+
if (_elementRef.nativeElement.nodeName.toLowerCase() === 'mat-spinner') {
207+
this.mode = 'indeterminate';
208+
}
209+
205210
if (defaults) {
206211
if (defaults.diameter) {
207212
this.diameter = defaults.diameter;
@@ -297,42 +302,6 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements
297302
}
298303
}
299304

300-
301-
/**
302-
* `<mat-spinner>` component.
303-
*
304-
* This is a component definition to be used as a convenience reference to create an
305-
* indeterminate `<mat-progress-spinner>` instance.
306-
*/
307-
@Component({
308-
moduleId: module.id,
309-
selector: 'mat-spinner',
310-
host: {
311-
'role': 'progressbar',
312-
'mode': 'indeterminate',
313-
'class': 'mat-spinner mat-progress-spinner',
314-
'[class._mat-animation-noopable]': `_noopAnimations`,
315-
'[style.width.px]': 'diameter',
316-
'[style.height.px]': 'diameter',
317-
},
318-
inputs: ['color'],
319-
templateUrl: 'progress-spinner.html',
320-
styleUrls: ['progress-spinner.css'],
321-
changeDetection: ChangeDetectionStrategy.OnPush,
322-
encapsulation: ViewEncapsulation.None,
323-
})
324-
export class MatSpinner extends MatProgressSpinner {
325-
constructor(elementRef: ElementRef<HTMLElement>, platform: Platform,
326-
@Optional() @Inject(DOCUMENT) document: any,
327-
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode: string,
328-
@Inject(MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS)
329-
defaults?: MatProgressSpinnerDefaultOptions) {
330-
super(elementRef, platform, document, animationMode, defaults);
331-
this.mode = 'indeterminate';
332-
}
333-
}
334-
335-
336305
/** Gets the shadow root of an element, if supported and the element is inside the Shadow DOM. */
337306
export function _getShadowRoot(element: HTMLElement, _document: Document): Node | null {
338307
// TODO(crisbeto): see whether we should move this into the CDK

src/material/progress-spinner/public-api.ts

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

9+
import {MatProgressSpinner} from './progress-spinner';
10+
911
export * from './progress-spinner-module';
1012
export {
1113
MatProgressSpinner,
12-
MatSpinner,
1314
MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS,
1415
ProgressSpinnerMode,
1516
MatProgressSpinnerDefaultOptions,
1617
MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS_FACTORY,
1718
} from './progress-spinner';
19+
20+
21+
/**
22+
* @deprecated Import `MatProgressSpinner` instead. Note that the
23+
* `mat-spinner` selector isn't deprecated.
24+
* @breaking-change 8.0.0
25+
*/
26+
// tslint:disable-next-line:variable-name
27+
export const MatSpinner = MatProgressSpinner;

tools/public_api_guard/material/progress-spinner.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ export interface MatProgressSpinnerDefaultOptions {
2424
strokeWidth?: number;
2525
}
2626

27-
export declare class MatSpinner extends MatProgressSpinner {
28-
constructor(elementRef: ElementRef<HTMLElement>, platform: Platform, document: any, animationMode: string, defaults?: MatProgressSpinnerDefaultOptions);
29-
}
27+
export declare const MatSpinner: typeof MatProgressSpinner;
3028

3129
export declare type ProgressSpinnerMode = 'determinate' | 'indeterminate';

0 commit comments

Comments
 (0)