UNPKG

rc-hooks

Version:
65 lines (64 loc) 2.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var react_1 = require("react"); var ut2_1 = require("ut2"); var getRef_1 = tslib_1.__importDefault(require("../utils/getRef")); var useLatest_1 = tslib_1.__importDefault(require("../useLatest")); /** * 管理目标元素外事件的 Hook。 * * @param {Object} ref Dom 节点或 Ref 对象,支持数组。 * @param {Function} onClickAway 触发事件的函数。 * @param {string | string[]} [events='click'] 监听事件名称,支持数组。默认 `click`。 * @example * const [count, setCount] = React.useState(0); * const ref = React.useRef<HTMLSpanElement>(null); * * useClickAway(ref, () => { * setCount((c) => c + 1); * }); * * return ( * <div> * <span ref={ref}> * <button>box</button> * </span> * <p>count: {count}</p> * </div> * ); */ function useClickAway(ref, onClickAway, events) { if (events === void 0) { events = 'click'; } var refs = (0, ut2_1.castArray)(ref); var latestRefs = (0, useLatest_1.default)(refs); var refsIsFunc = refs.every(function (item) { return typeof item === 'function'; }); var wrapperRefs = refsIsFunc ? latestRefs : refs; var onClickAwayRef = (0, useLatest_1.default)(onClickAway); var eventsArr = (0, ut2_1.castArray)(events); var eventsRef = (0, useLatest_1.default)(eventsArr); var eventsStr = eventsArr.join(''); (0, react_1.useEffect)(function () { var handler = function (event) { var _a; var targets = refsIsFunc ? wrapperRefs.current : wrapperRefs; if (!targets.some(function (targetItem) { var target = (0, getRef_1.default)(targetItem); return !target || (target === null || target === void 0 ? void 0 : target.contains(event.target)); })) { (_a = onClickAwayRef.current) === null || _a === void 0 ? void 0 : _a.call(onClickAwayRef, event); } }; var eventList = (0, ut2_1.castArray)(eventsRef.current); eventList.forEach(function (eventName) { document.addEventListener(eventName, handler); }); return function () { eventList.forEach(function (eventName) { document.removeEventListener(eventName, handler); }); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [wrapperRefs, refsIsFunc, eventsStr]); } exports.default = useClickAway;