diff --git a/packages/sanity/src/core/preview/components/PreviewLoader.tsx b/packages/sanity/src/core/preview/components/PreviewLoader.tsx index 414ab966964..42145d6bc30 100644 --- a/packages/sanity/src/core/preview/components/PreviewLoader.tsx +++ b/packages/sanity/src/core/preview/components/PreviewLoader.tsx @@ -42,10 +42,12 @@ export function PreviewLoader( const [element, setElement] = useState(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({ diff --git a/packages/sanity/src/core/preview/useVisibility.ts b/packages/sanity/src/core/preview/useVisibility.ts index a479b8ad510..74d22218d3c 100644 --- a/packages/sanity/src/core/preview/useVisibility.ts +++ b/packages/sanity/src/core/preview/useVisibility.ts @@ -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( @@ -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 }