{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-today",
  "title": "useToday",
  "description": "Today's date that rolls over at midnight and when the tab comes back, without a hydration mismatch.",
  "files": [
    {
      "path": "hooks/use-today.ts",
      "content": "import * as React from \"react\"\n\nfunction toDateKey(date: Date) {\n  const month = String(date.getMonth() + 1).padStart(2, \"0\")\n  const day = String(date.getDate()).padStart(2, \"0\")\n  return `${date.getFullYear()}-${month}-${day}`\n}\n\nfunction fromDateKey(key: string) {\n  const [year, month, day] = key.split(\"-\").map(Number)\n  return new Date(year, month - 1, day)\n}\n\nfunction subscribeToday(onChange: () => void) {\n  let timer: ReturnType<typeof setTimeout> | undefined\n\n  const schedule = () => {\n    const now = new Date()\n    const midnight = new Date(\n      now.getFullYear(),\n      now.getMonth(),\n      now.getDate() + 1\n    )\n    timer = setTimeout(\n      () => {\n        onChange()\n        schedule()\n      },\n      midnight.getTime() - now.getTime() + 1000\n    )\n  }\n\n  const onVisible = () => {\n    if (document.visibilityState === \"visible\") {\n      onChange()\n    }\n  }\n\n  schedule()\n  document.addEventListener(\"visibilitychange\", onVisible)\n\n  return () => {\n    clearTimeout(timer)\n    document.removeEventListener(\"visibilitychange\", onVisible)\n  }\n}\n\nfunction getTodayKey() {\n  return toDateKey(new Date())\n}\n\nfunction getNoTodayKey() {\n  return null\n}\n\nfunction useToday() {\n  const key = React.useSyncExternalStore(\n    subscribeToday,\n    getTodayKey,\n    getNoTodayKey\n  )\n\n  return React.useMemo(() => (key ? fromDateKey(key) : undefined), [key])\n}\n\nexport { fromDateKey, getTodayKey, subscribeToday, toDateKey, useToday }\n",
      "type": "registry:hook"
    }
  ],
  "type": "registry:hook"
}