File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -75,7 +75,10 @@ function normalizeContextMenuItems(source: readonly ContextMenuItem[]): ContextM
7575
7676 const normalizedItem : ContextMenuItem = {
7777 id : sourceItem . id ,
78- label : sourceItem . label ,
78+ label :
79+ typeof sourceItem . detail === "string" && sourceItem . detail . length > 0
80+ ? `${ sourceItem . label } (${ sourceItem . detail } )`
81+ : sourceItem . label ,
7982 destructive : sourceItem . destructive === true ,
8083 disabled : sourceItem . disabled === true ,
8184 ...( sourceItem . separatorBefore === true ? { separatorBefore : true } : { } ) ,
Original file line number Diff line number Diff line change @@ -2108,7 +2108,8 @@ export default function Sidebar({ routeReveal }: { routeReveal: SidebarRouteReve
21082108 children : [
21092109 ...snoozePresets . map ( ( preset ) => ( {
21102110 id : `snooze:${ preset . id } ` ,
2111- label : `${ preset . label } (${ preset . whenLabel } )` ,
2111+ label : preset . label ,
2112+ detail : preset . whenLabel ,
21122113 disabled : ! canOperateThreads ( selectedThreads ) ,
21132114 } ) ) ,
21142115 {
Original file line number Diff line number Diff line change @@ -144,7 +144,8 @@ export function buildThreadActionMenuItems(
144144 children : [
145145 ...state . snoozePresets . map ( ( preset ) => ( {
146146 id : `snooze:${ preset . id } ` as const ,
147- label : `${ preset . label } (${ preset . whenLabel } )` ,
147+ label : preset . label ,
148+ detail : preset . whenLabel ,
148149 } ) ) ,
149150 { id : "snooze:custom" as const , label : "Custom…" , separatorBefore : true } ,
150151 ] ,
Original file line number Diff line number Diff line change @@ -235,4 +235,12 @@ describe("showContextMenuFallback", () => {
235235
236236 await expect ( selectionPromise ) . resolves . toBe ( "rename" ) ;
237237 } ) ;
238+
239+ it ( "shows an item's detail beside its label and reads both to screen readers" , ( ) => {
240+ void showContextMenuFallback ( [ { id : "snooze:hour" , label : "In 1 hour" , detail : "3:00 PM" } ] ) ;
241+ const button = findButton ( "In 1 hour" ) ;
242+
243+ expect ( button ?. textContent ) . toBe ( "In 1 hour3:00 PM" ) ;
244+ expect ( button ?. attributes . get ( "aria-label" ) ) . toBe ( "In 1 hour, 3:00 PM" ) ;
245+ } ) ;
238246} ) ;
Original file line number Diff line number Diff line change @@ -371,6 +371,17 @@ export function showContextMenuFallback<T extends string>(
371371 label . textContent = item . label ;
372372 button . appendChild ( label ) ;
373373
374+ if ( item . detail ) {
375+ // The comma gives screen readers a pause between label and detail.
376+ button . setAttribute ( "aria-label" , `${ item . label } , ${ item . detail } ` ) ;
377+ const detail = document . createElement ( "span" ) ;
378+ detail . className = "ms-auto shrink-0 ps-4 text-muted-foreground text-xs" ;
379+ detail . style . cssText =
380+ "margin-inline-start:auto;flex-shrink:0;padding-inline-start:1rem;color:var(--contrast-muted-foreground);font-size:0.75rem;" ;
381+ detail . textContent = item . detail ;
382+ button . appendChild ( detail ) ;
383+ }
384+
374385 if ( hasChildren ) {
375386 button . setAttribute ( "aria-haspopup" , "menu" ) ;
376387 button . setAttribute ( "aria-expanded" , "false" ) ;
Original file line number Diff line number Diff line change @@ -24,6 +24,7 @@ import type {
2424export interface ContextMenuItem < T extends string = string > {
2525 id : T ;
2626 label : string ;
27+ detail ?: string ;
2728 destructive ?: boolean ;
2829 disabled ?: boolean ;
2930 header ?: boolean ;
@@ -40,6 +41,7 @@ export type QuitShortcutHintEvent =
4041export interface ContextMenuItemSchemaType {
4142 readonly id : string ;
4243 readonly label : string ;
44+ readonly detail ?: string ;
4345 readonly destructive ?: boolean ;
4446 readonly disabled ?: boolean ;
4547 readonly header ?: boolean ;
@@ -52,6 +54,7 @@ export interface ContextMenuItemSchemaType {
5254export const ContextMenuItemSchema : Schema . Codec < ContextMenuItemSchemaType > = Schema . Struct ( {
5355 id : Schema . String ,
5456 label : Schema . String ,
57+ detail : Schema . optionalKey ( Schema . String ) ,
5558 destructive : Schema . optionalKey ( Schema . Boolean ) ,
5659 disabled : Schema . optionalKey ( Schema . Boolean ) ,
5760 header : Schema . optionalKey ( Schema . Boolean ) ,
You can’t perform that action at this time.
0 commit comments