src/app/app.component.ts
selector | app-root |
styleUrls | ./app.component.scss |
templateUrl | ./app.component.html |
Properties |
Methods |
constructor(snotifyService: SnotifyService)
|
||||||
Defined in src/app/app.component.ts:25
|
||||||
Parameters :
|
getConfig |
getConfig()
|
Defined in src/app/app.component.ts:32
|
Returns :
SnotifyToastConfig
|
onAsyncLoading |
onAsyncLoading()
|
Defined in src/app/app.component.ts:76
|
Returns :
void
|
onClear |
onClear()
|
Defined in src/app/app.component.ts:202
|
Returns :
void
|
onConfirmation |
onConfirmation()
|
Defined in src/app/app.component.ts:136
|
Returns :
void
|
onError |
onError()
|
Defined in src/app/app.component.ts:60
|
Returns :
void
|
onHtml |
onHtml()
|
Defined in src/app/app.component.ts:196
|
Returns :
void
|
onInfo |
onInfo()
|
Defined in src/app/app.component.ts:57
|
Returns :
void
|
onPrompt |
onPrompt()
|
Defined in src/app/app.component.ts:165
|
Returns :
void
|
onSimple |
onSimple()
|
Defined in src/app/app.component.ts:66
|
Returns :
void
|
onSuccess |
onSuccess()
|
Defined in src/app/app.component.ts:54
|
Returns :
void
|
onWarning |
onWarning()
|
Defined in src/app/app.component.ts:63
|
Returns :
void
|
backdrop |
Default value : -1
|
Defined in src/app/app.component.ts:20
|
blockMax |
Type : number
|
Default value : 6
|
Defined in src/app/app.component.ts:22
|
body |
Type : string
|
Default value : 'Lorem ipsum dolor sit amet!'
|
Defined in src/app/app.component.ts:13
|
bodyMaxLength |
Type : number
|
Default value : 80
|
Defined in src/app/app.component.ts:25
|
closeClick |
Default value : true
|
Defined in src/app/app.component.ts:17
|
dockMax |
Type : number
|
Default value : 8
|
Defined in src/app/app.component.ts:21
|
filterDuplicates |
Default value : false
|
Defined in src/app/app.component.ts:19
|
newTop |
Default value : true
|
Defined in src/app/app.component.ts:18
|
pauseHover |
Default value : true
|
Defined in src/app/app.component.ts:23
|
position |
Type : SnotifyPosition
|
Default value : SnotifyPosition.rightBottom
|
Defined in src/app/app.component.ts:15
|
progressBar |
Default value : true
|
Defined in src/app/app.component.ts:16
|
style |
Type : string
|
Default value : 'material'
|
Defined in src/app/app.component.ts:11
|
timeout |
Type : number
|
Default value : 3000
|
Defined in src/app/app.component.ts:14
|
title |
Type : string
|
Default value : 'Snotify title!'
|
Defined in src/app/app.component.ts:12
|
titleMaxLength |
Type : number
|
Default value : 15
|
Defined in src/app/app.component.ts:24
|
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { SnotifyService, SnotifyPosition, SnotifyToastConfig } from 'ng-snotify';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
style = 'material';
title = 'Snotify title!';
body = 'Lorem ipsum dolor sit amet!';
timeout = 3000;
position: SnotifyPosition = SnotifyPosition.rightBottom;
progressBar = true;
closeClick = true;
newTop = true;
filterDuplicates = false;
backdrop = -1;
dockMax = 8;
blockMax = 6;
pauseHover = true;
titleMaxLength = 15;
bodyMaxLength = 80;
constructor(private snotifyService: SnotifyService) {}
/*
Change global configuration
*/
getConfig(): SnotifyToastConfig {
this.snotifyService.setDefaults({
global: {
newOnTop: this.newTop,
maxAtPosition: this.blockMax,
maxOnScreen: this.dockMax,
// @ts-ignore
filterDuplicates: this.filterDuplicates
}
});
return {
bodyMaxLength: this.bodyMaxLength,
titleMaxLength: this.titleMaxLength,
backdrop: this.backdrop,
position: this.position,
timeout: this.timeout,
showProgressBar: this.progressBar,
closeOnClick: this.closeClick,
pauseOnHover: this.pauseHover
};
}
onSuccess() {
this.snotifyService.success(this.body, this.title, this.getConfig());
}
onInfo() {
this.snotifyService.info(this.body, this.title, this.getConfig());
}
onError() {
this.snotifyService.error(this.body, this.title, this.getConfig());
}
onWarning() {
this.snotifyService.warning(this.body, this.title, this.getConfig());
}
onSimple() {
// const icon = `assets/custom-svg.svg`;
const icon = `https://placehold.it/48x100`;
this.snotifyService.simple(this.body, this.title, {
...this.getConfig(),
icon
});
}
onAsyncLoading() {
const errorAction = new Observable(observer => {
setTimeout(() => {
observer.error({
title: 'Error',
body: 'Example. Error 404. Service not found'
});
}, 2000);
});
const successAction = new Observable(observer => {
setTimeout(() => {
observer.next({
body: 'Still loading.....'
});
}, 2000);
setTimeout(() => {
observer.next({
title: 'Success',
body: 'Example. Data loaded!',
config: {
closeOnClick: true,
timeout: 5000,
showProgressBar: true
}
});
observer.complete();
}, 5000);
});
/*
You should pass Promise or Observable of type Snotify to change some data or do some other actions
More information how to work with observables:
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/create.md
*/
const { timeout, ...config } = this.getConfig(); // Omit timeout
this.snotifyService.async('This will resolve with error', 'Async', errorAction, config);
this.snotifyService.async('This will resolve with success', successAction, config);
this.snotifyService.async(
'Called with promise',
'Error async',
new Promise((resolve, reject) => {
setTimeout(
() =>
reject({
title: 'Error!!!',
body: 'We got an example error!',
config: {
closeOnClick: true
}
}),
1000
);
setTimeout(() => resolve(), 1500);
}),
config
);
}
onConfirmation() {
/*
Here we pass an buttons array, which contains of 2 element of type SnotifyButton
*/
const { timeout, closeOnClick, ...config } = this.getConfig(); // Omit props what i don't need
this.snotifyService.confirm(this.body, this.title, {
...config,
buttons: [
{ text: 'Yes', action: () => console.log('Clicked: Yes'), bold: false },
{ text: 'No', action: () => console.log('Clicked: No') },
{
text: 'Later',
action: toast => {
console.log('Clicked: Later');
this.snotifyService.remove(toast.id);
}
},
{
text: 'Close',
action: toast => {
console.log('Clicked: Close');
this.snotifyService.remove(toast.id);
},
bold: true
}
]
});
}
onPrompt() {
/*
Here we pass an buttons array, which contains of 2 element of type SnotifyButton
At the action of the first buttons we can get what user entered into input field.
At the second we can't get it. But we can remove this toast
*/
const { timeout, closeOnClick, ...config } = this.getConfig(); // Omit props what i don't need
this.snotifyService
.prompt(this.body, this.title, {
...config,
buttons: [
{
text: 'Yes',
action: toast => console.log('Said Yes: ' + toast.value)
},
{
text: 'No',
action: toast => {
console.log('Said No: ' + toast.value);
this.snotifyService.remove(toast.id);
}
}
],
placeholder: 'Enter "ng-snotify" to validate this input' // Max-length = 40
})
.on('input', toast => {
console.log(toast.value);
toast.valid = !!toast.value.match('ng-snotify');
});
}
onHtml() {
const html = `<div class="snotifyToast__title"><b>Html Bold Title</b></div>
<div class="snotifyToast__body"><i>Html</i> <b>toast</b> <u>content</u></div>`;
this.snotifyService.html(html, this.getConfig());
}
onClear() {
this.snotifyService.clear();
}
}
<div class="wrapper">
<aside>
<h3 class="text-center">Toast config</h3>
<div class="form-group">
<label for="title">Title</label>
<input [(ngModel)]="title" type="text" id="title" class="form-control" />
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea [(ngModel)]="body" id="body" rows="2" class="form-control"></textarea>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label for="titlemaxlen">Title max-length</label>
<input [(ngModel)]="titleMaxLength" type="text" id="titlemaxlen" class="form-control" />
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label for="bodymaxlen">Body max-length</label>
<input [(ngModel)]="bodyMaxLength" type="text" id="bodymaxlen" class="form-control" />
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label for="timeout">Timeout</label>
<input [(ngModel)]="timeout" type="number" id="timeout" class="form-control" />
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label for="backdrop">
Backdrop (0.0 - 1.0)
</label>
<input [(ngModel)]="backdrop" type="number" id="backdrop" class="form-control" min="-1" max="1" />
</div>
</div>
</div>
<div class="form-group">
<label for="position">Position</label>
<div class="row">
<div class="col-sm-12">
<select [(ngModel)]="position" id="position" class="form-control">
<option [ngValue]="'leftTop'">LEFT - TOP</option>
<option [ngValue]="'leftCenter'">LEFT - CENTER</option>
<option [ngValue]="'leftBottom'">LEFT - BOTTOM</option>
<option [ngValue]="'rightTop'">RIGHT - TOP</option>
<option [ngValue]="'rightCenter'">RIGHT - CENTER</option>
<option [ngValue]="'rightBottom'">RIGHT - BOTTOM</option>
<option [ngValue]="'centerTop'">CENTER - TOP</option>
<option [ngValue]="'centerCenter'">CENTER - CENTER</option>
<option [ngValue]="'centerBottom'">CENTER - BOTTOM</option>
</select>
</div>
</div>
</div>
<div class="switch-group-wrapper">
<div class="switch-wrapper">
<strong>Show progress bar?</strong>
<div class="switch">
<input [(ngModel)]="progressBar" id="progressBar" class="cmn-toggle cmn-toggle-yes-no" type="checkbox" />
<label for="progressBar" data-on="On" data-off="Off"></label>
</div>
</div>
<div class="switch-wrapper">
<strong>Close on click?</strong>
<div class="switch">
<input [(ngModel)]="closeClick" id="closeClick" class="cmn-toggle cmn-toggle-yes-no" type="checkbox" />
<label for="closeClick" data-on="On" data-off="Off"></label>
</div>
</div>
<div class="switch-wrapper">
<strong>Pause on hover?</strong>
<div class="switch">
<input [(ngModel)]="pauseHover" id="pauseHover" class="cmn-toggle cmn-toggle-yes-no" type="checkbox" />
<label for="pauseHover" data-on="On" data-off="Off"></label>
</div>
</div>
<div class="switch-wrapper">
<strong>New items on top?</strong>
<div class="switch">
<input [(ngModel)]="newTop" id="newTop" class="cmn-toggle cmn-toggle-yes-no" type="checkbox" />
<label for="newTop" data-on="On" data-off="Off"></label>
</div>
</div>
<div class="switch-wrapper">
<strong>Filter duplicates?</strong>
<div class="switch">
<input
[(ngModel)]="filterDuplicates"
id="filterDuplicates"
class="cmn-toggle cmn-toggle-yes-no"
type="checkbox"
/>
<label for="filterDuplicates" data-on="On" data-off="Off"></label>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label for="dockMax">
Max on screen
</label>
<input [(ngModel)]="dockMax" type="number" id="dockMax" class="form-control" min="1" />
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label for="blockMax">
Max at position
</label>
<input [(ngModel)]="blockMax" type="number" id="blockMax" class="form-control" min="1" />
</div>
</div>
</div>
<div class="form-group">
<label for="style">Toast Style</label>
<div class="row">
<div class="col-sm-12">
<select [(ngModel)]="style" id="style" class="form-control">
<option [ngValue]="'material'">Material</option>
<option [ngValue]="'dark'">Dark</option>
<option [ngValue]="'simple'">Simple</option>
</select>
</div>
</div>
</div>
<div class="form-group">
<div class="buttons">
<div class="btn-group btn-group-justified">
<div class="btn btn-success" (click)="onSuccess()">Success</div>
<div class="btn btn-info" (click)="onInfo()">Info</div>
<div class="btn btn-danger" (click)="onError()">Error</div>
<div class="btn btn-warning" (click)="onWarning()">Warning</div>
</div>
<div class="btn-group btn-group-justified">
<div class="btn btn-default" (click)="onSimple()">Simple</div>
<div class="btn btn-blue" (click)="onAsyncLoading()">Async</div>
<div class="btn btn-teal" (click)="onConfirmation()">Confirm</div>
<div class="btn btn-black" (click)="onPrompt()">Prompt</div>
</div>
<div class="btn-group btn-group-justified">
<div class="btn btn-default" (click)="onHtml()">HTML</div>
</div>
</div>
</div>
<div class="btn btn-block btn-primary" (click)="onClear()">Clear all</div>
</aside>
<div class="content">
<main>
<div class="brand">
<h1>Ng-Snotify</h1>
<p>Angular 2+ Notification Center</p>
</div>
</main>
<footer>
<div class="footer">
<a href="documentation/index.html" target="_blank">Documentation</a> ◉
<a href="compodoc/index.html" target="_blank">Compodoc</a> ◉
<a href="https://github.com/artemsky/ng-snotify" target="_blank">GitHub</a> ◉
<a href="https://www.npmjs.com/package/ng-snotify" target="_blank">NPM</a>
<h6>MIT © 2018 <a href="https://github.com/artemsky/">artemsky</a></h6>
</div>
</footer>
<ng-snotify class="{{ style }}"></ng-snotify>
</div>
</div>
./app.component.scss
@import url("https://fonts.googleapis.com/css?family=Audiowide");
.wrapper {
display: flex;
height: 100vh;
width: 100vw;
overflow: hidden;
@media (max-width: 767px) {
flex-flow: column nowrap;
height: auto;
font-size: 12px;
}
aside {
flex: 0 0 350px;
padding: 10px 15px;
overflow-y: auto;
z-index: 5;
.btn-group {
.btn {
padding: 6px 9px;
}
}
h3 {
margin: 0;
}
@media (max-width: 767px) {
order: 1;
overflow: initial;
}
}
.content {
position: relative;
width: 100%;
display: flex;
flex-flow: column nowrap;
background: #ea5c54; /* Old browsers */
background: -moz-linear-gradient(-45deg, #ea5c54 0%, #bb6dec 100%); /* FF3.6+ */
background: -webkit-gradient(
linear,
left top,
right bottom,
color-stop(0%, #ea5c54),
color-stop(100%, #bb6dec)
); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(-45deg, #ea5c54 0%, #bb6dec 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(-45deg, #ea5c54 0%, #bb6dec 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(-45deg, #ea5c54 0%, #bb6dec 100%); /* IE10+ */
background: linear-gradient(135deg, #ea5c54 0%, #bb6dec 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#EA5C54 ', endColorstr='#bb6dec',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
main {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.brand {
position: absolute;
color: #ffffff;
h1 {
font-family: "Audiowide", cursive;
font-display: swap;
font-size: 6em;
}
p {
font-size: 2em;
text-align: center;
}
@media (max-width: 992px) {
h1 {
font-size: 4.5em;
}
p {
font-size: 1.8em;
}
@media (max-width: 767px) {
h1 {
font-size: 4em;
}
p {
font-size: 1.5em;
}
}
}
}
@media (max-width: 767px) {
flex-flow: column nowrap;
order: 0;
height: 110px;
}
}
footer {
flex: 0 0 65px;
text-align: center;
color: #ffffff;
font-size: 1em;
a {
color: #fff;
}
h6 {
font-size: 0.9em;
}
@media (max-width: 767px) {
flex: 0 0 40px;
}
}
}
}
//
//main {
// position: fixed;
// top: 0;
// left: 0;
// width: 100%;
// height: 100%;
// background: #EA5C54 ; /* Old browsers */
// background: -moz-linear-gradient(-45deg, #EA5C54 0%, #bb6dec 100%); /* FF3.6+ */
// background: -webkit-gradient(linear, left top, right bottom, color-stop(0%,#EA5C54 ), color-stop(100%,#bb6dec)); /* Chrome,Safari4+ */
// background: -webkit-linear-gradient(-45deg, #EA5C54 0%,#bb6dec 100%); /* Chrome10+,Safari5.1+ */
// background: -o-linear-gradient(-45deg, #EA5C54 0%,#bb6dec 100%); /* Opera 11.10+ */
// background: -ms-linear-gradient(-45deg, #EA5C54 0%,#bb6dec 100%); /* IE10+ */
// background: linear-gradient(135deg, #EA5C54 0%,#bb6dec 100%); /* W3C */
// filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#EA5C54 ', endColorstr='#bb6dec',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
// z-index: 1;
//}
//
//aside {
// position: fixed;
// top: 0;
// left: 0;
// width: 340px;
// height: 100%;
// padding: 15px;
// background: #fff;
// overflow-y: auto;
// overflow-x: hidden;
// z-index: 3;
// .btn-group {
// .btn {
// padding: 6px 9px;
// }
// }
//
// h3 {
// margin: 0;
// }
//}
//
//.brand {
// position: absolute;
// top: 50%;
// left: 50%;
// transform: translateY(-50%) translateX(calc(-50% + 340px / 2));
// color: #ffffff;
// h1 {
// font-family: 'Audiowide', cursive;
// font-size: 6em;
// }
// p {
// font-size: 2em;
// text-align: center;
// }
//}
//
//textarea{
// resize: vertical;
//}
//
//footer {
// display: block;
// padding: 10px;
// position: fixed;
// bottom: 15px;
// left: 50%;
// font-size: 15px;
// text-align: center;
// color: white;
// width: calc(100% - 340px);
// transform: translateX(calc(-50% + 340px / 2));
// z-index:2;
// a {
// color: #ffffff;
// }
//}
.buttons {
margin: 20px 0;
}
.btn-group {
margin: 5px 0 0;
}
.btn-black {
color: #f8f8f8;
background-color: #2d2d2d;
border-color: #000000;
&:hover {
color: #fff;
background-color: #000000;
border-color: #000000;
}
}
.btn-blue {
color: #f8f8f8;
background-color: #2095f2;
border-color: #1a80d1;
&:hover {
color: #fff;
background-color: #1a80d1;
border-color: #1a80d1;
}
}
.btn-teal {
color: #f8f8f8;
background-color: #009587;
border-color: #018175;
&:hover {
color: #fff;
background-color: #018175;
border-color: #018175;
}
}
.switch-wrapper {
width: 50%;
}
.switch-group-wrapper {
display: flex;
flex-flow: row wrap;
margin: 5px 0 10px;
}
.cmn-toggle {
position: absolute;
margin-left: -9999px;
padding: 2px;
width: 60px;
height: 30px;
visibility: hidden;
+ label {
display: block;
position: relative;
padding: 2px;
width: 60px;
height: 30px;
cursor: pointer;
outline: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
&::before,
&::after {
display: block;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
color: #fff;
font-family: "Roboto Slab", serif;
font-size: 20px;
text-align: center;
line-height: 30px;
}
&::before {
background-color: #dddddd;
content: attr(data-off);
transition: transform 0.5s;
backface-visibility: hidden;
}
&::after {
background-color: #8ce196;
content: attr(data-on);
transition: transform 0.5s;
transform: rotateY(180deg);
backface-visibility: hidden;
}
}
&:checked {
+ label {
&::before {
transform: rotateY(180deg);
}
&::after {
transform: rotateY(0);
}
}
}
}