UNPKG

juln-hooks

Version:

juln 自己的 hooks 和 react-help 集合 (已完全支持 tree-shaking)

115 lines 3.75 kB
import { __assign, __read } from "tslib"; import { useEffect, useRef, useState } from "react"; /** * 处理类似于 `打开弹窗的按钮组件`和`弹窗组件` 的关联 * * @example * const App = () => { * const handler = useRef<HTMLButtonElement>(null); * const menu = useRef<HTMLDivElement>(null); * const { isShow: menuIsShow, close: closeMenu, toggle } = useFloatHandler({ * handler, * float: menu, * opts: { * disableHandlerToggle: false, * disableWindowBlur: false, * }, * }); * return ( * <> * <button ref={handler}>更多操作</button> * {menuIsShow && ( * <div ref={menu}> * 菜单 * <ul> * <li onClick={() => { console.log('添加'); closeMenu(); }}>添加</li> * <li onClick={() => { console.log('删除'); closeMenu(); }}>删除</li> * </ul> * </div> * )} * </> * ); * }; */ var useFloatHandler = function useFloatHandler(_a) { var _b, _c, _d; var handler = _a.handler, _float = _a["float"], opts = _a.opts; var disableHandlerToggle = (_b = opts === null || opts === void 0 ? void 0 : opts.disableHandlerToggle) !== null && _b !== void 0 ? _b : false; var disableBlurClose = (_c = opts === null || opts === void 0 ? void 0 : opts.disableBlurClose) !== null && _c !== void 0 ? _c : false; var disableWindowBlur = (_d = opts === null || opts === void 0 ? void 0 : opts.disableWindowBlur) !== null && _d !== void 0 ? _d : false; var _e = __read(useState(false), 2), isShow = _e[0], setIsShow = _e[1]; var open = function open() { return setIsShow(true); }; var close = function close() { return setIsShow(false); }; var toggle = function toggle() { return setIsShow(function (show) { return !show; }); }; var getEl = function getEl(elLick) { var elOrElRef = elLick instanceof Function ? elLick() : elLick; return elOrElRef instanceof HTMLElement ? elOrElRef : elOrElRef.current; }; useEffect(function () { var _a; var onClick = disableHandlerToggle ? open : toggle; (_a = getEl(handler)) === null || _a === void 0 ? void 0 : _a.addEventListener("click", onClick); return function () { var _a; return (_a = getEl(handler)) === null || _a === void 0 ? void 0 : _a.removeEventListener("click", onClick); }; }, [handler, disableHandlerToggle]); useEffect(function () { if (disableBlurClose) return; var onClick = function onClick(_a) { var _b, _c; var target = _a.target; if (!(target instanceof HTMLElement)) return; var isBlur = false; if (!((_b = getEl(handler)) === null || _b === void 0 ? void 0 : _b.contains(target)) && !((_c = getEl(_float)) === null || _c === void 0 ? void 0 : _c.contains(target))) { isBlur = true; } if (isBlur) { setIsShow(false); } }; window.addEventListener("click", onClick); return function () { return window.removeEventListener("click", onClick); }; }, [handler, _float, disableBlurClose]); useEffect(function () { if (disableWindowBlur) return; window.addEventListener("blur", close); return function () { return window.removeEventListener("blur", close); }; }, [disableWindowBlur]); return { isShow: isShow, open: open, toggle: toggle, close: close }; }; useFloatHandler.simple = function (opts) { var handlerRef = useRef(null); var floatRef = useRef(null); var result = useFloatHandler({ handler: handlerRef, "float": floatRef, opts: opts }); return __assign({ handlerRef: handlerRef, floatRef: floatRef }, result); }; export default useFloatHandler;