useScroll#

Reactive scroll position with edge-arrival and direction detection; writing x/y scrolls the target. Browser composable — import from @sigx/use-web.

TypeScript
import { effect } from 'sigx';
import { useScroll } from '@sigx/use-web';

const { y, arrivedState } = useScroll();      // defaults to the window
effect(() => { if (arrivedState.bottom) loadMore(); });
y.value = 0;                                   // scroll to top

The target defaults to the window, so there is deliberately no separate useWindowScroll — call useScroll() for the window, or pass an element/Document to scroll something else:

TypeScript
const el = signal<HTMLElement | null>(null);
const { x, y } = useScroll(el);

Signature#

TypeScript
function useScroll(target?: MaybeSignal<ScrollTarget>, options?: UseScrollOptions): UseScrollReturn;

type ScrollTarget = Element | Window | Document | null | undefined;

target is a MaybeSignal; a reactive target re-attaches the listener. Listeners are passive and detach with the owning scope.

Options#

OptionTypeDefaultDescription
throttlenumber0Throttle scroll handling to at most once per throttle ms (0 = off).
idlenumber200ms of quiet before isScrolling flips back to false.
offset{ left?, right?, top?, bottom? }Edge tolerance (px) for arrivedState.
behaviorScrollBehavior'auto'Scroll behavior for programmatic writes to x/y.
onScroll(event: Event) => voidCalled on each scroll event.
onStop(event: Event) => voidCalled when scrolling goes idle.
windowWindowdefaultWindowOverride the window (SSR/testing). See Configurable*.

Returns#

FieldTypeDescription
x / yWritableComputed<number>Scroll position; writing scrolls the target with the configured behavior.
isScrollingReadSignal<boolean>true while scrolling, back to false after idle ms of quiet.
arrivedStateReactiveView<{ left, right, top, bottom }>Which edges the position has arrived at (within offset).
directionsReactiveView<{ left, right, top, bottom }>Which directions the latest scroll moved in.
stopStopDetach the listener/watcher and clear timers — for standalone, no-scope use.

arrivedState and directions are reactive views — read fields by property access.

SSR#

On the server x/y read as 0, arrivedState/directions are all false, and writes are a no-op — nothing scrolls until the client takes over on mount.

See also#