Theme Provider
muffled-ui-registry/theme-providerFreeUtility
Light/dark switching for ink-and-paper tokens. Toggles .dark on html and persists to localStorage. Add themeInitScript to your root layout or index.html to avoid a flash.
Install it
npx shadcn@latest add https://ui.muffled.studio/r/theme-provider.jsonSource
1"use client"23import { createContext, useContext, useEffect, useState } from "react"45type Theme = "light" | "dark"67const STORAGE_KEY = "theme"89const themeFavicons = {10 light: "/logo-ink.svg",11 dark: "/logo-paper.svg",12} as const1314const ThemeContext = createContext<{15 theme: Theme16 setTheme: (theme: Theme) => void17} | null>(null)1819function getSystemTheme(): Theme {20 return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"21}2223function applyFavicon(theme: Theme) {24 const href = themeFavicons[theme]25 document26 .querySelectorAll<HTMLLinkElement>("link[data-theme-icon]")27 .forEach((link) => {28 link.href = href29 })30}3132function applyTheme(theme: Theme) {33 document.documentElement.classList.toggle("dark", theme === "dark")34 applyFavicon(theme)35}3637export function ThemeProvider({ children }: { children: React.ReactNode }) {38 const [theme, setThemeState] = useState<Theme>("light")3940 useEffect(() => {41 const stored = localStorage.getItem(STORAGE_KEY)42 const initial =43 stored === "dark" || stored === "light" ? stored : getSystemTheme()44 setThemeState(initial)45 applyTheme(initial)46 }, [])4748 function setTheme(next: Theme) {49 setThemeState(next)50 localStorage.setItem(STORAGE_KEY, next)51 applyTheme(next)52 }5354 return (55 <ThemeContext.Provider value={{ theme, setTheme }}>56 {children}57 </ThemeContext.Provider>58 )59}6061export function useTheme() {62 const context = useContext(ThemeContext)63 if (!context) {64 throw new Error("useTheme must be used within ThemeProvider")65 }66 return context67}6869export const themeInitScript = `(function(){try{var s=localStorage.getItem("${STORAGE_KEY}");var t=s==="dark"||s==="light"?s:matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";if(t==="dark")document.documentElement.classList.add("dark");var h=t==="dark"?"${themeFavicons.dark}":"${themeFavicons.light}";document.querySelectorAll("link[data-theme-icon]").forEach(function(l){l.href=h})}catch(e){}})()`
What it pulls in
Other registry items
Files it writes
More from muffled-ui-registry
All 55 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Surfacesurface | muffled-ui-registry | Utilities | Free | 2 deps |
