Skip to content

Commit

Permalink
fix(progress-spinner): unable to change mode on spinner directive
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
crisbeto committed May 10, 2020
1 parent 14a51ef commit 9a97b7b
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 47 deletions.
4 changes: 1 addition & 3 deletions src/material/progress-spinner/progress-spinner-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,17 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {MatCommonModule} from '@angular/material/core';
import {MatProgressSpinner, MatSpinner} from './progress-spinner';
import {MatProgressSpinner} from './progress-spinner';


@NgModule({
imports: [MatCommonModule, CommonModule],
exports: [
MatProgressSpinner,
MatSpinner,
MatCommonModule
],
declarations: [
MatProgressSpinner,
MatSpinner
],
})
export class MatProgressSpinnerModule {}
13 changes: 13 additions & 0 deletions src/material/progress-spinner/progress-spinner.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('MatProgressSpinner', () => {
ProgressSpinnerWithStringValues,
IndeterminateSpinnerInShadowDom,
IndeterminateSpinnerInShadowDomWithNgIf,
SpinnerWithMode,
],
}).compileComponents();
}));
Expand Down Expand Up @@ -425,6 +426,14 @@ describe('MatProgressSpinner', () => {
expect(shadowRoot.querySelector('style[mat-spinner-animation="27"]')).toBeTruthy();
});

it('should be able to change the mode on a mat-spinner', () => {
const fixture = TestBed.createComponent(SpinnerWithMode);
fixture.detectChanges();

const progressElement = fixture.debugElement.query(By.css('mat-spinner')).nativeElement;
expect(progressElement.getAttribute('mode')).toBe('determinate');
});

});


Expand Down Expand Up @@ -491,3 +500,7 @@ class IndeterminateSpinnerInShadowDomWithNgIf {
diameter: number;
}


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

43 changes: 7 additions & 36 deletions src/material/progress-spinner/progress-spinner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,12 @@ const INDETERMINATE_ANIMATION_TEMPLATE = `
* `<mat-progress-spinner>` component.
*/
@Component({
selector: 'mat-progress-spinner',
selector: 'mat-progress-spinner, mat-spinner',
exportAs: 'matProgressSpinner',
host: {
'role': 'progressbar',
'class': 'mat-progress-spinner',
// `mat-spinner` is here for backward compatibility.
'class': 'mat-progress-spinner mat-spinner',
'[class._mat-animation-noopable]': `_noopAnimations`,
'[style.width.px]': 'diameter',
'[style.height.px]': 'diameter',
Expand Down Expand Up @@ -201,6 +202,10 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements
this._noopAnimations = animationMode === 'NoopAnimations' &&
(!!defaults && !defaults._forceAnimations);

if (_elementRef.nativeElement.nodeName.toLowerCase() === 'mat-spinner') {
this.mode = 'indeterminate';
}

if (defaults) {
if (defaults.diameter) {
this.diameter = defaults.diameter;
Expand Down Expand Up @@ -299,37 +304,3 @@ export class MatProgressSpinner extends _MatProgressSpinnerMixinBase implements
static ngAcceptInputType_strokeWidth: NumberInput;
static ngAcceptInputType_value: NumberInput;
}


/**
* `<mat-spinner>` component.
*
* This is a component definition to be used as a convenience reference to create an
* indeterminate `<mat-progress-spinner>` instance.
*/
@Component({
selector: 'mat-spinner',
host: {
'role': 'progressbar',
'mode': 'indeterminate',
'class': 'mat-spinner mat-progress-spinner',
'[class._mat-animation-noopable]': `_noopAnimations`,
'[style.width.px]': 'diameter',
'[style.height.px]': 'diameter',
},
inputs: ['color'],
templateUrl: 'progress-spinner.html',
styleUrls: ['progress-spinner.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class MatSpinner extends MatProgressSpinner {
constructor(elementRef: ElementRef<HTMLElement>, platform: Platform,
@Optional() @Inject(DOCUMENT) document: any,
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode: string,
@Inject(MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS)
defaults?: MatProgressSpinnerDefaultOptions) {
super(elementRef, platform, document, animationMode, defaults);
this.mode = 'indeterminate';
}
}
12 changes: 11 additions & 1 deletion src/material/progress-spinner/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,22 @@
* found in the LICENSE file at https://angular.io/license
*/

import {MatProgressSpinner} from './progress-spinner';

export * from './progress-spinner-module';
export {
MatProgressSpinner,
MatSpinner,
MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS,
ProgressSpinnerMode,
MatProgressSpinnerDefaultOptions,
MAT_PROGRESS_SPINNER_DEFAULT_OPTIONS_FACTORY,
} from './progress-spinner';


/**
* @deprecated Import `MatProgressSpinner` instead. Note that the
* `mat-spinner` selector isn't deprecated.
* @breaking-change 8.0.0
*/
// tslint:disable-next-line:variable-name
export const MatSpinner = MatProgressSpinner;
10 changes: 3 additions & 7 deletions tools/public_api_guard/material/progress-spinner.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export declare class MatProgressSpinner extends _MatProgressSpinnerMixinBase imp
static ngAcceptInputType_diameter: NumberInput;
static ngAcceptInputType_strokeWidth: NumberInput;
static ngAcceptInputType_value: NumberInput;
static ɵcmp: i0.ɵɵComponentDefWithMeta<MatProgressSpinner, "mat-progress-spinner", ["matProgressSpinner"], { "color": "color"; "diameter": "diameter"; "strokeWidth": "strokeWidth"; "mode": "mode"; "value": "value"; }, {}, never, never>;
static ɵcmp: i0.ɵɵComponentDefWithMeta<MatProgressSpinner, "mat-progress-spinner, mat-spinner", ["matProgressSpinner"], { "color": "color"; "diameter": "diameter"; "strokeWidth": "strokeWidth"; "mode": "mode"; "value": "value"; }, {}, never, never>;
static ɵfac: i0.ɵɵFactoryDef<MatProgressSpinner, [null, null, { optional: true; }, { optional: true; }, null]>;
}

Expand All @@ -34,13 +34,9 @@ export interface MatProgressSpinnerDefaultOptions {

export declare class MatProgressSpinnerModule {
static ɵinj: i0.ɵɵInjectorDef<MatProgressSpinnerModule>;
static ɵmod: i0.ɵɵNgModuleDefWithMeta<MatProgressSpinnerModule, [typeof i1.MatProgressSpinner, typeof i1.MatSpinner], [typeof i2.MatCommonModule, typeof i3.CommonModule], [typeof i1.MatProgressSpinner, typeof i1.MatSpinner, typeof i2.MatCommonModule]>;
static ɵmod: i0.ɵɵNgModuleDefWithMeta<MatProgressSpinnerModule, [typeof i1.MatProgressSpinner], [typeof i2.MatCommonModule, typeof i3.CommonModule], [typeof i1.MatProgressSpinner, typeof i2.MatCommonModule]>;
}

export declare class MatSpinner extends MatProgressSpinner {
constructor(elementRef: ElementRef<HTMLElement>, platform: Platform, document: any, animationMode: string, defaults?: MatProgressSpinnerDefaultOptions);
static ɵcmp: i0.ɵɵComponentDefWithMeta<MatSpinner, "mat-spinner", never, { "color": "color"; }, {}, never, never>;
static ɵfac: i0.ɵɵFactoryDef<MatSpinner, [null, null, { optional: true; }, { optional: true; }, null]>;
}
export declare const MatSpinner: typeof MatProgressSpinner;

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

0 comments on commit 9a97b7b

Please sign in to comment.