UNPKG

@synergy-design-system/components

Version:
296 lines (289 loc) 8.63 kB
import { alert_styles_default } from "./chunk.UA5B6CPN.js"; import { blurActiveElement } from "./chunk.WXVOTRW5.js"; import { HasSlotController } from "./chunk.CHFWLQN5.js"; import { SynIconButton } from "./chunk.5XHXH7QA.js"; import { enableDefaultSettings } from "./chunk.WYMKPLYK.js"; import { waitForEvent } from "./chunk.LQDIH4Z5.js"; import { animateTo, stopAnimations } from "./chunk.DLSBQOBA.js"; import { getAnimation, setDefaultAnimation } from "./chunk.NIRQP534.js"; import { LocalizeController } from "./chunk.ZXMSJF2M.js"; import { watch } from "./chunk.UR2E7Y2Q.js"; import { component_styles_default } from "./chunk.2NT3B5WJ.js"; import { SynergyElement } from "./chunk.L2IYPRPF.js"; import { __decorateClass } from "./chunk.VK2FVWOF.js"; // src/components/alert/alert.component.ts import { classMap } from "lit/directives/class-map.js"; import { html } from "lit"; import { property, query, state } from "lit/decorators.js"; var SynAlert = class extends SynergyElement { constructor() { super(...arguments); this.hasSlotController = new HasSlotController(this, "icon", "suffix"); this.localize = new LocalizeController(this); this.open = false; this.closable = false; this.variant = "primary"; this.duration = Infinity; this.size = "medium"; this.remainingTime = this.duration; } static get toastStack() { if (!this.currentToastStack) { this.currentToastStack = Object.assign(document.createElement("div"), { className: "syn-toast-stack" }); } return this.currentToastStack; } firstUpdated() { this.base.hidden = !this.open; } restartAutoHide() { this.handleCountdownChange(); clearTimeout(this.autoHideTimeout); clearInterval(this.remainingTimeInterval); if (this.open && this.duration < Infinity) { this.autoHideTimeout = window.setTimeout(() => this.hide(), this.duration); this.remainingTime = this.duration; this.remainingTimeInterval = window.setInterval(() => { this.remainingTime -= 100; }, 100); } } pauseAutoHide() { var _a; (_a = this.countdownAnimation) == null ? void 0 : _a.pause(); clearTimeout(this.autoHideTimeout); clearInterval(this.remainingTimeInterval); } resumeAutoHide() { var _a; if (this.duration < Infinity) { this.autoHideTimeout = window.setTimeout(() => this.hide(), this.remainingTime); this.remainingTimeInterval = window.setInterval(() => { this.remainingTime -= 100; }, 100); (_a = this.countdownAnimation) == null ? void 0 : _a.play(); } } handleCountdownChange() { if (this.open && this.duration < Infinity && this.countdown) { const { countdownElement } = this; const start = "100%"; const end = "0"; this.countdownAnimation = countdownElement.animate([{ width: start }, { width: end }], { duration: this.duration, easing: "linear" }); } } handleCloseClick() { this.hide(); } async handleOpenChange() { if (this.open) { this.emit("syn-show"); if (this.duration < Infinity) { this.restartAutoHide(); } await stopAnimations(this.base); this.base.hidden = false; const { keyframes, options } = getAnimation(this, "alert.show", { dir: this.localize.dir() }); await animateTo(this.base, keyframes, options); this.emit("syn-after-show"); } else { blurActiveElement(this); this.emit("syn-hide"); clearTimeout(this.autoHideTimeout); clearInterval(this.remainingTimeInterval); await stopAnimations(this.base); const { keyframes, options } = getAnimation(this, "alert.hide", { dir: this.localize.dir() }); await animateTo(this.base, keyframes, options); this.base.hidden = true; this.emit("syn-after-hide"); } } handleDurationChange() { this.restartAutoHide(); } /** Shows the alert. */ async show() { if (this.open) { return void 0; } this.open = true; return waitForEvent(this, "syn-after-show"); } /** Hides the alert */ async hide() { if (!this.open) { return void 0; } this.open = false; return waitForEvent(this, "syn-after-hide"); } /** * Displays the alert as a toast notification. This will move the alert out of its position in the DOM and, when * dismissed, it will be removed from the DOM completely. By storing a reference to the alert, you can reuse it by * calling this method again. The returned promise will resolve after the alert is hidden. */ async toast() { return new Promise((resolve) => { this.handleCountdownChange(); if (SynAlert.toastStack.parentElement === null) { document.body.append(SynAlert.toastStack); } SynAlert.toastStack.appendChild(this); requestAnimationFrame(() => { this.clientWidth; this.show(); }); this.addEventListener( "syn-after-hide", () => { SynAlert.toastStack.removeChild(this); resolve(); if (SynAlert.toastStack.querySelector("syn-alert") === null) { SynAlert.toastStack.remove(); } }, { once: true } ); }); } render() { return html` <div part="base" class=${classMap({ alert: true, "alert--open": this.open, "alert--small": this.size === "small", "alert--medium": this.size === "medium", "alert--large": this.size === "large", "alert--closable": this.closable, "alert--has-icon": this.hasSlotController.test("icon"), "alert--primary": this.variant === "primary", "alert--success": this.variant === "success", "alert--neutral": this.variant === "neutral", "alert--warning": this.variant === "warning", "alert--danger": this.variant === "danger" })} role="alert" aria-hidden=${this.open ? "false" : "true"} @mouseenter=${this.pauseAutoHide} @mouseleave=${this.resumeAutoHide} > <div part="icon" class="alert__icon"> <slot name="icon"></slot> </div> <div part="message" class="alert__message" aria-live="polite"> <slot></slot> </div> ${this.closable ? html` <syn-icon-button part="close-button" exportparts="base:close-button__base" class="alert__close-button" name="x-lg" library="system" label=${this.localize.term("close")} @click=${this.handleCloseClick} ></syn-icon-button> ` : ""} <div role="timer" class="alert__timer">${this.remainingTime}</div> ${this.countdown ? html` <div class=${classMap({ alert__countdown: true, "alert__countdown--ltr": this.countdown === "ltr" })} > <div class="alert__countdown-elapsed"></div> </div> ` : ""} </div> `; } }; SynAlert.styles = [component_styles_default, alert_styles_default]; SynAlert.dependencies = { "syn-icon-button": SynIconButton }; __decorateClass([ query('[part~="base"]') ], SynAlert.prototype, "base", 2); __decorateClass([ query(".alert__countdown-elapsed") ], SynAlert.prototype, "countdownElement", 2); __decorateClass([ property({ type: Boolean, reflect: true }) ], SynAlert.prototype, "open", 2); __decorateClass([ property({ type: Boolean, reflect: true }) ], SynAlert.prototype, "closable", 2); __decorateClass([ property({ reflect: true }) ], SynAlert.prototype, "variant", 2); __decorateClass([ property({ type: Number }) ], SynAlert.prototype, "duration", 2); __decorateClass([ property({ reflect: true }) ], SynAlert.prototype, "size", 2); __decorateClass([ state() ], SynAlert.prototype, "remainingTime", 2); __decorateClass([ watch("open", { waitUntilFirstUpdate: true }) ], SynAlert.prototype, "handleOpenChange", 1); __decorateClass([ watch("duration") ], SynAlert.prototype, "handleDurationChange", 1); SynAlert = __decorateClass([ enableDefaultSettings("SynAlert") ], SynAlert); setDefaultAnimation("alert.show", { keyframes: [ { opacity: 0, scale: 0.8 }, { opacity: 1, scale: 1 } ], options: { duration: 250, easing: "ease" } }); setDefaultAnimation("alert.hide", { keyframes: [ { opacity: 1, scale: 1 }, { opacity: 0, scale: 0.8 } ], options: { duration: 250, easing: "ease" } }); export { SynAlert }; //# sourceMappingURL=chunk.I7A5QZZS.js.map