@sv-use/core
Version:
A collection of Svelte 5 utilities.
54 lines (53 loc) • 1.88 kB
JavaScript
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;
}
};
}