summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/theme
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-28 06:41:54 -0600
committerAdam <[email protected]>2025-12-28 06:41:59 -0600
commit82a876da4de0074ca3d4d6af9a31dc6e8cf20c3a (patch)
treee83d71404c832ff59b351540f4a56eecf2b97b36 /packages/ui/src/theme
parent69a15ae9c1e6737728649cebf3a4009d9ae8edd3 (diff)
downloadopencode-82a876da4de0074ca3d4d6af9a31dc6e8cf20c3a.tar.gz
opencode-82a876da4de0074ca3d4d6af9a31dc6e8cf20c3a.zip
chore: cleanup
Diffstat (limited to 'packages/ui/src/theme')
-rw-r--r--packages/ui/src/theme/context.tsx14
-rw-r--r--packages/ui/src/theme/preload.ts58
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;
})();`
}