UNPKG

@react-hookz/web

Version:

React hooks done right, for browser and SSR.

33 lines (32 loc) 1.29 kB
import { useEffect } from 'react'; import { off, on } from "../util/misc.js"; import { useSyncedRef } from '..'; const 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 = DEFAULT_EVENTS) { const cbRef = useSyncedRef(callback); const refRef = useSyncedRef(ref); useEffect(() => { function handler(event) { if (!refRef.current.current) return; const { target: evtTarget } = event; const cb = cbRef.current; if (!evtTarget || (!!evtTarget && !refRef.current.current.contains(evtTarget))) { cb.call(this, event); } } events.forEach((name) => on(document, name, handler, { passive: true })); return () => { events.forEach((name) => off(document, name, handler, { passive: true })); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [...events]); }