"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/components/Popover/Popover.tsx
var Popover_exports = {};
__export(Popover_exports, {
  Popover: () => Popover
});
module.exports = __toCommonJS(Popover_exports);
var import_icons3 = require("@simplybusiness/icons");
var import_dedupe3 = __toESM(require("classnames/dedupe"));
var import_react5 = require("react");
var import_react_dom = require("react-dom");
var import_mobius_hooks = require("@simplybusiness/mobius-hooks");

// src/components/Button/Button.tsx
var import_dedupe2 = __toESM(require("classnames/dedupe"));

// src/components/Button/Loading.tsx
var import_icons = require("@simplybusiness/icons");

// src/components/Icon/Icon.tsx
var import_dedupe = __toESM(require("classnames/dedupe"));
var import_Icon = require("@simplybusiness/mobius/src/components/Icon/Icon.css");
var import_jsx_runtime = require("react/jsx-runtime");
var ICON_PREFIX = "mobius-icon";
var capitaliseFirstLetter = (str) => str.charAt(0).toUpperCase() + str.slice(1);
function Icon({
  ref,
  icon,
  className,
  size = "xs",
  color,
  fixedWidth,
  spin,
  spinReverse,
  title,
  ...otherProps
}) {
  if (!icon) {
    throw new Error("Must specify icon object");
  }
  const classes = (0, import_dedupe.default)(
    "mobius",
    "mobius-icon",
    `svg-inline--${ICON_PREFIX}`,
    `--size-${size}`,
    className,
    {
      [`${ICON_PREFIX}-fw`]: fixedWidth,
      [`${ICON_PREFIX}-spin`]: spin || spinReverse,
      [`${ICON_PREFIX}-spin-reverse`]: spinReverse
    }
  );
  const { iconName, width, height, svgPathData } = icon;
  const formattedIconName = iconName.split("-").join(" ");
  const defaultTitle = `${capitaliseFirstLetter(formattedIconName)} icon`;
  const titleText = title || defaultTitle;
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
    "svg",
    {
      ref,
      focusable: "false",
      "data-icon": iconName,
      className: classes,
      role: "img",
      xmlns: "http://www.w3.org/2000/svg",
      viewBox: `0 0 ${width} ${height}`,
      style: { color },
      ...otherProps,
      children: [
        /* @__PURE__ */ (0, import_jsx_runtime.jsx)("title", { children: titleText }),
        /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { fill: "currentColor", d: svgPathData })
      ]
    }
  );
}

// src/components/VisuallyHidden/VisuallyHidden.tsx
var import_jsx_runtime2 = require("react/jsx-runtime");
function VisuallyHidden(props) {
  const {
    className,
    children,
    elementType: Component = "div",
    ...otherProps
  } = props;
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
    Component,
    {
      className,
      style: {
        border: 0,
        clip: "rect(0 0 0 0)",
        clipPath: "inset(50%)",
        height: "1px",
        margin: "-1px",
        overflow: "hidden",
        padding: 0,
        position: "absolute",
        width: "1px",
        whiteSpace: "nowrap"
      },
      ...otherProps,
      children
    }
  );
}

// src/components/Button/Loading.tsx
var import_jsx_runtime3 = require("react/jsx-runtime");
var Loading = (props) => {
  const { children } = props;
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
    /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mobius-button__icon-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { icon: import_icons.loading, spin: true, size: "md" }) }),
    /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(VisuallyHidden, { className: "mobius-button__loading-text", children: "Loading" }),
    children
  ] });
};

// src/hooks/useButton/useButton.tsx
var import_react = require("react");
function useButton({
  elementType = "button",
  type = "button",
  isDisabled = false,
  href,
  target,
  rel,
  role,
  name,
  value,
  onClick,
  onPress
}) {
  const realOnClick = (0, import_react.useCallback)(
    (event) => {
      if (isDisabled) {
        return;
      }
      onClick?.(event);
      onPress?.(event);
    },
    [isDisabled, onClick, onPress]
  );
  function getRole() {
    if (role) {
      return role;
    }
    if (elementType === "a") {
      return void 0;
    }
    return "button";
  }
  const extraProps = elementType === "button" ? { type } : {
    role: getRole()
  };
  return {
    buttonProps: {
      href: elementType === "a" ? href : void 0,
      target: elementType === "a" ? target : void 0,
      rel: elementType === "a" ? rel : void 0,
      tabIndex: isDisabled ? -1 : 0,
      disabled: isDisabled || void 0,
      "aria-disabled": isDisabled || void 0,
      name: elementType === "input" || elementType === "button" ? name : void 0,
      value: elementType === "input" || elementType === "button" ? value : void 0,
      ...extraProps,
      onClick: realOnClick
    }
  };
}

// src/components/Button/Success.tsx
var import_icons2 = require("@simplybusiness/icons");
var import_jsx_runtime4 = require("react/jsx-runtime");
var Success = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mobius-button__icon-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { icon: import_icons2.tick, size: "md" }) }),
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(VisuallyHidden, { className: "mobius-button__success-text", children: "Success" })
] });

// src/components/Button/Button.tsx
var import_Button = require("@simplybusiness/mobius/src/components/Button/Button.css");
var import_jsx_runtime5 = require("react/jsx-runtime");
var Button = ({ ref, ...props }) => {
  const {
    children,
    elementType: Component = "button",
    isDisabled,
    isLoading,
    isSuccess,
    variant = "primary",
    size = "md",
    onPress,
    onClick,
    ...otherProps
  } = props;
  const { buttonProps } = useButton(props);
  otherProps.className = (0, import_dedupe2.default)(
    "mobius",
    "mobius-button",
    `--variant-${variant}`,
    `--size-${size}`,
    {
      "--is-disabled": isDisabled,
      "--is-loading": isLoading,
      "--is-success": isSuccess && !isLoading
    },
    otherProps.className
  );
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Component, { ref, ...buttonProps, ...otherProps, children: [
    isLoading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Loading, { children }) : children,
    isSuccess && !isLoading && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Success, {})
  ] });
};
Button.displayName = "Button";

// src/components/Popover/Arrow.tsx
var import_jsx_runtime6 = require("react/jsx-runtime");
var Arrow = ({ ref, width = 20, className, style }) => {
  const height = width / 2;
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
    "svg",
    {
      ref,
      className,
      "aria-hidden": "true",
      width,
      height,
      viewBox: `0 0 ${width} ${height}`,
      style,
      children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: `M0,0 H${width} L${width / 2},${height} Z` })
    }
  );
};

// src/components/Popover/useAutoUpdate.ts
var import_react2 = require("react");
var useAutoUpdate = ({
  referenceRef,
  floatingRef,
  onUpdate,
  enabled
}) => {
  (0, import_react2.useEffect)(() => {
    if (!enabled) return;
    const reference = referenceRef.current;
    const floating = floatingRef.current;
    const scrollOpts = {
      capture: true,
      passive: true
    };
    window.addEventListener("scroll", onUpdate, scrollOpts);
    window.addEventListener("resize", onUpdate, { passive: true });
    const observer = typeof ResizeObserver === "function" ? new ResizeObserver(onUpdate) : null;
    if (observer && reference) observer.observe(reference);
    if (observer && floating) observer.observe(floating);
    return () => {
      window.removeEventListener("scroll", onUpdate, scrollOpts);
      window.removeEventListener("resize", onUpdate);
      observer?.disconnect();
    };
  }, [enabled, onUpdate, referenceRef, floatingRef]);
};

// src/components/Popover/useFloatingPosition.ts
var import_react3 = require("react");
var ABSOLUTE_FLOATING_STYLES = {
  position: "absolute",
  top: 0,
  left: 0,
  width: "max-content"
};
var FIXED_FLOATING_STYLES = {
  position: "fixed",
  top: 0,
  left: 0,
  width: "max-content"
};
var INITIAL_ARROW_STYLES = {
  position: "absolute"
};
var VIEWPORT_PADDING = 0;
var createsFixedContainingBlock = (el) => {
  const style = window.getComputedStyle(el);
  return style.transform !== "none" || style.filter !== "none" || style.backdropFilter !== "none" || style.perspective !== "none" || /\b(transform|filter|perspective)\b/.test(style.willChange);
};
var useFloatingPosition = ({
  referenceRef,
  floatingRef,
  arrowRef,
  isOpen,
  offsetPx,
  arrowWidth,
  useFixedStrategy
}) => {
  const update = (0, import_react3.useCallback)(() => {
    const reference = referenceRef.current;
    const floating = floatingRef.current;
    if (!reference || !floating) return;
    const refRect = reference.getBoundingClientRect();
    const floatingWidth = floating.offsetWidth;
    const floatingHeight = floating.offsetHeight;
    const scrollX = useFixedStrategy ? 0 : window.scrollX;
    const scrollY = useFixedStrategy ? 0 : window.scrollY;
    const parent = floating.parentElement;
    const parentIsCb = useFixedStrategy && !!parent && createsFixedContainingBlock(parent);
    const boundsRect = parentIsCb ? parent.getBoundingClientRect() : {
      left: 0,
      top: 0,
      right: window.innerWidth,
      bottom: window.innerHeight
    };
    const bottomTopViewport = refRect.bottom + offsetPx;
    const topTopViewport = refRect.top - floatingHeight - offsetPx;
    const overflowsBottom = bottomTopViewport + floatingHeight > boundsRect.bottom;
    const fitsTop = topTopViewport >= boundsRect.top;
    const nextPlacement = overflowsBottom && fitsTop ? "top" : "bottom";
    const topViewport = nextPlacement === "bottom" ? bottomTopViewport : topTopViewport;
    const rawLeftViewport = refRect.left + refRect.width / 2 - floatingWidth / 2;
    const minLeftViewport = boundsRect.left + VIEWPORT_PADDING;
    const maxLeftViewport = Math.max(
      minLeftViewport,
      boundsRect.right - floatingWidth - VIEWPORT_PADDING
    );
    const leftViewport = Math.min(
      Math.max(minLeftViewport, rawLeftViewport),
      maxLeftViewport
    );
    const cbOffsetLeft = parentIsCb ? boundsRect.left : 0;
    const cbOffsetTop = parentIsCb ? boundsRect.top : 0;
    floating.style.top = `${topViewport + scrollY - cbOffsetTop}px`;
    floating.style.left = `${leftViewport + scrollX - cbOffsetLeft}px`;
    const arrow = arrowRef.current;
    if (!arrow) return;
    const arrowHalf = arrowWidth / 2;
    const refCenterX = refRect.left + refRect.width / 2;
    const rawArrowLeft = refCenterX - leftViewport - arrowHalf;
    const maxArrowLeft = Math.max(0, floatingWidth - arrowWidth);
    const arrowLeft = Math.min(Math.max(0, rawArrowLeft), maxArrowLeft);
    arrow.style.left = `${arrowLeft}px`;
    if (nextPlacement === "bottom") {
      arrow.style.bottom = "100%";
      arrow.style.top = "";
      arrow.style.transform = "rotate(180deg)";
    } else {
      arrow.style.top = "100%";
      arrow.style.bottom = "";
      arrow.style.transform = "";
    }
  }, [
    referenceRef,
    floatingRef,
    arrowRef,
    offsetPx,
    arrowWidth,
    useFixedStrategy
  ]);
  (0, import_react3.useLayoutEffect)(() => {
    if (!isOpen) return;
    update();
  }, [isOpen, update]);
  return {
    initialFloatingStyles: useFixedStrategy ? FIXED_FLOATING_STYLES : ABSOLUTE_FLOATING_STYLES,
    initialArrowStyles: INITIAL_ARROW_STYLES,
    update
  };
};

// src/components/Popover/useOutsidePress.ts
var import_react4 = require("react");
var useOutsidePress = ({
  referenceRef,
  floatingRef,
  enabled,
  onOutsidePress
}) => {
  (0, import_react4.useEffect)(() => {
    if (!enabled) return;
    const handler = (event) => {
      const target = event.target;
      if (!target) return;
      if (referenceRef.current?.contains(target)) return;
      if (floatingRef.current?.contains(target)) return;
      onOutsidePress(event);
    };
    document.addEventListener("pointerdown", handler);
    return () => document.removeEventListener("pointerdown", handler);
  }, [enabled, onOutsidePress, referenceRef, floatingRef]);
};

// src/components/Popover/Popover.tsx
var import_Popover = require("@simplybusiness/mobius/src/components/Popover/Popover.css");
var import_jsx_runtime7 = require("react/jsx-runtime");
var OFFSET_FROM_CONTENT_DEFAULT = 10;
var ARROW_WIDTH = 20;
var Popover = (props) => {
  const { trigger, children, onOpen, onClose, className } = props;
  const referenceRef = (0, import_react5.useRef)(null);
  const floatingRef = (0, import_react5.useRef)(null);
  const arrowRef = (0, import_react5.useRef)(null);
  const [isOpen, setIsOpen] = (0, import_react5.useState)(false);
  const [portalTarget, setPortalTarget] = (0, import_react5.useState)(null);
  const isInsideDialog = portalTarget !== null && portalTarget.tagName === "DIALOG";
  const { initialFloatingStyles, initialArrowStyles, update } = useFloatingPosition({
    referenceRef,
    floatingRef,
    arrowRef,
    isOpen,
    offsetPx: OFFSET_FROM_CONTENT_DEFAULT,
    arrowWidth: ARROW_WIDTH,
    useFixedStrategy: isInsideDialog
  });
  useAutoUpdate({
    referenceRef,
    floatingRef,
    onUpdate: update,
    enabled: isOpen
  });
  useOutsidePress({
    referenceRef,
    floatingRef,
    enabled: isOpen,
    onOutsidePress: () => {
      onClose?.();
      setIsOpen(false);
    }
  });
  const containerClasses = (0, import_dedupe3.default)(
    "mobius",
    "mobius-popover__container",
    className
  );
  (0, import_react5.useEffect)(() => {
    const el = floatingRef.current;
    if (!el) return;
    const preventLabelActivation = (e) => {
      const target = e.target;
      if (!target.closest("a[href], input, select, textarea")) {
        e.preventDefault();
      }
    };
    el.addEventListener("click", preventLabelActivation);
    return () => el.removeEventListener("click", preventLabelActivation);
  }, [isOpen]);
  const toggleVisibility = () => {
    if (isOpen) {
      setIsOpen(false);
      onClose?.();
      return;
    }
    const dialog = referenceRef.current?.closest("dialog");
    setPortalTarget(dialog ?? document.body);
    setIsOpen(true);
    onOpen?.();
  };
  const setReferenceRef = (0, import_react5.useCallback)((node) => {
    referenceRef.current = node;
  }, []);
  const triggerComponent = (0, import_react5.cloneElement)(trigger, {
    ref: setReferenceRef,
    className: (0, import_dedupe3.default)(
      trigger.props.className,
      "mobius-popover__toggle"
    ),
    onClick: toggleVisibility
  });
  (0, import_mobius_hooks.useWindowEvent)("keydown", (e) => {
    if (e.key === "Escape" && isOpen) {
      setIsOpen(false);
      onClose?.();
      e.preventDefault();
      e.stopPropagation();
    }
  });
  const floatingElement = isOpen ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
    "div",
    {
      className: containerClasses,
      ref: floatingRef,
      style: initialFloatingStyles,
      children: [
        /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mobius-popover", children: [
          /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("header", { className: "mobius-popover__header", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
            Button,
            {
              type: "button",
              className: "mobius-popover__close-button",
              onClick: toggleVisibility,
              "aria-label": "Close",
              variant: "ghost",
              children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
                Icon,
                {
                  icon: import_icons3.cross,
                  size: "md",
                  className: "mobius-popover__close-icon"
                }
              )
            }
          ) }),
          /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mobius-popover__body", children })
        ] }),
        /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
          Arrow,
          {
            ref: arrowRef,
            style: initialArrowStyles,
            className: "mobius-popover__arrow-icon",
            width: ARROW_WIDTH
          }
        )
      ]
    }
  ) : null;
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
    triggerComponent,
    floatingElement && portalTarget ? (0, import_react_dom.createPortal)(floatingElement, portalTarget) : null
  ] });
};
//# sourceMappingURL=Popover.js.map
