@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
1 lines • 4.38 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","names":["useCallbackRef","ref"],"sources":["../../../../src/hooks/use-outside-click/index.ts"],"sourcesContent":["\"use client\"\n\nimport type { RefObject } from \"react\"\nimport { useCallback, useEffect, useRef } from \"react\"\nimport { getDocument, isArray, useCallbackRef } from \"../../utils\"\n\nexport interface UseOutsideClickProps {\n ref: RefObject<HTMLElement | null> | RefObject<HTMLElement | null>[]\n enabled?: boolean\n handler?: (ev: Event) => void\n}\n\n/**\n * `useOutsideClick` is a custom hook that detects click events outside of an element.\n *\n * @see https://yamada-ui.com/docs/hooks/use-outside-click\n */\nexport const useOutsideClick = ({\n ref,\n enabled = true,\n handler,\n}: UseOutsideClickProps) => {\n const handlerRef = useCallbackRef(handler)\n\n const state = useRef({\n ignoreEmulatedMouseEvents: false,\n isPointerDown: false,\n })\n\n const onPointerDown = useCallback(\n (ev: MouseEvent | TouchEvent) => {\n if (isValidEvent(ev, ref)) state.current.isPointerDown = true\n },\n [ref],\n )\n\n const onMouseUp = useCallback(\n (ev: MouseEvent) => {\n if (state.current.ignoreEmulatedMouseEvents) {\n state.current.ignoreEmulatedMouseEvents = false\n\n return\n }\n\n if (state.current.isPointerDown && handler && isValidEvent(ev, ref)) {\n state.current.isPointerDown = false\n\n handlerRef(ev)\n }\n },\n [handler, handlerRef, ref],\n )\n\n const onTouchEnd = useCallback(\n (ev: TouchEvent) => {\n state.current.ignoreEmulatedMouseEvents = true\n\n if (state.current.isPointerDown && handler && isValidEvent(ev, ref)) {\n state.current.isPointerDown = false\n\n handlerRef(ev)\n }\n },\n [handler, handlerRef, ref],\n )\n\n useEffect(() => {\n if (!enabled) return\n\n const doc = getDocument(isArray(ref) ? ref[0]?.current : ref.current)\n\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 }, [\n handler,\n ref,\n handlerRef,\n state,\n enabled,\n onPointerDown,\n onMouseUp,\n onTouchEnd,\n ])\n}\n\nconst isValidEvent = (\n ev: MouseEvent | TouchEvent,\n ref: RefObject<HTMLElement | null> | RefObject<HTMLElement | null>[],\n) => {\n const target = ev.target as HTMLElement | null\n\n if (\"button\" in ev && ev.button > 0) return false\n\n if (target) if (!getDocument(target).contains(target)) return false\n\n if (isArray(ref)) {\n return !ref.some((ref) => ref.current?.contains(target))\n } else {\n return !ref.current?.contains(target)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAiBA,MAAa,mBAAmB,EAC9B,KACA,UAAU,MACV,cAC0B;CAC1B,MAAM,aAAaA,2BAAe,QAAQ;CAE1C,MAAM,0BAAe;EACnB,2BAA2B;EAC3B,eAAe;EAChB,CAAC;CAEF,MAAM,wCACH,OAAgC;AAC/B,MAAI,aAAa,IAAI,IAAI,CAAE,OAAM,QAAQ,gBAAgB;IAE3D,CAAC,IAAI,CACN;CAED,MAAM,oCACH,OAAmB;AAClB,MAAI,MAAM,QAAQ,2BAA2B;AAC3C,SAAM,QAAQ,4BAA4B;AAE1C;;AAGF,MAAI,MAAM,QAAQ,iBAAiB,WAAW,aAAa,IAAI,IAAI,EAAE;AACnE,SAAM,QAAQ,gBAAgB;AAE9B,cAAW,GAAG;;IAGlB;EAAC;EAAS;EAAY;EAAI,CAC3B;CAED,MAAM,qCACH,OAAmB;AAClB,QAAM,QAAQ,4BAA4B;AAE1C,MAAI,MAAM,QAAQ,iBAAiB,WAAW,aAAa,IAAI,IAAI,EAAE;AACnE,SAAM,QAAQ,gBAAgB;AAE9B,cAAW,GAAG;;IAGlB;EAAC;EAAS;EAAY;EAAI,CAC3B;AAED,4BAAgB;AACd,MAAI,CAAC,QAAS;EAEd,MAAM,wGAA0B,IAAI,GAAG,IAAI,IAAI,UAAU,IAAI,QAAQ;AAErE,MAAI,iBAAiB,aAAa,eAAe,KAAK;AACtD,MAAI,iBAAiB,WAAW,WAAW,KAAK;AAChD,MAAI,iBAAiB,cAAc,eAAe,KAAK;AACvD,MAAI,iBAAiB,YAAY,YAAY,KAAK;AAElD,eAAa;AACX,OAAI,oBAAoB,aAAa,eAAe,KAAK;AACzD,OAAI,oBAAoB,WAAW,WAAW,KAAK;AACnD,OAAI,oBAAoB,cAAc,eAAe,KAAK;AAC1D,OAAI,oBAAoB,YAAY,YAAY,KAAK;;IAEtD;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;;AAGJ,MAAM,gBACJ,IACA,QACG;CACH,MAAM,SAAS,GAAG;AAElB,KAAI,YAAY,MAAM,GAAG,SAAS,EAAG,QAAO;AAE5C,KAAI,QAAQ;MAAI,oDAAa,OAAO,CAAC,SAAS,OAAO,CAAE,QAAO;;AAE9D,oDAAY,IAAI,CACd,QAAO,CAAC,IAAI,MAAM,UAAQC,MAAI,SAAS,SAAS,OAAO,CAAC;KAExD,QAAO,CAAC,IAAI,SAAS,SAAS,OAAO"}