@postnord/web-components
Version:
PostNord Web Components
445 lines (444 loc) • 16.4 kB
JavaScript
/*!
* Built with Stencil
* By PostNord.
*/
import { Host, h, Mixin } from "@stencil/core";
import { animateHeightFactory } from "../../../globals/mixins/index";
import { awaitTopbar, en, ripple } from "../../../index";
import { alert_info_circle, check_circle, alert_exclamation_triangle, alert_exclamation_circle, close, } from "pn-design-assets/pn-assets/icons.js";
import { translations } from "./translation";
/**
* This component is able to fill many roles of a classic toast.
* It has 4 different colors, a temporary state, hide button, icon and illustration support.
*
* The `pn-toast` will expand to its parent containers full width.
* Either limit the parent width or set a CSS rule to your specific width if needed.
*/
export class PnToast extends Mixin(animateHeightFactory) {
constructor() {
super();
}
toast;
button;
hostElement;
hasSlottedContent = false;
/**
* Set a title for the toast. Requires the `text` prop in order to work.
* @description Can be used together with slotted content.
*/
heading = '';
/**
* Set a paragraph of text for the toast.
* @description Can be used together with slotted content.
*/
text = '';
/** Give the toast a HTML ID. */
toastId;
/**
* Default color is blue, you also have the option of success (green), warning (orange) and error (red).
* @category Visual
*/
appearance;
/**
* This will apply a shadow and border to the toast.
* @category Visual
*/
temporary = false;
/**
* Set an SVG icon.
* @category Visual
*/
icon;
/**
* Set an SVG illustration.
* @category Visual
*/
illustration;
/**
* Control the visibility of the toast. If the `closable` prop is active, the toast will set the `hide` prop on its own.
* @see {@link closable}
* @category Features
*/
hide = false;
/**
* Show close button.
* @category Features
*/
closable = false;
/**
* Manually set the language, only needed if the `closable` prop is enabled.
* @see {@link closable}
* @category Features
*/
language = null;
handleHide() {
this.hostElement.style.overflow = 'hidden';
requestAnimationFrame(() => this.toggleToastVisibility());
}
/** Event fired when the close button is pressed. */
close;
/**
* This event is fired when the toast is fully hidden after the animation is finished.
* Triggers from the close button or if the prop `hide` is set to true.
* @since v7.6.0
**/
hidden;
async componentWillLoad() {
if (this.hide) {
this.hostElement.style.height = '0';
this.hostElement.style.overflow = 'hidden';
}
// Any text content at this stage means there is slotted content present.
this.hasSlottedContent = !!this.hostElement.textContent;
if (this.language === null)
await awaitTopbar(this.hostElement);
}
componentDidLoad() {
if (!!this.heading && !this.text && !this.hasSlottedContent)
console.warn('The %s prop is only available if you use the %s prop or slotted content.', 'heading', 'text');
}
toggleToastVisibility() {
if (this.hide)
this.closeDropdown(this.hostElement, this.toast.clientHeight);
else
this.openDropdown(this.hostElement, this.toast.clientHeight);
}
handleClick(event) {
this.hide = true;
this.close.emit(this.hide);
ripple(event, this.toast);
}
getIcon() {
if (this.illustration)
return '';
if (this.icon)
return this.icon;
if (this.appearance === 'success')
return check_circle;
if (this.appearance === 'warning')
return alert_exclamation_triangle;
if (this.appearance === 'error')
return alert_exclamation_circle;
return alert_info_circle;
}
getRole() {
return this.appearance === 'error' ? 'alert' : 'status';
}
showIcon() {
return !this.illustration;
}
showIllustration() {
return !this.showIcon();
}
showTitle() {
return (this.hasSlottedContent || !!this.text) && !!this.heading;
}
translate(prop) {
return translations?.[prop]?.[this.language || en] || prop;
}
hideToast() {
return this.hide && !this.isMoving();
}
render() {
return (h(Host, { key: '8fc8af6de122bae90d2909840a3d2c412cc3181d' }, h("div", { key: 'ad45d0c295ea660c6e03f1b98e91294519003886', id: this.toastId, class: "pn-toast", role: this.getRole(), "data-appearance": this.appearance, "data-temporary": this.temporary, "data-hide": this.hideToast(), ref: el => (this.toast = el) }, this.showIcon() && h("pn-icon", { key: '7e856fb052f535e72b15044347eb2a20dc141297', class: "pn-toast-icon", icon: this.getIcon() }), h("div", { key: 'b8549738d389bb4b3269192c9a6fa606e6500e25', class: "pn-toast-content" }, this.showTitle() && h("h4", { key: 'ef243b8a4d842c8583308bd8cd75a3c640ba811a', class: "pn-toast-heading" }, this.heading), this.text && h("p", { key: '7d4a03a243567f881ddaa826959c36cebd84ad00', class: "pn-toast-text" }, this.text), h("slot", { key: '1cf28e44d6f37c053b33634529ee0a2d1d7dc58d' })), this.showIllustration() && h("pn-illustration", { key: 'f219657a26c48361d1f31cccf947a13f749f6e7b', illustration: this.illustration, width: "5.5em", height: "5.5em" }), this.closable && (h("button", { key: '1bebf8881b20963d9a611cdcf8e293fb6f035cc7', class: "pn-toast-button", type: "button", "aria-label": this.translate('HIDE'), onClick: (event) => this.handleClick(event), ref: el => (this.button = el) }, h("pn-icon", { key: '14b4fee29de5810bd9d04476500e6d806fe3a2eb', icon: close }))))));
}
static get is() { return "pn-toast"; }
static get originalStyleUrls() {
return {
"$": ["pn-toast.scss"]
};
}
static get styleUrls() {
return {
"$": ["pn-toast.css"]
};
}
static get properties() {
return {
"heading": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "description",
"text": "Can be used together with slotted content."
}],
"text": "Set a title for the toast. Requires the `text` prop in order to work."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "heading",
"defaultValue": "''"
},
"text": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "description",
"text": "Can be used together with slotted content."
}],
"text": "Set a paragraph of text for the toast."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "text",
"defaultValue": "''"
},
"toastId": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Give the toast a HTML ID."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "toast-id"
},
"appearance": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'' | 'success' | 'warning' | 'error'",
"resolved": "\"\" | \"error\" | \"success\" | \"warning\"",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "category",
"text": "Visual"
}],
"text": "Default color is blue, you also have the option of success (green), warning (orange) and error (red)."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "appearance"
},
"temporary": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [{
"name": "category",
"text": "Visual"
}],
"text": "This will apply a shadow and border to the toast."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "temporary",
"defaultValue": "false"
},
"icon": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "category",
"text": "Visual"
}],
"text": "Set an SVG icon."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "icon"
},
"illustration": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "category",
"text": "Visual"
}],
"text": "Set an SVG illustration."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "illustration"
},
"hide": {
"type": "boolean",
"mutable": true,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [{
"name": "see",
"text": "{@link closable }"
}, {
"name": "category",
"text": "Features"
}],
"text": "Control the visibility of the toast. If the `closable` prop is active, the toast will set the `hide` prop on its own."
},
"getter": false,
"setter": false,
"reflect": true,
"attribute": "hide",
"defaultValue": "false"
},
"closable": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [{
"name": "category",
"text": "Features"
}],
"text": "Show close button."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "closable",
"defaultValue": "false"
},
"language": {
"type": "string",
"mutable": true,
"complexType": {
"original": "PnLanguages",
"resolved": "\"\" | \"da\" | \"en\" | \"fi\" | \"no\" | \"sv\"",
"references": {
"PnLanguages": {
"location": "import",
"path": "@/index",
"id": "src/index.ts::PnLanguages",
"referenceLocation": "PnLanguages"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [{
"name": "see",
"text": "{@link closable }"
}, {
"name": "category",
"text": "Features"
}],
"text": "Manually set the language, only needed if the `closable` prop is enabled."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "language",
"defaultValue": "null"
}
};
}
static get states() {
return {
"hasSlottedContent": {}
};
}
static get events() {
return [{
"method": "close",
"name": "close",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Event fired when the close button is pressed."
},
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
}
}, {
"method": "hidden",
"name": "hidden",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [{
"name": "since",
"text": "v7.6.0"
}],
"text": "This event is fired when the toast is fully hidden after the animation is finished.\nTriggers from the close button or if the prop `hide` is set to true."
},
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
}
}];
}
static get elementRef() { return "hostElement"; }
static get watchers() {
return [{
"propName": "hide",
"methodName": "handleHide"
}];
}
}