{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-session-storage",
  "title": "UseSessionStorage",
  "description": "Synchronizes a value with sessionStorage.",
  "files": [
    {
      "path": "registry/hooks/use-session-storage.tsx",
      "content": "'use client';\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\ninterface UseSessionStorageOptions<T> {\n  serialize?: (value: T) => string;\n  deserialize?: (value: string) => T;\n}\n\n/**\n * Hook to synchronize a value with sessionStorage in a type-safe, performant, and cross-tab reactive way.\n *\n * @param key sessionStorage key\n * @param initialValue Initial value\n * @param options Custom serialization/deserialization functions\n */\nfunction useSessionStorage<T>(\n  key: string,\n  initialValue: T,\n  options?: UseSessionStorageOptions<T>,\n) {\n  // Memoize serialize/deserialize to avoid unnecessary dependencies\n  const serialize = useMemo(\n    () => options?.serialize ?? JSON.stringify,\n    [options?.serialize],\n  );\n\n  const deserialize = useMemo(\n    () => options?.deserialize ?? JSON.parse,\n    [options?.deserialize],\n  );\n\n  // Ref to keep the initial value stable\n  const initialRef = useRef(initialValue);\n\n  const readValue = useCallback((): T => {\n    if (typeof window === 'undefined') return initialRef.current;\n\n    try {\n      const item = window.sessionStorage.getItem(key);\n\n      return item != null ? (deserialize(item) as T) : initialRef.current;\n    } catch (error) {\n      console.warn(\n        `[useSessionStorage] Error reading key \"${key}\" from sessionStorage:`,\n        error,\n      );\n\n      return initialRef.current;\n    }\n  }, [key, deserialize]);\n\n  // State synchronized with sessionStorage\n  const [storedValue, setStoredValue] = useState<T>(readValue);\n\n  const setValue = useCallback(\n    (value: T | ((val: T) => T)) => {\n      try {\n        setStoredValue((prev) => {\n          const valueToStore = value instanceof Function ? value(prev) : value;\n\n          window.sessionStorage.setItem(key, serialize(valueToStore));\n\n          return valueToStore;\n        });\n      } catch (error) {\n        console.warn(\n          `[useSessionStorage] Error setting key \"${key}\" in sessionStorage:`,\n          error,\n        );\n      }\n    },\n    [key, serialize],\n  );\n\n  // Synchronize between tabs\n  useEffect(() => {\n    const handleStorage = (event: StorageEvent) => {\n      if (event.storageArea === window.sessionStorage && event.key === key) {\n        setStoredValue(readValue());\n      }\n    };\n\n    window.addEventListener('storage', handleStorage);\n\n    return () => window.removeEventListener('storage', handleStorage);\n  }, [key, readValue]);\n\n  // Update the value if the key changes\n  useEffect(() => {\n    setStoredValue(readValue());\n  }, [key, readValue]);\n\n  return [storedValue, setValue] as const;\n}\n\nexport default useSessionStorage;\n",
      "type": "registry:hook",
      "target": "hooks/guarahooks/use-session-storage.tsx"
    }
  ],
  "categories": [
    "state-management"
  ],
  "type": "registry:hook"
}