-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(toast): Toast implementation (#3103)
Implementation of twbs/bootstrap##22980
- Loading branch information
Benoit Charbonnier
committed
Jun 24, 2019
1 parent
83f79cf
commit bd1e9fb
Showing
32 changed files
with
874 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
demo/src/app/components/toast/demos/closeable/toast-closeable.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<ngb-toast *ngIf="show" header="Click my close icon →" [autohide]="false" | ||
(hide)="close()"> | ||
If you close me, I will automatically re-appear after a few seconds. | ||
</ngb-toast> | ||
<p *ngIf="!show">I'll be back!</p> |
10 changes: 10 additions & 0 deletions
10
demo/src/app/components/toast/demos/closeable/toast-closeable.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import {NgModule} from '@angular/core'; | ||
import {BrowserModule} from '@angular/platform-browser'; | ||
import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; | ||
|
||
import {NgbdToastCloseable} from './toast-closeable'; | ||
|
||
|
||
@NgModule({imports: [BrowserModule, NgbModule], declarations: [NgbdToastCloseable], bootstrap: [NgbdToastCloseable]}) | ||
export class NgbdToastCloseableModule { | ||
} |
12 changes: 12 additions & 0 deletions
12
demo/src/app/components/toast/demos/closeable/toast-closeable.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import {Component} from '@angular/core'; | ||
|
||
@Component({selector: 'ngbd-toast-closeable', templateUrl: './toast-closeable.html'}) | ||
|
||
export class NgbdToastCloseable { | ||
show = true; | ||
|
||
close() { | ||
this.show = false; | ||
setTimeout(() => this.show = true, 5000); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
demo/src/app/components/toast/demos/custom-header/toast-custom-header.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<ngb-toast> | ||
<ng-template ngbToastHeader> | ||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path d="M16.896 10l-4.896-8-4.896 8-7.104-4 3 11v5h18v-5l3-11-7.104 4zm-11.896 10v-2h14v2h-14zm14.2-4h-14.4l-1.612-5.909 4.615 2.598 4.197-6.857 4.197 6.857 4.615-2.598-1.612 5.909z"/></svg> | ||
<strong class="mx-1">Fancy</strong>header here | ||
</ng-template> | ||
Hello, I am toast. Have you noticed my header has been generated from a Template? | ||
</ngb-toast> | ||
<ngb-alert type="secondary" [dismissible]="false">Clicking on the close icon won't do anything in this example.</ngb-alert> |
13 changes: 13 additions & 0 deletions
13
demo/src/app/components/toast/demos/custom-header/toast-custom-header.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { FormsModule } from '@angular/forms'; | ||
import { BrowserModule } from '@angular/platform-browser'; | ||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; | ||
|
||
import { NgbdToastCustomHeader } from './toast-custom-header'; | ||
|
||
@NgModule({ | ||
imports: [BrowserModule, FormsModule, NgbModule], | ||
declarations: [NgbdToastCustomHeader], | ||
bootstrap: [NgbdToastCustomHeader] | ||
}) | ||
export class NgbdToastCustomHeaderModule {} |
4 changes: 4 additions & 0 deletions
4
demo/src/app/components/toast/demos/custom-header/toast-custom-header.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { Component } from '@angular/core'; | ||
|
||
@Component({ selector: 'ngbd-toast-customheader', templateUrl: './toast-custom-header.html' }) | ||
export class NgbdToastCustomHeader {} |
11 changes: 11 additions & 0 deletions
11
demo/src/app/components/toast/demos/howto-global/toast-global.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<p>Please click one of the button to see a Toast being displayed in the top right corner of your screen:</p> | ||
<button class="btn btn-primary" (click)="showStandard()" ngbTooltip="Will disappear in 5s">Standard toast</button> | ||
<button class="btn btn-success" (click)="showSuccess()" ngbTooltip="Will disappear in 10s">Success toast</button> | ||
|
||
<ng-template #dangerTpl> | ||
<svg xmlns="http://www.w3.org/2000/svg" fill="#fff" width="24" height="24" viewBox="0 0 24 24"><path d="M10.872 6.831l1.695 3.904 3.654-1.561-1.79 3.426 3.333.954-3.417 1.338 2.231 4.196-4.773-2.582-2.869 2.287.413-3.004-3.792-.726 2.93-1.74-1.885-2.512 3.427.646.843-4.626zm-.786-6.831l-1.665 9.119-6.512-1.228 3.639 4.851-5.548 3.294 7.108 1.361-.834 6.076 5.742-4.577 9.438 5.104-4.288-8.064 6.834-2.677-6.661-1.907 3.25-6.22-6.98 2.982-3.523-8.114z"/></svg> | ||
Danger Danger ! | ||
</ng-template> | ||
<button class="btn btn-danger" (click)="showDanger(dangerTpl)" ngbTooltip="Will disappear in 15s">Danger toast</button> | ||
|
||
<app-toasts aria-live="polite" aria-atomic="true"></app-toasts> |
20 changes: 20 additions & 0 deletions
20
demo/src/app/components/toast/demos/howto-global/toast-global.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { Component } from '@angular/core'; | ||
|
||
import { ToastService } from './toast-service'; | ||
|
||
@Component({ selector: 'ngbd-toast-global', templateUrl: './toast-global.component.html' }) | ||
export class NgbdToastGlobal { | ||
constructor(public toastService: ToastService) {} | ||
|
||
showStandard() { | ||
this.toastService.show('I am a standard toast'); | ||
} | ||
|
||
showSuccess() { | ||
this.toastService.show('I am a success toast', { classname: 'bg-success text-light', delay: 10000 }); | ||
} | ||
|
||
showDanger(dangerTpl) { | ||
this.toastService.show(dangerTpl, { classname: 'bg-danger text-light', delay: 15000 }); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
demo/src/app/components/toast/demos/howto-global/toast-global.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { BrowserModule } from '@angular/platform-browser'; | ||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; | ||
|
||
import { NgbdToastGlobal } from './toast-global.component'; | ||
import { ToastsContainer } from './toasts-container.component'; | ||
|
||
@NgModule({ | ||
imports: [BrowserModule, NgbModule], | ||
declarations: [NgbdToastGlobal, ToastsContainer], | ||
bootstrap: [NgbdToastGlobal] | ||
}) | ||
export class NgbdToastGlobalModule {} |
14 changes: 14 additions & 0 deletions
14
demo/src/app/components/toast/demos/howto-global/toast-service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { Injectable, TemplateRef } from '@angular/core'; | ||
|
||
@Injectable({ providedIn: 'root' }) | ||
export class ToastService { | ||
toasts: any[] = []; | ||
|
||
show(textOrTpl: string | TemplateRef<any>, options: any = {}) { | ||
this.toasts.push({ textOrTpl, ...options }); | ||
} | ||
|
||
remove(toast) { | ||
this.toasts = this.toasts.filter(t => t !== toast); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
demo/src/app/components/toast/demos/howto-global/toasts-container.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import {Component, TemplateRef} from '@angular/core'; | ||
|
||
import {ToastService} from './toast-service'; | ||
|
||
|
||
@Component({ | ||
selector: 'app-toasts', | ||
template: ` | ||
<ngb-toast | ||
*ngFor="let toast of toastService.toasts" | ||
[class]="toast.classname" | ||
[autohide]="true" | ||
[delay]="toast.delay || 5000" | ||
(hide)="toastService.remove(toast)" | ||
> | ||
<ng-template [ngIf]="isTemplate(toast)" [ngIfElse]="text"> | ||
<ng-template [ngTemplateOutlet]="toast.textOrTpl"></ng-template> | ||
</ng-template> | ||
<ng-template #text>{{ toast.textOrTpl }}</ng-template> | ||
</ngb-toast> | ||
`, | ||
host: {'[class.ngb-toasts]': 'true'} | ||
}) | ||
export class ToastsContainer { | ||
constructor(public toastService: ToastService) {} | ||
|
||
isTemplate(toast) { return toast.textOrTpl instanceof TemplateRef; } | ||
} |
10 changes: 10 additions & 0 deletions
10
demo/src/app/components/toast/demos/inline/toast-inline.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<h6>Body only</h6> | ||
<ngb-toast> | ||
I am a simple static toast. | ||
</ngb-toast> | ||
|
||
<h6>With a text header</h6> | ||
<ngb-toast header="Hello" [autohide]="false"> | ||
I am a simple static toast with a header. | ||
</ngb-toast> | ||
<ngb-alert type="secondary" [dismissible]="false">Clicking on the close icon won't do anything in this example.</ngb-alert> |
8 changes: 8 additions & 0 deletions
8
demo/src/app/components/toast/demos/inline/toast-inline.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { BrowserModule } from '@angular/platform-browser'; | ||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; | ||
|
||
import { NgbdToastInline } from './toast-inline'; | ||
|
||
@NgModule({ imports: [BrowserModule, NgbModule], declarations: [NgbdToastInline], bootstrap: [NgbdToastInline] }) | ||
export class NgbdToastInlineModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { Component } from '@angular/core'; | ||
|
||
@Component({ selector: 'ngbd-toast-inline', templateUrl: './toast-inline.html' }) | ||
export class NgbdToastInline {} |
98 changes: 98 additions & 0 deletions
98
demo/src/app/components/toast/overview/toast-overview.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
<p> | ||
Toasts provide feedback messages as notifications to the user.<br /> | ||
Goal is to mimic the push notifications available both on mobile and desktop operating systems. | ||
</p> | ||
|
||
<ngbd-overview-section [section]="sections['inline-usage']"> | ||
<p><a [routerLink]="['..', 'api']" fragment="NgbToast">NgbToast</a> component allows you to only render the corresponding markup. Use it in one of your templates, and you are done. It will render a toast.</p> | ||
<ngbd-code [snippet]="TOAST_INLINE_BASIC"></ngbd-code> | ||
<br /> | ||
<p>Live example available <a [routerLink]="['..', 'examples']" fragment="inline" title="Declarative inline usage">here</a>.</p> | ||
<p> | ||
Nonetheless, with this inline technique, you must handle the toast's lifecycle yourself, i.e. it won't disappear automagically or in other words we don't remove the markup, nor destroy the component. | ||
</p><p> | ||
To make it disappear, you can listen to the <a [routerLink]="['..', 'api']" fragment="NgbToast"><code>(hide)</code></a> | ||
output and remove/destroy/hide it yourself, and <a routerLink="." fragment="toast-service">next section</a> details how to do that in a real application environment. | ||
</p> | ||
<ngbd-code [snippet]="TOAST_INLINE_LIFECYCLE"></ngbd-code> | ||
</ngbd-overview-section> | ||
|
||
<ngbd-overview-section [section]="sections['toast-service']"> | ||
<p>Let's take the opportunity to demonstrate how to simply build a global toast management service.</p> | ||
<ngb-alert [dismissible]="false" type="secondary"> | ||
<strong>TLDR;</strong> | ||
You don't feel reading these long explanations? Go to the live example <a [routerLink]="['..', 'examples']" fragment="howto-global" title="Toast management service">here</a>. | ||
</ngb-alert> | ||
|
||
<p>In order to create our global toast system, 3 simple steps need to be done:<p> | ||
<ol> | ||
<li>Create a global <code>AppToastService</code> to act as a global storage for toasts.</li> | ||
<li>Create a container component <code><app-toasts></code>, acting as the host in the application to display your toasts. | ||
You could use <code><ngb-toast></code> with an <code>*ngFor</code> to read the list of toasts to display from the service.</li> | ||
<li>Finally, use this container component in your application.</li> | ||
</ol> | ||
|
||
<h4>1. Global toast service</h4> | ||
<p> | ||
Relying on Angular dependency injection to share some piece of logic application-wide is always a good and solid starting choice. | ||
</p> | ||
<p> | ||
The service manages a collection of toasts. It also provides a public method to push a new toast to that same collection. | ||
<ngbd-code [snippet]="APP_TOAST_SERVICE"></ngbd-code> | ||
</p> | ||
|
||
<ngb-alert [dismissible]="false" type="warning"> | ||
<svg:svg ngbdIcon="lightbulb" fill="currentColor" /> | ||
You could also create an interface to type your toast instead of using <code>any[]</code> here. | ||
</ngb-alert> | ||
<p> | ||
Additionally, a method to remove an existing toast from the collection is also implemented. | ||
<ngbd-code [snippet]="APP_TOAST_SERVICE_REMOVE"></ngbd-code> | ||
</p> | ||
|
||
<h4>2. Toast container component</h4> | ||
<p> | ||
As stated previously, <code><ngb-toast></code> only generates a valid Bootstrap toast markup. | ||
You'll still have to position them properly on the screen. | ||
<br /> | ||
Thus, as a suggestion, toasts could be rendered in the top right corner of the application, as a kind of overlay. | ||
</p> | ||
<p> | ||
To achieve that, you could create a dedicated container component/element to render all toasts in a convenient way. | ||
For example, this container could be positionned using CSS property <code>position: static</code>. | ||
</p> | ||
<ngb-tabset> | ||
<ngb-tab title="Template"> | ||
<ngbd-code *ngbTabContent [snippet]="APP_TOASTS_CONTAINER_TPL"></ngbd-code> | ||
</ngb-tab> | ||
<ngb-tab title="Styles"> | ||
<div *ngbTabContent> | ||
<ngbd-code [snippet]="APP_TOASTS_CONTAINER_STYLES"></ngbd-code> | ||
<p>We provide a dedicated <code>ngb-toasts</code> CSS class you could use, or write your own styles in case some specificities would be needed.</p> | ||
</div> | ||
</ngb-tab> | ||
<ngb-tab title="Component"> | ||
<ngbd-code *ngbTabContent [snippet]="APP_TOASTS_CONTAINER"></ngbd-code> | ||
</ngb-tab> | ||
</ngb-tabset> | ||
<hr /> | ||
<p> | ||
Lastly, let's use this container. Common sense would suggest to put it somewhere quite high in your hierarchy of components. | ||
Your root component would be a good candidate. | ||
</p> | ||
<ngbd-code [snippet]="CONTAINER_USAGE"></ngbd-code> | ||
<p>You're done! Just inject and use your <code>AppToastService</code> anywhere you want to create a new toast. <code><app-toasts></code> will take care of displaying them.</p> | ||
|
||
<ngb-alert [dismissible]="false" type="warning" class="d-flex flex-row"> | ||
<div class="mr-1"> | ||
<svg:svg ngbdIcon="lightbulb" fill="currentColor" /> | ||
</div> | ||
<div> | ||
Note the accessibility attributes <code>aria-live="polite"</code> & <code>aria-atomic="true"</code>. They are <strong>mandatory</strong> in order to be compliant with screen readers technology. More information available on <a href="https://getbootstrap.com/docs/4.3/components/toasts/#accessibility" target="_blank" rel="noopener noreferrer">Bootstrap documentation</a>. | ||
</div> | ||
</ngb-alert> | ||
|
||
<p> | ||
Click <a [routerLink]="['..', 'examples']" fragment="howto-global" title="Toast management service">here</a> to see an example a bit more advanced of this how-to. | ||
</p> | ||
</ngbd-overview-section> |
Oops, something went wrong.