Scrolls the page to `window.location.hash` after a dependency resolves, using a `requestAnimationFrame` polling loop to handle lazy-mounted elements like Radix accordion panels or SWR-fetched rows. ## Key Components | Export | Type | Description | |---|---|---| | `useScrollToHash` | Hook | Main hook that drives hash-based scroll behavior | | `UseScrollToHashOptions` | Interface | Configuration options for the hook | | `MAX_POLL_FRAMES` | Constant | rAF poll budget (~1s at 60fps) before giving up | ### `UseScrollToHashOptions` | Property | Type | Default | Description | |---|---|---|---| | `headerOffset` | `number` | `0` | Pixels to subtract for sticky headers/chrome | ## Usage Example ```typescript // Basic — runs on mount for SSR-rendered anchors useScrollToHash() // Wait for async data before attempting scroll const { data } = useSWR('/api/items') useScrollToHash(data) // With sticky header compensation useScrollToHash(data, { headerOffset: 64 }) // Delay until accordion/drawer is fully open const [isOpen, setIsOpen] = useState(false) useScrollToHash(isOpen) ``` ## Behavior Notes - **Polling:** Calls `requestAnimationFrame` up to `MAX_POLL_FRAMES` (60) times, giving lazy-mounted DOM nodes ~1 second to appear before aborting. - **Skipped when** `readyDep` is `null` or `false` — safe to pass unresolved async state directly. - **Re-runs on:** `hashchange` events (browser back/forward navigation) and the synthetic `navigateSamePageHash` event, in addition to `readyDep` reference changes. - **Concurrent safety:** Cancels any in-flight rAF poll before starting a new one to prevent double-scroll races. - **SSR safe:** Guards against `window` being undefined. ## Source [`use-scroll-to-hash.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/use-scroll-to-hash.ts)