UNPKG

@postnord/web-components

Version:
445 lines (444 loc) 16.4 kB
/*! * 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" }]; } }