@telekom/scale-components
Version:
Scale is the digital design system for Telekom products and experiences.
483 lines (481 loc) • 14.2 kB
JavaScript
/**
* @license
* Scale https://github.com/telekom/scale
*
* Copyright (c) 2021 Egor Kirpichev and contributors, Deutsche Telekom AG
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { Component, Prop, Method, h, State, Element, Host, Event, } from '@stencil/core';
import classNames from 'classnames';
import statusNote from '../../utils/status-note';
import { emitEvent } from '../../utils/utils';
export class NotificationToast {
constructor() {
/** (optional) Toast variant */
this.variant = 'informational';
/** (optional) Animated toast */
this.animated = true;
/** (optional) Alignment choose for top and bottom */
this.alignment = 'top-right';
/** (optional) Toast position at the top */
this.positionVertical = 12;
/** (optional) Toast position right */
this.positionHorizontal = 12;
/** (optional) Toast auto hide */
this.autoHide = false;
/** (optional) Toast auto hide duration */
this.autoHideDuration = 3000;
/** (optional) Toast fade duration */
this.fadeDuration = 500;
/** (optional) Label for close button */
this.closeButtonLabel = 'close';
/** (optional) Title for close button */
this.closeButtonTitle = 'close';
/** (optional) Toast state height with offset */
this.toastHeightWithOffset = 0;
this.hideToast = false;
this.close = () => {
emitEvent(this, 'scaleClosing');
this.hideToast = true;
setTimeout(() => {
this.opened = false;
emitEvent(this, 'scaleClose');
}, this.fadeDuration);
};
this.transitions = (offset) => `
fadeIn {
from {
opacity: 0;
${this.alignmentVertical}: -${offset}px;
}
to {
opacity: 1;
${this.alignmentVertical}: ${this.positionVertical}px;
}
}
fadeOut {
from {
opacity: 1;
${this.alignmentVertical}: ${this.positionVertical}px;
}
to {
opacity: 0;
${this.alignmentVertical}: -${offset}px;
}
}
`;
this.animationStyle = (offset) => {
if (this.animated) {
return `
.notification-toast--show {
${this.alignmentHorizontal}: ${this.positionHorizontal}px;
animation: fadeIn ${this.fadeDuration / 1000}s ease-in-out;
${this.alignmentVertical}: ${this.positionVertical}px;
opacity: 1;
},
.notification-toast--show {
${this.alignmentHorizontal}: ${this.positionHorizontal}px;
animation: fadeOut ${this.fadeDuration / 1000}s ease-in-out;
${this.alignmentVertical}: -${offset}px;
opacity: 0;
}
`;
}
return `
.notification-toast--show {
${this.alignmentHorizontal}: ${this.positionHorizontal}px;
${this.alignmentVertical}: ${this.positionVertical}px;
opacity: 1;
},
.notification-toast--show {
${this.alignmentHorizontal}: ${this.positionHorizontal}px;
${this.alignmentVertical}: -${offset}px;
opacity: 0;
}
`;
};
}
connectedCallback() {
statusNote({ source: this.element, type: 'warn' });
}
componentWillLoad() {
const alignmentParts = this.alignment.split('-');
this.alignmentVertical = alignmentParts[0];
this.alignmentHorizontal = alignmentParts[1];
}
componentDidRender() {
if (this.autoHide === true) {
setTimeout(this.close, this.autoHideDuration);
}
}
handleIcons() {
if (this.variant) {
switch (this.variant) {
case 'success':
return (h("scale-icon-action-success", { class: "notification-toast__icon", size: 20, color: "#ffffff", selected: true, "aria-hidden": "true" }));
case 'informational':
return (h("scale-icon-alert-information", { class: "notification-toast__icon", size: 20, selected: true, color: "#ffffff", "aria-hidden": "true" }));
case 'error':
return (h("scale-icon-alert-error", { class: "notification-toast__icon", size: 20, selected: true, color: "#ffffff", "aria-hidden": "true" }));
case 'warning':
return (h("scale-icon-alert-warning", { class: "notification-toast__icon", color: "#ffff", size: 20, selected: true, "aria-hidden": "true" }));
}
}
return;
}
/** Toast method: open() */
async open() {
this.opened = true;
this.hideToast = false;
}
render() {
if (this.opened) {
return (h(Host, null,
this.styles && h("style", null, this.styles),
h("style", null, this.transitions(this.toastHeightWithOffset)),
h("style", null, this.animationStyle(this.toastHeightWithOffset)),
h("div", { role: "alert", style: { display: `${this.opened ? '' : 'none'}` }, class: this.getCssClassMap(), part: this.getBasePartMap(), tabindex: "0" },
h("div", { class: "notification-toast__icon-container" }, this.handleIcons()),
h("div", { class: "notification-toast__text-container" },
h("slot", { name: "header" }),
h("slot", { name: "body" }),
h("scale-link", { href: this.href, class: "notification-toast__link", role: "link" },
h("slot", { name: "link" }))),
h("button", { part: "button-dismissable", type: "button", class: "notification-toast__button-close", onClick: () => this.close(), tabindex: 0, "aria-label": this.closeButtonLabel, title: this.closeButtonTitle, onKeyDown: (e) => {
if (e.key === 'Enter') {
this.close();
}
} },
h("scale-icon-action-circle-close", null)))));
}
}
getToastHeightWithOffset() {
const toastHeight = this.element.shadowRoot.querySelector('.toast').scrollHeight;
this.toastHeightWithOffset = toastHeight + this.positionVertical;
}
getBasePartMap() {
return this.getCssOrBasePartMap('basePart');
}
getCssClassMap() {
return this.getCssOrBasePartMap('css');
}
getCssOrBasePartMap(mode) {
const component = 'notification-toast';
const prefix = mode === 'basePart' ? '' : `${component}`;
return classNames(mode === 'basePart' ? 'base' : component, this.variant && `${prefix}--variant-${this.variant}`, !!this.opened && `${prefix}--opened`, !!!this.hideToast && `${prefix}--show`, !!this.hideToast && `${prefix}--hide`, this.story && `${prefix}--story`);
}
static get is() { return "scale-notification-toast"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() { return {
"$": ["./notification-toast.css"]
}; }
static get styleUrls() { return {
"$": ["notification-toast.css"]
}; }
static get properties() { return {
"variant": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'error' | 'warning' | 'success' | 'informational'",
"resolved": "\"error\" | \"informational\" | \"success\" | \"warning\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Toast variant"
},
"attribute": "variant",
"reflect": false,
"defaultValue": "'informational'"
},
"opened": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Toast opened"
},
"attribute": "opened",
"reflect": true
},
"animated": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Animated toast"
},
"attribute": "animated",
"reflect": false,
"defaultValue": "true"
},
"alignment": {
"type": "string",
"mutable": false,
"complexType": {
"original": "| 'bottom-right'\n | 'bottom-left'\n | 'top-right'\n | 'top-left'",
"resolved": "\"bottom-left\" | \"bottom-right\" | \"top-left\" | \"top-right\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Alignment choose for top and bottom"
},
"attribute": "alignment",
"reflect": false,
"defaultValue": "'top-right'"
},
"positionVertical": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Toast position at the top"
},
"attribute": "position-vertical",
"reflect": false,
"defaultValue": "12"
},
"positionHorizontal": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Toast position right"
},
"attribute": "position-horizontal",
"reflect": false,
"defaultValue": "12"
},
"autoHide": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Toast auto hide"
},
"attribute": "auto-hide",
"reflect": false,
"defaultValue": "false"
},
"autoHideDuration": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Toast auto hide duration"
},
"attribute": "auto-hide-duration",
"reflect": false,
"defaultValue": "3000"
},
"fadeDuration": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Toast fade duration"
},
"attribute": "fade-duration",
"reflect": false,
"defaultValue": "500"
},
"styles": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Injected CSS styles"
},
"attribute": "styles",
"reflect": true
},
"closeButtonLabel": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Label for close button"
},
"attribute": "close-button-label",
"reflect": false,
"defaultValue": "'close'"
},
"closeButtonTitle": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(optional) Title for close button"
},
"attribute": "close-button-title",
"reflect": false,
"defaultValue": "'close'"
},
"story": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "(do not use) it is a helper prop for storybook"
},
"attribute": "story",
"reflect": false
},
"href": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"attribute": "href",
"reflect": false
}
}; }
static get states() { return {
"toastHeightWithOffset": {}
}; }
static get events() { return [{
"method": "scaleClosing",
"name": "scale-closing",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Triggered when the notification toast closing process begins"
},
"complexType": {
"original": "void",
"resolved": "void",
"references": {}
}
}, {
"method": "scaleClose",
"name": "scale-close",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Triggered when the notification toast has been dismissed"
},
"complexType": {
"original": "void",
"resolved": "void",
"references": {}
}
}]; }
static get methods() { return {
"open": {
"complexType": {
"signature": "() => Promise<void>",
"parameters": [],
"references": {
"Promise": {
"location": "global"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Toast method: open()",
"tags": []
}
}
}; }
static get elementRef() { return "element"; }
}