New: Activity Terrain +12 more

useToday

Today's date that rolls over at midnight and when the tab comes back, without a hydration mismatch.

2 examplesFrom HextaUI (MIT)

Installation

Run this in your project. It adds the files, installs the npm packages and anything this builds on, and sets up the theme:

npx shadcn@latest add https://kryptonite-ui.vercel.app/r/use-today.json
Install manually
  1. Copy this into hooks/use-today.ts:

    use-today.ts
    import * as React from "react"
    
    function toDateKey(date: Date) {
      const month = String(date.getMonth() + 1).padStart(2, "0")
      const day = String(date.getDate()).padStart(2, "0")
      return `${date.getFullYear()}-${month}-${day}`
    }
    
    function fromDateKey(key: string) {
      const [year, month, day] = key.split("-").map(Number)
      return new Date(year, month - 1, day)
    }
    
    function subscribeToday(onChange: () => void) {
      let timer: ReturnType<typeof setTimeout> | undefined
    
      const schedule = () => {
        const now = new Date()
        const midnight = new Date(
          now.getFullYear(),
          now.getMonth(),
          now.getDate() + 1
        )
        timer = setTimeout(
          () => {
            onChange()
            schedule()
          },
          midnight.getTime() - now.getTime() + 1000
        )
      }
    
      const onVisible = () => {
        if (document.visibilityState === "visible") {
          onChange()
        }
      }
    
      schedule()
      document.addEventListener("visibilitychange", onVisible)
    
      return () => {
        clearTimeout(timer)
        document.removeEventListener("visibilitychange", onVisible)
      }
    }
    
    function getTodayKey() {
      return toDateKey(new Date())
    }
    
    function getNoTodayKey() {
      return null
    }
    
    function useToday() {
      const key = React.useSyncExternalStore(
        subscribeToday,
        getTodayKey,
        getNoTodayKey
      )
    
      return React.useMemo(() => (key ? fromDateKey(key) : undefined), [key])
    }
    
    export { fromDateKey, getTodayKey, subscribeToday, toDateKey, useToday }

Usage

Date bounds

Feedback

Questions, bugs or ideas for useToday? Post them here, or reply to someone else. Sign in with GitHub to comment.