@thibault.sh/hooks
Version: 
A comprehensive collection of React hooks for browser storage, UI interactions, and more
1 lines • 5.58 kB
Source Map (JSON)
{"version":3,"sources":["../src/hooks/useCookieState.ts"],"names":["useCookieState","name","initialValue","value","setValue","useState","cookie","row","error","setCookie","useCallback","newValue","options","days","path","domain","secure","sameSite","expires","deleteCookie"],"mappings":"wCAkEO,SAASA,EACdC,CACAC,CAAAA,CAAAA,CACkF,CAClF,GAAM,CAACC,EAAOC,CAAQ,CAAA,CAAIC,eAAwB,IAAM,CACtD,GAAI,OAAO,MAAA,EAAW,YAAa,OAAOH,CAAAA,CAE1C,GAAI,CACF,IAAMI,EAAS,QAAS,CAAA,MAAA,CAAO,MAAM,IAAI,CAAA,CAAE,KAAMC,CAAQA,EAAAA,CAAAA,CAAI,WAAWN,CAAO,CAAA,GAAG,CAAC,CAEnF,CAAA,OAAOK,EAAS,kBAAmBA,CAAAA,CAAAA,CAAO,MAAM,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA,CAAIJ,CAC7D,CAASM,MAAAA,CAAAA,CAAO,CACd,OAAQ,OAAA,CAAA,IAAA,CAAK,yBAAyBP,CAAI,CAAA,EAAA,CAAA,CAAMO,CAAK,CAC9CN,CAAAA,CACT,CACF,CAAC,CAAA,CAEKO,EAAYC,iBAChB,CAAA,CAACC,EAAkBC,CAAyB,CAAA,KAAO,CACjD,GAAI,OAAO,MAAW,EAAA,WAAA,CAEtB,GAAI,CACF,GAAM,CAAE,IAAAC,CAAAA,CAAAA,CAAO,EAAG,IAAAC,CAAAA,CAAAA,CAAO,IAAK,MAAAC,CAAAA,CAAAA,CAAQ,OAAAC,CAAS,CAAA,CAAA,CAAA,CAAO,SAAAC,CAAW,CAAA,KAAM,EAAIL,CAErEM,CAAAA,CAAAA,CAAU,IAAI,IAAK,CAAA,IAAA,CAAK,KAAQL,CAAAA,CAAAA,CAAO,KAAK,CAAE,CAAA,WAAA,GAEpD,QAAS,CAAA,MAAA,CAAS,CAChB,CAAGZ,EAAAA,CAAI,IAAI,kBAAmBU,CAAAA,CAAQ,CAAC,CACvC,CAAA,CAAA,CAAA,QAAA,EAAWO,CAAO,CAClB,CAAA,CAAA,CAAA,KAAA,EAAQJ,CAAI,CACZC,CAAAA,CAAAA,CAAAA,CAAS,UAAUA,CAAM,CAAA,CAAA,CAAK,GAC9BC,CAAS,CAAA,QAAA,CAAW,GACpB,CAAYC,SAAAA,EAAAA,CAAQ,EACtB,CACG,CAAA,MAAA,CAAO,OAAO,CACd,CAAA,IAAA,CAAK,IAAI,CAEZb,CAAAA,CAAAA,CAASO,CAAQ,EACnB,CAAA,MAASH,EAAO,CACd,OAAA,CAAQ,KAAK,CAAyBP,sBAAAA,EAAAA,CAAI,KAAMO,CAAK,EACvD,CACF,CACA,CAAA,CAACP,CAAI,CACP,CAAA,CAEMkB,EAAeT,iBAAY,CAAA,IAAM,CACjC,OAAO,MAAA,EAAW,cAEtB,QAAS,CAAA,MAAA,CAAS,GAAGT,CAAI,CAAA,gDAAA,CAAA,CACzBG,EAAS,IAAI,CAAA,EACf,EAAG,CAACH,CAAI,CAAC,CAET,CAAA,OAAO,CAACE,CAAOM,CAAAA,CAAAA,CAAWU,CAAY,CACxC","file":"useCookieState.cjs","sourcesContent":["import { useState, useCallback } from \"react\";\n\n/**\n * Options for configuring cookie behavior\n */\ninterface CookieOptions {\n  /** Number of days until the cookie expires (default: 7) */\n  days?: number;\n  /** Cookie path (default: \"/\") */\n  path?: string;\n  /** Cookie domain */\n  domain?: string;\n  /** Whether the cookie requires HTTPS (default: false) */\n  secure?: boolean;\n  /** SameSite cookie attribute (default: \"Lax\") */\n  sameSite?: \"Strict\" | \"Lax\" | \"None\";\n}\n\n/**\n * Hook for managing state that persists in browser cookies with SSR support.\n *\n * Provides a React state-like interface for reading, writing, and deleting cookies.\n * Automatically handles encoding/decoding, error handling, and server-side rendering compatibility.\n *\n * @param name - The name of the cookie to manage\n * @param initialValue - The default value to use when no cookie exists or on server-side\n *\n * @returns A tuple containing:\n *   - `value`: Current cookie value as string, or null if not set\n *   - `setCookie`: Function to update the cookie with optional configuration\n *   - `deleteCookie`: Function to remove the cookie from the browser\n *\n * @example\n * ```tsx\n * const [theme, setTheme, deleteTheme] = useCookieState('theme', 'light');\n *\n * // Read current value\n * console.log(theme); // 'light' or saved value\n *\n * // Update cookie with default options (7 days expiry)\n * setTheme('dark');\n *\n * // Update with custom options\n * setTheme('dark', {\n *   days: 30,\n *   secure: true,\n *   sameSite: 'Strict'\n * });\n *\n * // Remove the cookie\n * deleteTheme();\n * ```\n *\n * @example\n * ```tsx\n * // User preferences with longer expiry\n * const [userPrefs, setUserPrefs] = useCookieState('preferences', '{}');\n *\n * const updatePreference = (key: string, value: any) => {\n *   const prefs = JSON.parse(userPrefs || '{}');\n *   prefs[key] = value;\n *   setUserPrefs(JSON.stringify(prefs), { days: 365 });\n * };\n * ```\n * @see https://thibault.sh/hooks/use-cookie-state\n */\nexport function useCookieState(\n  name: string,\n  initialValue: string\n): [string | null, (newValue: string, options?: CookieOptions) => void, () => void] {\n  const [value, setValue] = useState<string | null>(() => {\n    if (typeof window === \"undefined\") return initialValue;\n\n    try {\n      const cookie = document.cookie.split(\"; \").find((row) => row.startsWith(name + \"=\"));\n\n      return cookie ? decodeURIComponent(cookie.split(\"=\")[1]) : initialValue;\n    } catch (error) {\n      console.warn(`Error reading cookie \"${name}\":`, error);\n      return initialValue;\n    }\n  });\n\n  const setCookie = useCallback(\n    (newValue: string, options: CookieOptions = {}) => {\n      if (typeof window === \"undefined\") return;\n\n      try {\n        const { days = 7, path = \"/\", domain, secure = false, sameSite = \"Lax\" } = options;\n\n        const expires = new Date(Date.now() + days * 864e5).toUTCString();\n\n        document.cookie = [\n          `${name}=${encodeURIComponent(newValue)}`,\n          `expires=${expires}`,\n          `path=${path}`,\n          domain ? `domain=${domain}` : \"\",\n          secure ? \"secure\" : \"\",\n          `SameSite=${sameSite}`,\n        ]\n          .filter(Boolean)\n          .join(\"; \");\n\n        setValue(newValue);\n      } catch (error) {\n        console.warn(`Error setting cookie \"${name}\":`, error);\n      }\n    },\n    [name]\n  );\n\n  const deleteCookie = useCallback(() => {\n    if (typeof window === \"undefined\") return;\n\n    document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;\n    setValue(null);\n  }, [name]);\n\n  return [value, setCookie, deleteCookie];\n}\n"]}