@@ -5,6 +5,7 @@ import { makeEventListener } from "@solid-primitives/event-listener"
55import { Tooltip } from "@opencode-ai/ui/tooltip"
66import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2"
77import { useLanguage } from "@/context/language"
8+ import { usePlatform } from "@/context/platform"
89
910type Mem = Performance & {
1011 memory ?: {
@@ -107,15 +108,53 @@ function Cell(props: {
107108 )
108109}
109110
111+ function FocusCell ( props : { active : boolean ; inline ?: boolean ; onClick : ( ) => void } ) {
112+ const content = ( ) => (
113+ < button
114+ type = "button"
115+ aria-label = "Force focus styles on all interactive elements"
116+ aria-pressed = { props . active }
117+ classList = { {
118+ "flex min-w-0 items-center font-mono uppercase hover:bg-surface-raised-base focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-border-focus" : true ,
119+ "min-h-[20px] w-fit flex-row justify-start gap-1.5 rounded px-1.5 py-0.5 text-left" : ! ! props . inline ,
120+ "min-h-[42px] w-full flex-col justify-center rounded-[8px] px-0.5 py-1 text-center" : ! props . inline ,
121+ "bg-surface-raised-base text-text-strong" : props . active ,
122+ } }
123+ onClick = { props . onClick }
124+ >
125+ < span class = "text-[10px] leading-none font-black tracking-[0.04em] opacity-70" > FOCUS</ span >
126+ < span classList = { { "leading-none font-bold" : true , "text-[11px]" : ! ! props . inline , "text-[13px]" : ! props . inline } } >
127+ { props . active ? "ON" : "OFF" }
128+ </ span >
129+ </ button >
130+ )
131+
132+ if ( props . inline ) {
133+ return (
134+ < TooltipV2 value = "Force focus styles on all interactive elements" placement = "top" >
135+ { content ( ) }
136+ </ TooltipV2 >
137+ )
138+ }
139+
140+ return (
141+ < Tooltip value = "Force focus styles on all interactive elements" placement = "top" >
142+ { content ( ) }
143+ </ Tooltip >
144+ )
145+ }
146+
110147export function DebugBar ( props : { inline ?: boolean } = { } ) {
111148 const language = useLanguage ( )
149+ const platform = usePlatform ( )
112150 const location = useLocation ( )
113151 const routing = useIsRouting ( )
114152 const [ state , setState ] = createStore ( {
115153 cls : undefined as number | undefined ,
116154 delay : undefined as number | undefined ,
117155 fps : undefined as number | undefined ,
118156 gap : undefined as number | undefined ,
157+ focus : false ,
119158 heap : {
120159 limit : undefined as number | undefined ,
121160 used : undefined as number | undefined ,
@@ -142,6 +181,16 @@ export function DebugBar(props: { inline?: boolean } = {}) {
142181 }
143182 const longv = ( ) => ( state . long . count === undefined ? na ( ) : `${ time ( state . long . block ) ?? na ( ) } /${ state . long . count } ` )
144183 const navv = ( ) => ( state . nav . pending ? "..." : ( time ( state . nav . dur ) ?? na ( ) ) )
184+ const toggleFocus = async ( ) => {
185+ if ( ! platform . setForceFocus ) return
186+ const enabled = ! state . focus
187+ await platform . setForceFocus ( enabled )
188+ setState ( "focus" , enabled )
189+ }
190+
191+ onCleanup ( ( ) => {
192+ if ( state . focus ) void platform . setForceFocus ?.( false ) . catch ( ( ) => undefined )
193+ } )
145194
146195 let prev = ""
147196 let start = 0
@@ -490,8 +539,11 @@ export function DebugBar(props: { inline?: boolean } = {}) {
490539 bad = { bad ( heap ( ) , 0.8 ) }
491540 dim = { state . heap . used === undefined }
492541 inline = { props . inline }
493- wide
542+ wide = { ! platform . setForceFocus }
494543 />
544+ { platform . setForceFocus && (
545+ < FocusCell active = { state . focus } inline = { props . inline } onClick = { ( ) => void toggleFocus ( ) } />
546+ ) }
495547 </ div >
496548 </ aside >
497549 )
0 commit comments