11import { useState } from 'react' ;
2- import type { MouseEvent } from 'react' ;
2+ import type { KeyboardEvent , MouseEvent } from 'react' ;
33import type { ApiFormat , BillingDisplay } from '../../../types' ;
44import type { AccountRecord , QuotaDisplay , QuotaWindowDisplay , Translator } from '../model/types' ;
55import type { AccountUsageSummary } from '../model/accountUsage' ;
@@ -220,18 +220,37 @@ export function QuotaBars({ quotaDisplay, t }: QuotaBarsProps) {
220220 const refreshing = quotaDisplay . refreshing === true ;
221221 const hasTokenProgress = windows . some ( hasQuotaTokenProgress ) ;
222222
223- const handleToggleDisplayMode = ( event : MouseEvent < HTMLButtonElement > ) => {
224- event . stopPropagation ( ) ;
223+ const toggleDisplayMode = ( ) => {
225224 if ( ! hasTokenProgress ) return ;
226225 setDisplayMode ( ( current ) => current === 'percent' ? 'tokens' : 'percent' ) ;
227226 } ;
228227
228+ const handleToggleDisplayMode = ( event : MouseEvent < HTMLElement > ) => {
229+ event . stopPropagation ( ) ;
230+ toggleDisplayMode ( ) ;
231+ } ;
232+
233+ const handleToggleDisplayModeKeyDown = ( event : KeyboardEvent < HTMLElement > ) => {
234+ if ( event . key !== 'Enter' && event . key !== ' ' ) return ;
235+ event . preventDefault ( ) ;
236+ event . stopPropagation ( ) ;
237+ toggleDisplayMode ( ) ;
238+ } ;
239+
229240 return (
230- < div
231- className = "grid gap-2.5 border-b border-dashed border-[var(--border-color)] px-4 py-3"
241+ < section
242+ className = { `grid gap-2.5 border-b border-dashed border-[var(--border-color)] px-4 py-3 ${
243+ hasTokenProgress ? 'cursor-pointer transition-colors hover:bg-[var(--bg-surface)]' : ''
244+ } `}
232245 aria-busy = { refreshing }
246+ aria-pressed = { hasTokenProgress ? displayMode === 'tokens' : undefined }
247+ role = { hasTokenProgress ? 'button' : undefined }
248+ tabIndex = { hasTokenProgress ? 0 : undefined }
233249 data-quota-refreshing = { refreshing ? 'true' : undefined }
234250 data-quota-display-mode = { displayMode }
251+ data-account-card-ignore-click = { hasTokenProgress ? 'true' : undefined }
252+ onClick = { hasTokenProgress ? handleToggleDisplayMode : undefined }
253+ onKeyDown = { hasTokenProgress ? handleToggleDisplayModeKeyDown : undefined }
235254 >
236255 { windows . map ( ( window ) => {
237256 const resetTime = formatQuotaResetDisplayWithUnix ( window . resetLabel , window . resetAtUnix ) ;
@@ -253,21 +272,9 @@ export function QuotaBars({ quotaDisplay, t }: QuotaBarsProps) {
253272 < div className = "min-w-0 truncate font-mono text-[length:var(--font-size-ui-sm)] font-black uppercase tracking-[0.12em] text-[var(--text-muted)]" >
254273 { window . label }
255274 </ div >
256- { hasTokenProgress ? (
257- < button
258- type = "button"
259- className = "shrink-0 cursor-pointer text-right font-mono text-[length:var(--font-size-ui-sm)] font-black uppercase tracking-[0.08em] text-[var(--text-primary)] hover:underline"
260- aria-pressed = { displayMode === 'tokens' }
261- title = { `${ formatQuotaPercent ( window ) } / ${ formatQuotaTokenProgress ( window ) } ` }
262- onClick = { handleToggleDisplayMode }
263- >
264- { valueLabel }
265- </ button >
266- ) : (
267- < div className = "shrink-0 text-right font-mono text-[length:var(--font-size-ui-sm)] font-black uppercase tracking-[0.08em] text-[var(--text-primary)]" >
268- { valueLabel }
269- </ div >
270- ) }
275+ < div className = "shrink-0 text-right font-mono text-[length:var(--font-size-ui-sm)] font-black uppercase tracking-[0.08em] text-[var(--text-primary)]" >
276+ { valueLabel }
277+ </ div >
271278 </ div >
272279 < div className = "grid min-w-0 gap-1" >
273280 < div
@@ -299,7 +306,7 @@ export function QuotaBars({ quotaDisplay, t }: QuotaBarsProps) {
299306 </ div >
300307 ) ;
301308 } ) }
302- </ div >
309+ </ section >
303310 ) ;
304311}
305312
0 commit comments