UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

163 lines 5.83 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; const _excluded = ["children"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import React from 'react'; import { combineDescribedBy, warn } from '../../shared/component-helper'; import TooltipContainer from './TooltipContainer'; import { getRefElement, injectTooltipSemantic, isTouch, useHandleAria } from './TooltipHelpers'; import TooltipPortal from './TooltipPortal'; function TooltipWithEvents(props) { const { children } = props, restProps = _objectWithoutProperties(props, _excluded); const { active, target, skipPortal, noAnimation, showDelay, hideDelay, internalId } = restProps; const [isActive, setIsActive] = React.useState(active); const [isNotSemanticElement, setIsNotSemanticElement] = React.useState(false); const [isMounted, setIsMounted] = React.useState(!target); const delayTimeout = React.useRef(); const cloneRef = React.useRef(); const targetRef = React.useRef(); const clearTimers = () => { clearTimeout(delayTimeout.current); }; React.useLayoutEffect(() => { targetRef.current = getRefElement(cloneRef); }, [target]); React.useLayoutEffect(() => { if (targetRef.current) { setIsMounted(true); addEvents(targetRef.current); handleSemanticElement(); } return () => { clearTimers(); removeEvents(targetRef.current); }; }, []); const handleSemanticElement = () => { try { const targetElement = document.querySelector(`*[aria-describedby*="${internalId}"]`); if (targetElement) { const role = targetElement.getAttribute('role'); if (/div|p|span/i.test(targetElement === null || targetElement === void 0 ? void 0 : targetElement.tagName) && (!role || role === 'text')) { setIsNotSemanticElement(true); } } } catch (e) { warn(e); } }; const addEvents = element => { try { element.addEventListener('click', onMouseLeave); element.addEventListener('focus', onFocus); element.addEventListener('blur', onMouseLeave); element.addEventListener('mouseenter', onMouseEnter); element.addEventListener('mousedown', onMouseEnter); element.addEventListener('mouseleave', onMouseLeave); element.addEventListener('touchstart', onMouseEnter); element.addEventListener('touchend', onMouseLeave); } catch (e) { warn(e); } }; const removeEvents = element => { if (!element) return; try { element.removeEventListener('click', onMouseLeave); element.removeEventListener('focus', onFocus); element.removeEventListener('blur', onMouseLeave); element.removeEventListener('mouseenter', onMouseEnter); element.removeEventListener('mouseleave', onMouseLeave); element.removeEventListener('touchstart', onMouseEnter); element.removeEventListener('touchend', onMouseLeave); } catch (e) { warn(e); } }; const onFocus = e => { return onMouseEnter(e); }; const onMouseEnter = e => { try { const elem = e.currentTarget; if (elem.getAttribute('data-autofocus')) { return; } if (isTouch(e.type)) { elem.style.userSelect = 'none'; } } catch (e) { warn(e); } const run = () => { setIsActive(true); }; if (noAnimation || globalThis.IS_TEST) { run(); } else { clearTimers(); delayTimeout.current = setTimeout(run, parseFloat(String(showDelay)) || 1); } }; const onMouseLeave = e => { if (active) { return; } try { if (isTouch(e.type)) { const elem = e.currentTarget; elem.style.userSelect = ''; } } catch (e) { warn(e); } clearTimers(); const run = () => { setIsActive(false); }; if (skipPortal) { delayTimeout.current = setTimeout(run, parseFloat(String(hideDelay))); } else { run(); } }; const componentWrapper = React.useMemo(() => { if (React.isValidElement(target)) { const params = isNotSemanticElement ? injectTooltipSemantic({ className: props.className }) : {}; return React.cloneElement(target, _objectSpread(_objectSpread({ ref: cloneRef }, params), {}, { 'aria-describedby': combineDescribedBy(target.props, internalId) })); } else { cloneRef.current = target; } return null; }, [target]); useHandleAria(targetRef.current, internalId); return React.createElement(React.Fragment, null, isMounted && (skipPortal ? React.createElement(TooltipContainer, _extends({}, restProps, { active: isActive, targetElement: targetRef.current }), children) : React.createElement(TooltipPortal, _extends({}, restProps, { active: isActive, targetElement: targetRef.current, keepInDOM: true }), children)), componentWrapper); } export default TooltipWithEvents; //# sourceMappingURL=TooltipWithEvents.js.map