UNPKG

@postnord/web-components

Version:
220 lines (214 loc) 12.3 kB
/*! * Built with Stencil * By PostNord. */ import { r as registerInstance, c as createEvent, g as getElement, h, a as Host } from './index-C247oTEA.js'; import { reduceMotion, awaitTopbar, ripple, en } from './index.js'; import { a as alert_exclamation_circle } from './alert_exclamation_circle-B88w-Zxn.js'; import { a as alert_info_circle } from './alert_info_circle-BTqkgfeH.js'; import { c as check_circle } from './check_circle-D4GZ__oQ.js'; import { c as close } from './close-BvuWkoyY.js'; const icon = '<svg class="pn-icon-svg" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12.874 2.514a1 1 0 0 0-1.748 0l-10 18A1 1 0 0 0 2 22h20a1 1 0 0 0 .874-1.486zM12 5.06 20.3 20H3.7zm-1.375 4.936a1.38 1.38 0 1 1 2.75 0l-.292 3.509a1.087 1.087 0 0 1-2.166 0zM12 15.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3" clip-rule="evenodd"/></svg>'; const alert_exclamation_triangle = icon; const translations = { HIDE: { sv: 'Stäng meddelande', en: 'Dismiss message', da: 'Afvis besked', fi: 'Hylkää viesti', no: 'Avvis meldingen', }, }; const pnToastCss = "pn-toast{position:relative;display:block}pn-toast .pn-toast{position:relative;color:#2d2013;padding:1em;border-radius:0.5em;outline:none;font-size:1em;font-weight:400;background-color:#e0f8ff;border-color:#005d92;display:flex;align-items:center;gap:0.75em;visibility:visible;transition-property:visibility;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1)}@media (prefers-reduced-motion: reduce){pn-toast .pn-toast{transition-duration:0s;transition-delay:0s}}pn-toast .pn-toast .pn-ripple{animation:ripple 0.4s cubic-bezier(0.7, 0, 0.3, 1);position:absolute;border-radius:50%;background-color:#005d92;transform:translate(-50%, -50%) scale(0);opacity:0.1;pointer-events:none;z-index:3}@keyframes ripple{to{transform:translate(-50%, -50%) scale(1);opacity:0}}pn-toast .pn-toast[data-hide]{visibility:hidden;transition-delay:0.2s}pn-toast .pn-toast-heading{font-size:1em;font-style:normal;font-weight:500;margin:0}pn-toast .pn-toast-text{font-size:1em;font-style:normal;font-weight:400;margin:0 0 0.25em 0}pn-toast .pn-toast-text:last-child{margin-bottom:0}pn-toast .pn-toast-icon .pn-icon-svg path{fill:#2d2013}pn-toast .pn-toast-content{display:flex;flex-direction:column;align-self:center;align-items:flex-start;gap:0.25em;margin:0 auto 0 0}pn-toast .pn-toast-button{cursor:pointer;border-radius:50%;border:none;background:none;padding:0.25em;font-size:1em;display:flex;align-items:center;justify-content:center;transition-property:background-color, outline-color;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1)}@media (prefers-reduced-motion: reduce){pn-toast .pn-toast-button{transition-duration:0s;transition-delay:0s}}pn-toast .pn-toast-button{outline:0.2rem solid transparent;outline-offset:0.2rem}pn-toast .pn-toast-button:focus-visible{outline-color:#005d92;background-color:#8eddf9}pn-toast .pn-toast-button:hover{background-color:#8eddf9}pn-toast .pn-toast[data-appearance=success]{background-color:#dcf6e7}pn-toast .pn-toast[data-appearance=success] .pn-toast-button{outline:0.2rem solid transparent;outline-offset:0.2rem}pn-toast .pn-toast[data-appearance=success] .pn-toast-button:focus-visible{outline-color:#005e41;background-color:#abe3bb}pn-toast .pn-toast[data-appearance=success] .pn-toast-button:hover{background-color:#abe3bb}pn-toast .pn-toast[data-appearance=success] .pn-ripple{background-color:#005e41}pn-toast .pn-toast[data-appearance=success] .pn-toast-icon .pn-icon-svg path{fill:#005e41}pn-toast .pn-toast[data-appearance=success][data-temporary]{border-color:#005e41}pn-toast .pn-toast[data-appearance=warning]{background-color:#fff1e3}pn-toast .pn-toast[data-appearance=warning] .pn-toast-button{outline:0.2rem solid transparent;outline-offset:0.2rem}pn-toast .pn-toast[data-appearance=warning] .pn-toast-button:focus-visible{outline-color:#99290a;background-color:#ffc8a3}pn-toast .pn-toast[data-appearance=warning] .pn-toast-button:hover{background-color:#ffc8a3}pn-toast .pn-toast[data-appearance=warning] .pn-ripple{background-color:#99290a}pn-toast .pn-toast[data-appearance=warning] .pn-toast-icon .pn-icon-svg path{fill:#99290a}pn-toast .pn-toast[data-appearance=warning][data-temporary]{border-color:#ed7123}pn-toast .pn-toast[data-appearance=error]{background-color:#fdefee}pn-toast .pn-toast[data-appearance=error] .pn-toast-button{outline:0.2rem solid transparent;outline-offset:0.2rem}pn-toast .pn-toast[data-appearance=error] .pn-toast-button:focus-visible{outline-color:#a70707;background-color:#fbc2c1}pn-toast .pn-toast[data-appearance=error] .pn-toast-button:hover{background-color:#fbc2c1}pn-toast .pn-toast[data-appearance=error] .pn-ripple{background-color:#a70707}pn-toast .pn-toast[data-appearance=error] .pn-toast-icon .pn-icon-svg path{fill:#a70707}pn-toast .pn-toast[data-appearance=error][data-temporary]{border-color:#a70707}pn-toast .pn-toast[data-temporary]{border-style:solid;border-width:0.0625em;box-shadow:0 0.125em 0.25em rgba(0, 0, 0, 0.2)}"; const PnToast = class { constructor(hostRef) { registerInstance(this, hostRef); this.close = createEvent(this, "close"); this.hidden = createEvent(this, "hidden"); } toast; button; duration = 400; animationDuration = this.duration; animation; get hostElement() { return getElement(this); } isClosing = false; isExpanding = false; 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() { if (reduceMotion()) this.animationDuration = 0; else this.animationDuration = this.duration; this.hostElement.style.overflow = 'hidden'; requestAnimationFrame(() => { if (this.hide) this.closeToast(); else this.openToast(); }); } /** 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'; } if (this.language === null) await awaitTopbar(this.hostElement); // Any text content at this stage means there is slotted content present. this.hasSlottedContent = !!this.hostElement.textContent; } 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'); } getRect(element) { return element.getBoundingClientRect(); } openToast() { requestAnimationFrame(() => { const { clientHeight } = this.toast; const { height } = this.getRect(this.hostElement); this.hostElement.style.height = `${height}px`; this.isExpanding = true; this.animateToast(true, `${height}px`, `${clientHeight}px`); }); } closeToast() { const { clientHeight } = this.hostElement; this.hostElement.style.height = `0px`; this.isClosing = true; this.animateToast(false, `${clientHeight}px`, `0px`); } animateToast(open, startHeight, endHeight) { this.cancelAnimations(); this.animation = this.hostElement.animate({ height: [startHeight, endHeight], }, { duration: this.animationDuration, easing: 'cubic-bezier(0.6, 0, 0.2, 1)', }); this.animation.onfinish = () => this.animationFinish(); this.animation.oncancel = () => (open ? (this.isExpanding = false) : (this.isClosing = false)); } animationFinish() { this.cancelAnimations(); if (this.hide) this.hidden.emit(this.hide); else { this.hostElement.style.height = ''; this.hostElement.style.overflow = ''; } this.isClosing = false; this.isExpanding = false; } cancelAnimations() { if (this.animation) this.animation.cancel(); } 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; } isMoving() { return this.isClosing || this.isExpanding; } hideToast() { return this.hide && !this.isMoving(); } render() { return (h(Host, { key: '3cf1d74814cbc180b1c9086a94736a23276cb645' }, h("div", { key: 'af11e2541fdc70e08784a57ff8bee44389c70ad1', 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: '3b421c30b466575746dec912d84062b75d3748c0', class: "pn-toast-icon", icon: this.getIcon() }), h("div", { key: '1219c0ee1a8c562e5cec4de07a65cfc82e5e40d8', class: "pn-toast-content" }, this.showTitle() && h("h4", { key: '5e9799a8cc207a4ef73a91745ed91fb9f008e89b', class: "pn-toast-heading" }, this.heading), this.text && h("p", { key: '92e6733911aad5be4255694260ad5bc9e6a25fd6', class: "pn-toast-text" }, this.text), h("slot", { key: 'fe54b5da9541abc7c1d4130c37fce9bfffea1b17' })), this.showIllustration() && h("pn-illustration", { key: '7310562009f4c3e69238dccb07b25cdc1cc56437', illustration: this.illustration, width: "5.5em", height: "5.5em" }), this.closable && (h("button", { key: 'dba747b1754f14237ede20ebb9aea85e34037389', 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: '116b98596928d9b8d8942fc4aa3c636cf1e79f96', icon: close })))))); } static get watchers() { return { "hide": ["handleHide"] }; } }; PnToast.style = pnToastCss; export { PnToast as pn_toast }; //# sourceMappingURL=pn-toast.entry.js.map