diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index a00fee966c8..4a1b4e5bc30 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -2,9 +2,8 @@ import { render, useKeyboard, useRenderer, useTerminalDimensions } from "@opentu import { Clipboard } from "@tui/util/clipboard" import { TextAttributes } from "@opentui/core" import { RouteProvider, useRoute } from "@tui/context/route" -import { Switch, Match, createEffect, untrack, ErrorBoundary, createSignal, onMount, batch, Show, on } from "solid-js" +import { Switch, Match, createEffect, untrack, ErrorBoundary, createSignal, onMount, batch, on } from "solid-js" import { Installation } from "@/installation" -import { Global } from "@/global" import { Flag } from "@/flag/flag" import { DialogProvider, useDialog } from "@tui/ui/dialog" import { DialogProvider as DialogProviderList } from "@tui/component/dialog-provider" @@ -165,7 +164,7 @@ function App() { const command = useCommandDialog() const { event, client: sdkClient } = useSDK() const toast = useToast() - const { theme, mode, setMode } = useTheme() + const { theme, mode, setMode, transparent, setTransparent } = useTheme() const sync = useSync() const exit = useExit() const promptRef = usePromptRef() @@ -389,6 +388,15 @@ function App() { }, category: "System", }, + { + title: "Toggle transparency", + value: "theme.transparency", + onSelect: (dialog) => { + setTransparent(!transparent()) + dialog.clear() + }, + category: "System", + }, { title: "Help", value: "help.show", diff --git a/packages/opencode/src/cli/cmd/tui/context/theme.tsx b/packages/opencode/src/cli/cmd/tui/context/theme.tsx index 15620222592..8a03fdab84f 100644 --- a/packages/opencode/src/cli/cmd/tui/context/theme.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/theme.tsx @@ -1,6 +1,6 @@ import { SyntaxStyle, RGBA, type TerminalColors } from "@opentui/core" import path from "path" -import { createEffect, createMemo, onMount } from "solid-js" +import { createEffect, createMemo } from "solid-js" import { useSync } from "@tui/context/sync" import { createSimpleContext } from "./helper" import aura from "./theme/aura.json" with { type: "json" } @@ -95,6 +95,7 @@ type ThemeColors = { type Theme = ThemeColors & { _hasSelectedListItemText: boolean thinkingOpacity: number + transparent: boolean } export function selectedForeground(theme: Theme): RGBA { @@ -157,12 +158,12 @@ export const DEFAULT_THEMES: Record = { solarized, synthwave84, tokyonight, - vesper, vercel, + vesper, zenburn, } -function resolveTheme(theme: ThemeJson, mode: "dark" | "light") { +function resolveTheme(theme: ThemeJson, mode: "dark" | "light", transparent: boolean) { const defs = theme.defs ?? {} function resolveColor(c: ColorValue): RGBA { if (c instanceof RGBA) return c @@ -213,10 +214,17 @@ function resolveTheme(theme: ThemeJson, mode: "dark" | "light") { // Handle thinkingOpacity - optional with default of 0.6 const thinkingOpacity = theme.theme.thinkingOpacity ?? 0.6 + if (transparent) { + resolved.background = RGBA.fromInts(0, 0, 0, 0) + // NOTE: Could alternatively apply an alpha channel to the theme's base background color + // instead of forcing full transparency, allowing for adjustable opacity levels + } + return { ...resolved, _hasSelectedListItemText: hasSelectedListItemText, thinkingOpacity, + transparent, } as Theme } @@ -274,6 +282,7 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ themes: DEFAULT_THEMES, mode: kv.get("theme_mode", props.mode), active: (sync.data.config.theme ?? kv.get("theme", "opencode")) as string, + transparent: kv.get("theme_transparent", false), ready: false, }) @@ -298,7 +307,7 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ }) const values = createMemo(() => { - return resolveTheme(store.themes[store.active] ?? store.themes.opencode, store.mode) + return resolveTheme(store.themes[store.active] ?? store.themes.opencode, store.mode, store.transparent) }) const syntax = createMemo(() => generateSyntax(values())) @@ -330,6 +339,13 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ setStore("active", theme) kv.set("theme", theme) }, + transparent() { + return store.transparent + }, + setTransparent(transparent: boolean) { + setStore("transparent", transparent) + kv.set("theme_transparent", transparent) + }, get ready() { return store.ready },