Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 266x 36x 10x 2x 8x 8x 10x 121x 1x 120x 23x 97x 7x | import type { IntersectionEntry } from "./types";
/**
* Check if IntersectionObserver API is supported in the current environment
* Returns false in SSR environments or browsers without support
*/
export function isIntersectionObserverSupported(): boolean {
return (
typeof window !== "undefined" &&
"IntersectionObserver" in window
);
}
/**
* Convert a native IntersectionObserverEntry to our IntersectionEntry type
* Provides a consistent interface with additional convenience properties
*
* @param nativeEntry - The native IntersectionObserverEntry from the browser
* @returns IntersectionEntry with all properties
*/
export function toIntersectionEntry(
nativeEntry: IntersectionObserverEntry
): IntersectionEntry {
return {
entry: nativeEntry,
isIntersecting: nativeEntry.isIntersecting,
intersectionRatio: nativeEntry.intersectionRatio,
target: nativeEntry.target,
boundingClientRect: nativeEntry.boundingClientRect,
intersectionRect: nativeEntry.intersectionRect,
rootBounds: nativeEntry.rootBounds,
time: nativeEntry.time,
};
}
/**
* Create an initial IntersectionEntry for SSR or before first observation
* Used when initialIsIntersecting is true
*
* @param isIntersecting - Whether to set initial state as intersecting
* @param target - Optional target element (null for SSR)
* @returns A mock IntersectionEntry
*/
export function createInitialEntry(
isIntersecting: boolean,
target: Element | null = null
): IntersectionEntry | null {
if (!isIntersecting) {
return null;
}
// Create a placeholder DOMRect for SSR
const emptyRect: DOMRectReadOnly = {
x: 0,
y: 0,
width: 0,
height: 0,
top: 0,
right: 0,
bottom: 0,
left: 0,
toJSON: () => ({}),
};
// Create a mock native entry
const mockNativeEntry = {
target: target as Element,
isIntersecting,
intersectionRatio: isIntersecting ? 1 : 0,
boundingClientRect: emptyRect,
intersectionRect: emptyRect,
rootBounds: null,
time: typeof performance !== "undefined" ? performance.now() : Date.now(),
} as IntersectionObserverEntry;
return {
entry: mockNativeEntry,
isIntersecting,
intersectionRatio: isIntersecting ? 1 : 0,
target: target as Element,
boundingClientRect: emptyRect,
intersectionRect: emptyRect,
rootBounds: null,
time: mockNativeEntry.time,
};
}
/**
* Normalize threshold to always be an array
* Handles both single number and array inputs
*
* @param threshold - Single threshold or array of thresholds
* @returns Array of threshold values
*/
export function normalizeThreshold(
threshold: number | number[] | undefined
): number[] {
if (threshold === undefined) {
return [0];
}
if (Array.isArray(threshold)) {
return threshold;
}
return [threshold];
}
/**
* Create a no-op ref callback for SSR environments
* Returns a function that does nothing when called
*/
export function createNoopRef(): (node: Element | null) => void {
return () => {
// No-op for SSR
};
}
|