Repository navigation
[web] Add SemanticsRole.listBox and SemanticsRole.option - #192971
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the 'listBox' and 'option' semantics roles across the Flutter framework, engine, and Web UI, including a validation check to ensure 'option' is a descendant of 'listBox'. Feedback on the changes highlights a potential regression in 'SemanticScrollable' where 'role="group"' could be incorrectly applied to non-scrollable elements, and suggests a simplification to the parent traversal logic in '_semanticsOption' to improve readability.
…-a11y-listbox-option-role # Conflicts: # engine/src/flutter/lib/ui/semantics.dart # engine/src/flutter/lib/ui/semantics/semantics_node.h # engine/src/flutter/lib/web_ui/lib/semantics.dart # engine/src/flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart # engine/src/flutter/shell/platform/android/io/flutter/view/AccessibilityBridge.java
…ox semantics test
chunhtai
left a comment
There was a problem hiding this comment.
Adding new role SGTM, left some comment
- Remove the Semantics(role: listBox) wrapper from RawAutocomplete. It only owns the overlay container, not the items, so it would ship role=listbox with role=button children. Both roles will be assigned together in material_ui (flutter#194031). - Add isButton to one option node in the web engine test to lock in that the explicit role wins over the button flag (the shape material_ui emits). - Update GenericRole comment wording.
mboetger
left a comment
There was a problem hiding this comment.
LGTM from the Android review.
|
@chunhtai PTAL? |
option 1 sounds most reasonable to me because rawautocomplete doesn't know what the content will be |
- Assert that a SemanticsRole.listBox node is non-empty and that its children/leaf branches carry SemanticsRole.option (recursing through intermediate SemanticsRole.none container/scroll wrappers such as ListView). - Add widget tests in semantics_role_checks_test.dart covering empty listBox, direct non-option children, non-option children inside a ListView wrapper, and valid option children inside a ListView wrapper.
Roll Flutter from 4249ccbc18a3 to 426be968b5eb (44 revisions) flutter/flutter@4249ccb...426be96 2026-10-14 [email protected] Allow color delta tolerance in in-memory fuzzy image comparator (flutter/flutter#193937) 2026-10-14 [email protected] [web] Drop stale composing range after text is replaced mid-composition (flutter/flutter#194096) 2026-10-14 [email protected] Roll Skia from 2a2bbea66844 to acde3755d2e2 (1 revision) (flutter/flutter#194376) 2026-10-14 [email protected] Roll Skia from 128c983b12de to 2a2bbea66844 (1 revision) (flutter/flutter#194371) 2026-10-14 [email protected] Roll Skia from 48a294ed4955 to 128c983b12de (3 revisions) (flutter/flutter#194353) 2026-10-14 [email protected] feat(flutter_tools): extract WebDebugConfig from DebuggingOptions (flutter/flutter#194312) 2026-10-14 [email protected] Roll Skia from ea6781c5b6d1 to 48a294ed4955 (2 revisions) (flutter/flutter#194349) 2026-10-14 [email protected] Include <vector> in Android proc_table.h. (flutter/flutter#194325) 2026-10-14 [email protected] Roll Dart SDK from 5933cb486b4a to 6b50116630d0 (28 revisions) (flutter/flutter#194341) 2026-10-14 [email protected] Move GLES3 instancing API entry points to FOR_EACH_IMPELLER_GLES3_PROC (flutter/flutter#194319) 2026-10-14 [email protected] feat(flutter_tools): extract AndroidGradleConfig and move toGradleConfig to AndroidBuildInfo (flutter/flutter#194016) 2026-10-14 [email protected] Roll Skia from ae297bec6012 to ea6781c5b6d1 (8 revisions) (flutter/flutter#194331) 2026-10-14 [email protected] [flutter_tools] Migrate gradle_errors and deferred_components_prebuild_validator away from globals (flutter/flutter#193649) 2026-10-14 [email protected] [Impeller] Cache GLES sampler configuration in RenderPassStateCache (flutter/flutter#193922) 2026-10-14 [email protected] Roll pub packages (flutter/flutter#194332) 2026-10-13 [email protected] [tool] Migrate RunCommand to modular dependency injection (flutter/flutter#190791) 2026-10-13 [email protected] Include `engine/src/flutter/.ci.yaml` in quarterly `goldctl` checklist (flutter/flutter#194316) 2026-10-13 [email protected] [flutter_tools] Remove the last AMD module system support (flutter/flutter#193607) 2026-10-13 [email protected] Roll Skia from 8b3394a60654 to ae297bec6012 (5 revisions) (flutter/flutter#194310) 2026-10-13 [email protected] [web] Remove the a11y placeholder only after the gesture ends (flutter/flutter#194109) 2026-10-13 [email protected] Upgrade goldctl to the latest version (flutter/flutter#193932) 2026-10-13 [email protected] [flutter_tools] Lazily initialize AndroidStudio validation and optimize candidate selection (flutter/flutter#191968) 2026-10-13 [email protected] [flutter_tools] Clean up outdated widget preview TODOs and refactor static state (flutter/flutter#189437) 2026-10-13 [email protected] Roll Skia from e5b5db6d0d6f to 8b3394a60654 (2 revisions) (flutter/flutter#194306) 2026-10-13 [email protected] Redistribute TESTOWNERS for Android team (flutter/flutter#193861) 2026-10-13 [email protected] feat(flutter_tools): introduce Test and Drive specification objects (flutter/flutter#194017) 2026-10-13 [email protected] [Impeller] Keep the aspect ratio when shrinking images to the max texture size (flutter/flutter#194010) 2026-10-13 [email protected] [flutter tool] preserve inherited `DASH__SUPPRESS_ANALYTICS=true` for sub-tools (flutter/flutter#194261) 2026-10-13 [email protected] Roll Packages from d8d9e97 to a1ed23c (9 revisions) (flutter/flutter#194302) 2026-10-13 [email protected] Use PE/COFF AOT snapshots for Windows x64 (flutter/flutter#187594) 2026-10-13 [email protected] Fix Expansible crash when PageStorage holds a non-bool value (flutter/flutter#192195) 2026-10-13 [email protected] Roll Skia from ffeccb3ca58a to e5b5db6d0d6f (1 revision) (flutter/flutter#194297) 2026-10-13 [email protected] Explain why initState() is too early to depend on an inherited widget (flutter/flutter#192727) 2026-10-13 [email protected] Refactor TestPlatformDispatcher (flutter/flutter#192747) 2026-10-13 [email protected] Roll Skia from 3de0984208ec to ffeccb3ca58a (2 revisions) (flutter/flutter#194291) 2026-10-13 [email protected] Roll Skia from 0580c2b780f6 to 3de0984208ec (2 revisions) (flutter/flutter#194281) 2026-10-13 [email protected] Roll Skia from f641d55e07a8 to 0580c2b780f6 (3 revisions) (flutter/flutter#194275) 2026-10-13 [email protected] Roll Skia from 0e5d8d1be81b to f641d55e07a8 (1 revision) (flutter/flutter#194266) 2026-10-13 [email protected] Scaffold view metrics overrides (flutter/flutter#192764) 2026-10-13 [email protected] [web] Add SemanticsRole.listBox and SemanticsRole.option (flutter/flutter#192971) 2026-10-13 [email protected] Pin mac_unopt to macOS 15 (flutter/flutter#194254) 2026-10-13 [email protected] Roll pub packages (flutter/flutter#194257) 2026-10-12 [email protected] Roll Skia from 17f6986c226c to 0e5d8d1be81b (4 revisions) (flutter/flutter#194249) 2026-10-12 [email protected] Make DisplayLists' use of DlPaint, SkPaint, and impeller::Paint agree on the default isAntiAlias (flutter/flutter#193939) If this roll has caused a breakage, revert this CL and set the roller ...
) Adds `SemanticsRole.listBox` and `SemanticsRole.option` across `dart:ui`, the Web semantics engine (emitting `aria-selected` on selectable options), and `_DebugSemanticsRoleChecks` (widget wiring tracked in flutter#194031). Verified: `felt test test/engine/semantics/semantics_test.dart` and `flutter test test/widgets/semantics_role_checks_test.dart`. - `engine/src/flutter/lib/ui/semantics.dart`, `engine/src/flutter/lib/ui/semantics/semantics_node.h`, `AccessibilityBridge.java`, `engine/src/flutter/lib/web_ui/lib/semantics.dart`: Adds `SemanticsRole.listBox` (`kListBox = 34`) and `SemanticsRole.option` (`kOption = 35`). - `engine/src/flutter/lib/web_ui/lib/src/engine/semantics/list.dart`, `checkable.dart`, `scrollable.dart`, `semantics.dart`: Implements `SemanticListBox` (`role="listbox"`) and `SemanticOption` (`role="option"` with `aria-selected="true"|"false"`), and omits intermediate `role="group"` on unlabeled scrollables inside a `listBox`. - `packages/flutter/lib/src/semantics/semantics.dart` & `packages/flutter/test/widgets/semantics_role_checks_test.dart`: Validates in `_DebugSemanticsRoleChecks` that `SemanticsRole.option` has an ancestor `SemanticsRole.listBox`. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing.
Adds
SemanticsRole.listBoxandSemanticsRole.optionacrossdart:ui, the Web semantics engine (emittingaria-selectedon selectable options), and_DebugSemanticsRoleChecks(widget wiring tracked in #194031). Verified:felt test test/engine/semantics/semantics_test.dartandflutter test test/widgets/semantics_role_checks_test.dart.engine/src/flutter/lib/ui/semantics.dart,engine/src/flutter/lib/ui/semantics/semantics_node.h,AccessibilityBridge.java,engine/src/flutter/lib/web_ui/lib/semantics.dart: AddsSemanticsRole.listBox(kListBox = 34) andSemanticsRole.option(kOption = 35).engine/src/flutter/lib/web_ui/lib/src/engine/semantics/list.dart,checkable.dart,scrollable.dart,semantics.dart: ImplementsSemanticListBox(role="listbox") andSemanticOption(role="option"witharia-selected="true"|"false"), and omits intermediaterole="group"on unlabeled scrollables inside alistBox.packages/flutter/lib/src/semantics/semantics.dart&packages/flutter/test/widgets/semantics_role_checks_test.dart: Validates in_DebugSemanticsRoleChecksthatSemanticsRole.optionhas an ancestorSemanticsRole.listBox.Pre-launch Checklist
///).