omarchy registry
All items

useOmarchyTheme

Hook

Reads and writes the active Omarchy theme, mirroring it onto the document element and localStorage.

bunx --bun shadcn@latest add yamz8/omarchy-shadcn-registry/use-omarchy-theme

Preview

No visual preview
This item ships code rather than UI. Read the source below.

Registry dependencies

yamz8/omarchy-shadcn-registry/omarchy-palette

Source

registry/hooks/use-omarchy-theme.ts
"use client"

import * as React from "react"

import {
  DEFAULT_OMARCHY_THEME,
  isOmarchyThemeName,
  type OmarchyThemeName,
} from "@/lib/omarchy-palette"

const STORAGE_KEY = "omarchy-theme"

const listeners = new Set<() => void>()

function subscribe(onStoreChange: () => void) {
  listeners.add(onStoreChange)
  window.addEventListener("storage", onStoreChange)

  return () => {
    listeners.delete(onStoreChange)
    window.removeEventListener("storage", onStoreChange)
  }
}

function getSnapshot(): OmarchyThemeName {
  try {
    const stored = window.localStorage.getItem(STORAGE_KEY)

    if (stored && isOmarchyThemeName(stored)) {
      return stored
    }
  } catch {
    // Storage can be unavailable (private mode, blocked site data).
  }

  return DEFAULT_OMARCHY_THEME
}

function getServerSnapshot(): OmarchyThemeName {
  return DEFAULT_OMARCHY_THEME
}

/**
 * Reads and writes the active Omarchy theme, mirroring it onto
 * `document.documentElement[data-omarchy-theme]` and localStorage.
 */
export function useOmarchyTheme() {
  const theme = React.useSyncExternalStore(
    subscribe,
    getSnapshot,
    getServerSnapshot
  )

  React.useEffect(() => {
    document.documentElement.dataset.omarchyTheme = theme
  }, [theme])

  const setTheme = React.useCallback((next: OmarchyThemeName) => {
    try {
      window.localStorage.setItem(STORAGE_KEY, next)
    } catch {
      // Ignore write failures and keep the in-memory selection.
    }

    for (const listener of listeners) {
      listener()
    }
  }, [])

  return { theme, setTheme }
}