MCPcopy Create free account
hub / github.com/anomalyco/opencode / resolveTheme

Function resolveTheme

packages/tui/src/theme/index.ts:241–299  ·  view source on GitHub ↗
(theme: ThemeJson, mode: "dark" | "light")

Source from the content-addressed store, hash-verified

239}
240
241export function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
242 const defs = theme.defs ?? {}
243 function resolveColor(c: ColorValue, chain: string[] = []): RGBA {
244 if (c instanceof RGBA) return c
245 if (typeof c === "string") {
246 if (c === "transparent" || c === "none") return RGBA.fromInts(0, 0, 0, 0)
247
248 if (c.startsWith("#")) return RGBA.fromHex(c)
249
250 if (chain.includes(c)) {
251 throw new Error(`Circular color reference: ${[...chain, c].join(" -> ")}`)
252 }
253
254 const next = defs[c] ?? theme.theme[c as ThemeColor]
255 if (next === undefined) {
256 throw new Error(`Color reference "${c}" not found in defs or theme`)
257 }
258 return resolveColor(next, [...chain, c])
259 }
260 if (typeof c === "number") {
261 return ansiToRgba(c)
262 }
263 return resolveColor(c[mode], chain)
264 }
265
266 const resolved = Object.fromEntries(
267 Object.entries(theme.theme)
268 .filter(([key]) => key !== "selectedListItemText" && key !== "backgroundMenu" && key !== "thinkingOpacity")
269 .map(([key, value]) => {
270 return [key, resolveColor(value as ColorValue)]
271 }),
272 ) as Partial<Record<ThemeColor, RGBA>>
273
274 // Handle selectedListItemText separately since it's optional
275 const hasSelectedListItemText = theme.theme.selectedListItemText !== undefined
276 if (hasSelectedListItemText) {
277 resolved.selectedListItemText = resolveColor(theme.theme.selectedListItemText!)
278 } else {
279 // Backward compatibility: if selectedListItemText is not defined, use background color
280 // This preserves the current behavior for all existing themes
281 resolved.selectedListItemText = resolved.background
282 }
283
284 // Handle backgroundMenu - optional with fallback to backgroundElement
285 if (theme.theme.backgroundMenu !== undefined) {
286 resolved.backgroundMenu = resolveColor(theme.theme.backgroundMenu)
287 } else {
288 resolved.backgroundMenu = resolved.backgroundElement
289 }
290
291 // Handle thinkingOpacity - optional with default of 0.6
292 const thinkingOpacity = theme.theme.thinkingOpacity ?? 0.6
293
294 return {
295 ...resolved,
296 _hasSelectedListItemText: hasSelectedListItemText,
297 thinkingOpacity,
298 } as Theme

Callers 2

theme.test.tsFile · 0.90
theme.tsxFile · 0.90

Calls 1

resolveColorFunction · 0.70

Tested by

no test coverage detected