/ src / stores / scroll.ts
scroll.ts
 1  import { createSignal } from "solid-js";
 2  
 3  export type ScrollKey = string;
 4  
 5  type ScrollState = Readonly<Record<ScrollKey, number>>;
 6  
 7  const [positions, setPositions] = createSignal<ScrollState>({});
 8  
 9  /**
10   * Global scroll position store.
11   *
12   * Usage:
13   * - scroll.get("home")
14   * - scroll.set("home", window.scrollY)
15   * - scroll.clear("home")
16   * - scroll.clearAll()
17   */
18  const scroll = {
19    /**
20     * Returns the last saved scrollY for a key.
21     * If none exists, returns `fallback` (default `0`).
22     */
23    get(key: ScrollKey, fallback = 0): number {
24      const value = positions()[key];
25      return typeof value === "number" && Number.isFinite(value) ? value : fallback;
26    },
27  
28    /**
29     * Saves a scrollY for a key (clamped to >= 0).
30     */
31    set(key: ScrollKey, y: number): void {
32      const next = Number.isFinite(y) ? Math.max(0, y) : 0;
33      setPositions((prev) => {
34        if (prev[key] === next) return prev;
35        return { ...prev, [key]: next };
36      });
37    },
38  
39    clear(key: ScrollKey): void {
40      setPositions((prev) => {
41        if (!(key in prev)) return prev;
42        // eslint-disable-next-line @typescript-eslint/no-unused-vars
43        const { [key]: _removed, ...rest } = prev;
44        return rest;
45      });
46    },
47  
48    clearAll(): void {
49      setPositions({});
50    },
51  
52    positions,
53  } as const;
54  
55  export default scroll;