react-outer-click
Version:
React component and hook which detect mouse clicks outside of itself.
87 lines (75 loc) • 3.15 kB
JavaScript
import _extends from '@babel/runtime/helpers/extends';
import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/objectWithoutPropertiesLoose';
import PropTypes from 'prop-types';
import { useRef, useEffect, forwardRef, useCallback, createElement } from 'react';
import invariant from 'tiny-invariant';
var isObject = function isObject(value) {
return typeof value === 'object' && value !== null;
};
var updateRef = function updateRef(ref, value) {
if (typeof ref === 'function') {
ref(value);
}
if (isObject(ref)) {
ref.current = value;
}
};
var castArray = function castArray(value) {
return Array.isArray(value) ? value : [value];
};
var useOuterClick = function useOuterClick(refs, handler) {
!(Array.isArray(refs) || isObject(refs)) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected `refs` to be an array or object') : invariant(false) : void 0;
if (Array.isArray(refs)) {
!(refs.length > 0) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected `refs` to to not be empty') : invariant(false) : void 0;
refs.forEach(function (ref, i) {
!isObject(ref) ? process.env.NODE_ENV !== "production" ? invariant(false, "Expected `refs[" + i + "]` to be an object") : invariant(false) : void 0;
});
}
!(typeof handler === 'function' || handler == null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected `handler` to be a function') : invariant(false) : void 0;
var eventListenerRef = useRef();
useEffect(function () {
eventListenerRef.current = function (event) {
if (castArray(refs).every(function (ref) {
return !ref.current || ref.current !== event.target && !ref.current.contains(event.target);
})) {
handler == null ? void 0 : handler(event);
}
};
}, [handler, refs]);
useEffect(function () {
var eventListener = function eventListener(event) {
eventListenerRef.current(event);
};
document.addEventListener('mousedown', eventListener, true);
document.addEventListener('touchstart', eventListener, true);
return function () {
document.removeEventListener('mousedown', eventListener, true);
document.removeEventListener('touchstart', eventListener, true);
};
}, []);
};
var _excluded = ["as", "children", "onOuterClick"];
var OuterClick = /*#__PURE__*/forwardRef(function (_ref, userRef) {
var _ref$as = _ref.as,
as = _ref$as === void 0 ? 'div' : _ref$as,
_ref$children = _ref.children,
children = _ref$children === void 0 ? null : _ref$children,
onOuterClick = _ref.onOuterClick,
props = _objectWithoutPropertiesLoose(_ref, _excluded);
var libRef = useRef(null);
useOuterClick(libRef, onOuterClick);
var ref = useCallback(function (value) {
libRef.current = value;
updateRef(userRef, value);
}, [userRef]);
return /*#__PURE__*/createElement(as, _extends({}, props, {
ref: ref
}), children);
});
OuterClick.propTypes = {
as: PropTypes.elementType,
children: PropTypes.node,
onOuterClick: PropTypes.func
};
export { OuterClick, useOuterClick };
//# sourceMappingURL=index.esm.js.map