Skip to content

Commit

Permalink
add useOnDisappear hook
Browse files Browse the repository at this point in the history
This hook allows us to trigger a callback if the element becomes
"hidden". We use the bounding client rect and check the dimensions to
know wether we are "hidden" or not.
  • Loading branch information
RobinMalfait committed Apr 2, 2024
1 parent 4f89588 commit cef19c5
Showing 1 changed file with 41 additions and 0 deletions.
41 changes: 41 additions & 0 deletions packages/@headlessui-react/src/hooks/use-on-disappear.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useEffect, type MutableRefObject } from 'react'
import { disposables } from '../utils/disposables'
import { useLatestValue } from './use-latest-value'

export function useOnDisappear(
ref: MutableRefObject<HTMLElement | null> | HTMLElement | null,
cb: () => void,
enabled = true
) {
let listenerRef = useLatestValue((element: HTMLElement) => {
let rect = element.getBoundingClientRect()
if (rect.x === 0 && rect.y === 0 && rect.width === 0 && rect.height === 0) {
cb()
}
})

useEffect(() => {
if (!enabled) return

let element = ref === null ? null : ref instanceof HTMLElement ? ref : ref.current
if (!element) return

let d = disposables()

// Try using ResizeObserver
if (typeof ResizeObserver !== 'undefined') {
let observer = new ResizeObserver(() => listenerRef.current(element))
observer.observe(element)
d.add(() => observer.disconnect())
}

// Try using IntersectionObserver
if (typeof IntersectionObserver !== 'undefined') {
let observer = new IntersectionObserver(() => listenerRef.current(element))
observer.observe(element)
d.add(() => observer.disconnect())
}

return () => d.dispose()
}, [ref, listenerRef, enabled])
}

0 comments on commit cef19c5

Please sign in to comment.