Skip to content

Commit 314ee84

Browse files
author
Adam Plumer
committed
feat(progress-container): add progress-container component
* Add two new components: `mat-progress-container` and `mat-progress-content` for use with new directive `matProgress` * When triggered, the `matProgress` directive will emit an event that notifies the components which will, if triggered to show the progress container, add that template to the view and hide the progress content, and otherwise remove the template from the view and show the progress content
1 parent 0bd8899 commit 314ee84

34 files changed

+412
-7
lines changed

src/demo-app/demo-app/demo-app.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export class DemoApp {
7676
{name: 'Platform', route: '/platform'},
7777
{name: 'Portal', route: '/portal'},
7878
{name: 'Progress Bar', route: '/progress-bar'},
79+
{name: 'Progress Container', route: '/progress-container'},
7980
{name: 'Progress Spinner', route: '/progress-spinner'},
8081
{name: 'Radio', route: '/radio'},
8182
{name: 'Ripple', route: '/ripple'},

src/demo-app/demo-app/demo-module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import {VirtualScrollDemo} from '../virtual-scroll/virtual-scroll-demo';
6464
import {DemoApp, Home} from './demo-app';
6565
import {DEMO_APP_ROUTES} from './routes';
6666
import {DragAndDropDemo} from '../drag-drop/drag-drop-demo';
67+
import {ProgressContainerDemo} from '../progress-container/progress-container-demo';
6768

6869
@NgModule({
6970
imports: [
@@ -116,6 +117,7 @@ import {DragAndDropDemo} from '../drag-drop/drag-drop-demo';
116117
PlatformDemo,
117118
PortalDemo,
118119
ProgressBarDemo,
120+
ProgressContainerDemo,
119121
ProgressSpinnerDemo,
120122
RadioDemo,
121123
RippleDemo,

src/demo-app/demo-app/routes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import {PaginatorDemo} from '../paginator/paginator-demo';
5656
import {ExamplesPage} from '../examples-page/examples-page';
5757
import {TableDemo} from '../table/table-demo';
5858
import {DragAndDropDemo} from '../drag-drop/drag-drop-demo';
59+
import {ProgressContainerDemo} from '../progress-container/progress-container-demo';
5960

6061
export const DEMO_APP_ROUTES: Routes = [
6162
{path: '', component: DemoApp, children: [
@@ -86,6 +87,7 @@ export const DEMO_APP_ROUTES: Routes = [
8687
{path: 'platform', component: PlatformDemo},
8788
{path: 'portal', component: PortalDemo},
8889
{path: 'progress-bar', component: ProgressBarDemo},
90+
{path: 'progress-container', component: ProgressContainerDemo},
8991
{path: 'progress-spinner', component: ProgressSpinnerDemo},
9092
{path: 'radio', component: RadioDemo},
9193
{path: 'ripple', component: RippleDemo},

src/demo-app/demo-material-module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import {
4343
MatNativeDateModule,
4444
MatPaginatorModule,
4545
MatProgressBarModule,
46+
MatProgressContainerModule,
4647
MatProgressSpinnerModule,
4748
MatRadioModule,
4849
MatRippleModule,
@@ -87,6 +88,7 @@ import {
8788
MatMenuModule,
8889
MatPaginatorModule,
8990
MatProgressBarModule,
91+
MatProgressContainerModule,
9092
MatProgressSpinnerModule,
9193
MatRadioModule,
9294
MatRippleModule,
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<button mat-raised-button [matProgress]="trigger" (click)="trigger = !trigger">
2+
<mat-progress-container>
3+
<mat-spinner></mat-spinner>
4+
</mat-progress-container>
5+
<mat-progress-content>
6+
TOGGLE
7+
</mat-progress-content>
8+
</button>

src/demo-app/progress-container/progress-container-demo.scss

Whitespace-only changes.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {Component} from '@angular/core';
10+
11+
@Component({
12+
moduleId: module.id,
13+
selector: 'progress-container-demo',
14+
templateUrl: 'progress-container-demo.html',
15+
styleUrls: ['progress-container-demo.css'],
16+
})
17+
export class ProgressContainerDemo {
18+
trigger: boolean = false;
19+
}

src/demo-app/system-config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ System.config({
8585
'@angular/material/menu': 'dist/packages/material/menu/index.js',
8686
'@angular/material/paginator': 'dist/packages/material/paginator/index.js',
8787
'@angular/material/progress-bar': 'dist/packages/material/progress-bar/index.js',
88+
'@angular/material/progress-container': 'dist/packages/material/progress-container/index.js',
8889
'@angular/material/progress-spinner': 'dist/packages/material/progress-spinner/index.js',
8990
'@angular/material/radio': 'dist/packages/material/radio/index.js',
9091
'@angular/material/select': 'dist/packages/material/select/index.js',

src/e2e-app/e2e-app-module.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
MatMenuModule,
1818
MatNativeDateModule,
1919
MatProgressBarModule,
20+
MatProgressContainerModule,
2021
MatProgressSpinnerModule,
2122
MatRadioModule,
2223
MatSidenavModule,
@@ -45,6 +46,7 @@ import {SidenavE2E} from './sidenav/sidenav-e2e';
4546
import {SlideToggleE2E} from './slide-toggle/slide-toggle-e2e';
4647
import {BasicTabs} from './tabs/tabs-e2e';
4748
import {VirtualScrollE2E} from './virtual-scroll/virtual-scroll-e2e';
49+
import {ProgressContainerE2E} from './progress-container/progress-container-e2e';
4850

4951
/**
5052
* NgModule that contains all Material modules that are required to serve the e2e-app.
@@ -62,6 +64,7 @@ import {VirtualScrollE2E} from './virtual-scroll/virtual-scroll-e2e';
6264
MatListModule,
6365
MatMenuModule,
6466
MatProgressBarModule,
67+
MatProgressContainerModule,
6568
MatProgressSpinnerModule,
6669
MatRadioModule,
6770
MatSidenavModule,
@@ -97,6 +100,7 @@ export class E2eMaterialModule {}
97100
InputE2E,
98101
MenuE2E,
99102
ProgressBarE2E,
103+
ProgressContainerE2E,
100104
ProgressSpinnerE2E,
101105
SidenavE2E,
102106
SimpleCheckboxes,

src/e2e-app/e2e-app/routes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {SimpleCheckboxes} from '../checkbox/checkbox-e2e';
1010
import {DialogE2E} from '../dialog/dialog-e2e';
1111
import {GridListE2E} from '../grid-list/grid-list-e2e';
1212
import {ProgressBarE2E} from '../progress-bar/progress-bar-e2e';
13+
import {ProgressContainerE2E} from '../progress-container/progress-container-e2e';
1314
import {ProgressSpinnerE2E} from '../progress-spinner/progress-spinner-e2e';
1415
import {SlideToggleE2E} from '../slide-toggle/slide-toggle-e2e';
1516
import {InputE2E} from '../input/input-e2e';
@@ -38,6 +39,7 @@ export const E2E_APP_ROUTES: Routes = [
3839
{path: 'list', component: ListOverviewExample},
3940
{path: 'menu', component: MenuE2E},
4041
{path: 'progress-bar', component: ProgressBarE2E},
42+
{path: 'progress-container', component: ProgressContainerE2E},
4143
{path: 'progress-spinner', component: ProgressSpinnerE2E},
4244
{path: 'radio', component: SimpleRadioButtons},
4345
{path: 'sidenav', component: SidenavE2E},
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<button mat-raised-button [matProgress]="trigger" (click)="trigger = !trigger">
2+
<mat-progress-container>
3+
<mat-spinner></mat-spinner>
4+
</mat-progress-container>
5+
<mat-progress-content>
6+
TOGGLE
7+
</mat-progress-content>
8+
</button>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {Component} from '@angular/core';
2+
3+
@Component({
4+
moduleId: module.id,
5+
selector: 'progress-container-e2e',
6+
templateUrl: 'progress-container-e2e.html',
7+
})
8+
export class ProgressContainerE2E {
9+
trigger = true;
10+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package(default_visibility=["//visibility:public"])
2+
3+
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_library", "sass_binary")
4+
load("//tools:defaults.bzl", "ng_module")
5+
6+
ng_module(
7+
name = "progress-bar",
8+
srcs = glob(["**/*.ts"], exclude=["**/*.spec.ts"]),
9+
module_name = "@angular/material/progress-container",
10+
assets = [":progress-container.css"] + glob(["**/*.html"]),
11+
deps = [
12+
"@angular//packages/common",
13+
"@angular//packages/core",
14+
"@rxjs",
15+
"//src/lib/core",
16+
"//src/cdk/coercion"
17+
],
18+
)
19+
20+
21+
# TODO(jelbourn): replace this w/ sass_library when it supports acting like a filegroup
22+
filegroup(
23+
name = "progress_container_scss_partials",
24+
srcs = glob(["**/_*.scss"]),
25+
)
26+
27+
sass_binary(
28+
name = "progress_container_scss",
29+
src = "progress-container.scss",
30+
deps = ["//src/lib/core:core_scss_lib"],
31+
)
32+
33+
sass_library(
34+
name = "theme",
35+
srcs = glob(["**/*-theme.scss"]),
36+
)

src/lib/progress-container/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Please see the official documentation at https://material.angular.io/components/component/progress-container

src/lib/progress-container/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
export * from './public-api';
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {NgModule} from '@angular/core';
10+
import {CommonModule} from '@angular/common';
11+
import {MatCommonModule} from '@angular/material/core';
12+
import {MatProgressContainer} from './progress-container';
13+
import {MatProgress} from './progress-directive';
14+
import {MatProgressContent} from './progress-content';
15+
16+
17+
@NgModule({
18+
imports: [CommonModule, MatCommonModule],
19+
exports: [MatProgressContainer, MatProgress, MatProgressContent, MatCommonModule],
20+
declarations: [MatProgressContainer, MatProgress, MatProgressContent],
21+
})
22+
export class MatProgressContainerModule {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<ng-template>
2+
<div class="mat-progress-container">
3+
<ng-content></ng-content>
4+
</div>
5+
</ng-template>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
`<mat-progress-bar>` is a horizontal progress-bar for indicating progress and activity.
2+
3+
### Progress mode
4+
The progress-bar supports four modes: determinate, indeterminate, buffer and query.
5+
6+
#### Determinate
7+
Operations where the percentage of the operation complete is known should use the
8+
determinate indicator.
9+
10+
<!-- example(progress-bar-determinate) -->
11+
12+
This is the default mode and the progress is represented by the `value` property.
13+
14+
#### Indeterminate
15+
Operations where the user is asked to wait while something finishes and it’s
16+
not necessary to indicate how long it will take should use the indeterminate indicator.
17+
18+
<!-- example(progress-bar-indeterminate) -->
19+
20+
In this mode the `value` property is ignored.
21+
22+
#### Buffer
23+
Operations where the user wants to indicate some activity or loading from the server,
24+
use the buffer indicator.
25+
26+
<!-- example(progress-bar-buffer) -->
27+
28+
In "buffer" mode, `value` determines the progress of the primary bar while the `bufferValue` is
29+
used to show the additional buffering progress.
30+
31+
#### Query
32+
For situations where the user wants to indicate pre-loading (until the loading can actually be made),
33+
use the query indicator.
34+
35+
<!-- example(progress-bar-query) -->
36+
37+
In "query" mode, the progress-bar renders as an inverted "indeterminate" bar. Once the response
38+
progress is available, the `mode` should be changed to determinate to convey the progress. In
39+
this mode the `value` property is ignored.
40+
41+
### Theming
42+
The color of a progress-bar can be changed by using the `color` property. By default, progress-bars
43+
use the theme's primary color. This can be changed to `'accent'` or `'warn'`.
44+
45+
### Accessibility
46+
Each progress bar should be given a meaningful label via `aria-label` or `aria-labelledby`.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.mat-progress {
2+
opacity: 0;
3+
visibility: hidden;
4+
}
5+
6+
.mat-progress-container {
7+
position: absolute;
8+
top: 50%;
9+
left: 50%;
10+
transform: translate(-50%, -50%);
11+
}
12+
13+
.mat-progress-host {
14+
position: relative;
15+
}

src/lib/progress-container/progress-container.spec.ts

Whitespace-only changes.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import {
9+
ChangeDetectionStrategy,
10+
Component,
11+
Host,
12+
OnDestroy,
13+
OnInit,
14+
TemplateRef,
15+
ViewChild,
16+
ViewContainerRef,
17+
ViewEncapsulation,
18+
ViewRef,
19+
} from '@angular/core';
20+
import {MatProgress} from './progress-directive';
21+
import {Subscription} from 'rxjs';
22+
23+
@Component({
24+
moduleId: module.id,
25+
selector: 'mat-progress-container',
26+
templateUrl: 'progress-container.html',
27+
styleUrls: ['progress-container.css'],
28+
changeDetection: ChangeDetectionStrategy.OnPush,
29+
encapsulation: ViewEncapsulation.None,
30+
})
31+
export class MatProgressContainer implements OnInit, OnDestroy {
32+
@ViewChild(TemplateRef)
33+
private _templateRef: TemplateRef<any>;
34+
private _openSubscription: Subscription;
35+
private _containerViewRef: ViewRef | null = null;
36+
37+
constructor(@Host() private _progressDirective: MatProgress,
38+
private _viewContainerRef: ViewContainerRef) {
39+
if (!_progressDirective) {
40+
throw new Error(`Cannot instantiate MatProgressContainer without an ancestor
41+
MatProgress directive`);
42+
}
43+
this._toggleProgress = this._toggleProgress.bind(this);
44+
}
45+
46+
ngOnInit() {
47+
this._openSubscription = this._progressDirective.show.subscribe(this._toggleProgress);
48+
}
49+
50+
ngOnDestroy() {
51+
this._openSubscription.unsubscribe();
52+
}
53+
54+
private _toggleProgress(evt: boolean) {
55+
if (evt && !this._containerViewRef) {
56+
this._containerViewRef = this._viewContainerRef.createEmbeddedView(this._templateRef);
57+
} else if (!evt && this._containerViewRef) {
58+
this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._containerViewRef));
59+
this._containerViewRef = null;
60+
}
61+
}
62+
}

src/lib/progress-container/progress-content.spec.ts

Whitespace-only changes.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import {ChangeDetectionStrategy, Component, Host, ViewEncapsulation} from '@angular/core';
9+
import {MatProgress} from './progress-directive';
10+
11+
@Component({
12+
moduleId: module.id,
13+
selector: 'mat-progress-content',
14+
template: '<ng-content></ng-content>',
15+
host: {
16+
'[attr.aria-hidden]': '_showProgress',
17+
'[class.mat-progress]': '_showProgress',
18+
},
19+
changeDetection: ChangeDetectionStrategy.OnPush,
20+
encapsulation: ViewEncapsulation.None,
21+
})
22+
export class MatProgressContent {
23+
/** @docs-private */
24+
get _showProgress(): boolean {
25+
return this._progressDirective.showProgress;
26+
}
27+
28+
constructor(@Host() private _progressDirective: MatProgress) {}
29+
}

src/lib/progress-container/progress-directive.spec.ts

Whitespace-only changes.

0 commit comments

Comments
 (0)