@@ -58,6 +58,7 @@ import {
5858 type ReactNode ,
5959 useCallback ,
6060 useEffect ,
61+ useId ,
6162 useImperativeHandle ,
6263 useLayoutEffect ,
6364 useMemo ,
@@ -245,7 +246,11 @@ import { useEnvironmentQuery } from "~/state/query";
245246import { useDebouncedValue } from "~/state/queries" ;
246247import { ProviderModelPicker } from "./ProviderModelPicker" ;
247248import { resolveModelPickerSelectedModel } from "./ModelPickerContent" ;
248- import { type ComposerCommandItem , ComposerCommandMenu } from "./ComposerCommandMenu" ;
249+ import {
250+ type ComposerCommandItem ,
251+ ComposerCommandMenu ,
252+ composerSuggestionOptionId ,
253+ } from "./ComposerCommandMenu" ;
249254import { ComposerPendingApprovalActions } from "./ComposerPendingApprovalActions" ;
250255import { CompactComposerControlsMenu } from "./CompactComposerControlsMenu" ;
251256import { ComposerImageThumbnail } from "./ComposerImageThumbnail" ;
@@ -2108,6 +2113,8 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
21082113 resetTrigger : resetComposerTrigger ,
21092114 } = useComposerTriggerState ( ( ) => detectComposerTrigger ( prompt , prompt . length ) ) ;
21102115 const [ composerHighlightedItemId , setComposerHighlightedItemId ] = useState < string | null > ( null ) ;
2116+ const composerSuggestionId = useId ( ) ;
2117+ const composerSuggestionListId = `${ composerSuggestionId } -${ encodeURIComponent ( draftId ?? activeThreadId ?? "new" ) } -suggestions` ;
21112118 // Active ArrowUp recall. Cleared on edit and on thread switch.
21122119 const promptHistoryPositionRef = useRef < ComposerPromptHistoryPosition | null > ( null ) ;
21132120 const [ composerHighlightedSearchKey , setComposerHighlightedSearchKey ] = useState < string | null > (
@@ -2502,7 +2509,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
25022509
25032510 const composerMenuOpen = Boolean ( composerTrigger ) ;
25042511 const composerMenuSearchKey = composerTrigger
2505- ? `${ composerTrigger . kind } :${ composerTrigger . query . trim ( ) . toLowerCase ( ) } `
2512+ ? `${ composerSuggestionListId } : ${ composerTrigger . kind } :${ composerTrigger . query . trim ( ) . toLowerCase ( ) } `
25062513 : null ;
25072514 const activeComposerMenuItem = useMemo ( ( ) => {
25082515 const activeItemId = resolveComposerMenuActiveItemId ( {
@@ -2529,6 +2536,8 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
25292536 ) ;
25302537
25312538 const isComposerApprovalState = activePendingApproval !== null ;
2539+ const composerSuggestionsVisible = composerMenuOpen && ! isComposerApprovalState ;
2540+ const composerSuggestionListVisible = composerSuggestionsVisible && composerMenuItems . length > 0 ;
25322541 const activePendingUserInput = pendingUserInputs [ 0 ] ?? null ;
25332542 const isChoiceOnlyPendingQuestion =
25342543 activePendingProgress ?. activeQuestion ?. allowCustomAnswer === false ;
@@ -3176,6 +3185,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
31763185 // ------------------------------------------------------------------
31773186 useEffect ( ( ) => {
31783187 setComposerHighlightedItemId ( null ) ;
3188+ setComposerHighlightedSearchKey ( null ) ;
31793189 setComposerSubmissionError ( null ) ;
31803190 setProviderInputSubmissionError ( null ) ;
31813191 setComposerCursor ( collapseExpandedComposerCursor ( promptRef . current , promptRef . current . length ) ) ;
@@ -6454,9 +6464,19 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
64546464 </ ComposerCommandMenuLayer >
64556465 ) }
64566466
6457- { composerMenuOpen && ! isComposerApprovalState && (
6467+ < div role = "status" aria-atomic = "true" className = "sr-only" >
6468+ { composerSuggestionsVisible && composerMenuItems . length === 0
6469+ ? isComposerMenuLoading
6470+ ? composerTriggerKind === "pull-request"
6471+ ? "Finding pull request..."
6472+ : "Searching workspace files..."
6473+ : composerMenuEmptyState
6474+ : "" }
6475+ </ div >
6476+ { composerSuggestionsVisible && (
64586477 < ComposerCommandMenuLayer anchor = { composerMenuAnchor } >
64596478 < ComposerCommandMenu
6479+ listId = { composerSuggestionListId }
64606480 items = { composerMenuItems }
64616481 resolvedTheme = { resolvedTheme }
64626482 isLoading = { isComposerMenuLoading }
@@ -6845,6 +6865,16 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
68456865 ) : null }
68466866 < ComposerContextActionsContext value = { composerContextActions } >
68476867 < ComposerPromptEditor
6868+ ariaLabel = "Message"
6869+ suggestionListId = { composerSuggestionListId }
6870+ activeSuggestionId = {
6871+ composerSuggestionListVisible && activeComposerMenuItem
6872+ ? composerSuggestionOptionId (
6873+ composerSuggestionListId ,
6874+ activeComposerMenuItem . id ,
6875+ )
6876+ : undefined
6877+ }
68486878 editorRef = { composerEditorRef }
68496879 richTextEnabled = { settings . composerRichTextEnabled }
68506880 value = {
0 commit comments