From 5cb8badde09e1f0426f28525215f60e6c9f6ae0e Mon Sep 17 00:00:00 2001
From: Justin DuJardin
Date: Sun, 27 Dec 2015 10:58:54 -0800
Subject: [PATCH] feat(progress_linear): support buffer and query indicators
and add tests
---
examples/app.scss | 2 +-
.../progress_linear/basic_usage.html | 27 +--
.../progress_linear/basic_usage.scss | 50 ++++++
.../components/progress_linear/basic_usage.ts | 47 +-----
.../progress_linear/progress_linear.scss | 55 +++---
.../progress_linear/progress_linear.ts | 17 +-
ng2-material/core/style/default-theme.scss | 2 +-
.../progress_linear/progress_linear_spec.ts | 157 ++++++++++++++++++
8 files changed, 265 insertions(+), 92 deletions(-)
create mode 100644 examples/components/progress_linear/basic_usage.scss
create mode 100644 test/components/progress_linear/progress_linear_spec.ts
diff --git a/examples/app.scss b/examples/app.scss
index ff7f3c4f..694a9ac4 100644
--- a/examples/app.scss
+++ b/examples/app.scss
@@ -6,8 +6,8 @@ $md-font-url: '../public/font/';
demos-app {
md-content {
+ max-width: 800px;
> section {
- max-width: 800px;
> h1 {
margin-top: rem(6);
margin-bottom: rem(6);
diff --git a/examples/components/progress_linear/basic_usage.html b/examples/components/progress_linear/basic_usage.html
index b876c399..fba86fb1 100644
--- a/examples/components/progress_linear/basic_usage.html
+++ b/examples/components/progress_linear/basic_usage.html
@@ -24,8 +24,8 @@ Buffer
For operations where the user wants to indicate some activity or loading from the server,
use the buffer indicator:
-
+
Query
@@ -34,30 +34,17 @@ Query
use the query indicator:
-
-
+
+
Loading application libraries...
-
-
-
-
-
Query and Buffer progress linear indicators:
-
-
- {{ activated ? 'On' : 'Off' }}
-
-
+
- Note: With the above switch -- which simply clears the mode in each <md-progress-linear
- md-mode="">
element --
- developers now easily disable the animations and hide their progress indicators.
+ Hide indicators by adding a
hidden
attribute, or by binding to a dynamic value
[hidden]="yourValue"
+
diff --git a/examples/components/progress_linear/basic_usage.scss b/examples/components/progress_linear/basic_usage.scss
new file mode 100644
index 00000000..9ca42d2e
--- /dev/null
+++ b/examples/components/progress_linear/basic_usage.scss
@@ -0,0 +1,50 @@
+@import "../../../ng2-material/core/style/variables";
+@import "../../../ng2-material/core/style/theme-functions";
+@import "../../../ng2-material/core/style/default-theme";
+
+body {
+ padding: 20px;
+}
+
+h4 {
+ margin: 10px 0;
+}
+
+md-progress-linear:not([mode=query]) {
+ padding-top: 10px;
+ margin-bottom: 20px;
+}
+
+p.small > code {
+ font-size: 0.8em;
+}
+
+.visible {
+ opacity: 0;
+ border: 2px solid white !important;
+}
+
+.container {
+ display: block;
+ position: relative;
+ height: 100%;
+ width: 100%;
+ border: 2px solid md-color($md-primary, 100);
+ transition: opacity 0.1s linear;
+ border-top: 0px;
+}
+
+.bottom-block {
+ display: block;
+ position: relative;
+ background-color: rgba(255, 235, 169, 0.25);
+ height: 85px;
+ width: 100%;
+}
+
+.bottom-block > span {
+ display: inline-block;
+ margin-top: 10px;
+ padding: 25px;
+ font-size: 0.9em;
+}
diff --git a/examples/components/progress_linear/basic_usage.ts b/examples/components/progress_linear/basic_usage.ts
index c0f2a4e9..9ce93539 100644
--- a/examples/components/progress_linear/basic_usage.ts
+++ b/examples/components/progress_linear/basic_usage.ts
@@ -2,17 +2,15 @@ import {View, Component} from 'angular2/core';
import {MATERIAL_DIRECTIVES} from 'ng2-material/all';
@Component({selector: 'progress-linear-basic-usage'})
-@View({templateUrl: 'examples/components/progress_linear/basic_usage.html', directives: [MATERIAL_DIRECTIVES]})
+@View({
+ templateUrl: 'examples/components/progress_linear/basic_usage.html',
+ styleUrls: ['examples/components/progress_linear/basic_usage.css'],
+ directives: [MATERIAL_DIRECTIVES]
+})
export default class ProgressLinearBasicUsage {
- public modes: string[] = [];
- public mode: string = 'query';
- public activated: boolean = true;
public determinateValue: number = 30;
public determinateValue2: number = 30;
- private _counter: number = 0;
- private _j: number = 0;
-
constructor() {
// Iterate every 100ms, non-stop
@@ -26,42 +24,7 @@ export default class ProgressLinearBasicUsage {
if (this.determinateValue2 > 100) {
this.determinateValue2 = 30;
}
-
- // Incrementally start animation the five (5) Indeterminate,
- // themed progress circular bars
-
- if ((this._j < 2) && !this.modes[this._j] && this.activated) {
- this.modes[this._j] = (this._j === 0) ? 'buffer' : 'query';
- }
- if (this._counter++ % 4 === 0) {
- this._j++;
- }
-
- // Show the indicator in the "Used within Containers" after 200ms delay
- if (this._j === 2) {
- this.mode = 'indeterminate';
- }
}, 100, 0, true);
-
- setInterval(() => {
- this.mode = (this.mode === 'query' ? 'determinate' : 'query');
- }, 7200, 0, true);
-
}
- /**
- * Turn off or on the 5 themed loaders
- */
- toggleActivation() {
- if (!this.activated) {
- this.modes = [null,null,null,null,null];
- }
- if (this.activated) {
- this._j = this._counter = 0;
- this.determinateValue = 30;
- this.determinateValue2 = 30;
- }
- this.activated = !this.activated;
- };
-
}
diff --git a/ng2-material/components/progress_linear/progress_linear.scss b/ng2-material/components/progress_linear/progress_linear.scss
index df109154..2ea5b1c1 100644
--- a/ng2-material/components/progress_linear/progress_linear.scss
+++ b/ng2-material/components/progress_linear/progress_linear.scss
@@ -1,5 +1,4 @@
@import "../../core/style/variables";
-
// TODO(jelbourn): This goes away.
@import "../../core/style/default-theme";
@@ -10,6 +9,10 @@ md-progress-linear {
width: 100%;
height: $progress-linear-bar-height;
+ &[hidden] {
+ display: none;
+ }
+
*, *:before {
box-sizing: border-box;
}
@@ -18,7 +21,7 @@ md-progress-linear {
overflow: hidden;
position: relative;
height: $progress-linear-bar-height;
- top: $progress-linear-bar-height;
+ //top: $progress-linear-bar-height;
transform: translate(0, 5px) scale(1, 0);
transition: all .3s linear;
}
@@ -37,13 +40,13 @@ md-progress-linear {
transition: all 0.2s linear;
}
- &[mode="determinate"] {
+ &[mode=determinate] {
.md-progress-linear-bar1 {
display: none;
}
}
- &[mode="indeterminate"] {
+ &[mode=indeterminate] {
.md-progress-linear-bar1 {
animation: indeterminate1 4s infinite linear;
}
@@ -53,7 +56,7 @@ md-progress-linear {
}
}
- &[mode="buffer"] {
+ &[mode=buffer] {
.md-progress-linear-container {
background-color: transparent !important;
}
@@ -72,7 +75,10 @@ md-progress-linear {
}
}
- &[mode="query"] {
+ &[mode=query] {
+ .md-progress-linear-bar1 {
+ display: none;
+ }
.md-progress-linear-bar2 {
animation: query .8s infinite cubic-bezier(0.390, 0.575, 0.565, 1.000);
}
@@ -152,7 +158,7 @@ md-progress-linear {
0% {
transform: translateX(-50%) scale(0, 1);
}
- 25.99%{
+ 25.99% {
transform: translateX(-50%) scale(0, 1);
}
28% {
@@ -209,35 +215,42 @@ md-progress-linear {
}
}
-
// THEME
md-progress-linear {
.md-progress-linear-container {
background-color: md-color($md-primary, 100);
}
-
.md-progress-linear-bar {
background-color: md-color($md-primary);
}
- &.md-warn .md-progress-linear-container {
- background-color: md-color($md-warn, 100);
- }
-
- &.md-warn .md-progress-linear-bar {
- background-color: md-color($md-warn);
- }
-
- &.md-accent .md-progress-linear-container {
- background-color: md-color($md-accent, 100);
+ &.md-warn {
+ .md-progress-linear-container {
+ background-color: md-color($md-warn, 100);
+ }
+ .md-progress-linear-bar {
+ background-color: md-color($md-warn);
+ }
}
- &.md-accent .md-progress-linear-bar {
- background-color: md-color($md-accent);
+ &.md-accent {
+ .md-progress-linear-container {
+ background-color: md-color($md-accent, 100);
+ }
+ .md-progress-linear-bar {
+ background-color: md-color($md-accent);
+ }
}
&[mode=buffer] {
+ background-color: transparent !important;
+ transition: all 0.2s linear;
+ .md-progress-linear-display:before {
+ display: block;
+ animation: buffer 3s infinite linear;
+ }
+
&.md-primary {
.md-progress-linear-bar1 {
background-color: md-color($md-primary, 100);
diff --git a/ng2-material/components/progress_linear/progress_linear.ts b/ng2-material/components/progress_linear/progress_linear.ts
index 5162607d..4a4a5baf 100644
--- a/ng2-material/components/progress_linear/progress_linear.ts
+++ b/ng2-material/components/progress_linear/progress_linear.ts
@@ -6,7 +6,7 @@ import {Input} from 'angular2/core';
/** Different display / behavior modes for progress_linear. */
@CONST()
-class ProgressMode {
+export class ProgressMode {
@CONST() static DETERMINATE = 'determinate';
@CONST() static INDETERMINATE = 'indeterminate';
@CONST() static BUFFER = 'buffer';
@@ -15,12 +15,13 @@ class ProgressMode {
@Component({
selector: 'md-progress-linear',
- inputs: ['value', 'bufferValue'],
+ inputs: ['value', 'bufferValue', 'mode'],
host: {
'role': 'progressbar',
'aria-valuemin': '0',
'aria-valuemax': '100',
- '[attr.aria-valuenow]': 'value'
+ '[attr.aria-valuenow]': 'value',
+ '[attr.mode]': 'mode'
}
})
@View({
@@ -76,15 +77,17 @@ export class MdProgressLinear implements OnChanges {
ngOnChanges(_) {
// If the mode does not use a value, or if there is no value, do nothing.
- if (this.mode === ProgressMode.QUERY || this.mode === ProgressMode.INDETERMINATE ||
- isBlank(this.value)) {
+ if (this.mode === ProgressMode.QUERY || this.mode === ProgressMode.INDETERMINATE) {
return;
}
- this.primaryBarTransform = this.transformForValue(this.value);
+ if (!isBlank(this.value)) {
+ this.primaryBarTransform = this.transformForValue(this.value);
+ }
+
// The bufferValue is only used in buffer mode.
- if (this.mode === ProgressMode.BUFFER) {
+ if (this.mode === ProgressMode.BUFFER && !isBlank(this.bufferValue)) {
this.secondaryBarTransform = this.transformForValue(this.bufferValue);
}
}
diff --git a/ng2-material/core/style/default-theme.scss b/ng2-material/core/style/default-theme.scss
index 1e4009bb..77275c33 100644
--- a/ng2-material/core/style/default-theme.scss
+++ b/ng2-material/core/style/default-theme.scss
@@ -9,5 +9,5 @@ $md-is-dark-theme: false;
$md-primary: md-palette($md-indigo, 500, 100, 700, $md-contrast-palettes);
$md-accent: md-palette($md-pink, 500, 300, 700, $md-contrast-palettes);
$md-background: md-palette($md-grey, 500, 0, 600, $md-contrast-palettes);
-$md-warn: md-palette($md-red, 500, 300, 800, $md-contrast-palettes);
+$md-warn: md-palette($md-red, 500, 100, 700, $md-contrast-palettes);
$md-foreground: if($md-is-dark-theme, $md-dark-theme-foreground, $md-light-theme-foreground);
diff --git a/test/components/progress_linear/progress_linear_spec.ts b/test/components/progress_linear/progress_linear_spec.ts
new file mode 100644
index 00000000..71a6bd8c
--- /dev/null
+++ b/test/components/progress_linear/progress_linear_spec.ts
@@ -0,0 +1,157 @@
+import {
+ AsyncTestCompleter,
+ TestComponentBuilder,
+ beforeEach,
+ beforeEachProviders,
+ describe,
+ expect,
+ inject,
+ it,
+} from 'angular2/testing_internal';
+import {DebugElement} from 'angular2/src/core/debug/debug_element';
+import {Component, View, provide} from 'angular2/core';
+import {UrlResolver} from 'angular2/compiler';
+import {TestUrlResolver} from '../../test_url_resolver';
+import {MdTab, MdTabs} from '../../../ng2-material/components/tabs/tabs';
+import {MATERIAL_PROVIDERS} from '../../../ng2-material/all';
+import {ComponentFixture} from "angular2/testing";
+import {CORE_DIRECTIVES} from "angular2/common";
+import {findChildrenByAttribute,findChildrenByTag,findChildByTag} from "../../util";
+import {TimerWrapper} from "angular2/src/facade/async";
+import {Ink} from "../../../ng2-material/core/util/ink";
+import {MdProgressLinear, ProgressMode} from "../../../ng2-material/components/progress_linear/progress_linear";
+
+
+export function main() {
+
+ interface IProgressFixture {
+ fixture:ComponentFixture;
+ progress:MdProgressLinear;
+ debug:DebugElement;
+ }
+ @Component({selector: 'test-app'})
+ @View({
+ directives: [CORE_DIRECTIVES, MdProgressLinear],
+ template: ``
+ })
+ class TestComponent {
+ value: number = 25;
+ bufferValue: number = 50;
+ blankValue:number;
+ modeDeterminate:string = ProgressMode.DETERMINATE;
+ modeIndeterminate:string = ProgressMode.INDETERMINATE;
+ modeBuffer:string = ProgressMode.BUFFER;
+ modeQuery:string = ProgressMode.QUERY;
+ }
+
+ describe('Progress Linear', () => {
+ let builder: TestComponentBuilder;
+
+ function setup(template: string = null): Promise {
+ let prep = template === null ?
+ builder.createAsync(TestComponent) :
+ builder.overrideTemplate(TestComponent, template).createAsync(TestComponent);
+ return prep.then((fixture: ComponentFixture) => {
+ fixture.detectChanges();
+ let debug = findChildByTag(fixture.debugElement, 'md-progress-linear');
+ let component = debug.componentInstance;
+ return {
+ fixture: fixture,
+ progress: component,
+ debug: debug
+ };
+ }).catch(console.error.bind(console));
+ }
+
+ beforeEachProviders(() => [
+ MATERIAL_PROVIDERS,
+ provide(UrlResolver, {useValue: new TestUrlResolver()}),
+ ]);
+ beforeEach(inject([TestComponentBuilder], (tcb) => {
+ builder = tcb;
+ }));
+
+ describe('md-progress-linear', () => {
+
+ describe('value', () => {
+ it('should be blank until specified', inject([AsyncTestCompleter], (async) => {
+ setup(``).then((api: IProgressFixture) => {
+ expect(api.progress.value).toBeUndefined();
+ async.done();
+ });
+ }));
+ it('should set from binding', inject([AsyncTestCompleter], (async) => {
+ setup(``).then((api: IProgressFixture) => {
+ expect(api.progress.value).toBe(25);
+ async.done();
+ });
+ }));
+ it('should do nothing with undefined value', inject([AsyncTestCompleter], (async) => {
+ setup(``).then((api: IProgressFixture) => {
+ expect(api.progress.value).toBeUndefined();
+ async.done();
+ });
+ }));
+
+ });
+
+ describe('mode', () => {
+ it('should default to determinate', inject([AsyncTestCompleter], (async) => {
+ setup(``).then((api: IProgressFixture) => {
+ expect(api.progress.mode).toBe(ProgressMode.DETERMINATE);
+ async.done();
+ });
+ }));
+ it('should set from attribute', inject([AsyncTestCompleter], (async) => {
+ setup(``).then((api: IProgressFixture) => {
+ expect(api.progress.mode).toBe(ProgressMode.INDETERMINATE);
+ async.done();
+ });
+ }));
+ it('should set from binding', inject([AsyncTestCompleter], (async) => {
+ setup(``).then((api: IProgressFixture) => {
+ expect(api.progress.mode).toBe(ProgressMode.QUERY);
+ async.done();
+ });
+ }));
+
+ });
+
+ describe('bufferValue', () => {
+ it('should be blank until specified', inject([AsyncTestCompleter], (async) => {
+ setup(``).then((api: IProgressFixture) => {
+ expect(api.progress.bufferValue).toBeUndefined();
+ async.done();
+ });
+ }));
+ it('should set from binding', inject([AsyncTestCompleter], (async) => {
+ let template = `
+ `
+ setup(template).then((api: IProgressFixture) => {
+ expect(api.progress.bufferValue).toBe(50);
+ async.done();
+ });
+ }));
+ it('should do nothing with undefined value', inject([AsyncTestCompleter], (async) => {
+ let template = `
+ `;
+ setup(template).then((api: IProgressFixture) => {
+ expect(api.progress.bufferValue).toBeUndefined();
+ async.done();
+ });
+ }));
+
+ });
+
+
+ });
+ });
+
+
+}
+