UNPKG

@solid-primitives/intersection-observer

Version:
172 lines (171 loc) 8.22 kB
import type { JSX, Accessor } from "solid-js"; import { type FalsyValue, type MaybeAccessor } from "@solid-primitives/utils"; export type AddIntersectionObserverEntry = (el: Element) => void; export type RemoveIntersectionObserverEntry = (el: Element) => void; export type EntryCallback = (entry: IntersectionObserverEntry, instance: IntersectionObserver) => void; export type AddViewportObserverEntry = (el: Element, callback: MaybeAccessor<EntryCallback>) => void; export type RemoveViewportObserverEntry = (el: Element) => void; export type CreateViewportObserverReturnValue = [ AddViewportObserverEntry, { remove: RemoveViewportObserverEntry; start: () => void; stop: () => void; instance: IntersectionObserver; } ]; declare module "solid-js" { namespace JSX { interface Directives { intersectionObserver: true | EntryCallback; } } } export type E = JSX.Element; /** * @deprecated Please use native {@link IntersectionObserver}, or {@link createIntersectionObserver} instead. */ export declare function makeIntersectionObserver(elements: Element[], onChange: IntersectionObserverCallback, options?: IntersectionObserverInit): { add: AddIntersectionObserverEntry; remove: RemoveIntersectionObserverEntry; start: VoidFunction; reset: VoidFunction; stop: VoidFunction; instance: IntersectionObserver; }; /** * Creates a reactive Intersection Observer primitive. * * @param elements - A list of elements to watch * @param onChange - An event handler that returns an array of observer entires * @param options - IntersectionObserver constructor options: * - `root` — The Element or Document whose bounds are used as the bounding box when testing for intersection. * - `rootMargin` — A string which specifies a set of offsets to add to the root's bounding_box when calculating intersections, effectively shrinking or growing the root for calculation purposes. * - `threshold` — Either a single number or an array of numbers between 0.0 and 1.0, specifying a ratio of intersection area to total bounding box area for the observed target. * * @example * ```tsx * const createIntersectionObserver(els, entries => * console.log(entries) * ); * ``` */ export declare function createIntersectionObserver(elements: Accessor<Element[]>, onChange: IntersectionObserverCallback, options?: IntersectionObserverInit): void; /** * Creates a more advanced viewport observer for complex tracking with multiple objects in a single IntersectionObserver instance. * * @param elements - A list of elements to watch * @param callback - Element intersection change event handler * @param options - IntersectionObserver constructor options: * - `root` — The Element or Document whose bounds are used as the bounding box when testing for intersection. * - `rootMargin` — A string which specifies a set of offsets to add to the root's bounding_box when calculating intersections, effectively shrinking or growing the root for calculation purposes. * - `threshold` — Either a single number or an array of numbers between 0.0 and 1.0, specifying a ratio of intersection area to total bounding box area for the observed target. * * @example * ```tsx * const [add, { remove, start, stop, instance }] = createViewportObserver(els, (e) => {...}); * add(el, e => console.log(e.isIntersecting)) * * // directive usage: * const [intersectionObserver] = createViewportObserver() * <div use:intersectionObserver={(e) => console.log(e.isIntersecting)}></div> * ``` */ export declare function createViewportObserver(elements: MaybeAccessor<Element[]>, callback: EntryCallback, options?: IntersectionObserverInit): CreateViewportObserverReturnValue; export declare function createViewportObserver(initial: MaybeAccessor<[Element, EntryCallback][]>, options?: IntersectionObserverInit): CreateViewportObserverReturnValue; export declare function createViewportObserver(options?: IntersectionObserverInit): CreateViewportObserverReturnValue; export type VisibilitySetter<Ctx extends {} = {}> = (entry: IntersectionObserverEntry, context: Ctx & { visible: boolean; }) => boolean; /** * Creates reactive signal that changes when a single element's visibility changes. * * @param options - A Primitive and IntersectionObserver constructor options: * - `root` — The Element or Document whose bounds are used as the bounding box when testing for intersection. * - `rootMargin` — A string which specifies a set of offsets to add to the root's bounding_box when calculating intersections, effectively shrinking or growing the root for calculation purposes. * - `threshold` — Either a single number or an array of numbers between 0.0 and 1.0, specifying a ratio of intersection area to total bounding box area for the observed target. * - `initialValue` — Initial value of the signal *(default: false)* * * @returns A configured *"use"* function for creating a visibility signal for a single element. The passed element can be a **reactive signal** or a DOM element. Returning a falsy value will remove the element from the observer. * ```ts * (element: Accessor<Element | FalsyValue> | Element) => Accessor<boolean> * ``` * * @example * ```tsx * let el: HTMLDivElement | undefined * const useVisibilityObserver = createVisibilityObserver({ threshold: 0.8 }) * const visible = useVisibilityObserver(() => el) * <div ref={el}>{ visible() ? "Visible" : "Hidden" }</div> * ``` */ export declare function createVisibilityObserver(options?: IntersectionObserverInit & { initialValue?: boolean; }, setter?: MaybeAccessor<VisibilitySetter>): (element: Accessor<Element | FalsyValue> | Element) => Accessor<boolean>; export declare enum Occurrence { Entering = "Entering", Leaving = "Leaving", Inside = "Inside", Outside = "Outside" } /** * Calculates the occurrence of an element in the viewport. */ export declare function getOccurrence(isIntersecting: boolean, prevIsIntersecting: boolean | undefined): Occurrence; /** * A visibility setter factory function. It provides information about element occurrence in the viewport — `"Entering"`, `"Leaving"`, `"Inside"` or `"Outside"`. * @param setter - A function that sets the occurrence of an element in the viewport. * @returns A visibility setter function. * @example * ```ts * const useVisibilityObserver = createVisibilityObserver( * { threshold: 0.8 }, * withOccurrence((entry, { occurrence }) => { * console.log(occurrence); * return entry.isIntersecting; * }) * ); * ``` */ export declare function withOccurrence<Ctx extends {}>(setter: MaybeAccessor<VisibilitySetter<Ctx & { occurrence: Occurrence; }>>): () => VisibilitySetter<Ctx>; export declare enum DirectionX { Left = "Left", Right = "Right", None = "None" } export declare enum DirectionY { Top = "Top", Bottom = "Bottom", None = "None" } /** * Calculates the direction of an element in the viewport. The direction is calculated based on the element's rect, it's previous rect and the `isIntersecting` flag. * @returns A direction string: `"Left"`, `"Right"`, `"Top"`, `"Bottom"` or `"None"`. */ export declare function getDirection(rect: DOMRectReadOnly, prevRect: DOMRectReadOnly | undefined, intersecting: boolean): { directionX: DirectionX; directionY: DirectionY; }; /** * A visibility setter factory function. It provides information about element direction on the screen — `"Left"`, `"Right"`, `"Top"`, `"Bottom"` or `"None"`. * @param setter - A function that sets the occurrence of an element in the viewport. * @returns A visibility setter function. * @example * ```ts * const useVisibilityObserver = createVisibilityObserver( * { threshold: 0.8 }, * withDirection((entry, { directionY, directionX, visible }) => { * if (!entry.isIntersecting && directionY === "Top" && visible) { * return true; * } * return entry.isIntersecting; * }) * ); * ``` */ export declare function withDirection<Ctx extends {}>(callback: MaybeAccessor<VisibilitySetter<Ctx & { directionX: DirectionX; directionY: DirectionY; }>>): () => VisibilitySetter<Ctx>;