Skip to content

Commit

Permalink
refactor(preview): improve useVisibility
Browse files Browse the repository at this point in the history
  • Loading branch information
bjoerge committed Sep 30, 2024
1 parent 63a1217 commit 007801c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 11 deletions.
10 changes: 6 additions & 4 deletions packages/sanity/src/core/preview/components/PreviewLoader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ export function PreviewLoader(
const [element, setElement] = useState<HTMLDivElement | null>(null)

// Subscribe to visibility
const isVisible = useVisibility({
element: skipVisibilityCheck ? null : element,
hideDelay: _HIDE_DELAY,
})
const isVisible =
useVisibility({
disabled: skipVisibilityCheck,
element: element,
hideDelay: _HIDE_DELAY,
}) || skipVisibilityCheck

// Subscribe document preview value
const preview = useValuePreview({
Expand Down
29 changes: 22 additions & 7 deletions packages/sanity/src/core/preview/useVisibility.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
import {useEffect, useState} from 'react'
import {useLayoutEffect, useState} from 'react'
import {concat, of} from 'rxjs'
import {delay, distinctUntilChanged, map, switchMap} from 'rxjs/operators'

import {intersectionObservableFor} from './streams/intersectionObservableFor'
import {visibilityChange$} from './streams/visibilityChange'

export function useVisibility(props: {element: HTMLElement | null; hideDelay?: number}): boolean {
const {element, hideDelay = 0} = props
interface Props {
/**
* Disable the check. The hook will return false if disabled
*/
disabled?: boolean
/** DOM Node to check visibility for */
element: HTMLElement | null
/** When element is hidden, wait this delay in milliseconds before reporting it as */
hideDelay?: number
}

export function useVisibility(props: Props): boolean {
const {element, hideDelay = 0, disabled} = props
const [visible, setVisible] = useState(false)

useEffect(() => {
if (!element) {
useLayoutEffect(() => {
if (!element || disabled) {
return undefined
}

if (element && 'checkVisibility' in element) {
setVisible(element.checkVisibility())
}

const isDocumentVisible$ = concat(
of(!document.hidden),
visibilityChange$.pipe(
Expand All @@ -34,7 +49,7 @@ export function useVisibility(props: {element: HTMLElement | null; hideDelay?: n
const sub = visible$.subscribe(setVisible)

return () => sub.unsubscribe()
}, [element, hideDelay])
}, [element, hideDelay, disabled])

return visible
return disabled ? false : visible
}

0 comments on commit 007801c

Please sign in to comment.