Skip to content
DesignOSby h4rithd
Components/Theme Provider
ui / foundations

Theme Provider

A persistent dark-first DesignOS theme provider and theme hook.

PREVIEW READY
LIVE PREVIEWDARK / LIGHT COMPATIBLE
THEME PROVIDER

Designed as a complete stateful module

Responsive, keyboard-ready, theme-aware, and owned by your project after installation.

INSTALL / SOURCE REGISTRY

Add Theme Provider to your project

The command adds the component source and its DesignOS base dependency.

$pnpm dlx shadcn@latest add https://designos.h4rithd.com/r/theme-provider.json
registry/default/ui/theme-provider.tsx
"use client"

import * as React from "react"
import "@/components/designos/designos.css"

type Theme = "dark" | "light"
type ThemeContextValue = { theme: Theme; setTheme: (theme: Theme) => void; toggleTheme: () => void }
const ThemeContext = React.createContext<ThemeContextValue | null>(null)

export function DesignOSProvider({ children, defaultTheme = "dark", storageKey = "designos-theme", className }: { children: React.ReactNode; defaultTheme?: Theme; storageKey?: string; className?: string }) {
  const [theme, setThemeState] = React.useState<Theme>(() => typeof window === "undefined" ? defaultTheme : window.localStorage.getItem(storageKey) === "light" ? "light" : defaultTheme)
  React.useEffect(() => { document.documentElement.dataset.theme = theme; window.localStorage.setItem(storageKey, theme) }, [storageKey, theme])
  const setTheme = React.useCallback((next: Theme) => setThemeState(next), [])
  const toggleTheme = React.useCallback(() => setThemeState((current) => current === "dark" ? "light" : "dark"), [])
  return <ThemeContext.Provider value={{ theme, setTheme, toggleTheme }}><div className={`dos-root${className ? ` ${className}` : ""}`}>{children}</div></ThemeContext.Provider>
}

export function useDesignOSTheme() {
  const context = React.useContext(ThemeContext)
  if (!context) throw new Error("useDesignOSTheme must be used inside DesignOSProvider")
  return context
}

Component contract

  • Source-owned after installation
  • Dark and light theme variables
  • Keyboard and visible-focus behavior
  • Reduced-motion fallback
  • Responsive from 320px upward
  • IBM Plex Sans + JetBrains Mono hierarchy