{"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":[]}