@@ -33,7 +33,7 @@ import { createStore, produce } from "solid-js/store"
3333import { Global } from "@/global"
3434import { Filesystem } from "@/util/filesystem"
3535
36- type Theme = {
36+ type ThemeColors = {
3737 primary : RGBA
3838 secondary : RGBA
3939 accent : RGBA
@@ -43,9 +43,11 @@ type Theme = {
4343 info : RGBA
4444 text : RGBA
4545 textMuted : RGBA
46+ selectedListItemText : RGBA
4647 background : RGBA
4748 backgroundPanel : RGBA
4849 backgroundElement : RGBA
50+ backgroundMenu : RGBA
4951 border : RGBA
5052 borderActive : RGBA
5153 borderSubtle : RGBA
@@ -86,6 +88,27 @@ type Theme = {
8688 syntaxPunctuation : RGBA
8789}
8890
91+ type Theme = ThemeColors & {
92+ _hasSelectedListItemText : boolean
93+ }
94+
95+ export function selectedForeground ( theme : Theme ) : RGBA {
96+ // If theme explicitly defines selectedListItemText, use it
97+ if ( theme . _hasSelectedListItemText ) {
98+ return theme . selectedListItemText
99+ }
100+
101+ // For transparent backgrounds, calculate contrast based on primary color
102+ if ( theme . background . a === 0 ) {
103+ const { r, g, b } = theme . primary
104+ const luminance = 0.299 * r + 0.587 * g + 0.114 * b
105+ return luminance > 0.5 ? RGBA . fromInts ( 0 , 0 , 0 ) : RGBA . fromInts ( 255 , 255 , 255 )
106+ }
107+
108+ // Fall back to background color
109+ return theme . background
110+ }
111+
89112type HexColor = `#${string } `
90113type RefName = string
91114type Variant = {
@@ -96,7 +119,10 @@ type ColorValue = HexColor | RefName | Variant | RGBA
96119type ThemeJson = {
97120 $schema ?: string
98121 defs ?: Record < string , HexColor | RefName >
99- theme : Record < keyof Theme , ColorValue >
122+ theme : Omit < Record < keyof ThemeColors , ColorValue > , "selectedListItemText" | "backgroundMenu" > & {
123+ selectedListItemText ?: ColorValue
124+ backgroundMenu ?: ColorValue
125+ }
100126}
101127
102128export const DEFAULT_THEMES : Record < string , ThemeJson > = {
@@ -137,19 +163,44 @@ function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
137163
138164 if ( defs [ c ] ) {
139165 return resolveColor ( defs [ c ] )
140- } else if ( theme . theme [ c as keyof Theme ] ) {
141- return resolveColor ( theme . theme [ c as keyof Theme ] )
166+ } else if ( theme . theme [ c as keyof ThemeColors ] !== undefined ) {
167+ return resolveColor ( theme . theme [ c as keyof ThemeColors ] ! )
142168 } else {
143169 throw new Error ( `Color reference "${ c } " not found in defs or theme` )
144170 }
145171 }
146172 return resolveColor ( c [ mode ] )
147173 }
148- return Object . fromEntries (
149- Object . entries ( theme . theme ) . map ( ( [ key , value ] ) => {
150- return [ key , resolveColor ( value ) ]
151- } ) ,
152- ) as Theme
174+
175+ const resolved = Object . fromEntries (
176+ Object . entries ( theme . theme )
177+ . filter ( ( [ key ] ) => key !== "selectedListItemText" && key !== "backgroundMenu" )
178+ . map ( ( [ key , value ] ) => {
179+ return [ key , resolveColor ( value ) ]
180+ } ) ,
181+ ) as Partial < ThemeColors >
182+
183+ // Handle selectedListItemText separately since it's optional
184+ const hasSelectedListItemText = theme . theme . selectedListItemText !== undefined
185+ if ( hasSelectedListItemText ) {
186+ resolved . selectedListItemText = resolveColor ( theme . theme . selectedListItemText ! )
187+ } else {
188+ // Backward compatibility: if selectedListItemText is not defined, use background color
189+ // This preserves the current behavior for all existing themes
190+ resolved . selectedListItemText = resolved . background
191+ }
192+
193+ // Handle backgroundMenu - optional with fallback to backgroundElement
194+ if ( theme . theme . backgroundMenu !== undefined ) {
195+ resolved . backgroundMenu = resolveColor ( theme . theme . backgroundMenu )
196+ } else {
197+ resolved . backgroundMenu = resolved . backgroundElement
198+ }
199+
200+ return {
201+ ...resolved ,
202+ _hasSelectedListItemText : hasSelectedListItemText ,
203+ } as Theme
153204}
154205
155206export const { use : useTheme , provider : ThemeProvider } = createSimpleContext ( {
@@ -288,11 +339,13 @@ function generateSystem(colors: TerminalColors, mode: "dark" | "light"): ThemeJs
288339 // Text colors
289340 text : fg ,
290341 textMuted,
342+ selectedListItemText : bg ,
291343
292344 // Background colors
293345 background : bg ,
294346 backgroundPanel : grays [ 2 ] ,
295347 backgroundElement : grays [ 3 ] ,
348+ backgroundMenu : grays [ 3 ] ,
296349
297350 // Border colors
298351 borderSubtle : grays [ 6 ] ,
0 commit comments