useElementVisibility
Tracks whether a DOM element is visible within the viewport (or a specified scroll container). Returns a reactive Observable<boolean> that updates automatically via the IntersectionObserver API.
Scroll down in the box — the target turns green when ≥50% is visible.
import { const useRef$: { <T = any>(initialValue: null): Ref$<T | null>; <T = any>(initialValue: T): Ref$<T>; <T = any>(): Ref$<T | null>;}
useRef$ } from "@usels/core";import { const useElementVisibility: (element: MaybeEventTarget, options?: DeepMaybeObservable<UseElementVisibilityOptions>) => Observable<boolean>
useElementVisibility } from "@usels/web";
function function Component(): JSX.Element
Component() { const const el$: Ref$<HTMLDivElement | null>
el$ = useRef$<HTMLDivElement>(): Ref$<HTMLDivElement | null> (+2 overloads)
Core (framework-agnostic) version of useRef$.
Creates an observable element ref with opaque wrapping.
- non-null value →
Ref$<T>: current, get(), peek() return T
- null / no arg →
Ref$<T | null>: current, get(), peek() return T | null
Nullability is expressed via the type parameter, mirroring T | null at the call site.
useRef$<interface HTMLDivElement
HTMLDivElement>(); const const isVisible$: any
isVisible$ = function useElementVisibility(element: MaybeEventTarget, options?: DeepMaybeObservable<UseElementVisibilityOptions>): Observable<boolean>
Framework-agnostic reactive element visibility tracker.
Tracks whether a DOM element is intersecting the viewport (or a specified
scroll container). Returns a reactive Observable<boolean> that updates
automatically via the IntersectionObserver API.
useElementVisibility(const el$: Ref$<HTMLDivElement | null>
el$);
return <JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div RefAttributes<HTMLDivElement>.ref?: Ref<HTMLDivElement> | undefined
Allows getting a ref to the component instance.
Once the component unmounts, React will set ref.current to null
(or call the ref with null if you passed a callback ref).
ref={const el$: Ref$<HTMLDivElement | null>
el$} />;}import { createRef$ } from "@usels/core";import { createElementVisibility } from "@usels/web";
function Component() { "use scope" const el$ = createRef$<HTMLDivElement>(); const isVisible$ = createElementVisibility(el$);
return <div ref={el$} />;}With initial value
Section titled “With initial value”const isVisible$ = useElementVisibility(el$, { initialValue: true });const isVisible$ = createElementVisibility(el$, { initialValue: true });Stop after first visible
Section titled “Stop after first visible”Use once: true to automatically stop observing after the element becomes visible for the first time:
const isVisible$ = useElementVisibility(el$, { once: true });const isVisible$ = createElementVisibility(el$, { once: true });Custom scroll container
Section titled “Custom scroll container”Pass a scrollTarget to observe intersection within a scrollable container instead of the viewport:
const container$ = useRef$<HTMLDivElement>();const isVisible$ = useElementVisibility(el$, { scrollTarget: container$ });const container$ = createRef$<HTMLDivElement>();const isVisible$ = createElementVisibility(el$, { scrollTarget: container$ });Threshold and rootMargin
Section titled “Threshold and rootMargin”const isVisible$ = useElementVisibility(el$, { threshold: 0.5, rootMargin: "0px 0px -100px 0px",});const isVisible$ = createElementVisibility(el$, { threshold: 0.5, rootMargin: "0px 0px -100px 0px",});Reactive options
Section titled “Reactive options”All options accept Observable<T> for reactive control:
import { observable } from "@usels/core";
const threshold$ = observable<number | number[]>(0.5);const rootMargin$ = observable("0px");
const isVisible$ = useElementVisibility(el$, { threshold: threshold$, rootMargin: rootMargin$,});
// later — update reactivelythreshold$.set(0.75);rootMargin$.set("-50px 0px");import { observable } from "@usels/core";
const threshold$ = observable<number | number[]>(0.5);const rootMargin$ = observable("0px");
const isVisible$ = createElementVisibility(el$, { threshold: threshold$, rootMargin: rootMargin$,});
// later — update reactivelythreshold$.set(0.75);rootMargin$.set("-50px 0px");Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
element | MaybeEventTarget | - Element to observe (Ref$, Observable element, or raw element). |
options | UseElementVisibilityOptions (optional) | - Optional configuration — plain, per-field Observable, or fully Observable. |
UseElementVisibilityOptions
Section titled “UseElementVisibilityOptions”Returns
Section titled “Returns”ObservableBoolean<boolean>
| Name | Type | Description |
|---|---|---|
toggle | () => void | - |
peek | { (): boolean; (): boolean; } | - |
get | (trackingType?: TrackingType | GetOptions) => boolean | - |
onChange | (cb: ListenerFn<boolean>, options?: { trackingType?: TrackingType; initial?: boolean | undefined; immediate?: boolean | undefined; noArgs?: boolean | undefined; } | undefined) => () => void | - |
set | { (value: (prev: boolean) => boolean): void; (value: ObservableBoolean<boolean>): void; (value: boolean | ImmutableObservableBase<boolean> | ... 4 more ... | (() => boolean | ... 1 more ... | Promise<...>)): void; (value: Promise<...>): void; (value: boolean): void; } | - |
delete | () => void | - |