@nex-ui/react
Version:
🎉 A beautiful, modern, and reliable React component library.
97 lines (93 loc) • 3.51 kB
JavaScript
"use client";
;
var utils = require('@nex-ui/utils');
var react = require('react');
var PopperContext = require('./PopperContext.cjs');
var isFocusVisible = require('../utils/isFocusVisible.cjs');
const PopperTrigger = (props)=>{
const focusVisibleRef = react.useRef(false);
const { open, setOpen, handleClose, handleOpen, referenceRef, popperRootRef } = PopperContext.usePopper();
const { children, elementProps, action = 'hover', interactive = true, closeOnClick = true } = props;
react.useEffect(()=>{
if (open && action === 'click') {
const doc = utils.ownerDocument(referenceRef.current);
return utils.addEventListener(doc.body, 'click', (e)=>{
// istanbul ignore next
if (!open) return;
const target = e.target;
if (!interactive || !popperRootRef?.current?.contains(target) && !referenceRef?.current?.contains(target)) {
handleClose();
}
});
}
}, [
action,
handleClose,
interactive,
open,
popperRootRef,
referenceRef
]);
react.useEffect(()=>{
if (open && interactive && action === 'hover' && popperRootRef.current) {
const removeMouseenter = utils.addEventListener(popperRootRef.current, 'mouseenter', handleOpen);
const removeMouseleave = utils.addEventListener(popperRootRef.current, 'mouseleave', handleClose);
return ()=>{
removeMouseenter();
removeMouseleave();
};
}
}, [
action,
handleClose,
interactive,
open,
popperRootRef,
handleOpen
]);
const renderChildren = ()=>{
const element = children;
const props = {
ref: referenceRef
};
if (action === 'click') {
const handleClick = ()=>{
if (!open) {
handleOpen();
} else if (closeOnClick) {
setOpen(false);
}
};
props.onClick = handleClick;
} else if (action === 'hover') {
const handleMouseEnter = handleOpen;
const handleMouseLeave = handleClose;
const handleClick = ()=>{
if (closeOnClick && open) setOpen(false);
};
const handleFocus = (event)=>{
if (isFocusVisible.isFocusVisible(event.currentTarget)) {
handleOpen();
focusVisibleRef.current = true;
}
};
const handleBlur = (event)=>{
if (focusVisibleRef.current && !isFocusVisible.isFocusVisible(event.currentTarget)) {
handleClose();
focusVisibleRef.current = false;
}
};
props.onMouseEnter = handleMouseEnter;
props.onMouseLeave = handleMouseLeave;
props.onClick = handleClick;
props.onFocus = handleFocus;
props.onBlur = handleBlur;
}
return /*#__PURE__*/ react.cloneElement(element, {
...utils.mergeProps(elementProps, element.props, props),
ref: utils.mergeRefs(elementProps?.ref, element.props.ref, props.ref)
});
};
return /*#__PURE__*/ react.isValidElement(children) ? renderChildren() : children;
};
exports.PopperTrigger = PopperTrigger;