@ducor/react
Version:
admin template ui interface
97 lines (96 loc) • 3.67 kB
JavaScript
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import { useCallback, useEffect, useRef } from "react";
export function useCallbackRef(callback, deps) {
if (deps === void 0) { deps = []; }
var callbackRef = useRef(callback);
useEffect(function () {
callbackRef.current = callback;
});
return useCallback((function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return (_a = callbackRef.current) === null || _a === void 0 ? void 0 : _a.call.apply(_a, __spreadArray([callbackRef], args, false));
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
deps);
}
function isElement(el) {
return (el != null &&
typeof el == "object" &&
"nodeType" in el &&
el.nodeType === Node.ELEMENT_NODE);
}
function getOwnerDocument(el) {
return isElement(el) ? el.ownerDocument : document;
}
/**
* `useOutsideClick` is a custom hook that detects click events outside of an element.
*
* @see Docs https://ui.ducor.net/hooks/use-outside-click
*/
var useOutsideClick = function (_a) {
var ref = _a.ref, _b = _a.enabled, enabled = _b === void 0 ? true : _b, handler = _a.handler;
var handlerRef = useCallbackRef(handler);
var state = useRef({
ignoreEmulatedMouseEvents: false,
isPointerDown: false,
});
useEffect(function () {
if (!enabled)
return;
var onPointerDown = function (ev) {
if (isValidEvent(ev, ref))
state.current.isPointerDown = true;
};
var onMouseUp = function (ev) {
if (state.current.ignoreEmulatedMouseEvents) {
state.current.ignoreEmulatedMouseEvents = false;
return;
}
if (state.current.isPointerDown && handler && isValidEvent(ev, ref)) {
state.current.isPointerDown = false;
handlerRef(ev);
}
};
var onTouchEnd = function (ev) {
state.current.ignoreEmulatedMouseEvents = true;
if (handler && state.current.isPointerDown && isValidEvent(ev, ref)) {
state.current.isPointerDown = false;
handlerRef(ev);
}
};
var doc = getOwnerDocument(ref.current);
doc.addEventListener("mousedown", onPointerDown, true);
doc.addEventListener("mouseup", onMouseUp, true);
doc.addEventListener("touchstart", onPointerDown, true);
doc.addEventListener("touchend", onTouchEnd, true);
return function () {
doc.removeEventListener("mousedown", onPointerDown, true);
doc.removeEventListener("mouseup", onMouseUp, true);
doc.removeEventListener("touchstart", onPointerDown, true);
doc.removeEventListener("touchend", onTouchEnd, true);
};
}, [handler, ref, handlerRef, state, enabled]);
};
var isValidEvent = function (ev, ref) {
var _a;
var target = ev.target;
if ("button" in ev && ev.button > 0)
return false;
if (target)
if (!getOwnerDocument(target).contains(target))
return false;
return !((_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(target));
};
export default useOutsideClick;