@shopify/polaris
Version:
Shopify’s product component library
89 lines (78 loc) • 2.79 kB
JavaScript
import React$1, { useState, useRef, useEffect } from 'react';
import { useUniqueId } from '../../utilities/unique-id/hooks.js';
import { findFirstFocusableNode } from '../../utilities/focus.js';
import { Portal as Portal$1 } from '../Portal/Portal.js';
import { useToggle as useToggle$1 } from '../../utilities/use-toggle.js';
import styles from './Tooltip.scss.js';
import { TooltipOverlay as TooltipOverlay$1 } from './components/TooltipOverlay/TooltipOverlay.js';
function Tooltip({
children,
content,
light,
dismissOnMouseOut,
active: originalActive,
preferredPosition = 'below',
activatorWrapper = 'span'
}) {
var WrapperComponent = activatorWrapper;
var {
value: active,
setTrue: handleFocus,
setFalse: handleBlur
} = useToggle$1(Boolean(originalActive));
var [activatorNode, setActivatorNode] = useState(null);
var id = useUniqueId('TooltipContent');
var activatorContainer = useRef(null);
var mouseEntered = useRef(false);
useEffect(() => {
var firstFocusable = activatorContainer.current ? findFirstFocusableNode(activatorContainer.current) : null;
var accessibilityNode = firstFocusable || activatorContainer.current;
if (!accessibilityNode) return;
accessibilityNode.tabIndex = 0;
accessibilityNode.setAttribute('aria-describedby', id);
}, [id, children]);
var portal = activatorNode ? /*#__PURE__*/React$1.createElement(Portal$1, {
idPrefix: "tooltip"
}, /*#__PURE__*/React$1.createElement(TooltipOverlay$1, {
id: id,
preferredPosition: preferredPosition,
activator: activatorNode,
active: active,
onClose: noop,
light: light,
preventInteraction: dismissOnMouseOut
}, /*#__PURE__*/React$1.createElement("div", {
className: styles.Label
}, content))) : null;
return /*#__PURE__*/React$1.createElement(WrapperComponent, {
onFocus: handleFocus,
onBlur: handleBlur,
onMouseLeave: handleMouseLeave,
onMouseOver: handleMouseEnterFix,
ref: setActivator
}, children, portal);
function setActivator(node) {
var 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;
handleFocus();
}
function handleMouseLeave() {
mouseEntered.current = false;
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() {}
export { Tooltip };