UNPKG

@react-hookz/web

Version:

React hooks done right, for browser and SSR.

43 lines (42 loc) 1.76 kB
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 { useEffect } from 'react'; import { off, on } from "../util/misc.js"; import { useSyncedRef } from '..'; var DEFAULT_EVENTS = ['mousedown', 'touchstart']; /** * Triggers callback when user clicks outside the target element. * * @param ref React ref object with target HTML element. * @param callback Callback that will be triggered during the click. * @param events Events list that will be used as triggers for outside click. * Default: 'mousedown', 'touchstart' */ export function useClickOutside(ref, callback, events) { if (events === void 0) { events = DEFAULT_EVENTS; } var cbRef = useSyncedRef(callback); var refRef = useSyncedRef(ref); useEffect(function () { function handler(event) { if (!refRef.current.current) return; var evtTarget = event.target; var cb = cbRef.current; if (!evtTarget || (!!evtTarget && !refRef.current.current.contains(evtTarget))) { cb.call(this, event); } } events.forEach(function (name) { return on(document, name, handler, { passive: true }); }); return function () { events.forEach(function (name) { return off(document, name, handler, { passive: true }); }); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, __spreadArray([], events, true)); }