summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/theme/context.tsx
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-28 10:21:32 -0600
committerAdam <[email protected]>2025-12-28 10:21:32 -0600
commit040939fb720f8666eaee3d3b1866fe84e40151ca (patch)
tree744ff5e64dd848eb7f5b5a6ec8d868ff72be93fc /packages/ui/src/theme/context.tsx
parentf89b83a6d797568b1240c0c141db526e170c0299 (diff)
downloadopencode-040939fb720f8666eaee3d3b1866fe84e40151ca.tar.gz
opencode-040939fb720f8666eaee3d3b1866fe84e40151ca.zip
chore: cleanup theme stuff
Diffstat (limited to 'packages/ui/src/theme/context.tsx')
-rw-r--r--packages/ui/src/theme/context.tsx102
1 files changed, 2 insertions, 100 deletions
diff --git a/packages/ui/src/theme/context.tsx b/packages/ui/src/theme/context.tsx
index e2c31477c..d2fbed3a1 100644
--- a/packages/ui/src/theme/context.tsx
+++ b/packages/ui/src/theme/context.tsx
@@ -1,12 +1,3 @@
-/**
- * Theme context for SolidJS applications.
- * Provides reactive theme management with localStorage persistence and caching.
- *
- * Works in conjunction with the preload script to provide zero-FOUC theming:
- * 1. Preload script applies cached CSS immediately from localStorage
- * 2. ThemeProvider takes over, resolves theme, and updates cache
- */
-
import {
createContext,
useContext,
@@ -24,19 +15,12 @@ import { DEFAULT_THEMES } from "./default-themes"
export type ColorScheme = "light" | "dark" | "system"
interface ThemeContextValue {
- /** Currently active theme ID */
themeId: Accessor<string>
- /** Current color scheme preference */
colorScheme: Accessor<ColorScheme>
- /** Resolved current mode (light or dark) */
mode: Accessor<"light" | "dark">
- /** All available themes */
themes: Accessor<Record<string, DesktopTheme>>
- /** Set the active theme by ID */
setTheme: (id: string) => void
- /** Set color scheme preference */
setColorScheme: (scheme: ColorScheme) => void
- /** Register a custom theme */
registerTheme: (theme: DesktopTheme) => void
}
@@ -52,59 +36,6 @@ function getThemeCacheKey(themeId: string, mode: "light" | "dark"): string {
return `${STORAGE_KEYS.THEME_CSS_PREFIX}-${themeId}-${mode}`
}
-/**
- * Static tokens that don't change between themes
- */
-const STATIC_TOKENS = `
- --font-family-sans: "Inter", "Inter Fallback";
- --font-family-sans--font-feature-settings: "ss03" 1;
- --font-family-mono: "IBM Plex Mono", "IBM Plex Mono Fallback";
- --font-family-mono--font-feature-settings: "ss01" 1;
- --font-size-small: 13px;
- --font-size-base: 14px;
- --font-size-large: 16px;
- --font-size-x-large: 20px;
- --font-weight-regular: 400;
- --font-weight-medium: 500;
- --line-height-large: 150%;
- --line-height-x-large: 180%;
- --line-height-2x-large: 200%;
- --letter-spacing-normal: 0;
- --letter-spacing-tight: -0.16;
- --letter-spacing-tightest: -0.32;
- --paragraph-spacing-base: 0;
- --spacing: 0.25rem;
- --breakpoint-sm: 40rem;
- --breakpoint-md: 48rem;
- --breakpoint-lg: 64rem;
- --breakpoint-xl: 80rem;
- --breakpoint-2xl: 96rem;
- --container-3xs: 16rem;
- --container-2xs: 18rem;
- --container-xs: 20rem;
- --container-sm: 24rem;
- --container-md: 28rem;
- --container-lg: 32rem;
- --container-xl: 36rem;
- --container-2xl: 42rem;
- --container-3xl: 48rem;
- --container-4xl: 56rem;
- --container-5xl: 64rem;
- --container-6xl: 72rem;
- --container-7xl: 80rem;
- --radius-xs: 0.125rem;
- --radius-sm: 0.25rem;
- --radius-md: 0.375rem;
- --radius-lg: 0.5rem;
- --radius-xl: 0.625rem;
- --shadow-xs: 0 1px 2px -1px rgba(19, 16, 16, 0.04), 0 1px 2px 0 rgba(19, 16, 16, 0.06), 0 1px 3px 0 rgba(19, 16, 16, 0.08);
- --shadow-md: 0 6px 8px -4px rgba(19, 16, 16, 0.12), 0 4px 3px -2px rgba(19, 16, 16, 0.12), 0 1px 2px -1px rgba(19, 16, 16, 0.12);
- --shadow-xs-border: 0 0 0 1px var(--border-base), 0 1px 2px -1px rgba(19, 16, 16, 0.04), 0 1px 2px 0 rgba(19, 16, 16, 0.06), 0 1px 3px 0 rgba(19, 16, 16, 0.08);
- --shadow-xs-border-base: 0 0 0 1px var(--border-weak-base), 0 1px 2px -1px rgba(19, 16, 16, 0.04), 0 1px 2px 0 rgba(19, 16, 16, 0.06), 0 1px 3px 0 rgba(19, 16, 16, 0.08);
- --shadow-xs-border-select: 0 0 0 3px var(--border-weak-selected), 0 0 0 1px var(--border-selected), 0 1px 2px -1px rgba(19, 16, 16, 0.25), 0 1px 2px 0 rgba(19, 16, 16, 0.08), 0 1px 3px 0 rgba(19, 16, 16, 0.12);
- --shadow-xs-border-focus: 0 0 0 1px var(--border-base), 0 1px 2px -1px rgba(19, 16, 16, 0.25), 0 1px 2px 0 rgba(19, 16, 16, 0.08), 0 1px 3px 0 rgba(19, 16, 16, 0.12), 0 0 0 2px var(--background-weak), 0 0 0 3px var(--border-selected);
-`
-
const THEME_STYLE_ID = "oc-theme"
function ensureThemeStyleElement(): HTMLStyleElement {
@@ -118,41 +49,29 @@ function ensureThemeStyleElement(): HTMLStyleElement {
return element
}
-/**
- * Resolve a mode from system preference
- */
function getSystemMode(): "light" | "dark" {
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
}
-/**
- * Apply theme CSS to the document
- */
function applyThemeCss(theme: DesktopTheme, themeId: string, mode: "light" | "dark"): void {
const isDark = mode === "dark"
const variant = isDark ? theme.dark : theme.light
const tokens = resolveThemeVariant(variant, isDark)
const css = themeToCss(tokens)
- // Cache to localStorage for preload script
if (themeId !== "oc-1") {
const cacheKey = getThemeCacheKey(themeId, mode)
try {
localStorage.setItem(cacheKey, css)
- } catch {
- // localStorage might be full or disabled
- }
+ } catch {}
}
- // Build full CSS
const fullCss = `:root {
- ${STATIC_TOKENS}
color-scheme: ${mode};
--text-mix-blend-mode: ${isDark ? "plus-lighter" : "multiply"};
${css}
}`
- // Remove preload style if it exists
const preloadStyle = document.getElementById("oc-theme-preload")
if (preloadStyle) {
preloadStyle.remove()
@@ -161,14 +80,10 @@ function applyThemeCss(theme: DesktopTheme, themeId: string, mode: "light" | "da
const themeStyleElement = ensureThemeStyleElement()
themeStyleElement.textContent = fullCss
- // Update data attributes
document.documentElement.dataset.theme = themeId
document.documentElement.dataset.colorScheme = mode
}
-/**
- * Cache both light and dark variants of a theme
- */
function cacheThemeVariants(theme: DesktopTheme, themeId: string): void {
if (themeId === "oc-1") return
@@ -180,9 +95,7 @@ function cacheThemeVariants(theme: DesktopTheme, themeId: string): void {
const cacheKey = getThemeCacheKey(themeId, mode)
try {
localStorage.setItem(cacheKey, css)
- } catch {
- // localStorage might be full or disabled
- }
+ } catch {}
}
}
@@ -192,7 +105,6 @@ export function ThemeProvider(props: { children: JSX.Element; defaultTheme?: str
const [colorScheme, setColorSchemeSignal] = createSignal<ColorScheme>("system")
const [mode, setMode] = createSignal<"light" | "dark">(getSystemMode())
- // Listen for system color scheme changes
onMount(() => {
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
const handler = () => {
@@ -203,29 +115,23 @@ export function ThemeProvider(props: { children: JSX.Element; defaultTheme?: str
mediaQuery.addEventListener("change", handler)
onCleanup(() => mediaQuery.removeEventListener("change", handler))
- // Load saved preferences
const savedTheme = localStorage.getItem(STORAGE_KEYS.THEME_ID)
const savedScheme = localStorage.getItem(STORAGE_KEYS.COLOR_SCHEME) as ColorScheme | null
-
if (savedTheme && themes()[savedTheme]) {
setThemeIdSignal(savedTheme)
}
-
if (savedScheme) {
setColorSchemeSignal(savedScheme)
if (savedScheme !== "system") {
setMode(savedScheme)
}
}
-
- // Cache current theme variants for future preloads
const currentTheme = themes()[themeId()]
if (currentTheme) {
cacheThemeVariants(currentTheme, themeId())
}
})
- // Apply theme when themeId or mode changes
createEffect(() => {
const id = themeId()
const m = mode()
@@ -241,18 +147,14 @@ export function ThemeProvider(props: { children: JSX.Element; defaultTheme?: str
console.warn(`Theme "${id}" not found`)
return
}
-
setThemeIdSignal(id)
localStorage.setItem(STORAGE_KEYS.THEME_ID, id)
-
- // Cache both variants for future preloads
cacheThemeVariants(theme, id)
}
const setColorSchemePref = (scheme: ColorScheme) => {
setColorSchemeSignal(scheme)
localStorage.setItem(STORAGE_KEYS.COLOR_SCHEME, scheme)
-
if (scheme === "system") {
setMode(getSystemMode())
} else {