<script lang="ts">
	import { onMount, onDestroy } from 'svelte';

	export let top = 0;
	export let bottom = 0;
	export let left = 0;
	export let right = 0;
	export let steps = 100;
	export let threshold = 0.01;
	export let once = false;

	let element: Element;
	let percent: number = 0;
	let visible = false;
	let observer: IntersectionObserver;

	const intersectPercent = (
		entries: IntersectionObserverEntry[],
		observer: IntersectionObserver
	) => {
		for (let entry of entries)
			if (entry.target === element) {
				percent = Math.round(entry.intersectionRatio * 100);
				visible = entry.intersectionRatio >= threshold;

				if (visible && once) observer.unobserve(element);

				break;
			}
	};

	onMount(() => {
		if ('IntersectionObserver' in window) {
			let options = {
				rootMargin: `${top}px ${right}px ${bottom}px ${left}px`,
				threshold: Array.from({ length: steps }, (_, i) => i / (steps - 1))
			};

			observer = new IntersectionObserver(intersectPercent, options);
			observer.observe(element);
		}
	});

	onDestroy(() => observer?.unobserve(element));
</script>

<div bind:this={element}>
	<slot {visible} {percent} />
</div>
