"use strict";
const jsxRuntime = require("react/jsx-runtime");
const React = require("react");
const reactPopperTooltip = require("react-popper-tooltip");
const isMobile = require("is-mobile");
const assert = require("assert");
const reactDom = require("react-dom");
const styles_lib_components_Accordion_AccordionItem_cjs = require("../Accordion/AccordionItem.cjs");
const sideEffects_lib_components_BraidProvider_BraidProvider_cjs = require("../../../../side-effects/lib/components/BraidProvider/BraidProvider.cjs");
const styles_lib_components_BraidProvider_VanillaThemeContainer_cjs = require("../BraidProvider/VanillaThemeContainer.cjs");
const styles_lib_css_atoms_atoms_cjs = require("../../css/atoms/atoms.cjs");
const styles_lib_components_Tabs_Tab_cjs = require("../Tabs/Tab.cjs");
const styles_lib_components_Box_Box_cjs = require("../Box/Box.cjs");
const styles_lib_components_TooltipRenderer_TooltipRenderer_css_cjs = require("./TooltipRenderer.css.cjs");
const styles_lib_components_Tabs_Tabs_cjs = require("../Tabs/Tabs.cjs");
const _interopDefaultCompat = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
const isMobile__default = /* @__PURE__ */ _interopDefaultCompat(isMobile);
const assert__default = /* @__PURE__ */ _interopDefaultCompat(assert);
const BraidPortal = ({ children, container }) => {
  const { vanillaTheme } = sideEffects_lib_components_BraidProvider_BraidProvider_cjs.useBraidTheme();
  return reactDom.createPortal(
    /* @__PURE__ */ jsxRuntime.jsx(styles_lib_components_Accordion_AccordionItem_cjs.TextContext.Provider, { value: null, children: /* @__PURE__ */ jsxRuntime.jsx(styles_lib_components_BraidProvider_VanillaThemeContainer_cjs.VanillaThemeContainer, { theme: vanillaTheme, setDefaultTextTones: true, children }) }),
    container ?? document.body
  );
};
const useThemeName = () => sideEffects_lib_components_BraidProvider_BraidProvider_cjs.useBraidTheme().name;
const StaticTooltipContext = React.createContext(false);
const TooltipTextDefaultsProvider = ({
  children
}) => {
  const themeName = useThemeName();
  return /* @__PURE__ */ jsxRuntime.jsx(
    styles_lib_components_Accordion_AccordionItem_cjs.DefaultTextPropsProvider,
    {
      size: themeName === "docs" ? "small" : void 0,
      weight: "medium",
      children
    }
  );
};
const borderRadius = "large";
const TooltipContent = ({
  children,
  opacity,
  arrowProps
}) => /* @__PURE__ */ jsxRuntime.jsx(
  styles_lib_components_Box_Box_cjs.Box,
  {
    display: "flex",
    position: "relative",
    transition: "fast",
    opacity: opacity === 0 ? 0 : void 0,
    className: opacity === 0 ? styles_lib_components_TooltipRenderer_TooltipRenderer_css_cjs.verticalOffsetBeforeEntrance : styles_lib_components_TooltipRenderer_TooltipRenderer_css_cjs.translateZ0,
    children: /* @__PURE__ */ jsxRuntime.jsx(
      styles_lib_components_Box_Box_cjs.Box,
      {
        boxShadow: "large",
        background: "neutral",
        borderRadius,
        padding: "small",
        className: [styles_lib_components_TooltipRenderer_TooltipRenderer_css_cjs.maxWidth, styles_lib_components_TooltipRenderer_TooltipRenderer_css_cjs.translateZ0],
        children: /* @__PURE__ */ jsxRuntime.jsxs(TooltipTextDefaultsProvider, { children: [
          /* @__PURE__ */ jsxRuntime.jsx(styles_lib_components_Box_Box_cjs.Box, { position: "relative", zIndex: 1, children }),
          /* @__PURE__ */ jsxRuntime.jsx(
            styles_lib_components_Box_Box_cjs.Box,
            {
              ...arrowProps,
              borderRadius,
              background: "neutral",
              className: styles_lib_components_TooltipRenderer_TooltipRenderer_css_cjs.arrow
            }
          )
        ] })
      }
    )
  }
);
const validPlacements = ["top", "bottom"];
const normaliseRect = (domRect) => ({
  top: Math.round((domRect == null ? void 0 : domRect.top) || 0),
  left: Math.round((domRect == null ? void 0 : domRect.left) || 0),
  height: Math.round((domRect == null ? void 0 : domRect.height) || 0),
  width: Math.round((domRect == null ? void 0 : domRect.width) || 0)
});
const defaultRect = normaliseRect();
const doesBoundingBoxNeedUpdating = (element, previousRect) => {
  const currentRect = normaliseRect(element == null ? void 0 : element.getBoundingClientRect());
  return JSON.stringify(currentRect) !== JSON.stringify(previousRect);
};
const TooltipRenderer = ({
  id,
  tooltip,
  placement = "top",
  children
}) => {
  assert__default.default(
    validPlacements.includes(placement),
    `The 'placement' prop must be one of the following: ${validPlacements.join(
      ", "
    )}`
  );
  const isStatic = React.useContext(StaticTooltipContext);
  const [controlledVisible, setControlledVisible] = React.useState(false);
  const [opacity, setOpacity] = React.useState(0);
  const { grid, space } = styles_lib_components_Tabs_Tab_cjs.useSpace();
  const triggerBoundingBoxRef = React.useRef(defaultRect);
  const tooltipBoundingRectRef = React.useRef(defaultRect);
  const {
    visible,
    getTooltipProps,
    setTooltipRef,
    tooltipRef,
    setTriggerRef,
    triggerRef,
    getArrowProps,
    update
  } = reactPopperTooltip.usePopperTooltip(
    {
      placement,
      trigger: [isMobile__default.default() ? "click" : "hover", "focus"],
      visible: isStatic || controlledVisible,
      onVisibleChange: (newState) => {
        triggerBoundingBoxRef.current = normaliseRect(
          triggerRef == null ? void 0 : triggerRef.getBoundingClientRect()
        );
        tooltipBoundingRectRef.current = normaliseRect(
          tooltipRef == null ? void 0 : tooltipRef.getBoundingClientRect()
        );
        setControlledVisible(newState);
      }
    },
    {
      modifiers: [
        {
          name: "preventOverflow",
          options: {
            padding: space.xsmall * grid
          }
        },
        {
          name: "offset",
          options: {
            offset: [0, space.small * grid]
          }
        },
        {
          name: "arrow",
          options: {
            padding: space.xsmall * grid
          }
        },
        ...isStatic ? [
          {
            name: "flip",
            options: {
              fallbackPlacements: []
            }
          }
        ] : []
      ]
    }
  );
  styles_lib_components_Tabs_Tabs_cjs.useIsomorphicLayoutEffect(() => {
    if (controlledVisible && update && (doesBoundingBoxNeedUpdating(triggerRef, triggerBoundingBoxRef.current) || doesBoundingBoxNeedUpdating(tooltipRef, tooltipBoundingRectRef.current))) {
      triggerBoundingBoxRef.current = normaliseRect(
        triggerRef == null ? void 0 : triggerRef.getBoundingClientRect()
      );
      tooltipBoundingRectRef.current = normaliseRect(
        tooltipRef == null ? void 0 : tooltipRef.getBoundingClientRect()
      );
      update();
    }
  });
  React.useEffect(() => {
    if (visible) {
      const handleKeyDown = ({ key }) => {
        if (key === "Escape") {
          setControlledVisible(false);
        }
      };
      const handleScroll = () => {
        setControlledVisible(false);
      };
      const scrollHandlerOptions = {
        capture: true,
        passive: true
      };
      document.addEventListener("keydown", handleKeyDown);
      document.addEventListener("scroll", handleScroll, scrollHandlerOptions);
      return () => {
        document.removeEventListener("keydown", handleKeyDown);
        document.removeEventListener(
          "scroll",
          handleScroll,
          scrollHandlerOptions
        );
      };
    }
  }, [visible]);
  React.useEffect(() => {
    if (!triggerRef) {
      return;
    }
    if (visible) {
      const handleFocusIn = (event) => {
        if (event.currentTarget !== triggerRef) {
          setControlledVisible(false);
        }
      };
      document.addEventListener("focusin", handleFocusIn);
      return () => {
        document.removeEventListener("focusin", handleFocusIn);
      };
    }
  }, [triggerRef, visible]);
  assert__default.default(
    React.useEffect(() => {
      if (tooltipRef) {
        assert__default.default(
          tooltipRef.querySelectorAll("button, input, select, textarea, a").length === 0,
          "For accessibility reasons, tooltips must not contain interactive elements"
        );
      }
    }, [tooltipRef]) === void 0
  );
  React.useEffect(() => {
    if (!tooltipRef || !visible) {
      return setOpacity(0);
    }
    const timeout = setTimeout(() => setOpacity(100), isMobile__default.default() ? 0 : 250);
    return () => clearTimeout(timeout);
  }, [tooltipRef, visible]);
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
    children({
      triggerProps: {
        tabIndex: 0,
        ref: setTriggerRef,
        "aria-describedby": id
      }
    }),
    triggerRef && /* @__PURE__ */ jsxRuntime.jsx(BraidPortal, { children: /* @__PURE__ */ jsxRuntime.jsx(
      "div",
      {
        id,
        role: "tooltip",
        hidden: !visible ? true : void 0,
        className: styles_lib_css_atoms_atoms_cjs.atoms({
          reset: "div",
          zIndex: "notification",
          pointerEvents: "none",
          display: triggerRef && visible ? void 0 : "none"
        }),
        ...visible ? getTooltipProps({
          ref: setTooltipRef
        }) : null,
        children: /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { opacity, arrowProps: getArrowProps(), children: tooltip })
      }
    ) })
  ] });
};
exports.BraidPortal = BraidPortal;
exports.TooltipRenderer = TooltipRenderer;
exports.useThemeName = useThemeName;
