excalidraw/src/hooks/useOutsideClick.ts
David Luzar 8c298336fc
fix: hide canvas-modifying UI in view mode (#5815)
* fix: hide canvas-modifying UI in view mode

* add class for better targeting

* fix missing `key`

* fix: useOutsideClick not working in view mode
2022-11-01 22:25:12 +01:00

43 lines
1.3 KiB
TypeScript

import { useEffect, useRef } from "react";
export const useOutsideClickHook = (handler: (event: Event) => void) => {
const ref = useRef(null);
useEffect(
() => {
const listener = (event: Event) => {
const current = ref.current as HTMLElement | null;
// Do nothing if clicking ref's element or descendent elements
if (
!current ||
current.contains(event.target as Node) ||
[...document.querySelectorAll("[data-prevent-outside-click]")].some(
(el) => el.contains(event.target as Node),
)
) {
return;
}
handler(event);
};
document.addEventListener("pointerdown", listener);
document.addEventListener("touchstart", listener);
return () => {
document.removeEventListener("pointerdown", listener);
document.removeEventListener("touchstart", listener);
};
},
// Add ref and handler to effect dependencies
// It's worth noting that because passed in handler is a new ...
// ... function on every render that will cause this effect ...
// ... callback/cleanup to run every render. It's not a big deal ...
// ... but to optimize you can wrap handler in useCallback before ...
// ... passing it into this hook.
[ref, handler],
);
return ref;
};