juln-hooks
Version:
juln 自己的 hooks 和 react-help 集合 (已完全支持 tree-shaking)
115 lines • 3.75 kB
JavaScript
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;