UNPKG

@sv-use/core

Version:

A collection of Svelte 5 utilities.

54 lines (53 loc) 1.88 kB
import { watch } from '../watch/index.svelte.js'; import { isSupported } from '../__internal__/is.svelte.js'; import { defaultDocument, defaultWindow } from '../__internal__/configurable.js'; import { noop, normalizeValue, notNullish, toArray } from '../__internal__/utils.svelte.js'; import { onDestroy } from 'svelte'; export function observeIntersection(targets, callback, options = {}) { const { root = defaultDocument, rootMargin = '0px', threshold = 0, autoCleanup = true, window = defaultWindow, immediate = true } = options; const _isSupported = isSupported(() => window !== undefined && 'IntersectionObserver' in window); const _targets = $derived(toArray(targets).map(normalizeValue).filter(notNullish)); let cleanup = noop; let _isActive = $state(immediate); if (_isSupported.current) { watch([() => _targets, () => normalizeValue(root), () => _isActive], ([targets, root]) => { cleanup(); if (!_isActive) return; if (!targets.length) return; const observer = new IntersectionObserver(callback, { root: root, rootMargin, threshold }); targets.forEach((el) => el && observer.observe(el)); cleanup = () => { observer.disconnect(); cleanup = noop; }; }, { runOnMounted: immediate }); } if (autoCleanup) { onDestroy(() => { pause(); }); } function pause() { cleanup(); _isActive = false; } return { get isSupported() { return _isSupported.current; }, get isActive() { return _isActive; }, pause, cleanup: pause, resume() { _isActive = true; } }; }