@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
163 lines • 5.83 kB
JavaScript
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