diff --git a/src/material-experimental/mdc-progress-bar/progress-bar.spec.ts b/src/material-experimental/mdc-progress-bar/progress-bar.spec.ts index 772f4dfd660a..9af4edd53f34 100644 --- a/src/material-experimental/mdc-progress-bar/progress-bar.spec.ts +++ b/src/material-experimental/mdc-progress-bar/progress-bar.spec.ts @@ -175,6 +175,45 @@ describe('MDC-based MatProgressBar', () => { expect(progressElement.componentInstance.mode).toBe('buffer'); expect(progressElement.componentInstance.color).toBe('warn'); }); + + it('should update the DOM transform when the value has changed', () => { + const fixture = createComponent(BasicProgressBar); + fixture.detectChanges(); + + const progressElement = fixture.debugElement.query(By.css('mat-progress-bar'))!; + const progressComponent = progressElement.componentInstance; + const primaryBar = progressElement.nativeElement.querySelector( + '.mdc-linear-progress__primary-bar', + ); + + expect(primaryBar.style.transform).toBe('scaleX(0)'); + + progressComponent.value = 40; + fixture.detectChanges(); + + expect(primaryBar.style.transform).toBe('scaleX(0.4)'); + }); + + it('should update the DOM transform when the bufferValue has changed', () => { + const fixture = createComponent(BasicProgressBar); + fixture.detectChanges(); + + const progressElement = fixture.debugElement.query(By.css('mat-progress-bar'))!; + const progressComponent = progressElement.componentInstance; + const bufferBar = progressElement.nativeElement.querySelector( + '.mdc-linear-progress__buffer-bar', + ); + + progressComponent.mode = 'buffer'; + fixture.detectChanges(); + + expect(bufferBar.style.flexBasis).toBe('0%'); + + progressComponent.bufferValue = 40; + fixture.detectChanges(); + + expect(bufferBar.style.flexBasis).toBe('40%'); + }); }); describe('animation trigger on determinate setting', () => { diff --git a/src/material/progress-bar/progress-bar.spec.ts b/src/material/progress-bar/progress-bar.spec.ts index c80cb1120613..a2a0b0844d65 100644 --- a/src/material/progress-bar/progress-bar.spec.ts +++ b/src/material/progress-bar/progress-bar.spec.ts @@ -218,6 +218,41 @@ describe('MatProgressBar', () => { expect(progressElement.componentInstance.mode).toBe('buffer'); expect(progressElement.componentInstance.color).toBe('warn'); }); + + it('should update the DOM transform when the value has changed', () => { + const fixture = createComponent(BasicProgressBar); + fixture.detectChanges(); + + const progressElement = fixture.debugElement.query(By.css('mat-progress-bar'))!; + const progressComponent = progressElement.componentInstance; + const primaryBar = progressElement.nativeElement.querySelector('.mat-progress-bar-primary'); + + expect(primaryBar.style.transform).toBe('scale3d(0, 1, 1)'); + + progressComponent.value = 40; + fixture.detectChanges(); + + expect(primaryBar.style.transform).toBe('scale3d(0.4, 1, 1)'); + }); + + it('should update the DOM transform when the bufferValue has changed', () => { + const fixture = createComponent(BasicProgressBar); + fixture.detectChanges(); + + const progressElement = fixture.debugElement.query(By.css('mat-progress-bar'))!; + const progressComponent = progressElement.componentInstance; + const bufferBar = progressElement.nativeElement.querySelector('.mat-progress-bar-buffer'); + + progressComponent.mode = 'buffer'; + fixture.detectChanges(); + + expect(bufferBar.style.transform).toBeFalsy(); + + progressComponent.bufferValue = 40; + fixture.detectChanges(); + + expect(bufferBar.style.transform).toBe('scale3d(0.4, 1, 1)'); + }); }); describe('animation trigger on determinate setting', () => { diff --git a/src/material/progress-bar/progress-bar.ts b/src/material/progress-bar/progress-bar.ts index 3614ac0576a9..c35b625ab09f 100644 --- a/src/material/progress-bar/progress-bar.ts +++ b/src/material/progress-bar/progress-bar.ts @@ -23,6 +23,7 @@ import { Output, ViewChild, ViewEncapsulation, + ChangeDetectorRef, } from '@angular/core'; import {CanColor, mixinColor, ThemePalette} from '@angular/material/core'; import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; @@ -135,16 +136,20 @@ export class MatProgressBar @Optional() @Inject(MAT_PROGRESS_BAR_DEFAULT_OPTIONS) defaults?: MatProgressBarDefaultOptions, + /** + * @deprecated `_changeDetectorRef` parameter to be made required. + * @breaking-change 11.0.0 + */ + private _changeDetectorRef?: ChangeDetectorRef, ) { super(elementRef); // We need to prefix the SVG reference with the current path, otherwise they won't work // in Safari if the page has a `` tag. Note that we need quotes inside the `url()`, - - // because named route URLs can contain parentheses (see #12338). Also we don't use since - // we can't tell the difference between whether - // the consumer is using the hash location strategy or not, because `Location` normalizes - // both `/#/foo/bar` and `/foo/bar` to the same thing. + // because named route URLs can contain parentheses (see #12338). Also we don't use `Location` + // since we can't tell the difference between whether the consumer is using the hash location + // strategy or not, because `Location` normalizes both `/#/foo/bar` and `/foo/bar` to + // the same thing. const path = location ? location.getPathname().split('#')[0] : ''; this._rectangleFillValue = `url('${path}#${this.progressbarId}')`; this._isNoopAnimation = _animationMode === 'NoopAnimations'; @@ -168,6 +173,9 @@ export class MatProgressBar } set value(v: NumberInput) { this._value = clamp(coerceNumberProperty(v) || 0); + + // @breaking-change 11.0.0 Remove null check for _changeDetectorRef. + this._changeDetectorRef?.markForCheck(); } private _value: number = 0; @@ -178,6 +186,9 @@ export class MatProgressBar } set bufferValue(v: number) { this._bufferValue = clamp(v || 0); + + // @breaking-change 11.0.0 Remove null check for _changeDetectorRef. + this._changeDetectorRef?.markForCheck(); } private _bufferValue: number = 0; diff --git a/tools/public_api_guard/material/progress-bar.md b/tools/public_api_guard/material/progress-bar.md index 2d8d805e280b..5f66ada26733 100644 --- a/tools/public_api_guard/material/progress-bar.md +++ b/tools/public_api_guard/material/progress-bar.md @@ -7,6 +7,7 @@ import { _AbstractConstructor } from '@angular/material/core'; import { AfterViewInit } from '@angular/core'; import { CanColor } from '@angular/material/core'; +import { ChangeDetectorRef } from '@angular/core'; import { _Constructor } from '@angular/material/core'; import { ElementRef } from '@angular/core'; import { EventEmitter } from '@angular/core'; @@ -31,7 +32,8 @@ export function MAT_PROGRESS_BAR_LOCATION_FACTORY(): MatProgressBarLocation; // @public export class MatProgressBar extends _MatProgressBarBase implements CanColor, AfterViewInit, OnDestroy { constructor(elementRef: ElementRef, _ngZone: NgZone, _animationMode?: string | undefined, - location?: MatProgressBarLocation, defaults?: MatProgressBarDefaultOptions); + location?: MatProgressBarLocation, defaults?: MatProgressBarDefaultOptions, + _changeDetectorRef?: ChangeDetectorRef | undefined); readonly animationEnd: EventEmitter; // (undocumented) _animationMode?: string | undefined; @@ -58,7 +60,7 @@ export class MatProgressBar extends _MatProgressBarBase implements CanColor, Aft // (undocumented) static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) - static ɵfac: i0.ɵɵFactoryDeclaration; + static ɵfac: i0.ɵɵFactoryDeclaration; } // @public