Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7480e3b

Browse files
fix(material/progress-spinner): unable to change mode on spinner directive (#14514)
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 229dd6e commit 7480e3b

File tree

6 files changed

+48
-70
lines changed

6 files changed

+48
-70
lines changed

‎src/material-experimental/mdc-progress-spinner/progress-spinner.spec.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ describe('MDC-based MatProgressSpinner', () => {
2424
ProgressSpinnerWithStringValues,
2525
IndeterminateSpinnerInShadowDom,
2626
IndeterminateSpinnerInShadowDomWithNgIf,
27+
SpinnerWithMode,
2728
],
2829
}).compileComponents();
2930
}),
@@ -397,6 +398,14 @@ describe('MDC-based MatProgressSpinner', () => {
397398
expect(children.length).toBeGreaterThan(0);
398399
expect(children.every(child => child.getAttribute('aria-hidden') === 'true')).toBe(true);
399400
});
401+
402+
it('should be able to change the mode on a mat-spinner', () => {
403+
const fixture = TestBed.createComponent(SpinnerWithMode);
404+
fixture.detectChanges();
405+
406+
const progressElement = fixture.debugElement.query(By.css('mat-spinner')).nativeElement;
407+
expect(progressElement.getAttribute('mode')).toBe('determinate');
408+
});
400409
});
401410

402411
@Component({template: '<mat-progress-spinner></mat-progress-spinner>'})
@@ -470,3 +479,6 @@ class IndeterminateSpinnerInShadowDomWithNgIf {
470479

471480
diameter: number;
472481
}
482+
483+
@Component({template: '<mat-spinner mode="determinate"></mat-spinner>'})
484+
class SpinnerWithMode {}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
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
@NgModule({
1414
imports: [MatCommonModule, CommonModule],
15-
exports: [MatProgressSpinner, MatSpinner,MatCommonModule],
16-
declarations: [MatProgressSpinner,MatSpinner],
15+
exports: [MatProgressSpinner, MatCommonModule],
16+
declarations: [MatProgressSpinner],
1717
})
1818
export class MatProgressSpinnerModule {}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ describe('MatProgressSpinner', () => {
2626
ProgressSpinnerWithStringValues,
2727
IndeterminateSpinnerInShadowDom,
2828
IndeterminateSpinnerInShadowDomWithNgIf,
29+
SpinnerWithMode,
2930
],
3031
}).compileComponents();
3132
}),
@@ -540,6 +541,14 @@ describe('MatProgressSpinner', () => {
540541
expect(children.length).toBeGreaterThan(0);
541542
expect(children.every(child => child.getAttribute('aria-hidden') === 'true')).toBe(true);
542543
});
544+
545+
it('should be able to change the mode on a mat-spinner', () => {
546+
const fixture = TestBed.createComponent(SpinnerWithMode);
547+
fixture.detectChanges();
548+
549+
const progressElement = fixture.debugElement.query(By.css('mat-spinner')).nativeElement;
550+
expect(progressElement.getAttribute('mode')).toBe('determinate');
551+
});
543552
});
544553

545554
@Component({template: '<mat-progress-spinner></mat-progress-spinner>'})
@@ -616,3 +625,6 @@ class IndeterminateSpinnerInShadowDomWithNgIf {
616625

617626
diameter: number;
618627
}
628+
629+
@Component({template: '<mat-spinner mode="determinate"></mat-spinner>'})
630+
class SpinnerWithMode {}

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

Lines changed: 7 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,12 @@ const INDETERMINATE_ANIMATION_TEMPLATE = `
111111
* `<mat-progress-spinner>` component.
112112
*/
113113
@Component({
114-
selector: 'mat-progress-spinner',
114+
selector: 'mat-progress-spinner, mat-spinner',
115115
exportAs: 'matProgressSpinner',
116116
host: {
117117
'role': 'progressbar',
118-
'class': 'mat-progress-spinner',
118+
// `mat-spinner` is here for backward compatibility.
119+
'class': 'mat-progress-spinner mat-spinner',
119120
// set tab index to -1 so screen readers will read the aria-label
120121
// Note: there is a known issue with JAWS that does not read progressbar aria labels on FireFox
121122
'tabindex': '-1',
@@ -229,6 +230,10 @@ export class MatProgressSpinner
229230
this._noopAnimations =
230231
animationMode === 'NoopAnimations' && !!defaults && !defaults._forceAnimations;
231232

233+
if (elementRef.nativeElement.nodeName.toLowerCase() === 'mat-spinner') {
234+
this.mode = 'indeterminate';
235+
}
236+
232237
if (defaults) {
233238
if (defaults.color) {
234239
this.color = this.defaultColor = defaults.color;
@@ -356,56 +361,3 @@ export class MatProgressSpinner
356361
return this.diameter.toString().replace('.', '_');
357362
}
358363
}
359-
360-
/**
361-
* `<mat-spinner>` component.
362-
*
363-
* This is a component definition to be used as a convenience reference to create an
364-
* indeterminate `<mat-progress-spinner>` instance.
365-
*/
366-
@Component({
367-
selector: 'mat-spinner',
368-
host: {
369-
'role': 'progressbar',
370-
'mode': 'indeterminate',
371-
'class': 'mat-spinner mat-progress-spinner',
372-
'[class._mat-animation-noopable]': `_noopAnimations`,
373-
'[style.width.px]': 'diameter',
374-
'[style.height.px]': 'diameter',
375-
},
376-
inputs: ['color'],
377-
templateUrl: 'progress-spinner.html',
378-
styleUrls: ['progress-spinner.css'],
379-
changeDetection: ChangeDetectionStrategy.OnPush,
380-
encapsulation: ViewEncapsulation.None,
381-
})
382-
export class MatSpinner extends MatProgressSpinner {
383-
constructor(
384-
elementRef: ElementRef<HTMLElement>,
385-
platform: Platform,
386-
@Optional() @Inject(DOCUMENT) document: any,
387-
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode: string,
388-
@Inject(MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS)
389-
defaults?: MatProgressSpinnerDefaultOptions,
390-
/**
391-
* @deprecated `changeDetectorRef`, `viewportRuler` and `ngZone`
392-
* parameters to become required.
393-
* @breaking-change 14.0.0
394-
*/
395-
changeDetectorRef?: ChangeDetectorRef,
396-
viewportRuler?: ViewportRuler,
397-
ngZone?: NgZone,
398-
) {
399-
super(
400-
elementRef,
401-
platform,
402-
document,
403-
animationMode,
404-
defaults,
405-
changeDetectorRef,
406-
viewportRuler,
407-
ngZone,
408-
);
409-
this.mode = 'indeterminate';
410-
}
411-
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,21 @@
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+
* @deprecated Import `MatProgressSpinner` instead. Note that the
22+
* `mat-spinner` selector isn't deprecated.
23+
* @breaking-change 8.0.0
24+
*/
25+
// tslint:disable-next-line:variable-name
26+
export const MatSpinner = MatProgressSpinner;

‎tools/public_api_guard/material/progress-spinner.md‎

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export class MatProgressSpinner extends _MatProgressSpinnerBase implements OnIni
5151
get value(): number;
5252
set value(newValue: NumberInput);
5353
// (undocumented)
54-
static ɵcmp: i0.ɵɵComponentDeclaration<MatProgressSpinner, "mat-progress-spinner", ["matProgressSpinner"], { "color": "color"; "diameter": "diameter"; "strokeWidth": "strokeWidth"; "mode": "mode"; "value": "value"; }, {}, never, never>;
54+
static ɵcmp: i0.ɵɵComponentDeclaration<MatProgressSpinner, "mat-progress-spinner, mat-spinner", ["matProgressSpinner"], { "color": "color"; "diameter": "diameter"; "strokeWidth": "strokeWidth"; "mode": "mode"; "value": "value"; }, {}, never, never>;
5555
// (undocumented)
5656
static ɵfac: i0.ɵɵFactoryDeclaration<MatProgressSpinner, [null, null, { optional: true; }, { optional: true; }, null, null, null, null]>;
5757
}
@@ -71,18 +71,11 @@ export class MatProgressSpinnerModule {
7171
// (undocumented)
7272
static ɵinj: i0.ɵɵInjectorDeclaration<MatProgressSpinnerModule>;
7373
// (undocumented)
74-
static ɵmod: i0.ɵɵNgModuleDeclaration<MatProgressSpinnerModule, [typeof i1.MatProgressSpinner, typeofi1.MatSpinner], [typeof i2.MatCommonModule, typeof i3.CommonModule], [typeof i1.MatProgressSpinner, typeofi1.MatSpinner, typeof i2.MatCommonModule]>;
74+
static ɵmod: i0.ɵɵNgModuleDeclaration<MatProgressSpinnerModule, [typeof i1.MatProgressSpinner], [typeof i2.MatCommonModule, typeof i3.CommonModule], [typeof i1.MatProgressSpinner, typeof i2.MatCommonModule]>;
7575
}
7676

77-
// @public
78-
export class MatSpinner extends MatProgressSpinner {
79-
constructor(elementRef: ElementRef<HTMLElement>, platform: Platform, document: any, animationMode: string, defaults?: MatProgressSpinnerDefaultOptions,
80-
changeDetectorRef?: ChangeDetectorRef, viewportRuler?: ViewportRuler, ngZone?: NgZone);
81-
// (undocumented)
82-
static ɵcmp: i0.ɵɵComponentDeclaration<MatSpinner, "mat-spinner", never, { "color": "color"; }, {}, never, never>;
83-
// (undocumented)
84-
static ɵfac: i0.ɵɵFactoryDeclaration<MatSpinner, [null, null, { optional: true; }, { optional: true; }, null, null, null, null]>;
85-
}
77+
// @public @deprecated (undocumented)
78+
export const MatSpinner: typeof MatProgressSpinner;
8679

8780
// @public
8881
export type ProgressSpinnerMode = 'determinate' | 'indeterminate';

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /