import {
  SolidElement,
  customElement
} from "./chunk.H53WQBDK.js";
import {
  __decorateClass
} from "./chunk.S3NI7NKU.js";

// src/components/popup/popup.ts
import { arrow, autoUpdate, computePosition, flip, offset, shift, size } from "@floating-ui/dom";
import { css, html } from "lit";
import { property, query } from "lit/decorators.js";
import cx from "classix";
var SdPopup = class extends SolidElement {
  constructor() {
    super(...arguments);
    this.active = false;
    this.placement = "top";
    this.strategy = "absolute";
    this.distance = 0;
    this.skidding = 0;
    this.arrow = false;
    this.arrowPlacement = "anchor";
    this.arrowPadding = 10;
    this.flip = false;
    this.flipFallbackPlacements = "";
    this.flipFallbackStrategy = "best-fit";
    this.flipPadding = 0;
    this.shift = false;
    this.shiftPadding = 0;
    this.autoSizePadding = 0;
  }
  async connectedCallback() {
    super.connectedCallback();
    await this.updateComplete;
    this.start();
    this.setupMutationObserver();
  }
  disconnectedCallback() {
    this.stop();
    if (this.mutationObserver) {
      this.mutationObserver.disconnect();
    }
  }
  async updated(changedProps) {
    super.updated(changedProps);
    if (changedProps.has("active")) {
      if (this.active) {
        this.start();
      } else {
        this.stop();
      }
    }
    if (changedProps.has("anchor")) {
      this.handleAnchorChange();
    }
    if (this.active) {
      await this.updateComplete;
      this.reposition();
    }
  }
  setupMutationObserver() {
    this.mutationObserver = new MutationObserver((mutations) => this.handleCurrentPlacementChange(mutations));
    const config = { attributes: true };
    this.mutationObserver.observe(this, config);
  }
  handleCurrentPlacementChange(mutations) {
    return mutations.forEach((mutation) => {
      if (mutation.attributeName === "data-current-placement") {
        const currentPlacement = this.getAttribute("data-current-placement");
        this.emit("sd-current-placement", { detail: currentPlacement });
      }
    });
  }
  async handleAnchorChange() {
    await this.stop();
    if (this.anchor && typeof this.anchor === "string") {
      const root = this.getRootNode();
      this.anchorEl = root.getElementById(this.anchor);
    } else if (this.anchor instanceof HTMLElement) {
      this.anchorEl = this.anchor;
    } else {
      this.anchorEl = this.querySelector('[slot="anchor"]');
    }
    if (this.anchorEl instanceof HTMLSlotElement) {
      this.anchorEl = this.anchorEl.assignedElements({ flatten: true })[0];
    }
    if (!this.anchorEl) {
      throw new Error(
        "Invalid anchor element: no anchor could be found using the anchor slot or the anchor attribute."
      );
    }
    this.start();
  }
  start() {
    if (!this.anchorEl) {
      return;
    }
    this.cleanup = autoUpdate(this.anchorEl, this.popup, () => {
      this.reposition();
    });
  }
  async stop() {
    return new Promise((resolve) => {
      if (this.cleanup) {
        this.cleanup();
        this.cleanup = void 0;
        this.removeAttribute("data-current-placement");
        this.style.removeProperty("--auto-size-available-width");
        this.style.removeProperty("--auto-size-available-height");
        requestAnimationFrame(() => resolve());
      } else {
        resolve();
      }
    });
  }
  /** Forces the popup to recalculate and reposition itself. */
  reposition() {
    if (!this.active || !this.anchorEl) {
      return;
    }
    const middleware = [
      // The offset middleware goes first
      offset({ mainAxis: this.distance, crossAxis: this.skidding })
    ];
    if (this.sync) {
      middleware.push(
        size({
          apply: ({ rects }) => {
            const syncWidth = this.sync === "width" || this.sync === "both";
            const syncHeight = this.sync === "height" || this.sync === "both";
            this.popup.style.width = syncWidth ? `${rects.reference.width}px` : "";
            this.popup.style.height = syncHeight ? `${rects.reference.height}px` : "";
          }
        })
      );
    } else {
      this.popup.style.width = "";
      this.popup.style.height = "";
    }
    if (this.flip) {
      middleware.push(
        flip({
          boundary: this.flipBoundary,
          // @ts-expect-error - We're converting a string attribute to an array here
          fallbackPlacements: this.flipFallbackPlacements,
          fallbackStrategy: this.flipFallbackStrategy === "best-fit" ? "bestFit" : "initialPlacement",
          padding: this.flipPadding
        })
      );
    }
    if (this.shift) {
      middleware.push(
        shift({
          boundary: this.shiftBoundary,
          padding: this.shiftPadding
        })
      );
    }
    if (this.autoSize) {
      middleware.push(
        size({
          boundary: this.autoSizeBoundary,
          padding: this.autoSizePadding,
          apply: ({ availableWidth, availableHeight }) => {
            if (this.autoSize === "vertical" || this.autoSize === "both") {
              this.style.setProperty("--auto-size-available-height", `${availableHeight}px`);
            } else {
              this.style.removeProperty("--auto-size-available-height");
            }
            if (this.autoSize === "horizontal" || this.autoSize === "both") {
              this.style.setProperty("--auto-size-available-width", `${availableWidth}px`);
            } else {
              this.style.removeProperty("--auto-size-available-width");
            }
          }
        })
      );
    } else {
      this.style.removeProperty("--auto-size-available-width");
      this.style.removeProperty("--auto-size-available-height");
    }
    if (this.arrow) {
      middleware.push(
        arrow({
          element: this.arrowEl,
          padding: this.arrowPadding
        })
      );
    }
    computePosition(this.anchorEl, this.popup, {
      placement: this.placement,
      middleware,
      strategy: this.strategy
    }).then(({ x, y, middlewareData, placement }) => {
      const isRtl = getComputedStyle(this).direction === "rtl";
      const staticSide = { top: "bottom", right: "left", bottom: "top", left: "right" }[placement.split("-")[0]];
      this.setAttribute("data-current-placement", placement);
      Object.assign(this.popup.style, {
        left: `${x}px`,
        top: `${y}px`
      });
      if (this.arrow) {
        const arrowX = middlewareData.arrow.x;
        const arrowY = middlewareData.arrow.y;
        let top = "";
        let right = "";
        let bottom = "";
        let left = "";
        if (this.arrowPlacement === "start") {
          const value = typeof arrowX === "number" ? `calc(${this.arrowPadding}px - var(--arrow-padding-offset))` : "";
          top = typeof arrowY === "number" ? `calc(${this.arrowPadding}px - var(--arrow-padding-offset))` : "";
          right = isRtl ? value : "";
          left = isRtl ? "" : value;
        } else if (this.arrowPlacement === "end") {
          const value = typeof arrowX === "number" ? `calc(${this.arrowPadding}px - var(--arrow-padding-offset))` : "";
          right = isRtl ? "" : value;
          left = isRtl ? value : "";
          bottom = typeof arrowY === "number" ? `calc(${this.arrowPadding}px - var(--arrow-padding-offset))` : "";
        } else if (this.arrowPlacement === "center") {
          left = typeof arrowX === "number" ? `calc(50% - var(--arrow-size-diagonal))` : "";
          top = typeof arrowY === "number" ? `calc(50% - var(--arrow-size-diagonal))` : "";
        } else {
          left = typeof arrowX === "number" ? `${arrowX}px` : "";
          top = typeof arrowY === "number" ? `${arrowY}px` : "";
        }
        Object.assign(this.arrowEl.style, {
          top,
          right,
          bottom,
          left,
          [staticSide]: "calc(var(--arrow-size-diagonal) * -1)"
        });
      }
    });
    this.emit("sd-reposition");
  }
  render() {
    return html`<slot name="anchor" @slotchange="${this.handleAnchorChange}"></slot><div part="popup" class="${cx("isolate z-20", this.strategy !== "fixed" ? "absolute" : "fixed", !this.active && "hidden")}"><slot></slot>${this.arrow ? html`<div part="arrow" class="absolute rotate-45 -z-10" role="presentation"></div>` : ""}</div>`;
  }
};
SdPopup.styles = [
  ...SolidElement.styles,
  css`/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */@layer theme,base,components,utilities;
:host{--arrow-color:var(--sd-color-neutral-1000);--arrow-size:6px;--arrow-size-diagonal:calc(var(--arrow-size) * 0.7071);--arrow-padding-offset:calc(var(--arrow-size-diagonal) - var(--arrow-size));display:contents}[part=popup]{max-width:var(--auto-size-available-width,none);max-height:var(--auto-size-available-height,none)}[part=arrow]{width:calc(var(--arrow-size-diagonal) * 2);height:calc(var(--arrow-size-diagonal) * 2);background:var(--arrow-color)}`
];
__decorateClass([
  query('[part="popup"]')
], SdPopup.prototype, "popup", 2);
__decorateClass([
  query('[part="arrow"]')
], SdPopup.prototype, "arrowEl", 2);
__decorateClass([
  property({ reflect: true })
], SdPopup.prototype, "anchor", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdPopup.prototype, "active", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdPopup.prototype, "placement", 2);
__decorateClass([
  property({ type: String, reflect: true })
], SdPopup.prototype, "strategy", 2);
__decorateClass([
  property({ type: Number, reflect: true })
], SdPopup.prototype, "distance", 2);
__decorateClass([
  property({ type: Number, reflect: true })
], SdPopup.prototype, "skidding", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdPopup.prototype, "arrow", 2);
__decorateClass([
  property({ type: String, attribute: "arrow-placement", reflect: true })
], SdPopup.prototype, "arrowPlacement", 2);
__decorateClass([
  property({ attribute: "arrow-padding", type: Number, reflect: true })
], SdPopup.prototype, "arrowPadding", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], SdPopup.prototype, "flip", 2);
__decorateClass([
  property({
    attribute: "flip-fallback-placements",
    converter: {
      fromAttribute: (value) => {
        return value.split(" ").map((p) => p.trim()).filter((p) => p !== "");
      },
      toAttribute: (value) => {
        return value.join(" ");
      }
    }
  })
], SdPopup.prototype, "flipFallbackPlacements", 2);
__decorateClass([
  property({ type: String, attribute: "flip-fallback-strategy" })
], SdPopup.prototype, "flipFallbackStrategy", 2);
__decorateClass([
  property({ type: Object })
], SdPopup.prototype, "flipBoundary", 2);
__decorateClass([
  property({ attribute: "flip-padding", type: Number })
], SdPopup.prototype, "flipPadding", 2);
__decorateClass([
  property({ type: Boolean })
], SdPopup.prototype, "shift", 2);
__decorateClass([
  property({ type: Object })
], SdPopup.prototype, "shiftBoundary", 2);
__decorateClass([
  property({ attribute: "shift-padding", type: Number })
], SdPopup.prototype, "shiftPadding", 2);
__decorateClass([
  property({ type: String, attribute: "auto-size" })
], SdPopup.prototype, "autoSize", 2);
__decorateClass([
  property()
], SdPopup.prototype, "sync", 2);
__decorateClass([
  property({ type: Object })
], SdPopup.prototype, "autoSizeBoundary", 2);
__decorateClass([
  property({ attribute: "auto-size-padding", type: Number })
], SdPopup.prototype, "autoSizePadding", 2);
SdPopup = __decorateClass([
  customElement("sd-6-22-0-popup")
], SdPopup);

export {
  SdPopup
};
