import {
  kebabToCamelCase,
  uppercaseFirstLetter
} from "./chunk.SF6AUNJF.js";
import {
  getAnimation,
  setDefaultAnimation
} from "./chunk.N4LHE3QK.js";
import {
  waitForEvent
} from "./chunk.B4BZKR24.js";
import {
  LocalizeController
} from "./chunk.X3FE7OHE.js";
import {
  watch
} from "./chunk.X2OQMWGY.js";
import {
  SolidElement,
  customElement
} from "./chunk.H53WQBDK.js";
import {
  animateTo,
  shimKeyframesHeightAuto,
  stopAnimations
} from "./chunk.HQWAKJBV.js";
import {
  __decorateClass
} from "./chunk.S3NI7NKU.js";

// src/components/notification/notification.ts
import { css, html } from "lit";
import { ifDefined } from "lit/directives/if-defined.js";
import { property, query } from "lit/decorators.js";
import cx from "classix";
var stacks = {
  "top-right": null,
  "bottom-center": null
};
var loadStacks = () => {
  Object.entries(stacks).forEach(([name]) => {
    const stack = document.querySelector(`#sd-toast-stack--${name}`);
    if (stack) {
      stack.setAttribute("role", "region");
      stacks[name] = stack;
      return;
    }
    stacks[name] = Object.assign(document.createElement("div"), {
      role: "region",
      id: `sd-toast-stack--${name}`,
      className: `sd-toast-stack sd-toast-stack--${name}`
    });
  });
};
loadStacks();
var SdNotification = class extends SolidElement {
  constructor() {
    super(...arguments);
    this.localize = new LocalizeController(this);
    this.variant = "info";
    this.open = false;
    this.closable = false;
    this.duration = Infinity;
    this.durationIndicator = false;
    this.toastStack = "top-right";
    this.remainingDuration = this.duration;
    this.startTime = Date.now();
  }
  get stack() {
    return stacks[this.toastStack];
  }
  connectedCallback() {
    super.connectedCallback();
    if (!this.stack.parentElement) {
      document.body.append(this.stack);
      this.stack.ariaLabel = this.localize.term("notifications");
    }
  }
  disconnectedCallback() {
    super.disconnectedCallback();
  }
  firstUpdated() {
    this.wrapper.hidden = !this.open;
  }
  startAutoHide() {
    clearTimeout(this.autoHideTimeout);
    this.startTime = Date.now();
    this.remainingDuration = this.duration;
    if (this.open && this.duration < Infinity) {
      this.autoHideTimeout = window.setTimeout(() => this.hide(), this.duration);
    }
  }
  onHover() {
    clearTimeout(this.autoHideTimeout);
    if (this.duration < Infinity) {
      this.remainingDuration -= Date.now() - this.startTime;
    }
  }
  onHoverEnd() {
    this.startTime = Date.now();
    clearTimeout(this.autoHideTimeout);
    if (this.open && this.duration < Infinity) {
      this.autoHideTimeout = window.setTimeout(() => {
        this.hide();
      }, this.remainingDuration);
    }
  }
  handleCloseClick() {
    this.hide();
  }
  handleKeyDown(event) {
    if (this.closable && event.key === "Escape") {
      this.hide();
    }
  }
  async handleOpenChange() {
    if (this.open) {
      this.emit("sd-show");
      if (this.duration < Infinity) {
        this.startAutoHide();
      }
      await Promise.all([stopAnimations(this.base), stopAnimations(this.wrapper)]);
      this.wrapper.hidden = false;
      const baseAnimation = getAnimation(this, "notification.show", { dir: this.localize.dir() });
      const wrapperAnimation = getAnimation(
        this,
        `notification.wrapper.show${uppercaseFirstLetter(kebabToCamelCase(this.toastStack))}`,
        { dir: this.localize.dir() }
      );
      await Promise.all([
        animateTo(
          this.base,
          shimKeyframesHeightAuto(baseAnimation.keyframes, this.base.scrollHeight),
          baseAnimation.options
        ),
        animateTo(this.wrapper, wrapperAnimation.keyframes, wrapperAnimation.options)
      ]);
      this.emit("sd-after-show");
    } else {
      this.emit("sd-hide");
      clearTimeout(this.autoHideTimeout);
      await Promise.all([stopAnimations(this.base), stopAnimations(this.wrapper)]);
      const baseAnimation = getAnimation(this, "notification.hide", { dir: this.localize.dir() });
      const wrapperAnimation = getAnimation(
        this,
        `notification.wrapper.hide${uppercaseFirstLetter(kebabToCamelCase(this.toastStack))}`,
        { dir: this.localize.dir() }
      );
      await Promise.all([
        animateTo(
          this.base,
          shimKeyframesHeightAuto(baseAnimation.keyframes, this.base.scrollHeight),
          baseAnimation.options
        ),
        animateTo(this.wrapper, wrapperAnimation.keyframes, wrapperAnimation.options)
      ]);
      this.wrapper.hidden = true;
      this.emit("sd-after-hide");
    }
  }
  handleDurationChange() {
    this.startAutoHide();
  }
  /** Shows the notification. */
  async show() {
    if (this.open) {
      return void 0;
    }
    this.open = true;
    return waitForEvent(this, "sd-after-show");
  }
  /** Hides the notification */
  async hide() {
    if (!this.open) {
      return void 0;
    }
    this.open = false;
    return waitForEvent(this, "sd-after-hide");
  }
  /**
   * Displays the notification as a toast notification. This will move the notification out of its position in the DOM and, when
   * dismissed, it will be removed from the DOM completely. By storing a reference to the notification, you can reuse it by
   * calling this method again. The returned promise will resolve after the notification is hidden.
   */
  async toast() {
    return new Promise((resolve) => {
      if (this.stack.parentElement === null) {
        document.body.append(this.stack);
      }
      this.stack.appendChild(this);
      requestAnimationFrame(() => {
        this.clientWidth;
        this.show();
      });
      this.addEventListener(
        "sd-after-hide",
        () => {
          this.stack.removeChild(this);
          resolve();
        },
        { once: true }
      );
    });
  }
  render() {
    return html`<div part="base" class="${cx("w-full flex items-stretch m-2 focus-visible:focus-outline")}" id="notification" tabindex="${ifDefined(this.closable ? "0" : void 0)}" role="alert" aria-labelledby="message" aria-hidden="${this.open ? "false" : "true"}" @mouseenter="${this.onHover}" @mouseleave="${this.onHoverEnd}" @keydown="${this.handleKeyDown}"><div part="wrapper" class="${cx("w-full h-fit overflow-hidden flex items-stretch relative")}"><slot name="icon" part="icon" class="${cx(
      "min-w-min flex items-center px-3 justify-center",
      {
        info: "bg-info",
        success: "bg-success",
        warning: "bg-warning",
        error: "bg-error"
      }[this.variant]
    )}"><sd-icon name="${{
      info: "info-circle",
      success: "confirm-circle",
      warning: "exclamation-circle",
      error: "warning"
    }[this.variant] || ""}" library="_internal" class="h-6 w-6 text-white"></sd-icon></slot><div part="content" class="${cx(
      "h-full w-full p-1 gap-2 flex items-center justify-stretch bg-white",
      "border-solid border-[1px] border-l-0 sd-notification-color-border",
      {
        info: "sd-notification--info-color-background",
        success: "sd-notification--success-color-background",
        warning: "sd-notification--warning-color-background",
        error: "sd-notification--error-color-background"
      }[this.variant]
    )}"><slot id="message" part="message" class="block w-full pl-3 py-2"></slot>${this.closable ? html`<sd-button size="md" variant="tertiary" part="close-button" class="ml-auto flex flex-[0_0_auto] items-stretch" @click="${this.handleCloseClick}"><sd-icon label="${this.localize.term("close")}" name="close" library="_internal" color="currentColor"></sd-icon></sd-button>` : ""}</div>${this.durationIndicator ? html`<div part="duration-indicator__elapsed" id="duration-indicator__elapsed" style="${`animation-duration: ${this.duration}ms`}" class="${cx(
      `absolute w-0 h-[2px] bottom-0 sd-notification__duration-indicator-color-background z-10 animate-grow`
    )}"></div><div part="duration-indicator__total" class="w-full h-[2px] bottom-0 absolute border border-neutral-400"></div>` : ""}</div></div>`;
  }
};
/**
 * Inherits global stylesheet including TailwindCSS
 */
SdNotification.styles = [
  ...SolidElement.styles,
  css`/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */@layer theme,base,components,utilities;
:host{display:contents}#notification:hover #duration-indicator__elapsed{animation-play-state:paused!important}`
];
__decorateClass([
  query('[part~="base"]')
], SdNotification.prototype, "base", 2);
__decorateClass([
  query('[part~="wrapper"]')
], SdNotification.prototype, "wrapper", 2);
__decorateClass([
  query('[part~="close-button"]')
], SdNotification.prototype, "close", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdNotification.prototype, "variant", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdNotification.prototype, "open", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdNotification.prototype, "closable", 2);
__decorateClass([
  property({ type: Number, reflect: true })
], SdNotification.prototype, "duration", 2);
__decorateClass([
  property({ type: Boolean, reflect: true, attribute: "duration-indicator" })
], SdNotification.prototype, "durationIndicator", 2);
__decorateClass([
  property({ type: String, reflect: true, attribute: "toast-stack" })
], SdNotification.prototype, "toastStack", 2);
__decorateClass([
  watch("open", { waitUntilFirstUpdate: true })
], SdNotification.prototype, "handleOpenChange", 1);
__decorateClass([
  watch("duration")
], SdNotification.prototype, "handleDurationChange", 1);
SdNotification = __decorateClass([
  customElement("sd-notification")
], SdNotification);
setDefaultAnimation("notification.show", {
  keyframes: [
    { opacity: 0, height: 0 },
    { opacity: 1, height: "auto" }
  ],
  options: { duration: "var(--sd-duration-medium, 300)", easing: "ease-in-out" }
});
setDefaultAnimation("notification.hide", {
  keyframes: [
    { opacity: 1, height: "auto" },
    { opacity: 0, height: 0 }
  ],
  options: { duration: "var(--sd-duration-fast, 150)", easing: "ease-in-out" }
});
setDefaultAnimation("notification.wrapper.showTopRight", {
  keyframes: [{ bottom: "32px" }, { bottom: "0" }],
  options: { duration: "var(--sd-duration-medium, 300)", easing: "ease-in-out" }
});
setDefaultAnimation("notification.wrapper.hideTopRight", {
  keyframes: [{ bottom: "0" }, { bottom: "32px" }],
  options: { duration: "var(--sd-duration-fast, 150)", easing: "ease-in-out" }
});

export {
  SdNotification
};
