/ src / lib / islands.ts
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  }