'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var React = require('react');
var focus = require('../../utilities/focus.js');
var useToggle = require('../../utilities/use-toggle.js');
var css = require('../../utilities/css.js');
var Tooltip$1 = require('./Tooltip.scss.js');
var hooks = require('../../utilities/ephemeral-presence-manager/hooks.js');
var TooltipOverlay = require('./components/TooltipOverlay/TooltipOverlay.js');
var hooks$1 = require('../../utilities/unique-id/hooks.js');
var Portal = require('../Portal/Portal.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);

const HOVER_OUT_TIMEOUT = 150;
function Tooltip({
  children,
  content,
  dismissOnMouseOut,
  active: originalActive,
  hoverDelay,
  preferredPosition = 'above',
  activatorWrapper = 'span',
  accessibilityLabel,
  width = 'default',
  padding = 'default',
  borderRadius = '1',
  zIndexOverride,
  hasUnderline,
  persistOnClick,
  onOpen,
  onClose
}) {
  const WrapperComponent = activatorWrapper;
  const {
    value: active,
    setTrue: setActiveTrue,
    setFalse: handleBlur
  } = useToggle.useToggle(Boolean(originalActive));
  const {
    value: persist,
    toggle: togglePersisting
  } = useToggle.useToggle(Boolean(originalActive) && Boolean(persistOnClick));
  const [activatorNode, setActivatorNode] = React.useState(null);
  const {
    presenceList,
    addPresence,
    removePresence
  } = hooks.useEphemeralPresenceManager();
  const id = hooks$1.useUniqueId('TooltipContent');
  const activatorContainer = React.useRef(null);
  const mouseEntered = React.useRef(false);
  const [shouldAnimate, setShouldAnimate] = React.useState(Boolean(!originalActive));
  const hoverDelayTimeout = React.useRef(null);
  const hoverOutTimeout = React.useRef(null);
  const handleFocus = React.useCallback(() => {
    if (originalActive !== false) {
      setActiveTrue();
    }
  }, [originalActive, setActiveTrue]);
  React.useEffect(() => {
    const firstFocusable = activatorContainer.current ? focus.findFirstFocusableNode(activatorContainer.current) : null;
    const accessibilityNode = firstFocusable || activatorContainer.current;
    if (!accessibilityNode) return;
    accessibilityNode.tabIndex = 0;
    accessibilityNode.setAttribute('aria-describedby', id);
    accessibilityNode.setAttribute('data-polaris-tooltip-activator', 'true');
  }, [id, children]);
  React.useEffect(() => {
    return () => {
      if (hoverDelayTimeout.current) {
        clearTimeout(hoverDelayTimeout.current);
      }

      if (hoverOutTimeout.current) {
        clearTimeout(hoverOutTimeout.current);
      }
    };
  }, []);
  const handleOpen = React.useCallback(() => {
    setShouldAnimate(!presenceList.tooltip && !active);
    onOpen === null || onOpen === void 0 ? void 0 : onOpen();
    addPresence('tooltip');
  }, [addPresence, presenceList.tooltip, onOpen, active]);
  const handleClose = React.useCallback(() => {
    onClose === null || onClose === void 0 ? void 0 : onClose();
    setShouldAnimate(false);
    hoverOutTimeout.current = setTimeout(() => {
      removePresence('tooltip');
    }, HOVER_OUT_TIMEOUT);
  }, [removePresence, onClose]);
  const handleKeyUp = React.useCallback(event => {
    if (event.key !== 'Escape') return;
    handleClose === null || handleClose === void 0 ? void 0 : handleClose();
    handleBlur();
    persistOnClick && togglePersisting();
  }, [handleBlur, handleClose, persistOnClick, togglePersisting]);
  const portal = activatorNode ? /*#__PURE__*/React__default["default"].createElement(Portal.Portal, {
    idPrefix: "tooltip"
  }, /*#__PURE__*/React__default["default"].createElement(TooltipOverlay.TooltipOverlay, {
    id: id,
    preferredPosition: preferredPosition,
    activator: activatorNode,
    active: active,
    accessibilityLabel: accessibilityLabel,
    onClose: noop,
    preventInteraction: dismissOnMouseOut,
    width: width,
    padding: padding,
    borderRadius: borderRadius,
    zIndexOverride: zIndexOverride,
    instant: !shouldAnimate
  }, content)) : null;
  const wrapperClassNames = css.classNames(activatorWrapper === 'div' && Tooltip$1["default"].TooltipContainer, hasUnderline && Tooltip$1["default"].HasUnderline);
  return /*#__PURE__*/React__default["default"].createElement(WrapperComponent, {
    onFocus: () => {
      handleOpen();
      handleFocus();
    },
    onBlur: () => {
      handleClose();
      handleBlur();

      if (persistOnClick) {
        togglePersisting();
      }
    },
    onMouseLeave: handleMouseLeave,
    onMouseOver: handleMouseEnterFix,
    onMouseDown: persistOnClick ? togglePersisting : undefined,
    ref: setActivator,
    onKeyUp: handleKeyUp,
    className: wrapperClassNames
  }, children, portal);

  function setActivator(node) {
    const activatorContainerRef = activatorContainer;

    if (node == null) {
      activatorContainerRef.current = null;
      setActivatorNode(null);
      return;
    }

    node.firstElementChild instanceof HTMLElement && setActivatorNode(node.firstElementChild);
    activatorContainerRef.current = node;
  }

  function handleMouseEnter() {
    mouseEntered.current = true;

    if (hoverDelay && !presenceList.tooltip) {
      hoverDelayTimeout.current = setTimeout(() => {
        handleOpen();
        handleFocus();
      }, hoverDelay);
    } else {
      handleOpen();
      handleFocus();
    }
  }

  function handleMouseLeave() {
    if (hoverDelayTimeout.current) {
      clearTimeout(hoverDelayTimeout.current);
      hoverDelayTimeout.current = null;
    }

    mouseEntered.current = false;
    handleClose();

    if (!persist) {
      handleBlur();
    }
  } // https://github.com/facebook/react/issues/10109
  // Mouseenter event not triggered when cursor moves from disabled button


  function handleMouseEnterFix() {
    !mouseEntered.current && handleMouseEnter();
  }
}

function noop() {}

exports.Tooltip = Tooltip;
