Scrum4Me/lib/use-local-storage-pref.ts
Janpeter Visser 1f8cbacb0a
feat: shared backlog filter popover + sprint header polish (v1.3.3) (#184)
- Move sprint switcher into sprint header, centered between title and actions
- Extract BacklogFilterPopover as shared component used by sprint and product backlog
- Add sort options (code/priority/status) with single-pill asc/desc toggle
- Default sprint backlog status filter to OPEN, remove "alleen niet klaar" button
- Persist collapsed state and filter popover open in localStorage
- Fix hydration flicker: defer localStorage read to useEffect with prefsLoaded gate for writes
- Increase sprint switcher text size for readability

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 11:12:04 +02:00

22 lines
903 B
TypeScript

/**
* SSR-safe synchronous read of a localStorage value with a typed parser.
*
* Use inside `useState(() => readLocalStoragePref(...))` so the first render
* already has the persisted value — no useEffect-driven re-render flicker.
*
* On the server `window` is undefined → returns `fallback`. On the client the
* raw value is parsed; if the parser returns `null` the fallback is used.
* Hydration mismatches between server-rendered HTML (default) and the
* client-rendered tree (persisted) are accepted: React adapts the DOM in the
* same hydration pass without a visible flicker for matching values.
*/
export function readLocalStoragePref<T>(
key: string,
parse: (raw: string) => T | null,
fallback: T,
): T {
if (typeof window === 'undefined') return fallback
const raw = window.localStorage.getItem(key)
if (raw === null) return fallback
return parse(raw) ?? fallback
}