diff options
| author | Adam <[email protected]> | 2025-12-28 06:41:54 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2025-12-28 06:41:59 -0600 |
| commit | 82a876da4de0074ca3d4d6af9a31dc6e8cf20c3a (patch) | |
| tree | e83d71404c832ff59b351540f4a56eecf2b97b36 /packages/ui/src/theme | |
| parent | 69a15ae9c1e6737728649cebf3a4009d9ae8edd3 (diff) | |
| download | opencode-82a876da4de0074ca3d4d6af9a31dc6e8cf20c3a.tar.gz opencode-82a876da4de0074ca3d4d6af9a31dc6e8cf20c3a.zip | |
chore: cleanup
Diffstat (limited to 'packages/ui/src/theme')
| -rw-r--r-- | packages/ui/src/theme/context.tsx | 14 | ||||
| -rw-r--r-- | packages/ui/src/theme/preload.ts | 58 |
2 files changed, 27 insertions, 45 deletions
diff --git a/packages/ui/src/theme/context.tsx b/packages/ui/src/theme/context.tsx index d8ca6d507..9a2013ee9 100644 --- a/packages/ui/src/theme/context.tsx +++ b/packages/ui/src/theme/context.tsx @@ -126,11 +126,13 @@ function applyThemeCss(theme: DesktopTheme, themeId: string, mode: "light" | "da const css = themeToCss(tokens) // Cache to localStorage for preload script - const cacheKey = getThemeCacheKey(themeId, mode) - try { - localStorage.setItem(cacheKey, css) - } catch { - // localStorage might be full or disabled + if (themeId !== "oc-1") { + const cacheKey = getThemeCacheKey(themeId, mode) + try { + localStorage.setItem(cacheKey, css) + } catch { + // localStorage might be full or disabled + } } // Build full CSS @@ -159,6 +161,8 @@ function applyThemeCss(theme: DesktopTheme, themeId: string, mode: "light" | "da * Cache both light and dark variants of a theme */ function cacheThemeVariants(theme: DesktopTheme, themeId: string): void { + if (themeId === "oc-1") return + for (const mode of ["light", "dark"] as const) { const isDark = mode === "dark" const variant = isDark ? theme.dark : theme.light diff --git a/packages/ui/src/theme/preload.ts b/packages/ui/src/theme/preload.ts index eb54082fa..7e1143202 100644 --- a/packages/ui/src/theme/preload.ts +++ b/packages/ui/src/theme/preload.ts @@ -4,15 +4,13 @@ * Generates a minimal inline script that: * 1. Reads theme preferences from localStorage * 2. Applies cached theme CSS immediately (avoiding FOUC) - * 3. Falls back to embedded default theme CSS on first visit + * + * The default (oc-1) theme is provided by `@opencode-ai/ui/styles` via `theme.css`, + * so the preload script only runs when a non-default theme is selected. * * The script should be placed in the document <head> before any stylesheets. */ -import { resolveThemeVariant, themeToCss } from "./resolve" -import type { DesktopTheme } from "./types" -import oc1Theme from "./themes/oc-1.json" - // Storage keys used by both the preload script and the ThemeProvider export const STORAGE_KEYS = { THEME_ID: "opencode-theme-id", @@ -28,33 +26,16 @@ export function getThemeCacheKey(themeId: string, mode: "light" | "dark"): strin } /** - * Generate the embedded default theme CSS for the preload script. - * This is used as a fallback when no cached theme exists. - */ -function generateEmbeddedDefaults(): { light: string; dark: string } { - const theme = oc1Theme as DesktopTheme - const lightTokens = resolveThemeVariant(theme.light, false) - const darkTokens = resolveThemeVariant(theme.dark, true) - - return { - light: themeToCss(lightTokens), - dark: themeToCss(darkTokens), - } -} - -/** * Generate the inline preload script. * * This script should be placed in the document <head> to avoid FOUC. - * It reads theme preferences from localStorage and applies the theme CSS - * immediately, falling back to an embedded default theme. + * It reads theme preferences from localStorage and applies cached theme CSS + * immediately. */ export function generatePreloadScript(): string { - const defaults = generateEmbeddedDefaults() - // Minified version of the preload logic // Variables: T=themeId, S=scheme, D=isDark, M=mode, C=css, K=cacheKey - return `(function(){var T=localStorage.getItem("${STORAGE_KEYS.THEME_ID}")||"oc-1";var S=localStorage.getItem("${STORAGE_KEYS.COLOR_SCHEME}")||"system";var D=S==="dark"||(S==="system"&&matchMedia("(prefers-color-scheme:dark)").matches);var M=D?"dark":"light";var K="${STORAGE_KEYS.THEME_CSS_PREFIX}-"+T+"-"+M;var C=localStorage.getItem(K);if(!C&&T==="oc-1"){C=D?${JSON.stringify(defaults.dark)}:${JSON.stringify(defaults.light)}}if(C){var s=document.createElement("style");s.id="oc-theme-preload";s.textContent=":root{color-scheme:"+M+";--text-mix-blend-mode:"+(D?"plus-lighter":"multiply")+";"+C+"}";document.head.appendChild(s)}document.documentElement.dataset.theme=T;document.documentElement.dataset.colorScheme=M})();` + return `(function(){var T=localStorage.getItem("${STORAGE_KEYS.THEME_ID}");if(!T)return;var S=localStorage.getItem("${STORAGE_KEYS.COLOR_SCHEME}")||"system";var D=S==="dark"||(S==="system"&&matchMedia("(prefers-color-scheme:dark)").matches);var M=D?"dark":"light";document.documentElement.dataset.theme=T;document.documentElement.dataset.colorScheme=M;if(T==="oc-1")return;var K="${STORAGE_KEYS.THEME_CSS_PREFIX}-"+T+"-"+M;var C=localStorage.getItem(K);if(C){var s=document.createElement("style");s.id="oc-theme-preload";s.textContent=":root{color-scheme:"+M+";--text-mix-blend-mode:"+(D?"plus-lighter":"multiply")+";"+C+"}";document.head.appendChild(s)}})();` } /** @@ -62,15 +43,16 @@ export function generatePreloadScript(): string { * Useful for debugging. */ export function generatePreloadScriptFormatted(): string { - const defaults = generateEmbeddedDefaults() - return `(function() { var THEME_KEY = "${STORAGE_KEYS.THEME_ID}"; var SCHEME_KEY = "${STORAGE_KEYS.COLOR_SCHEME}"; var CSS_PREFIX = "${STORAGE_KEYS.THEME_CSS_PREFIX}"; - // Read preferences from localStorage - var themeId = localStorage.getItem(THEME_KEY) || "oc-1"; + // Only preload when a theme is selected + var themeId = localStorage.getItem(THEME_KEY); + if (!themeId) return; + + // Read color scheme preference var scheme = localStorage.getItem(SCHEME_KEY) || "system"; // Determine if dark mode @@ -78,17 +60,17 @@ export function generatePreloadScriptFormatted(): string { (scheme === "system" && matchMedia("(prefers-color-scheme: dark)").matches); var mode = isDark ? "dark" : "light"; + // Set data attributes for CSS/JS reference + document.documentElement.dataset.theme = themeId; + document.documentElement.dataset.colorScheme = mode; + + // Default theme is handled by theme.css + if (themeId === "oc-1") return; + // Try to get cached CSS for this theme + mode var cacheKey = CSS_PREFIX + "-" + themeId + "-" + mode; var css = localStorage.getItem(cacheKey); - // Fallback to embedded default for oc-1 theme - if (!css && themeId === "oc-1") { - css = isDark - ? ${JSON.stringify(defaults.dark)} - : ${JSON.stringify(defaults.light)}; - } - // Apply CSS if we have it if (css) { var style = document.createElement("style"); @@ -100,9 +82,5 @@ export function generatePreloadScriptFormatted(): string { "}"; document.head.appendChild(style); } - - // Set data attributes for CSS/JS reference - document.documentElement.dataset.theme = themeId; - document.documentElement.dataset.colorScheme = mode; })();` } |
