Skip to content

fix(web): make composer suggestions usable with screen readers - #10154

Open
akj wants to merge 18 commits into
pingdotgg:mainfrom
akj:fix/composer-screen-reader-suggestions
Open

akj wants to merge 18 commits into
pingdotgg:mainfrom
akj:fix/composer-screen-reader-suggestions

Conversation

@akj

@akj akj commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

Screen reader users cannot identify the highlighted composer suggestion because the editor does not reference the suggestion list. This connects the existing keyboard selection to the multiline Message field for files, skills, commands, and pull requests, while keeping focus in the editor and preserving the visual layout.

The list has a name that matches its contents. A persistent status region exposes loading and empty results, and closed menus leave no dangling list or option references. The Settings font preview has its own name and does not advertise suggestions. Option IDs also accept lone UTF-16 surrogates without throwing or collapsing distinct filenames.

This now uses the current Tiptap editor in both rich and plain composer modes. The sync preserves the two commits contributed by @Leos-Khai in akj#1 after #11666 closed in favor of this PR.

Escape dismissal landed separately on main in #12836, so this PR now relies on that behavior instead of carrying its own.

Closes #10153.

Validation

  • After merging main on 2026-09-24, 139 focused tests passed across six composer test files, including malformed UTF-16 option IDs and highlight recovery. Web typecheck, targeted lint, and formatting passed.
  • 202 focused tests passed on the previous head, before the merge.
  • Scoped web typecheck, targeted lint, formatting, and diff checks passed. Full CI passed on 25c20ea4a9.
  • Before the merge, isolated Chrome checks covered all four list labels, active-option references and selection, focus retention, arrows, Enter and Tab selection, Escape dismissal, reopening after edits, loading and empty feedback, recovery, and thread-specific IDs. Both rich and plain composer modes were exercised.
  • Settings preview exposed a named multiline textbox without autocomplete, popup, list, or active-option attributes. Typing a trigger did not open suggestions.
  • Andrew tested the updated Tiptap composer with NVDA in Chrome on Windows and reported that it looks good. Packaged desktop, native mobile, and simultaneously mounted composers were not runtime-tested. Desktop uses this shared web composer; the native mobile composer is outside this change.

Earlier visual evidence

These captures document the original Lexical version of this PR. They are retained as historical evidence, not validation of the current Tiptap editor. This update changes semantics without changing styling.

Before After
Original slash-command suggestions Accessible slash-command suggestions with the same visual layout

Earlier silent keyboard demonstration:

keyboard-demo.mp4

Updated with GPT-6 in the Codex harness. Contributor commits retain their original authorship.

Summary by CodeRabbit

  • Accessibility

    • Improved keyboard and screen-reader support for composer suggestion menus.
    • Added clearer announcements for loading and empty suggestion states.
    • Added accessible labels and selection tracking for suggestions.
    • Pressing Escape now dismisses the suggestion menu.
  • Bug Fixes

    • Improved suggestion highlighting when results become empty and later return.
    • Added clearer labeling for prompt font previews.

@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 5, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 5ddfc53

Macroscope's review found this PR approvable — This is a focused accessibility correction to the existing web composer, adding screen-reader labels, live status announcements, keyboard dismissal, and stable suggestion selection semantics. The changes are isolated to the composer UI and accompanying tests, with no product-default, schema, deployment, or sensitive-data impact.

You can add or adjust custom eligibility rules. Learn more.

@akj akj changed the title fix(web): announce composer suggestions and skill chips to screen readers fix(web): make composer suggestions usable with screen readers Sep 5, 2026
@coderabbitai

coderabbitai Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 76c01498-7578-4921-9e56-c9807e4a69e8

📥 Commits

Reviewing files that changed from the base of the PR and between b14d1b3 and 25c20ea.

📒 Files selected for processing (5)
  • apps/web/src/components/ComposerPromptEditorTiptap.tsx
  • apps/web/src/components/chat/ChatComposer.tsx
  • apps/web/src/components/chat/ComposerCommandMenu.test.tsx
  • apps/web/src/components/chat/ComposerCommandMenu.tsx
  • apps/web/src/components/settings/SettingsFontPreviews.tsx

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The composer now exposes accessible suggestion lists and active options to screen readers. It adds stable list and option IDs, editor ARIA attributes, status announcements, and Escape dismissal behavior. Tests cover option ID generation and empty-result highlight recovery.

Changes

Composer suggestion interaction

Layer / File(s) Summary
Editor keyboard and accessibility contracts
apps/web/src/components/ComposerPromptEditorTiptap.tsx, apps/web/src/components/settings/SettingsFontPreviews.tsx
The editor exposes textbox and suggestion-list ARIA attributes, accepts Escape events, and receives an accessible label in the font preview.
Suggestion menu option semantics
apps/web/src/components/chat/ComposerCommandMenu.tsx, apps/web/src/components/chat/ComposerCommandMenu.test.tsx, apps/web/src/components/chat/composerMenuHighlight.test.ts
The menu receives a list ID, generates encoded option IDs, labels each list by trigger type, marks the active option, and tests edge-case IDs and empty-result recovery.
Composer dismissal and accessibility wiring
apps/web/src/components/chat/ChatComposer.tsx
The composer scopes suggestion IDs, connects the editor to the menu, announces loading and empty states, and suppresses or resets suggestion triggers after Escape dismissal.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant ScreenReader
  participant ComposerPromptEditor
  participant ChatComposer
  participant ComposerCommandMenu
  ScreenReader->>ComposerPromptEditor: Focus the message textbox
  ComposerPromptEditor->>ChatComposer: Send navigation or Escape key
  ChatComposer->>ComposerCommandMenu: Update suggestion state
  ComposerCommandMenu->>ComposerPromptEditor: Provide active option ID
  ComposerPromptEditor->>ScreenReader: Announce the active option or status
Loading

Suggested reviewers: juliusmarminge, chrisdeeming

Merge Risk: ⚪ Minimal · up to 25c20

The accessibility wiring introduces no supported merge-blocking risk in the reviewed changes.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 7 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Issue #10153 requires screen reader users to identify, navigate, and select skills, files, and slash commands while staying in the editor. The PR adds listbox and option semantics, active-option refer…
Out of Scope Changes check ✅ Passed The changes remain connected to issue #10153. The pull-request suggestion support extends the same composer suggestion accessibility behavior. The Settings font preview label and skill-chip name addre…
Title check ✅ Passed The title clearly and concisely describes the main change: improving composer suggestion accessibility for screen reader users.
Description check ✅ Passed The description explains what changed, why it changed, UI evidence, validation results, test coverage, known runtime-testing limits, and the linked issue. It does not use the template's exact checklis…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@akj

akj commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

I'm leaving the docstring-coverage suggestion unchanged. AGENTS.md asks for comments that explain constraints the code cannot show. Docstrings added solely to meet an 80% target would repeat the behavior of these React components and the option-ID helper.

The update from main passed 91 focused tests, web typechecking, formatting, and CI. CodeRabbit reported no actionable correctness findings.

@cursor

cursor Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@cursor

cursor Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

Leos-Khai and others added 2 commits September 15, 2026 07:03
A single "Composer suggestions" name tells a screen reader user that a list
opened but not which one. Naming it by trigger ("Files and folders",
"Commands", "Skills", "Pull requests") says what the options are before
any row is read.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ComposerPromptEditor is also the Settings font preview, which has no
trigger menus. Hardcoding the "Message" label, aria-autocomplete and
aria-haspopup on the editor made that preview announce as a chat field
with autocomplete. The chat composer now opts in by passing the label and
its listbox id; the font preview passes neither and reads as a plain
multiline field.

aria-controls follows the active option rather than list visibility, which
is the same moment in practice but keeps the reference from ever pointing
at a listbox with no highlighted row.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@akj

akj commented Sep 18, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@akj

akj commented Sep 18, 2026

Copy link
Copy Markdown
Contributor Author

@juliusmarminge This pr is ready for maintainer review and merging. Please let me know if pinging you here is bad form, or if there's a better team member for pinging about a11y fixes.

Main now dismisses composer suggestions with Escape (pingdotgg#12836), so this drops the branch's own snapshot-based dismissal and keeps only the listbox and active-option wiring.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size:M 30-99 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Sep 24, 2026
akj and others added 4 commits September 25, 2026 19:05
The status region said "Searching workspace files..." after every pause in
typing, even while earlier results stayed visible and an option remained
active. It now speaks only when the visible menu shows loading or empty text.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Screen reader users cannot select composer suggestions

2 participants