Skip to content

useDarkMode

Custom hook that returns the current state of the dark mode.

Usage

tsx
import { useDarkMode } from 'vhooks'

export default function Component() {
  const { isDarkMode, toggle, enable, disable } = useDarkMode()

  return (
    <div>
      <p>Current theme: {isDarkMode ? 'dark' : 'light'}</p>
      <button onClick={toggle}>Toggle</button>
      <button onClick={enable}>Enable</button>
      <button onClick={disable}>Disable</button>
    </div>
  )
}

Installation

sh
pnpm dlx scaflo@latest https://raw.githubusercontent.com/programming-with-ia/vDocs/scaflos/hooks/useDarkMode.json -e %src%/hooks
sh
npx scaflo@latest https://raw.githubusercontent.com/programming-with-ia/vDocs/scaflos/hooks/useDarkMode.json -e %src%/hooks
sh
bunx scaflo@latest https://raw.githubusercontent.com/programming-with-ia/vDocs/scaflos/hooks/useDarkMode.json -e %src%/hooks
sh
yarn dlx scaflo@latest https://raw.githubusercontent.com/programming-with-ia/vDocs/scaflos/hooks/useDarkMode.json -e %src%/hooks

API

useDarkMode(options?): DarkModeReturn

Custom hook that returns the current state of the dark mode.

Parameters

NameTypeDescription
options?DarkModeOptionsThe initial value of the dark mode, default false.

Returns

DarkModeReturn

An object containing the dark mode's state and its controllers.

Type aliases

Ƭ DarkModeOptions: Object

The hook options.

Type declaration

NameTypeDescription
defaultValue?booleanThe initial value of the dark mode. Default ts false
initializeWithValue?booleanIf true (default), the hook will initialize reading localStorage. In SSR, you should set it to false, returning the defaultValue or false initially. Default ts true
localStorageKey?stringThe key to use in the local storage. Default ts 'vhooks-dark-mode'

Ƭ DarkModeReturn: Object

The hook return type.

Type declaration

NameTypeDescription
disable() => void-
enable() => void-
isDarkModebooleanThe current state of the dark mode.
set(value: boolean) => void-
toggle() => void-

Hook

ts
import { useIsomorphicLayoutEffect, useLocalStorage, useMediaQuery } from 'vhooks'

const COLOR_SCHEME_QUERY = '(prefers-color-scheme: dark)'
const LOCAL_STORAGE_KEY = 'vhooks-dark-mode'

type DarkModeOptions = {
    defaultValue?: boolean
    localStorageKey?: string
    initializeWithValue?: boolean
}

type DarkModeReturn = {
    isDarkMode: boolean
    toggle: () => void
    enable: () => void
    disable: () => void
    set: (value: boolean) => void
}

export function useDarkMode(options: DarkModeOptions = {}): DarkModeReturn {
  const {
    defaultValue,
    localStorageKey = LOCAL_STORAGE_KEY,
    initializeWithValue = true,
  } = options

  const isDarkOS = useMediaQuery(COLOR_SCHEME_QUERY, {
    initializeWithValue,
    defaultValue,
  })
  const [isDarkMode, setDarkMode] = useLocalStorage<boolean>(
    localStorageKey,
    defaultValue ?? isDarkOS ?? false,
    { initializeWithValue },
  )

  // Update darkMode if os prefers changes
  useIsomorphicLayoutEffect(() => {
    if (isDarkOS !== isDarkMode) {
      setDarkMode(isDarkOS)
    }
  }, [isDarkOS])

  return {
    isDarkMode,
    toggle: () => {
      setDarkMode(prev => !prev)
    },
    enable: () => {
      setDarkMode(true)
    },
    disable: () => {
      setDarkMode(false)
    },
    set: value => {
      setDarkMode(value)
    },
  }
}

vDocs