1 line
4.0 KiB
Plaintext
1 line
4.0 KiB
Plaintext
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\"\nimport { useCallbackRef } from \"@chakra-ui/react-use-callback-ref\"\n\nexport interface UseOutsideClickProps {\n /**\n * Whether the hook is enabled\n */\n enabled?: boolean\n /**\n * The reference to a DOM element.\n */\n ref: React.RefObject<HTMLElement>\n /**\n * Function invoked when a click is triggered outside the referenced element.\n */\n handler?: (e: Event) => void\n}\n\n/**\n * Example, used in components like Dialogs and Popovers, so they can close\n * when a user clicks outside them.\n */\nexport function useOutsideClick(props: UseOutsideClickProps) {\n const { ref, handler, enabled = true } = props\n const savedHandler = useCallbackRef(handler)\n\n const stateRef = useRef({\n isPointerDown: false,\n ignoreEmulatedMouseEvents: false,\n })\n\n const state = stateRef.current\n\n useEffect(() => {\n if (!enabled) return\n const onPointerDown: any = (e: PointerEvent) => {\n if (isValidEvent(e, ref)) {\n state.isPointerDown = true\n }\n }\n\n const onMouseUp: any = (event: MouseEvent) => {\n if (state.ignoreEmulatedMouseEvents) {\n state.ignoreEmulatedMouseEvents = false\n return\n }\n\n if (state.isPointerDown && handler && isValidEvent(event, ref)) {\n state.isPointerDown = false\n savedHandler(event)\n }\n }\n\n const onTouchEnd = (event: TouchEvent) => {\n state.ignoreEmulatedMouseEvents = true\n if (handler && state.isPointerDown && isValidEvent(event, ref)) {\n state.isPointerDown = false\n savedHandler(event)\n }\n }\n\n const doc = getOwnerDocument(ref.current)\n doc.addEventListener(\"mousedown\", onPointerDown, true)\n doc.addEventListener(\"mouseup\", onMouseUp, true)\n doc.addEventListener(\"touchstart\", onPointerDown, true)\n doc.addEventListener(\"touchend\", onTouchEnd, true)\n\n return () => {\n doc.removeEventListener(\"mousedown\", onPointerDown, true)\n doc.removeEventListener(\"mouseup\", onMouseUp, true)\n doc.removeEventListener(\"touchstart\", onPointerDown, true)\n doc.removeEventListener(\"touchend\", onTouchEnd, true)\n }\n }, [handler, ref, savedHandler, state, enabled])\n}\n\nfunction isValidEvent(event: Event, ref: React.RefObject<HTMLElement>) {\n const target = event.target as HTMLElement\n\n if (target) {\n const doc = getOwnerDocument(target)\n if (!doc.contains(target)) return false\n }\n\n return !ref.current?.contains(target)\n}\n\nfunction getOwnerDocument(node?: Element | null): Document {\n return node?.ownerDocument ?? document\n}\n"],"mappings":";;;AAAA,SAAS,WAAW,cAAc;AAClC,SAAS,sBAAsB;AAqBxB,SAAS,gBAAgB,OAA6B;AAC3D,QAAM,EAAE,KAAK,SAAS,UAAU,KAAK,IAAI;AACzC,QAAM,eAAe,eAAe,OAAO;AAE3C,QAAM,WAAW,OAAO;AAAA,IACtB,eAAe;AAAA,IACf,2BAA2B;AAAA,EAC7B,CAAC;AAED,QAAM,QAAQ,SAAS;AAEvB,YAAU,MAAM;AACd,QAAI,CAAC;AAAS;AACd,UAAM,gBAAqB,CAAC,MAAoB;AAC9C,UAAI,aAAa,GAAG,GAAG,GAAG;AACxB,cAAM,gBAAgB;AAAA,MACxB;AAAA,IACF;AAEA,UAAM,YAAiB,CAAC,UAAsB;AAC5C,UAAI,MAAM,2BAA2B;AACnC,cAAM,4BAA4B;AAClC;AAAA,MACF;AAEA,UAAI,MAAM,iBAAiB,WAAW,aAAa,OAAO,GAAG,GAAG;AAC9D,cAAM,gBAAgB;AACtB,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAEA,UAAM,aAAa,CAAC,UAAsB;AACxC,YAAM,4BAA4B;AAClC,UAAI,WAAW,MAAM,iBAAiB,aAAa,OAAO,GAAG,GAAG;AAC9D,cAAM,gBAAgB;AACtB,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAEA,UAAM,MAAM,iBAAiB,IAAI,OAAO;AACxC,QAAI,iBAAiB,aAAa,eAAe,IAAI;AACrD,QAAI,iBAAiB,WAAW,WAAW,IAAI;AAC/C,QAAI,iBAAiB,cAAc,eAAe,IAAI;AACtD,QAAI,iBAAiB,YAAY,YAAY,IAAI;AAEjD,WAAO,MAAM;AACX,UAAI,oBAAoB,aAAa,eAAe,IAAI;AACxD,UAAI,oBAAoB,WAAW,WAAW,IAAI;AAClD,UAAI,oBAAoB,cAAc,eAAe,IAAI;AACzD,UAAI,oBAAoB,YAAY,YAAY,IAAI;AAAA,IACtD;AAAA,EACF,GAAG,CAAC,SAAS,KAAK,cAAc,OAAO,OAAO,CAAC;AACjD;AAEA,SAAS,aAAa,OAAc,KAAmC;AA5EvE;AA6EE,QAAM,SAAS,MAAM;AAErB,MAAI,QAAQ;AACV,UAAM,MAAM,iBAAiB,MAAM;AACnC,QAAI,CAAC,IAAI,SAAS,MAAM;AAAG,aAAO;AAAA,EACpC;AAEA,SAAO,GAAC,SAAI,YAAJ,mBAAa,SAAS;AAChC;AAEA,SAAS,iBAAiB,MAAiC;AAvF3D;AAwFE,UAAO,kCAAM,kBAAN,YAAuB;AAChC;","names":[]} |