From 0c9fd25dc1dbba87d15356a2490b4db7007c1c48 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Mon, 10 Dec 2018 18:01:12 +0200 Subject: [PATCH 1/9] refactor(linear-progress): modify styles and template for indeterminate state --- .../progress/_progress-component.scss | 85 +++++++------------ .../components/progress/_progress-theme.scss | 78 +++++++++++++---- .../lib/progressbar/progressbar.component.ts | 54 ++++++++---- .../templates/linear-bar.component.html | 25 +++--- src/app/progressbar/progressbar.sample.html | 7 +- 5 files changed, 152 insertions(+), 97 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss index 84bae9236a4..e16c21003de 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss @@ -7,47 +7,19 @@ //// /// Linear Progress -@include b(progress-linear) { +@include b(igx-linear-bar) { $this: bem--selector-to-string(&); @include register-component(str-slice($this, 2, -1)); @extend %linear-display !optional; - @include e(bar) { + @include e(base) { @extend %linear-bar !optional; } - @include e(bar-base) { - @extend %linear-bar-base !optional; - } - - @include e(bar-progress) { - @extend %linear-bar-progress !optional; - } - - @include e(bar-progress, $m: default) { - @extend %linear-bar-progress !optional; - @extend %linear-bar-progress--default !optional; - } - - @include e(bar-progress, $m: danger) { - @extend %linear-bar-progress !optional; - @extend %linear-bar-progress--danger !optional; - } - - @include e(bar-progress, $m: warning) { - @extend %linear-bar-progress !optional; - @extend %linear-bar-progress--warning !optional; - } - - @include e(bar-progress, $m: info) { - @extend %linear-bar-progress !optional; - @extend %linear-bar-progress--info !optional; - } - - @include e(bar-progress, $m: success) { - @extend %linear-bar-progress !optional; - @extend %linear-bar-progress--success !optional; + @include e(indicator) { + @extend %linear-indicator !optional; + @extend %linear-indicator--default !optional; } @include e(value) { @@ -80,35 +52,44 @@ @extend %linear-value--hidden !optional; } - @include m(striped) { - @include e(bar-progress) { - @extend %linear-bar-progress !optional; - @extend %linear-bar-progress--striped !optional; + @include m(danger) { + @include e(indicator) { + @extend %linear-indicator--danger !optional; + } + } + + @include m(warning) { + @include e(indicator) { + @extend %linear-indicator--warning !optional; } + } - @include e(bar-progress, $m: default) { - @extend %linear-bar-progress !optional; - @extend %linear-bar-progress--striped !optional; + @include m(info) { + @include e(indicator) { + @extend %linear-indicator--info !optional; } + } - @include e(bar-progress, $m: danger) { - @extend %linear-bar-progress !optional; - @extend %linear-bar-progress--striped !optional; + @include m(success) { + @include e(indicator) { + @extend %linear-indicator--success !optional; } + } - @include e(bar-progress, $m: warning) { - @extend %linear-bar-progress !optional; - @extend %linear-bar-progress--striped !optional; + @include m(striped) { + @include e(indicator) { + @extend %linear-indicator--striped !optional; } + } - @include e(bar-progress, $m: info) { - @extend %linear-bar-progress !optional; - @extend %linear-bar-progress--striped !optional; + @include m(indeterminate) { + @include e(indicator) { + @extend %linear-indicator--indeterminate !optional; } - @include e(bar-progress, $m: success) { - @extend %linear-bar-progress !optional; - @extend %linear-bar-progress--striped !optional; + @include e(value) { + @extend %linear-value !optional; + @extend %linear-value--hidden !optional; } } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss index 368b72ebe93..522f71fa5f7 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss @@ -82,27 +82,21 @@ } %linear-bar { - width: inherit; - height: $bar-height; - overflow: hidden; - } - - %linear-bar-base { position: absolute; width: inherit; - height: inherit; + height: $bar-height; background: --var($theme, 'track-color'); + overflow: hidden; z-index: 0; } - %linear-bar-progress { + %linear-indicator { width: 100%; position: relative; height: inherit; - backface-visibility: hidden; } - %linear-bar-progress--striped { + %linear-indicator--striped { background-image: linear-gradient( -45deg, $stripe-color 25%, @@ -116,23 +110,39 @@ background-size: 40px 40px; } - %linear-bar-progress--default { + %linear-indicator--indeterminate { + animation: indeterminate-progress 2s cubic-bezier(0, .085, .68, .53) infinite; + width: 100% !important; + + &::before { + position: absolute; + content: ''; + top: 0; + left: -200%; + width: 100%; + height: inherit; + background-color: inherit; + transform-origin: top right; + } + } + + %linear-indicator--default { background: --var($theme, 'fill-color-default') } - %linear-bar-progress--danger { + %linear-indicator--danger { background-color: --var($theme, 'fill-color-danger'); } - %linear-bar-progress--warning { + %linear-indicator--warning { background-color: --var($theme, 'fill-color-warning'); } - %linear-bar-progress--info { + %linear-indicator--info { background-color: --var($theme, 'fill-color-info'); } - %linear-bar-progress--success { + %linear-indicator--success { background-color: --var($theme, 'fill-color-success'); } @@ -163,6 +173,23 @@ %linear-value--hidden { display: none; } + + @keyframes indeterminate-progress { + 0% { + transform: scaleX(0) translateX(-100%); + transform-origin: left; + } + + 50% { + transform: scaleX(1) translateX(50%); + transform-origin: right; + } + + 100% { + transform: scaleX(0) translateX(200%); + transform-origin: right; + } + } } /// @param {Map} $palette [$default-palette] - The palette used as basis for styling the component. @@ -202,7 +229,6 @@ text-color: $text-color )); } - /// @param {Map} $theme - The theme used to style the component. /// @requires {mixin} igx-root-css-vars /// @requires rem @@ -229,8 +255,7 @@ %circular-circle { fill: transparent; stroke: --var($theme, 'progress-circle-color'); - stroke-width: 6; - stroke-linecap: round; + stroke-width: 4; stroke-dashoffset: 289; stroke-dasharray: 289; transform-origin: 50% 50%; @@ -246,4 +271,21 @@ %circular-text--hidden { visibility: hidden; } + + @keyframes indeterminate-progress { + 0% { + transform: scaleX(0) translateX(-100%); + transform-origin: left; + } + + 50% { + transform: scaleX(1) translateX(50%); + transform-origin: right; + } + + 100% { + transform: scaleX(0) translateX(200%); + transform-origin: right; + } + } } diff --git a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts index 11d324420fa..c45c516f590 100644 --- a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts +++ b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts @@ -1,17 +1,14 @@ import { CommonModule } from '@angular/common'; import { - AfterViewInit, Component, ElementRef, EventEmitter, HostBinding, Input, NgModule, - OnChanges, Output, Renderer2, ViewChild, - TemplateRef, ContentChild } from '@angular/core'; import { IgxProcessBarTextTemplateDirective } from './progressbar.common'; @@ -110,8 +107,8 @@ export abstract class BaseProgress { this.updateProgress(val); cancelAnimationFrame(this.requestAnimationId); } else if (this.isInLimitRange(progressValue, passedValue, step)) { - this.updateProgress(val); - cancelAnimationFrame(this.requestAnimationId); + this.updateProgress(val); + cancelAnimationFrame(this.requestAnimationId); } else { this.valueInPercent = progressValue; this.requestAnimationId = requestAnimationFrame(() => this.updateProgressSmoothly.call(this, val, step)); @@ -183,6 +180,40 @@ let NEXT_CIRCULAR_ID = 0; templateUrl: 'templates/linear-bar.component.html' }) export class IgxLinearProgressBarComponent extends BaseProgress { + @HostBinding('attr.aria-valuemin') + private valueMin = 0; + + @HostBinding('class.igx-linear-bar') + public cssClass = 'igx-linear-bar'; + + /** + *Set `IgxLinearProgressBarComponent` to have striped style. By default it is set to false. + *```html + * + *``` + */ + @HostBinding('class.igx-linear-bar--striped') + @Input() + public striped = false; + + /** + *Set `IgxLinearProgressBarComponent` to have indeterminate. By default it is set to false. + *```html + * + *``` + */ + @HostBinding('class.igx-linear-bar--indeterminate') + @Input() + public indeterminate = false; + + /**An @Input property that sets the value of the `role` attribute. If not provided it will be automatically set to `progressbar`. + * ```html + * + * ``` + */ + @HostBinding('attr.role') + @Input() + public role = 'progressbar'; /**An @Input property that sets the value of `id` attribute. If not provided it will be automatically generated. * ```html @@ -237,15 +268,6 @@ export class IgxLinearProgressBarComponent extends BaseProgress { @Input() public text: string; - /** - *Set `IgxLinearProgressBarComponent` to have striped style. By default it is set to false. - *```html - * - *``` - */ - @Input() - public striped = false; - /** *Set type of the `IgxLinearProgressBarComponent`. Possible options - `default`, `success`, `info`, `warning`, and `danger`. *```html @@ -287,6 +309,7 @@ export class IgxLinearProgressBarComponent extends BaseProgress { * *``` */ + @HostBinding('attr.aria-valuemax') @Input() set max(maxNum: number) { this._max = maxNum; @@ -348,6 +371,7 @@ export class IgxLinearProgressBarComponent extends BaseProgress { *} *``` */ + @HostBinding('attr.aria-valuenow') @Input() get value(): number { return this._value; @@ -466,7 +490,7 @@ export class IgxCircularProgressBarComponent extends BaseProgress { */ public get context(): any { return { - $implicit: { value: this.value, valueInPercent: this.valueInPercent, max: this.max} + $implicit: { value: this.value, valueInPercent: this.valueInPercent, max: this.max } }; } diff --git a/projects/igniteui-angular/src/lib/progressbar/templates/linear-bar.component.html b/projects/igniteui-angular/src/lib/progressbar/templates/linear-bar.component.html index 8409ef2b14c..b3b2b1eb8d3 100644 --- a/projects/igniteui-angular/src/lib/progressbar/templates/linear-bar.component.html +++ b/projects/igniteui-angular/src/lib/progressbar/templates/linear-bar.component.html @@ -1,12 +1,15 @@ -
-
-
-
-
- - {{text ? text : valueInPercent + '%'}} - +
+
+ + + {{text ? text : valueInPercent + '%'}} + diff --git a/src/app/progressbar/progressbar.sample.html b/src/app/progressbar/progressbar.sample.html index 5b9c49d566c..17630330fb9 100644 --- a/src/app/progressbar/progressbar.sample.html +++ b/src/app/progressbar/progressbar.sample.html @@ -6,7 +6,7 @@

Linear progress bar

- +
@@ -29,6 +29,11 @@

Linear progress bar

+ +
+ + +
From 86827b386aa26854ccd9c2e21eea925da1401d21 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Tue, 11 Dec 2018 16:55:24 +0200 Subject: [PATCH 2/9] refactor(circular-bar): add indeterminate state and animation --- .../progress/_progress-component.scss | 22 ++++-- .../components/progress/_progress-theme.scss | 78 ++++++++++--------- .../styles/themes/schemas/dark/_index.scss | 4 +- .../styles/themes/schemas/light/_index.scss | 4 +- .../themes/schemas/light/_progress.scss | 4 - .../lib/progressbar/progressbar.component.ts | 10 +++ .../templates/circular-bar.component.html | 12 +-- src/app/progressbar/progressbar.sample.html | 3 + 8 files changed, 83 insertions(+), 54 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss index e16c21003de..b862f5f675b 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-component.scss @@ -95,18 +95,18 @@ } /// Circular Progress -@include b(progress-circular) { +@include b(igx-circular-bar) { $this: bem--selector-to-string(&); @include register-component(str-slice($this, 2, -1)); @extend %circular-display !optional; - @include e(innercircle) { - @extend %circular-innercircle !optional; + @include e(inner) { + @extend %circular-inner !optional; } - @include e(circle) { - @extend %circular-circle !optional; + @include e(outer) { + @extend %circular-outer !optional; } @include e(text) { @@ -117,4 +117,16 @@ @extend %circular-text !optional; @extend %circular-text--hidden !optional; } + + @include m(indeterminate) { + @extend %circular-display--indeterminate !optional; + + @include e(outer) { + @extend %circular-outer--indeterminate !optional; + } + + @include e(text) { + @extend %circular-text--hidden !optional; + } + } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss index 522f71fa5f7..f72d0e48661 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss @@ -41,7 +41,7 @@ $stripes-color: null, $text-color: null ) { - $name: 'igx-progress-linear'; + $name: 'igx-linear-bar'; $theme: apply-palette(map-get($schema, $name), $palette); @return extend($theme, ( @@ -111,7 +111,7 @@ } %linear-indicator--indeterminate { - animation: indeterminate-progress 2s cubic-bezier(0, .085, .68, .53) infinite; + @include animation(indeterminate-bar 2s cubic-bezier(0, .085, .68, .53) infinite); width: 100% !important; &::before { @@ -173,23 +173,6 @@ %linear-value--hidden { display: none; } - - @keyframes indeterminate-progress { - 0% { - transform: scaleX(0) translateX(-100%); - transform-origin: left; - } - - 50% { - transform: scaleX(1) translateX(50%); - transform-origin: right; - } - - 100% { - transform: scaleX(0) translateX(200%); - transform-origin: right; - } - } } /// @param {Map} $palette [$default-palette] - The palette used as basis for styling the component. @@ -218,7 +201,7 @@ $progress-circle-color: null, $text-color: null ) { - $name: 'igx-progress-circular'; + $name: 'igx-circular-bar'; $theme: apply-palette(map-get($schema, $name), $palette); @return extend($theme, ( @@ -232,8 +215,12 @@ /// @param {Map} $theme - The theme used to style the component. /// @requires {mixin} igx-root-css-vars /// @requires rem +/// @requires {mixin} rotate-center /// @requires --var @mixin igx-progress-circular($theme) { + // Include rotate animation + @include rotate-center(); + @include igx-root-css-vars($theme); // @debug $theme; @@ -246,13 +233,17 @@ height: 100%; } - %circular-innercircle { + %circular-display--indeterminate { + @include animation(rotate-center 1.4s linear infinite); + } + + %circular-inner { stroke-width: 4; fill: transparent; stroke: --var($theme, 'base-circle-color'); } - %circular-circle { + %circular-outer { fill: transparent; stroke: --var($theme, 'progress-circle-color'); stroke-width: 4; @@ -262,6 +253,12 @@ transform: rotate(-90deg); } + %circular-outer--indeterminate { + stroke-dashoffset: 180; + stroke-dasharray: 180; + @include animation(indeterminate-accordion 1.5s cubic-bezier(0, .085, .68, .53) infinite); + } + %circular-text { font-size: $circular-value-fs; font-weight: $circular-value-fw; @@ -271,21 +268,32 @@ %circular-text--hidden { visibility: hidden; } +} - @keyframes indeterminate-progress { - 0% { - transform: scaleX(0) translateX(-100%); - transform-origin: left; - } +@include keyframes('indeterminate-bar') { + 0% { + transform: scaleX(0) translateX(-100%); + transform-origin: left; + } - 50% { - transform: scaleX(1) translateX(50%); - transform-origin: right; - } + 50% { + transform: scaleX(1) translateX(50%); + transform-origin: right; + } - 100% { - transform: scaleX(0) translateX(200%); - transform-origin: right; - } + 100% { + transform: scaleX(0) translateX(200%); + transform-origin: right; + } +} + +@include keyframes('indeterminate-accordion') { + 50% { + stroke-dashoffset: 260; + stroke-dasharray: 289; + } + + 100% { + stroke-dashoffset: -180; } } diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss index 2a96244a1df..bfef3f35ef7 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss @@ -108,8 +108,8 @@ $dark-schema: ( igx-navbar: $_dark-navbar, igx-navdrawer: $_dark-navdrawer, igx-overlay: $_dark-overlay, - igx-progress-linear: $_dark-progress-linear, - igx-progress-circular: $_dark-progress-circular, + igx-linear-bar: $_dark-progress-linear, + igx-circular-bar: $_dark-progress-circular, igx-radio: $_dark-radio, igx-ripple: $_dark-ripple, igx-slider: $_dark-slider, diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss index 3bd6057c9db..93b62f8998c 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss @@ -114,8 +114,8 @@ $light-schema: ( igx-navbar: $_light-navbar, igx-navdrawer: $_light-navdrawer, igx-overlay: $_light-overlay, - igx-progress-linear: $_light-progress-linear, - igx-progress-circular: $_light-progress-circular, + igx-linear-bar: $_light-progress-linear, + igx-circular-bar: $_light-progress-circular, igx-radio: $_light-radio, igx-ripple: $_light-ripple, igx-slider: $_light-slider, diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_progress.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_progress.scss index 94deb7defdf..86a8faf8d2b 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_progress.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_progress.scss @@ -19,8 +19,6 @@ /// @see $default-palette $_light-progress-linear: ( - name: 'igx-progress-linear', - track-color: ( igx-color: ('grays', 300) ), @@ -62,8 +60,6 @@ $_light-progress-linear: ( /// @see $default-palette $_light-progress-circular: ( - name: 'igx-progress-circular', - base-circle-color: ( igx-color: ('grays', 300) ), diff --git a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts index c45c516f590..aa81ca79b8e 100644 --- a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts +++ b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts @@ -461,6 +461,16 @@ export class IgxCircularProgressBarComponent extends BaseProgress { @Input() public id = `igx-circular-bar-${NEXT_CIRCULAR_ID++}`; + /** + *An @Input property that sets the value of the `indeterminate` attribute. If not provided it will be automatically set to false. + *```html + * + *``` + */ + @HostBinding('class.igx-circular-bar--indeterminate') + @Input() + public indeterminate = false; + /** *Sets the text visibility. By default it is set to true. *```html diff --git a/projects/igniteui-angular/src/lib/progressbar/templates/circular-bar.component.html b/projects/igniteui-angular/src/lib/progressbar/templates/circular-bar.component.html index 537895cb1c6..fb55d899ec2 100644 --- a/projects/igniteui-angular/src/lib/progressbar/templates/circular-bar.component.html +++ b/projects/igniteui-angular/src/lib/progressbar/templates/circular-bar.component.html @@ -1,13 +1,13 @@ - - - - + + + - {{textContent ? textContent: valueInPercent + '%'}} + {{textContent ? textContent: valueInPercent + '%'}} - \ No newline at end of file + diff --git a/src/app/progressbar/progressbar.sample.html b/src/app/progressbar/progressbar.sample.html index 17630330fb9..b6da600483b 100644 --- a/src/app/progressbar/progressbar.sample.html +++ b/src/app/progressbar/progressbar.sample.html @@ -87,6 +87,9 @@

Circular progress indicator

+
+ +
From 8e452644e96d2ae26515903e23da35de9b14de06 Mon Sep 17 00:00:00 2001 From: Aleksandar Kamenov Date: Wed, 12 Dec 2018 11:30:35 +0200 Subject: [PATCH 3/9] refactor(progressbar): apply type classes to the host and refactor the tests --- .../progressbar/circularbar.component.spec.ts | 51 ++-- .../progressbar/linearbar.component.spec.ts | 89 ++++--- .../lib/progressbar/progressbar.component.ts | 235 ++++++++++-------- 3 files changed, 222 insertions(+), 153 deletions(-) diff --git a/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts b/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts index 79cbcb08f94..bb93ed03cdb 100644 --- a/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts @@ -12,6 +12,12 @@ import { Common } from './common.spec'; import { configureTestSuite } from '../test-utils/configure-suite'; +const CIRCULAR_INNER_CLASS = 'igx-circular-bar__inner'; +const CIRCULAR_OUTER_CLASS = 'igx-circular-bar__outer'; +const CIRCULAR_TEXT_CLASS = 'igx-circular-bar__text'; +const CIRCULAR_HIDDEN_TEXT_CLASS = 'igx-circular-bar__text--hidden'; +const CIRCULAR_INDETERMINATE_CLASS = 'igx-circular-bar--indeterminate'; + describe('IgCircularBar', () => { configureTestSuite(); const tickTime = 2000; @@ -277,7 +283,7 @@ describe('IgCircularBar', () => { }); it(`when step value is not divisble to passed value the result returned from the - value getter should be as same as the passed one`, fakeAsync(() => { + value getter should be the same as the passed one`, fakeAsync(() => { const fix = TestBed.createComponent(InitCircularProgressBarComponent); fix.detectChanges(); @@ -309,19 +315,19 @@ describe('IgCircularBar', () => { const componentInstance = fixture.componentInstance; const progressBarElem = fixture.debugElement.nativeElement - .querySelector('.progress-circular'); + .querySelector('.igx-circular-bar'); fixture.detectChanges(); expect(progressBarElem.attributes['aria-valuenow'].textContent).toBe('20'); - expect(progressBarElem.children[0].classList.value).toBe('progress-circular__innercircle'); - expect(progressBarElem.children[1].classList.value).toBe('progress-circular__circle'); + expect(progressBarElem.children[0].classList.value).toBe(CIRCULAR_INNER_CLASS); + expect(progressBarElem.children[1].classList.value).toBe(CIRCULAR_OUTER_CLASS); expect(progressBarElem.children[2].children.length).toBe(2); expect(progressBarElem.children[2].children[0].textContent.trim()).toBe('Value is:'); expect(progressBarElem.children[2].children[1].textContent.trim()).toMatch('20'); componentInstance.progressbar.textVisibility = false; fixture.detectChanges(); - expect(progressBarElem.children[2].classList.value).toMatch('progress-circular__text--hidden'); + expect(progressBarElem.children[2].classList.value).toMatch(CIRCULAR_HIDDEN_TEXT_CLASS); }); // UI TESTS @@ -333,7 +339,7 @@ describe('IgCircularBar', () => { const componentInstance = fixture.componentInstance; const progressBarElem = fixture.debugElement.nativeElement - .querySelector('.progress-circular'); + .querySelector('.igx-circular-bar'); let expectedTextContent = componentInstance.circularBar.value + '%'; tick(tickTime); @@ -342,9 +348,9 @@ describe('IgCircularBar', () => { expect(progressBarElem.attributes['aria-valuenow'].textContent).toBe(componentInstance.value.toString()); expect(progressBarElem.attributes['aria-valuemax'].textContent).toBe(componentInstance.max.toString()); - expect(progressBarElem.children[0].classList.value).toBe('progress-circular__innercircle'); - expect(progressBarElem.children[1].classList.value).toBe('progress-circular__circle'); - expect(progressBarElem.children[2].children[0].classList.value).toBe('progress-circular__text'); + expect(progressBarElem.children[0].classList.value).toBe(CIRCULAR_INNER_CLASS); + expect(progressBarElem.children[1].classList.value).toBe(CIRCULAR_OUTER_CLASS); + expect(progressBarElem.children[2].children[0].classList.value).toBe(CIRCULAR_TEXT_CLASS); expect(progressBarElem.children[2].children[0].textContent.trim()).toMatch(expectedTextContent); componentInstance.circularBar.text = 'No progress'; @@ -356,7 +362,7 @@ describe('IgCircularBar', () => { componentInstance.circularBar.textVisibility = false; fixture.detectChanges(); - expect(progressBarElem.children[2].classList.value).toMatch('progress-circular__text--hidden'); + expect(progressBarElem.children[2].classList.value).toMatch(CIRCULAR_HIDDEN_TEXT_CLASS); })); it('The max representation should respond correctly to passed maximum value', fakeAsync(() => { @@ -365,7 +371,7 @@ describe('IgCircularBar', () => { const componentInstance = fixture.componentInstance; const progressBarElem = fixture.debugElement.nativeElement - .querySelector('.progress-circular'); + .querySelector('.igx-circular-bar'); tick(tickTime); fixture.detectChanges(); @@ -378,9 +384,6 @@ describe('IgCircularBar', () => { fixture.detectChanges(); expect(progressBarElem.attributes['aria-valuemax'].textContent).toBe(componentInstance.max.toString()); - expect(progressBarElem.children[0].classList.value).toBe('progress-circular__innercircle'); - expect(progressBarElem.children[1].classList.value).toBe('progress-circular__circle'); - expect(progressBarElem.children[2].children[0].classList.value).toBe('progress-circular__text'); })); it('Manipulate progressbar with floating point numbers', fakeAsync(() => { @@ -397,8 +400,8 @@ describe('IgCircularBar', () => { fix.detectChanges(); const progressRepresentation = Common.calcPercentage(val, maxVal); - const progressBarElem = fix.debugElement.query(By.css('.progress-circular')); - const valueInPercent = progressBarElem.query(By.css('.progress-circular__text')).nativeElement; + const progressBarElem = fix.debugElement.query(By.css('.igx-circular-bar')); + const valueInPercent = progressBarElem.query(By.css(`.${CIRCULAR_TEXT_CLASS}`)).nativeElement; expect(valueInPercent.textContent.trim()).toBe(`${progressRepresentation}%`); })); @@ -416,10 +419,24 @@ describe('IgCircularBar', () => { tick(tickTime + tickTime); // enough time to exceed the progress update. fix.detectChanges(); - const progressBarContainer = fix.debugElement.query(By.css('.progress-circular')).nativeElement; + const progressBarContainer = fix.debugElement.query(By.css('.igx-circular-bar')).nativeElement; expect(parseFloat(progressBarContainer.attributes['aria-valuenow'].textContent)).toBe(value); expect(bar.value).toBe(value); })); + + it('When enable indeterminate mode, then the appropriate class should be applied.', () => { + const fix = TestBed.createComponent(InitCircularProgressBarComponent); + fix.detectChanges(); + + const bar = fix.debugElement.nativeElement.querySelector('igx-circular-bar'); + expect(bar.classList.contains(CIRCULAR_INDETERMINATE_CLASS)).toEqual(false); + + const barComponent = fix.componentInstance.circularBar; + barComponent.indeterminate = true; + fix.detectChanges(); + + expect(bar.classList.contains(CIRCULAR_INDETERMINATE_CLASS)).toEqual(true); + }); }); }); @Component({ template: `` }) diff --git a/projects/igniteui-angular/src/lib/progressbar/linearbar.component.spec.ts b/projects/igniteui-angular/src/lib/progressbar/linearbar.component.spec.ts index 83d2e1e8527..910e51d8174 100644 --- a/projects/igniteui-angular/src/lib/progressbar/linearbar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/progressbar/linearbar.component.spec.ts @@ -11,6 +11,14 @@ import { Common } from './common.spec'; import { configureTestSuite } from '../test-utils/configure-suite'; +const SUCCESS_TYPE_CLASS = 'igx-linear-bar--success'; +const INFO_TYPE_CLASS = 'igx-linear-bar--info'; +const WARNING_TYPE_CLASS = 'igx-linear-bar--warning'; +const DANGER_TYPE_CLASS = 'igx-linear-bar--danger'; +const STRIPED_CLASS = 'igx-linear-bar--striped'; +const LINEAR_BAR_TAG = 'igx-linear-bar'; +const INDETERMINATE_CLASS = 'igx-linear-bar--indeterminate'; + describe('IgLinearBar', () => { configureTestSuite(); const tickTime = 2000; @@ -30,7 +38,7 @@ describe('IgLinearBar', () => { fixture.detectChanges(); const progress = fixture.componentInstance.linearBar; - const domProgress = fixture.debugElement.query(By.css('igx-linear-bar')).nativeElement; + const domProgress = fixture.debugElement.query(By.css(LINEAR_BAR_TAG)).nativeElement; const defaultMaxValue = 100; const defaultValue = 0; const defaultStriped = false; @@ -144,7 +152,7 @@ describe('IgLinearBar', () => { it('Should update value when we try to decrese it', fakeAsync(() => { const fixture = TestBed.createComponent(LinearBarComponent); fixture.detectChanges(); - const progressBar = fixture.componentInstance.linearBar; + const progressBar = fixture.componentInstance.progressbar; let expectedValue = 50; fixture.componentInstance.value = expectedValue; @@ -167,7 +175,7 @@ describe('IgLinearBar', () => { it('Should update value when we try to decrease it (without animation)', () => { const fixture = TestBed.createComponent(LinearBarComponent); - const progressBar = fixture.componentInstance.linearBar; + const progressBar = fixture.componentInstance.progressbar; let expectedValue = 50; fixture.componentInstance.animate = false; @@ -187,24 +195,24 @@ describe('IgLinearBar', () => { const fix = TestBed.createComponent(LinearBarComponent); fix.detectChanges(); - const datepicker = fix.componentInstance.linearBar; + const progressbar = fix.componentInstance.linearBar; const expectedRes = fix.componentInstance.value; tick(tickTime); fix.detectChanges(); - expect(datepicker.value).toEqual(expectedRes); + expect(progressbar.value).toEqual(expectedRes); - datepicker.value = '0345-234'; + progressbar.value = '0345-234'; tick(tickTime); fix.detectChanges(); - expect(datepicker.value).toEqual(expectedRes); + expect(progressbar.value).toEqual(expectedRes); })); it('The update step is 1% of the maximum value, which prevents from slow update with big nums', () => { const fix = TestBed.createComponent(LinearBarComponent); fix.detectChanges(); - const bar = fix.componentInstance.linearBar; + const bar = fix.componentInstance.progressbar; const ONE_PERCENT = 0.01; let expectedValue = bar.max * ONE_PERCENT; expect(bar.step).toBe(expectedValue); @@ -225,7 +233,7 @@ describe('IgLinearBar', () => { fix.detectChanges(); tick(tickTime); - const bar = compInstance.linearBar; + const bar = compInstance.progressbar; const expectedRes = 0; expect(bar.value).toBe(expectedRes); expect(bar.valueInPercent).toBe(expectedRes); @@ -248,7 +256,7 @@ describe('IgLinearBar', () => { compInstance.value = value; fix.detectChanges(); - const bar = compInstance.linearBar; + const bar = compInstance.progressbar; tick(tickTime); expect(bar.value).toBe(max); expect(bar.valueInPercent).toBe(100); @@ -333,70 +341,62 @@ describe('IgLinearBar', () => { fixture.detectChanges(); const componentInstance = fixture.componentInstance; - const progressBarContainer = - fixture.debugElement.nativeElement.querySelector('.progress-linear__bar'); - const progressBarElem = progressBarContainer.querySelector('[class*=\'progress-linear__bar-progress\']'); + const linearBar = fixture.debugElement.nativeElement.querySelector(LINEAR_BAR_TAG); + const progressIndicator = linearBar.querySelector('.igx-linear-bar__indicator'); tick(tickTime); fixture.detectChanges(); - expect(progressBarElem.style.width).toBe(componentInstance.value + '%'); - expect(progressBarContainer.attributes['aria-valuenow'].textContent).toBe(componentInstance.value.toString()); + expect(progressIndicator.style.width).toBe(componentInstance.value + '%'); + expect(linearBar.attributes['aria-valuenow'].textContent).toBe(componentInstance.value.toString()); })); it('Should change class suffix which would be relevant to the type that has been passed', () => { const fixture = TestBed.createComponent(LinearBarComponent); fixture.detectChanges(); - const progressBarContainer = - fixture.debugElement.nativeElement.querySelector('.progress-linear__bar'); - const progressBarElem = progressBarContainer.querySelector('[class*=\'progress-linear__bar-progress\']'); + const linearBar = + fixture.debugElement.nativeElement.querySelector(LINEAR_BAR_TAG); - expect(progressBarElem.classList.contains('progress-linear__bar-progress--default')).toBe(true); + expect(linearBar.classList.length).toEqual(1); + expect(linearBar.classList.contains(LINEAR_BAR_TAG)).toEqual(true); fixture.componentInstance.type = 'info'; fixture.detectChanges(); - expect(progressBarElem.classList.contains('progress-linear__bar-progress--info')).toBe(true); + expect(linearBar.classList.contains(INFO_TYPE_CLASS)).toEqual(true); }); it('Change progressbar style to be striped', () => { const fixture = TestBed.createComponent(LinearBarComponent); fixture.detectChanges(); - const progressElem = fixture.debugElement.nativeElement - .getElementsByClassName('progress-linear')[0]; + const linerBar = fixture.debugElement.nativeElement.querySelector(LINEAR_BAR_TAG); - expect(progressElem.classList.contains('progress-linear--striped')).toBe(false); + expect(linerBar.classList.contains(STRIPED_CLASS)).toEqual(false); fixture.componentInstance.striped = true; fixture.detectChanges(); - expect(progressElem.classList.contains('progress-linear--striped')).toBe(true); + expect(linerBar.classList.contains(STRIPED_CLASS)).toEqual(true); }); it('should stay striped when the type has changed', () => { const fixture = TestBed.createComponent(LinearBarComponent); fixture.detectChanges(); - const progressElem = fixture.debugElement.nativeElement - .getElementsByClassName('progress-linear')[0]; - - const progressBarContainer = - fixture.debugElement.nativeElement.querySelector('.progress-linear__bar'); - const progressBarElem = progressBarContainer.querySelector('[class*=\'progress-linear__bar-progress\']'); + const linearBar = fixture.debugElement.nativeElement.querySelector(LINEAR_BAR_TAG); fixture.componentInstance.striped = true; fixture.detectChanges(); - expect(progressBarElem.classList.contains('progress-linear__bar-progress--default')).toBe(true); - expect(progressElem.classList.contains('progress-linear--striped')).toBe(true); + expect(linearBar.classList.contains(STRIPED_CLASS)).toEqual(true); fixture.componentInstance.type = 'success'; fixture.detectChanges(); - expect(progressBarElem.classList.contains('progress-linear__bar-progress--success')).toBe(true); - expect(progressElem.classList.contains('progress-linear--striped')).toBe(true); + expect(linearBar.classList.contains(SUCCESS_TYPE_CLASS)).toEqual(true); + expect(linearBar.classList.contains(STRIPED_CLASS)).toEqual(true); }); it('Manipulate progressbar with floating point numbers', fakeAsync(() => { @@ -413,8 +413,9 @@ describe('IgLinearBar', () => { fix.detectChanges(); const progressRepresentation = Common.calcPercentage(val, maxVal); - const getProgressIndicator = fix.debugElement.query(By.css(`[class*='progress-linear__bar-progress']`)); - expect(getProgressIndicator.styles.width).toBe(`${progressRepresentation}%`); + const progressbar = fix.debugElement.nativeElement.querySelector(LINEAR_BAR_TAG); + const progressIndicator = progressbar.querySelector('.igx-linear-bar__indicator'); + expect(progressIndicator.style.width).toBe(`${progressRepresentation}%`); })); it('Prevent constant update of progress value when value and max value differ', fakeAsync(() => { @@ -431,10 +432,23 @@ describe('IgLinearBar', () => { tick(tickTime + tickTime); // enough time to exceed the progress update. fix.detectChanges(); - const progressBarContainer = fix.debugElement.query(By.css('.progress-linear__bar')).nativeElement; + const progressBarContainer = fix.debugElement.nativeElement.querySelector(LINEAR_BAR_TAG); expect(parseFloat(progressBarContainer.attributes['aria-valuenow'].textContent)).toBe(value); expect(bar.value).toBe(value); })); + + it('When enable indeterminate mode, then the appropriate class should be applied.', () => { + const fix = TestBed.createComponent(LinearBarComponent); + fix.detectChanges(); + + const bar = fix.debugElement.nativeElement.querySelector(LINEAR_BAR_TAG); + expect(bar.classList.contains(INDETERMINATE_CLASS)).toEqual(false); + + fix.componentInstance.progressbar.indeterminate = true; + + fix.detectChanges(); + expect(bar.classList.contains(INDETERMINATE_CLASS)).toEqual(true); + }); }); }); @@ -451,7 +465,6 @@ class InitLinearProgressBarComponent {
` }) class LinearBarComponent { @ViewChild(IgxLinearProgressBarComponent) public progressbar: IgxLinearProgressBarComponent; - @ViewChild('wrapper') public wrapper; @ViewChild('linearBar') public linearBar; public value: string | number = 30; diff --git a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts index aa81ca79b8e..f38b617da3b 100644 --- a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts +++ b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts @@ -22,6 +22,13 @@ export enum IgxTextAlign { END = 'end' } +export enum IgxProgressType { + DANGER = 'danger', + INFO = 'info', + WARNING = 'warning', + SUCCESS = 'success' +} + export interface IChangeProgressEventArgs { previousValue: number; currentValue: number; @@ -180,102 +187,6 @@ let NEXT_CIRCULAR_ID = 0; templateUrl: 'templates/linear-bar.component.html' }) export class IgxLinearProgressBarComponent extends BaseProgress { - @HostBinding('attr.aria-valuemin') - private valueMin = 0; - - @HostBinding('class.igx-linear-bar') - public cssClass = 'igx-linear-bar'; - - /** - *Set `IgxLinearProgressBarComponent` to have striped style. By default it is set to false. - *```html - * - *``` - */ - @HostBinding('class.igx-linear-bar--striped') - @Input() - public striped = false; - - /** - *Set `IgxLinearProgressBarComponent` to have indeterminate. By default it is set to false. - *```html - * - *``` - */ - @HostBinding('class.igx-linear-bar--indeterminate') - @Input() - public indeterminate = false; - - /**An @Input property that sets the value of the `role` attribute. If not provided it will be automatically set to `progressbar`. - * ```html - * - * ``` - */ - @HostBinding('attr.role') - @Input() - public role = 'progressbar'; - - /**An @Input property that sets the value of `id` attribute. If not provided it will be automatically generated. - * ```html - * - * ``` - */ - @HostBinding('attr.id') - @Input() - public id = `igx-linear-bar-${NEXT_LINEAR_ID++}`; - - /** - *Set the position that defines where the text is aligned. - Possible options - `IgxTextAlign.START` (default), `IgxTextAlign.CENTER`, `IgxTextAlign.END`. - *```typescript - *public positionCenter: IgxTextAlign; - *public ngOnInit() { - * this.positionCenter = IgxTextAlign.CENTER; - *} - * //... - *``` - * ```html - * - *``` - */ - @Input() - public textAlign: IgxTextAlign = IgxTextAlign.START; - - /** - *Set the text to be visible. By default it is set to true. - * ```html - * - *``` - */ - @Input() - public textVisibility = true; - - /** - *Set the position that defines if the text should be aligned above the progress line. By default is set to false. - *```html - * - *``` - */ - @Input() - public textTop = false; - - /** - *Set a custom text that is displayed according to the defined position. - * ```html - * - *``` - */ - @Input() - public text: string; - - /** - *Set type of the `IgxLinearProgressBarComponent`. Possible options - `default`, `success`, `info`, `warning`, and `danger`. - *```html - * - *``` - */ - @Input() - public type = 'default'; /** *Animation on progress `IgxLinearProgressBarComponent`. By default it is set to true. @@ -408,6 +319,106 @@ export class IgxLinearProgressBarComponent extends BaseProgress { this.onProgressChanged.emit(changedValues); } + constructor() { + super(); + } + @HostBinding('attr.aria-valuemin') + public valueMin = 0; + + @HostBinding('class.igx-linear-bar') + public cssClass = 'igx-linear-bar'; + + /** + *Set `IgxLinearProgressBarComponent` to have striped style. By default it is set to false. + *```html + * + *``` + */ + @HostBinding('class.igx-linear-bar--striped') + @Input() + public striped = false; + + /** + *Set `IgxLinearProgressBarComponent` to have indeterminate. By default it is set to false. + *```html + * + *``` + */ + @HostBinding('class.igx-linear-bar--indeterminate') + @Input() + public indeterminate = false; + + /**An @Input property that sets the value of the `role` attribute. If not provided it will be automatically set to `progressbar`. + * ```html + * + * ``` + */ + @HostBinding('attr.role') + @Input() + public role = 'progressbar'; + + /**An @Input property that sets the value of `id` attribute. If not provided it will be automatically generated. + * ```html + * + * ``` + */ + @HostBinding('attr.id') + @Input() + public id = `igx-linear-bar-${NEXT_LINEAR_ID++}`; + + /** + *Set the position that defines where the text is aligned. + Possible options - `IgxTextAlign.START` (default), `IgxTextAlign.CENTER`, `IgxTextAlign.END`. + *```typescript + *public positionCenter: IgxTextAlign; + *public ngOnInit() { + * this.positionCenter = IgxTextAlign.CENTER; + *} + * //... + *``` + * ```html + * + *``` + */ + @Input() + public textAlign: IgxTextAlign = IgxTextAlign.START; + + /** + *Set the text to be visible. By default it is set to true. + * ```html + * + *``` + */ + @Input() + public textVisibility = true; + + /** + *Set the position that defines if the text should be aligned above the progress line. By default is set to false. + *```html + * + *``` + */ + @Input() + public textTop = false; + + /** + *Set a custom text that is displayed according to the defined position. + * ```html + * + *``` + */ + @Input() + public text: string; + + /** + *Set type of the `IgxLinearProgressBarComponent`. Possible options - `default`, `success`, `info`, `warning`, and `danger`. + *```html + * + *``` + */ + @Input() + public type = 'default'; + /** *An event, which is triggered after a progress is changed. *```typescript @@ -422,8 +433,36 @@ export class IgxLinearProgressBarComponent extends BaseProgress { */ @Output() public onProgressChanged = new EventEmitter(); - constructor() { - super(); + /** + * @hidden + */ + @HostBinding('class.igx-linear-bar--danger') + public get danger() { + return this.type === IgxProgressType.DANGER; + } + + /** + * @hidden + */ + @HostBinding('class.igx-linear-bar--info') + public get info() { + return this.type === IgxProgressType.INFO; + } + + /** + * @hidden + */ + @HostBinding('class.igx-linear-bar--warning') + public get warning() { + return this.type === IgxProgressType.WARNING; + } + + /** + * @hidden + */ + @HostBinding('class.igx-linear-bar--success') + public get success() { + return this.type === IgxProgressType.SUCCESS; } } From 0bcf8bb413334b830b49784efc6b8abfd2fe657e Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 13 Dec 2018 10:53:54 +0200 Subject: [PATCH 4/9] fix(progress): fix progress bars to work in IE11 --- .../components/progress/_progress-theme.scss | 15 ++++++++++---- .../lib/progressbar/progressbar.component.ts | 4 ++++ .../templates/circular-bar.component.html | 10 ++++++++-- src/app/progressbar/progressbar.sample.css | 12 ++++++----- src/app/progressbar/progressbar.sample.html | 20 +++++++++---------- 5 files changed, 40 insertions(+), 21 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss index f72d0e48661..2b669c0743c 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/progress/_progress-theme.scss @@ -76,9 +76,8 @@ %linear-display { position: relative; display: flex; - align-items: center; - flex-flow: column nowrap; width: 100%; + flex: 1 1 100%; } %linear-bar { @@ -229,12 +228,20 @@ $circular-value-fw: 600; %circular-display { - width: 100%; - height: 100%; + display: inline-flex; + flex: 1 1 auto; + + svg { + width: 100%; + height: 100%; + min-width: 24px; + min-height: 24px; + } } %circular-display--indeterminate { @include animation(rotate-center 1.4s linear infinite); + transform-origin: 50% 50%; } %circular-inner { diff --git a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts index f38b617da3b..47768a94309 100644 --- a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts +++ b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts @@ -475,6 +475,10 @@ export class IgxCircularProgressBarComponent extends BaseProgress { private readonly STROKE_OPACITY_DVIDER = 100; private readonly STROKE_OPACITY_ADDITION = .2; + /** @hidden */ + @HostBinding('class.igx-circular-bar') + public cssClass = 'igx-circular-bar'; + /** *An event, which is triggered after a progress is changed. *```typescript diff --git a/projects/igniteui-angular/src/lib/progressbar/templates/circular-bar.component.html b/projects/igniteui-angular/src/lib/progressbar/templates/circular-bar.component.html index fb55d899ec2..ae9b8f5208d 100644 --- a/projects/igniteui-angular/src/lib/progressbar/templates/circular-bar.component.html +++ b/projects/igniteui-angular/src/lib/progressbar/templates/circular-bar.component.html @@ -1,5 +1,11 @@ - + diff --git a/src/app/progressbar/progressbar.sample.css b/src/app/progressbar/progressbar.sample.css index 73d5c7c6359..158fc149e17 100644 --- a/src/app/progressbar/progressbar.sample.css +++ b/src/app/progressbar/progressbar.sample.css @@ -5,15 +5,17 @@ .circular-container { display: flex; - width: 84px; - height: 84px; - padding: 16px; + margin: 16px; } -.linear-container + .linear-container{ - padding-top: 16px; +.circular-sample { + width: 54px; + height: 54px; } +.linear-container+.linear-container { + padding-top: 16px; +} .button-container { position: fixed; diff --git a/src/app/progressbar/progressbar.sample.html b/src/app/progressbar/progressbar.sample.html index b6da600483b..d24d60f4405 100644 --- a/src/app/progressbar/progressbar.sample.html +++ b/src/app/progressbar/progressbar.sample.html @@ -68,32 +68,32 @@

Striped linear progress bar

Circular progress indicator

- +
- +
- +
- +
- +
- +
- +
- + Value is: {{process.value}} @@ -101,10 +101,10 @@

Circular progress indicator

- +
- +
From 48ef0590c3d0653ed1ecd2fe1be73ed1ad34e751 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 13 Dec 2018 11:43:10 +0200 Subject: [PATCH 5/9] chore(changelog, readme): update to reflect the new indeterminate property --- CHANGELOG.md | 3 +++ projects/igniteui-angular/src/lib/progressbar/README.md | 2 ++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5957a8528fe..bab34bcb93d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Ignite UI for Angular Change Log All notable changes for each version of this project will be documented in this file. +## 7.1.1 +- **Progress Indicators**: + - `igx-circular-bar` and `igx-linear-bar` now feature an indeterminate input property. When this property is set to true the indicator will be continually growing and shrinking along the track. ## 7.1.0 ### Features diff --git a/projects/igniteui-angular/src/lib/progressbar/README.md b/projects/igniteui-angular/src/lib/progressbar/README.md index ff4ba52ae08..5b4f153d056 100644 --- a/projects/igniteui-angular/src/lib/progressbar/README.md +++ b/projects/igniteui-angular/src/lib/progressbar/README.md @@ -43,6 +43,7 @@ export class AppModule {} | `textVisibility` | boolean | Set the text to be visible. By default is set to `true`. | | `textTop` | boolean | Set the position that defene is text to be aligned above the progress line. By default is set to `false`. | | `text` | string | Set a custom text that is displayed according defined position. | +| `indeterminate` | boolean | Display the indicator continually growing and shrinking along the track. | ## igx-circular-bar | Name | Type | Description | |:----------|:-------------:|:------| @@ -51,6 +52,7 @@ export class AppModule {} | `value` | number | Set value that indicates the completed bar position. | | `animate` | boolean | animation on progress bar. | | `textVisibility` | boolean | Set the text to be visible. By default is set to `true`. | +| `indeterminate` | boolean | Display the indicator continually growing and shrinking along the track. | ## Common | Name | Description | |:----------|:------| From 153afe480812f20a70ce3f079b7d3adfd059cdcc Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 13 Dec 2018 11:51:10 +0200 Subject: [PATCH 6/9] refactor(progressbar): update circular progress when not in indeterminate --- .../lib/progressbar/progressbar.component.ts | 28 ++++++++++--------- src/app/progressbar/progressbar.sample.html | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts index 47768a94309..da9c584d9a5 100644 --- a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts +++ b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts @@ -697,19 +697,21 @@ export class IgxCircularProgressBarComponent extends BaseProgress { */ public updateProgressSmoothly(val: number, step: number) { // Set frames for the animation - const FRAMES = [{ - strokeDashoffset: this.getProgress(this._value), - strokeOpacity: (this._value / this.STROKE_OPACITY_DVIDER) + this.STROKE_OPACITY_ADDITION - }, { - strokeDashoffset: this.getProgress(this.valueInPercent), - strokeOpacity: (this.valueInPercent / this.STROKE_OPACITY_DVIDER) + this.STROKE_OPACITY_ADDITION - }]; - this._svgCircle.nativeElement.animate(FRAMES, { - easing: 'ease-out', - fill: 'forwards' - }); - - super.updateProgressSmoothly(val, step); + if (!this.indeterminate) { + const FRAMES = [{ + strokeDashoffset: this.getProgress(this._value), + strokeOpacity: (this._value / this.STROKE_OPACITY_DVIDER) + this.STROKE_OPACITY_ADDITION + }, { + strokeDashoffset: this.getProgress(this.valueInPercent), + strokeOpacity: (this.valueInPercent / this.STROKE_OPACITY_DVIDER) + this.STROKE_OPACITY_ADDITION + }]; + this._svgCircle.nativeElement.animate(FRAMES, { + easing: 'ease-out', + fill: 'forwards' + }); + + super.updateProgressSmoothly(val, step); + } } /** diff --git a/src/app/progressbar/progressbar.sample.html b/src/app/progressbar/progressbar.sample.html index d24d60f4405..290cf992cb0 100644 --- a/src/app/progressbar/progressbar.sample.html +++ b/src/app/progressbar/progressbar.sample.html @@ -68,7 +68,7 @@

Striped linear progress bar

Circular progress indicator

- +
From 6a8927714b4e2fbf573a83e95ed660ede6e3fa72 Mon Sep 17 00:00:00 2001 From: Aleksandar Kamenov Date: Thu, 13 Dec 2018 14:01:07 +0200 Subject: [PATCH 7/9] test(progressbar): fix circularbar tests Closes #1997 #1986 --- .../src/lib/progressbar/circularbar.component.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts b/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts index bb93ed03cdb..03d6af9e7cb 100644 --- a/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts @@ -315,7 +315,7 @@ describe('IgCircularBar', () => { const componentInstance = fixture.componentInstance; const progressBarElem = fixture.debugElement.nativeElement - .querySelector('.igx-circular-bar'); + .querySelector('.igx-circular-bar').firstChild; fixture.detectChanges(); expect(progressBarElem.attributes['aria-valuenow'].textContent).toBe('20'); @@ -339,7 +339,7 @@ describe('IgCircularBar', () => { const componentInstance = fixture.componentInstance; const progressBarElem = fixture.debugElement.nativeElement - .querySelector('.igx-circular-bar'); + .querySelector('.igx-circular-bar').firstChild; let expectedTextContent = componentInstance.circularBar.value + '%'; tick(tickTime); @@ -371,7 +371,7 @@ describe('IgCircularBar', () => { const componentInstance = fixture.componentInstance; const progressBarElem = fixture.debugElement.nativeElement - .querySelector('.igx-circular-bar'); + .querySelector('.igx-circular-bar').firstChild; tick(tickTime); fixture.detectChanges(); @@ -419,7 +419,7 @@ describe('IgCircularBar', () => { tick(tickTime + tickTime); // enough time to exceed the progress update. fix.detectChanges(); - const progressBarContainer = fix.debugElement.query(By.css('.igx-circular-bar')).nativeElement; + const progressBarContainer = fix.debugElement.query(By.css('.igx-circular-bar')).nativeElement.firstChild; expect(parseFloat(progressBarContainer.attributes['aria-valuenow'].textContent)).toBe(value); expect(bar.value).toBe(value); })); From 551f4fdb8b4a1223a7a849fe48da73ef41820c56 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 13 Dec 2018 14:03:31 +0200 Subject: [PATCH 8/9] test(progress): fix failing tests after binding test to host --- .../progressbar/circularbar.component.spec.ts | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts b/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts index bb93ed03cdb..04279396efa 100644 --- a/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts @@ -32,7 +32,7 @@ describe('IgCircularBar', () => { IgxProgressBarModule ] }) - .compileComponents(); + .compileComponents(); })); it('Initialize circularProgressbar with default values', () => { @@ -41,12 +41,9 @@ describe('IgCircularBar', () => { fixture.detectChanges(); const progress = fixture.componentInstance.circularBar; - const domProgress = fixture.debugElement.query(By.css('igx-circular-bar')).nativeElement; - const value = 0; const defaultMaxValue = 100; expect(progress.id).toContain('igx-circular-bar-'); - expect(domProgress.id).toContain('igx-circular-bar-'); expect(progress.max).toBe(defaultMaxValue); expect(progress.value).toBe(0); }); @@ -314,8 +311,8 @@ describe('IgCircularBar', () => { fixture.detectChanges(); const componentInstance = fixture.componentInstance; - const progressBarElem = fixture.debugElement.nativeElement - .querySelector('.igx-circular-bar'); + const progressBarElem = fixture.debugElement.query(By.css('svg')).nativeElement; + fixture.detectChanges(); expect(progressBarElem.attributes['aria-valuenow'].textContent).toBe('20'); @@ -338,8 +335,7 @@ describe('IgCircularBar', () => { fixture.detectChanges(); const componentInstance = fixture.componentInstance; - const progressBarElem = fixture.debugElement.nativeElement - .querySelector('.igx-circular-bar'); + const progressBarElem = fixture.debugElement.query(By.css('svg')).nativeElement; let expectedTextContent = componentInstance.circularBar.value + '%'; tick(tickTime); @@ -370,8 +366,7 @@ describe('IgCircularBar', () => { fixture.detectChanges(); const componentInstance = fixture.componentInstance; - const progressBarElem = fixture.debugElement.nativeElement - .querySelector('.igx-circular-bar'); + const progressBarElem = fixture.debugElement.query(By.css('svg')).nativeElement; tick(tickTime); fixture.detectChanges(); @@ -400,7 +395,7 @@ describe('IgCircularBar', () => { fix.detectChanges(); const progressRepresentation = Common.calcPercentage(val, maxVal); - const progressBarElem = fix.debugElement.query(By.css('.igx-circular-bar')); + const progressBarElem = fix.debugElement.query(By.css('svg')); const valueInPercent = progressBarElem.query(By.css(`.${CIRCULAR_TEXT_CLASS}`)).nativeElement; expect(valueInPercent.textContent.trim()).toBe(`${progressRepresentation}%`); })); @@ -414,12 +409,12 @@ describe('IgCircularBar', () => { const value = 2.55; bar.step = 0.634; bar.max = maxVal; - bar.value = value; + bar.value = value; tick(tickTime + tickTime); // enough time to exceed the progress update. fix.detectChanges(); - const progressBarContainer = fix.debugElement.query(By.css('.igx-circular-bar')).nativeElement; + const progressBarContainer = fix.debugElement.query(By.css('svg')).nativeElement; expect(parseFloat(progressBarContainer.attributes['aria-valuenow'].textContent)).toBe(value); expect(bar.value).toBe(value); })); From 88aece76d8d6e254738ec8901573e3ff989a0955 Mon Sep 17 00:00:00 2001 From: Aleksandar Kamenov Date: Thu, 13 Dec 2018 16:18:46 +0200 Subject: [PATCH 9/9] fix(progressbar): prevent value update when indeterminate mode is on Closes #1997 #1986 --- .../progressbar/circularbar.component.spec.ts | 20 +++ .../progressbar/linearbar.component.spec.ts | 20 +++ .../lib/progressbar/progressbar.component.ts | 128 +++++++++--------- 3 files changed, 104 insertions(+), 64 deletions(-) diff --git a/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts b/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts index 04279396efa..ca6bd20a09f 100644 --- a/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/progressbar/circularbar.component.spec.ts @@ -327,6 +327,26 @@ describe('IgCircularBar', () => { expect(progressBarElem.children[2].classList.value).toMatch(CIRCULAR_HIDDEN_TEXT_CLASS); }); + it('When indeterminate mode is on value should not be updated', () => { + const fix = TestBed.createComponent(InitCircularProgressBarComponent); + fix.detectChanges(); + + const progressbar = fix.componentInstance.circularBar; + expect(progressbar.value).toEqual(0); + + progressbar.indeterminate = true; + progressbar.value = 20; + fix.detectChanges(); + + expect(progressbar.value).toEqual(0); + + progressbar.animate = false; + progressbar.value = 30; + fix.detectChanges(); + + expect(progressbar.value).toEqual(0); + }); + // UI TESTS describe('Circular bar UI TESTS', () => { configureTestSuite(); diff --git a/projects/igniteui-angular/src/lib/progressbar/linearbar.component.spec.ts b/projects/igniteui-angular/src/lib/progressbar/linearbar.component.spec.ts index 910e51d8174..26a36eacc35 100644 --- a/projects/igniteui-angular/src/lib/progressbar/linearbar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/progressbar/linearbar.component.spec.ts @@ -333,6 +333,26 @@ describe('IgLinearBar', () => { expect(bar.valueInPercent).toBe(valueInPercent); })); + it('When indeterminate mode is on value should not be updated', () => { + const fix = TestBed.createComponent(InitLinearProgressBarComponent); + fix.detectChanges(); + + const progressbar = fix.componentInstance.linearBar; + expect(progressbar.value).toEqual(0); + + progressbar.indeterminate = true; + progressbar.value = 30; + fix.detectChanges(); + + expect(progressbar.value).toEqual(0); + + progressbar.animate = false; + progressbar.value = 20; + fix.detectChanges(); + + expect(progressbar.value).toEqual(0); + }); + // UI Tests describe('UI tests linear bar', () => { configureTestSuite(); diff --git a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts index da9c584d9a5..bc02e2f8137 100644 --- a/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts +++ b/projects/igniteui-angular/src/lib/progressbar/progressbar.component.ts @@ -271,57 +271,10 @@ export class IgxLinearProgressBarComponent extends BaseProgress { this._step = Number(val); } - /** - *Returns value that indicates the current `IgxLinearProgressBarComponent` position. - *```typescript - *@ViewChild("MyProgressBar") - *public progressBar: IgxLinearProgressBarComponent; - *public getValue(event) { - * let value = this.progressBar.value; - * alert(value); - *} - *``` - */ - @HostBinding('attr.aria-valuenow') - @Input() - get value(): number { - return this._value; - } - - /** - *Set value that indicates the current `IgxLinearProgressBarComponent` position. - *```html - * - *``` - */ - set value(val) { - val = Number(val); - if (this._value === val) { - return; - } - - const valueInRange = getValueInProperRange(val, this.max); - if (isNaN(valueInRange)) { - return; - } - const changedValues = { - currentValue: valueInRange, - previousValue: this._value - }; - - const updateValue = super.directionFlow(this._value, val, this.step); - if (this._animate && val >= this.step) { - super.runAnimation(valueInRange, updateValue); - } else { - super.updateProgressDirectly(valueInRange); - } - - this.onProgressChanged.emit(changedValues); - } - constructor() { super(); } + @HostBinding('attr.aria-valuemin') public valueMin = 0; @@ -416,9 +369,58 @@ export class IgxLinearProgressBarComponent extends BaseProgress { * *``` */ + @Input() public type = 'default'; + /** + *Returns value that indicates the current `IgxLinearProgressBarComponent` position. + *```typescript + *@ViewChild("MyProgressBar") + *public progressBar: IgxLinearProgressBarComponent; + *public getValue(event) { + * let value = this.progressBar.value; + * alert(value); + *} + *``` + */ + @HostBinding('attr.aria-valuenow') + @Input() + get value(): number { + return this._value; + } + + /** + *Set value that indicates the current `IgxLinearProgressBarComponent` position. + *```html + * + *``` + */ + set value(val) { + val = Number(val); + if (this._value === val || this.indeterminate) { + return; + } + + const valueInRange = getValueInProperRange(val, this.max); + if (isNaN(valueInRange)) { + return; + } + const changedValues = { + currentValue: valueInRange, + previousValue: this._value + }; + + const updateValue = super.directionFlow(this._value, val, this.step); + if (this._animate && val >= this.step) { + super.runAnimation(valueInRange, updateValue); + } else { + super.updateProgressDirectly(valueInRange); + } + + this.onProgressChanged.emit(changedValues); + } + /** *An event, which is triggered after a progress is changed. *```typescript @@ -659,7 +661,7 @@ export class IgxCircularProgressBarComponent extends BaseProgress { */ set value(val: number) { val = Number(val); - if (this._value === val) { + if (this._value === val || this.indeterminate) { return; } @@ -697,21 +699,19 @@ export class IgxCircularProgressBarComponent extends BaseProgress { */ public updateProgressSmoothly(val: number, step: number) { // Set frames for the animation - if (!this.indeterminate) { - const FRAMES = [{ - strokeDashoffset: this.getProgress(this._value), - strokeOpacity: (this._value / this.STROKE_OPACITY_DVIDER) + this.STROKE_OPACITY_ADDITION - }, { - strokeDashoffset: this.getProgress(this.valueInPercent), - strokeOpacity: (this.valueInPercent / this.STROKE_OPACITY_DVIDER) + this.STROKE_OPACITY_ADDITION - }]; - this._svgCircle.nativeElement.animate(FRAMES, { - easing: 'ease-out', - fill: 'forwards' - }); - - super.updateProgressSmoothly(val, step); - } + const FRAMES = [{ + strokeDashoffset: this.getProgress(this._value), + strokeOpacity: (this._value / this.STROKE_OPACITY_DVIDER) + this.STROKE_OPACITY_ADDITION + }, { + strokeDashoffset: this.getProgress(this.valueInPercent), + strokeOpacity: (this.valueInPercent / this.STROKE_OPACITY_DVIDER) + this.STROKE_OPACITY_ADDITION + }]; + this._svgCircle.nativeElement.animate(FRAMES, { + easing: 'ease-out', + fill: 'forwards' + }); + + super.updateProgressSmoothly(val, step); } /**