fix(progress-spinner): circle not rendering correctly when switching modes in Safari (#12151)

Fixes the SVG `circle` element not rendering property when switching from `indeterminate` to `determinate` mode.

Fixes #12140.
This commit is contained in:
Kristiyan Kostadinov
2018-07-12 16:40:06 +02:00
committed by Jeremy Elbourn
parent eb6c456585
commit 623cd3d2fd
3 changed files with 42 additions and 4 deletions
@@ -6,12 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {MatCommonModule} from '@angular/material/core';
import {MatProgressSpinner, MatSpinner} from './progress-spinner';
@NgModule({
imports: [MatCommonModule],
imports: [MatCommonModule, CommonModule],
exports: [
MatProgressSpinner,
MatSpinner,
+19 -1
View File
@@ -10,9 +10,18 @@
[style.height.px]="diameter"
[attr.viewBox]="_viewBox"
preserveAspectRatio="xMidYMid meet"
focusable="false">
focusable="false"
[ngSwitch]="mode === 'indeterminate'">
<!--
Technically we can reuse the same `circle` element, however Safari has an issue that breaks
the SVG rendering in determinate mode, after switching between indeterminate and determinate.
Using a different element avoids the issue. An alternative to this is adding `display: none`
for a split second and then removing it when switching between modes, but it's hard to know
for how long to hide the element and it can cause the UI to blink.
-->
<circle
*ngSwitchCase="true"
cx="50%"
cy="50%"
[attr.r]="_circleRadius"
@@ -20,4 +29,13 @@
[style.stroke-dashoffset.px]="_strokeDashOffset"
[style.stroke-dasharray.px]="_strokeCircumference"
[style.stroke-width.%]="_circleStrokeWidth"></circle>
<circle
*ngSwitchCase="false"
cx="50%"
cy="50%"
[attr.r]="_circleRadius"
[style.stroke-dashoffset.px]="_strokeDashOffset"
[style.stroke-dasharray.px]="_strokeCircumference"
[style.stroke-width.%]="_circleStrokeWidth"></circle>
</svg>

Before

Width:  |  Height:  |  Size: 770 B

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -83,6 +83,24 @@ describe('MatProgressSpinner', () => {
expect(progressElement.componentInstance.value).toBe(75);
});
it('should use different `circle` elements depending on the mode', () => {
const fixture = TestBed.createComponent(ProgressSpinnerWithValueAndBoundMode);
fixture.componentInstance.mode = 'determinate';
fixture.detectChanges();
const determinateCircle = fixture.nativeElement.querySelector('circle');
fixture.componentInstance.mode = 'indeterminate';
fixture.detectChanges();
const indeterminateCircle = fixture.nativeElement.querySelector('circle');
expect(determinateCircle).toBeTruthy();
expect(indeterminateCircle).toBeTruthy();
expect(determinateCircle).not.toBe(indeterminateCircle);
});
it('should clamp the value of the progress between 0 and 100', () => {
let fixture = TestBed.createComponent(BasicProgressSpinner);
fixture.detectChanges();
@@ -138,12 +156,13 @@ describe('MatProgressSpinner', () => {
it('should allow a custom stroke width', () => {
const fixture = TestBed.createComponent(ProgressSpinnerCustomStrokeWidth);
const circleElement = fixture.nativeElement.querySelector('circle');
const svgElement = fixture.nativeElement.querySelector('svg');
fixture.componentInstance.strokeWidth = 40;
fixture.detectChanges();
const circleElement = fixture.nativeElement.querySelector('circle');
const svgElement = fixture.nativeElement.querySelector('svg');
expect(parseInt(circleElement.style.strokeWidth)).toBe(40, 'Expected the custom stroke ' +
'width to be applied to the circle element as a percentage of the element size.');
expect(svgElement.getAttribute('viewBox'))