# All files / src/_hooks ClickOutside.ts

100% Statements 16/16
93.33% Branches 14/15
100% Functions 4/4
100% Lines 14/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    59x

    59x
    58x

    55x

    3x

    59x
    160x
    160x

    160x
    50x
    3x

    160x

    160x

    160x

     import React from 'react'
    import { useEventListener } from './EventListener'

    export interface ClickOutsideConfig {
      /**
       * @since 10.19.0
       */
      onClickOutside: (event: MouseEvent) => void
      /**
       * @since 10.19.0
       */
      refs: Array<React.RefObject<HTMLElement>>
    }

    export interface ClickOutsideProps extends ClickOutsideConfig {
      /**
       * @since 10.19.0
       */
      children: React.ReactElement
    }

    /**
     * @deprecatedSince 9
     * @deprecated Never officially documented/supported
     */
    // To support MenuRef had to change to any. Could manually do <HTMLElement & MenuRef> but seems brittle
    export function isEventSource(ref: React.RefObject<any>, event: Event) {
      if (
        ref?.current &&
        event &&
        (event.target instanceof HTMLElement || event.target instanceof SVGElement)
      ) {
        return ref.current.contains(event.target)
      } else {
        return false
      }
    }

    /**
     * @deprecatedSince 9
     * @deprecated Never officially documented/supported
     */
    export function useClickOutside({
      refs = [],
      onClickOutside,
    }: ClickOutsideConfig) {
      const handler = (event: MouseEvent) => {
        if (onClickOutside && !refs.find((ref) => isEventSource(ref, event))) {
          onClickOutside(event)
        }
      }

      const options = { capture: true }

      useEventListener({ event: 'click', handler, options })

      useEventListener({ event: 'touchend', handler, options })
    }