Skip to content

Commit

Permalink
[components] Add useClickOutside hook
Browse files Browse the repository at this point in the history
  • Loading branch information
mariuslundgard authored and rexxars committed Oct 6, 2020
1 parent 12d6698 commit 9c32a7d
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/@sanity/components/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useClickOutside'
45 changes: 45 additions & 0 deletions packages/@sanity/components/src/hooks/useClickOutside.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {useEffect, useState} from 'react'

type ClickOutsideListener = (event: Event) => void

export function useClickOutside(
listener: ClickOutsideListener,
elementsArg: Array<HTMLElement | null> = []
) {
const [element, setElement] = useState<HTMLElement | null>(null)
const elements = [element, ...elementsArg]

useEffect(() => {
if (!listener) return undefined

const handleWindowMouseDown = (evt: MouseEvent) => {
const target = evt.target

if (!target) {
return
}

let clickInside = false

for (const el of elements) {
if (el && el.contains(target as Node)) {
clickInside = true
}
}

if (!clickInside) {
listener(evt)
}
}

window.addEventListener('mousedown', handleWindowMouseDown)

return () => {
window.removeEventListener('mousedown', handleWindowMouseDown)
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [listener, ...elements])

return setElement
}
1 change: 1 addition & 0 deletions packages/@sanity/components/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './hooks'
export * from './types'

0 comments on commit 9c32a7d

Please sign in to comment.