islands.ts
1 import type { Component } from "svelte"; 2 3 export type Island = { 4 name: string; 5 component: Component; 6 }; 7 8 export function observeIslands({ 9 islands = [], 10 onObservation = () => {}, 11 }: { 12 islands: Island[]; 13 onObservation?: ({ 14 island, 15 entry, 16 }: { 17 island: Island; 18 entry: IntersectionObserverEntry; 19 }) => void; 20 }) { 21 const islandMap = new Map<HTMLElement, Island>(); 22 23 const handleEntry = (entry: IntersectionObserverEntry) => { 24 const island = islandMap.get(entry.target as HTMLElement); 25 if (!island) return; 26 27 if (entry.isIntersecting) { 28 onObservation({ island, entry }); 29 observer.unobserve(entry.target); 30 } 31 }; 32 33 const handleIntersection = (entries: IntersectionObserverEntry[]) => 34 entries.forEach(handleEntry); 35 36 const observer = new IntersectionObserver(handleIntersection); 37 38 islands.forEach((island) => { 39 const target = document.getElementById(island.name); 40 if (!target) return; 41 islandMap.set(target, island); 42 observer.observe(target); 43 }); 44 }