snapshot of https://github.com/mountain-loop/yaak.git (main, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Lint and Test / Lint/Test (push) Has been cancelled
Generate Sponsors README / deploy (push) Has been skipped

This commit is contained in:
upstream-mirror
2026-09-23 17:39:41 +05:00
commit 906fb231cc
1544 changed files with 164131 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
import type { RefObject } from "react";
import { useEffect, useRef } from "react";
/**
* Get notified when a mouse click happens outside the target ref
* @param ref The element to be notified when a mouse click happens outside it
* @param onClickAway
* @param ignored Optional outside element to ignore (useful for dropdown triggers)
*/
export function useClickOutside(
ref: RefObject<HTMLElement | null>,
onClickAway: (event: MouseEvent) => void,
ignored?: RefObject<HTMLElement | null>,
) {
const savedCallback = useRef(onClickAway);
useEffect(() => {
savedCallback.current = onClickAway;
}, [onClickAway]);
useEffect(() => {
const handler = (event: MouseEvent) => {
if (ref.current == null || !(event.target instanceof HTMLElement)) {
return;
}
const isIgnored = ignored?.current?.contains(event.target);
const clickedOutside = !ref.current.contains(event.target);
if (!isIgnored && clickedOutside) {
savedCallback.current(event);
}
};
// NOTE: We're using mousedown instead of click to handle some edge cases like when a context
// menu is open with the ctrl key.
document.addEventListener("mousedown", handler, { capture: true });
document.addEventListener("contextmenu", handler, { capture: true });
return () => {
document.removeEventListener("mousedown", handler);
document.removeEventListener("contextmenu", handler);
};
}, [ignored, ref]);
}