diff --git a/apps/web/src/components/ComposerPromptEditor.tsx b/apps/web/src/components/ComposerPromptEditor.tsx index 08d7576636ec..4bb0a1de9c97 100644 --- a/apps/web/src/components/ComposerPromptEditor.tsx +++ b/apps/web/src/components/ComposerPromptEditor.tsx @@ -872,6 +872,14 @@ interface ComposerPromptEditorProps { skills: ReadonlyArray; disabled: boolean; placeholder: string; + ariaLabel?: string | undefined; + /** + * Suggestion-menu wiring for screen readers. `suggestionListId` marks an + * editor that can open a suggestion list at all, so editors without menus + * (the Settings font preview) are not announced as having autocomplete. + * `activeSuggestionId` is the highlighted option while that list is + * rendered; it drives aria-activedescendant and aria-controls. + */ suggestionListId?: string | undefined; activeSuggestionId?: string | undefined; containerClassName?: string; @@ -1635,6 +1643,7 @@ function ComposerPromptEditorInner({ skills, disabled, placeholder, + ariaLabel, suggestionListId, activeSuggestionId, containerClassName, @@ -1995,12 +2004,12 @@ function ComposerPromptEditorInner({ className, )} data-testid="composer-editor" - ariaLabel="Message" + ariaLabel={ariaLabel} ariaMultiline={true} - ariaAutoComplete="list" - ariaControls={suggestionListId} + ariaAutoComplete={suggestionListId ? "list" : undefined} + ariaControls={activeSuggestionId ? suggestionListId : undefined} ariaActiveDescendant={activeSuggestionId} - aria-haspopup="listbox" + aria-haspopup={suggestionListId ? "listbox" : undefined} aria-placeholder={placeholder} placeholder={} onKeyDown={(event) => { @@ -2088,6 +2097,7 @@ export function ComposerPromptEditor({ skills, disabled, placeholder, + ariaLabel, suggestionListId, activeSuggestionId, containerClassName, @@ -2137,6 +2147,7 @@ export function ComposerPromptEditor({ skills={skills} disabled={disabled} placeholder={placeholder} + ariaLabel={ariaLabel} suggestionListId={suggestionListId} activeSuggestionId={activeSuggestionId} {...(containerClassName ? { containerClassName } : {})} diff --git a/apps/web/src/components/chat/ChatComposer.tsx b/apps/web/src/components/chat/ChatComposer.tsx index 41ca47ba6955..ca5de4f7e400 100644 --- a/apps/web/src/components/chat/ChatComposer.tsx +++ b/apps/web/src/components/chat/ChatComposer.tsx @@ -6698,9 +6698,8 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) ) : null} 0 ? ( @@ -227,6 +227,13 @@ export function composerSuggestionOptionId(listId: string, itemId: string): stri return `${listId}-${encodeURIComponent(itemId)}`; } +const LISTBOX_LABEL_BY_TRIGGER: Record = { + path: "Files and folders", + "pull-request": "Pull requests", + "slash-command": "Commands", + skill: "Skills", +}; + const SKILL_SOURCE_ICON_BY_KIND: Record = { app: BlocksIcon, repo: FolderIcon,