Repository navigation
[web] Propagate aria-label to inner slider input - #192964
Conversation
- Mirror computed aria-label onto SemanticIncrementable inner <input type='range' role='slider'> (b/463248173). - Always set aria-label on SemanticTextField editableElement and fall back to hint when label is empty (b/463281931, Fixes flutter#172206, Fixes flutter#192618). - Assign _previousLabel in AriaLabelRepresentation.update.
There was a problem hiding this comment.
Code Review
This pull request updates the web semantics implementation to improve accessibility. Specifically, it allows SemanticTextField to fall back to using its hint as the aria-label when the primary label is empty, and prevents duplicate screen reader announcements by only setting aria-description when both a non-empty label and hint are present. It also updates AriaLabelRepresentation to correctly track and clean up its previous label state, and synchronizes aria-label attributes in SemanticIncrementable. The review feedback suggests using trim().isNotEmpty in SemanticIncrementable to prevent setting whitespace-only labels and maintain consistency with the text field changes.
|
CI had a failure that stopped further tests from running. We need to investigate to determine the root cause. SHA at time of execution: b6ab1dc. Possible causes:
A blank commit, or merging to head, will be required to resume running CI for this PR. Error Details: Stack trace: |
|
Does this fix #192618 ? The issue is about buttons missing aria labels |
|
Good catch @chunhtai! #192618 is specifically about |
flutter-zl
left a comment
There was a problem hiding this comment.
Thanks for this! I tested it with two demos, the same app on master and on this PR:
- Before: https://flutter-demo-66-before.web.app
- After: https://flutter-demo-66-after.web.app
The slider fix works. On master, VoiceOver reads the slider as "50%, slider". With this PR, it reads "50%, Volume, slider".
The text field part needs changes:
- It doesn't help
hintTextfields. In the demo, ahintTextfield still has no name after typing, in both builds. - It doesn't fix #172206. The reporter still gets two inputs, "Login_email" and "Email". The DOM is the same before and after.
- The description doesn't match the code. There is no
_updateLabels, and master doesn't remove the label when a field loses focus.
REQUEST CHANGES. I'd land the slider fix on its own and rework the text field part.
- Revert SemanticTextField changes so InputDecorator.hintText (which is dropped from the semantics tree via AnimatedOpacity(opacity: 0.0) when !isEmpty) can be addressed in the framework separately. - Add unit test in _testIncrementables() verifying aria-label propagation and cleanup on the inner <input role="slider"> element.
|
Thanks for testing this with VoiceOver and catching the Root cause on the As you suggested, I've scoped this PR strictly to the verified |
flutter-zl
left a comment
There was a problem hiding this comment.
Thanks for scoping this down! The slider fix and the new test look good.
With VoiceOver in Chrome:
- master: "Volume, group ... 50%, slider"
- this PR: "Volume, group ... 50%, Volume, slider"
|
autosubmit label was removed for flutter/flutter/192964, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label. |
On Flutter Web, `SemanticIncrementable` (`role="slider"`) renders an outer `<flt-semantics>` container alongside an inner `<input type="range" role="slider">`. Previously, `AriaLabelRepresentation` set `aria-label` exclusively on the outer `<flt-semantics>` wrapper (`role="none"` when active), leaving the interactive `<input role="slider">` element without an accessible name in the browser's accessibility tree (`name: ""` in Chrome `Accessibility.getFullAXTree` and `"50%, slider"` in VoiceOver). This change: 1. Propagates `semanticsObject.label` to the inner `<input role="slider">` element's `aria-label` attribute in `SemanticIncrementable.update()`, removing it when the label becomes empty. 2. Tracks `_previousLabel` in `AriaLabelRepresentation` so stale `aria-label` attributes are cleaned up when a label is cleared. 3. Adds unit tests in `semantics_test.dart` (`_testIncrementables()`) verifying `aria-label` propagation and cleanup on `<input role="slider">`. Fixes http://b/463248173 ## 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. --------- Co-authored-by: zhongliugo <[email protected]>
On Flutter Web,
SemanticIncrementable(role="slider") renders an outer<flt-semantics>container alongside an inner<input type="range" role="slider">. Previously,AriaLabelRepresentationsetaria-labelexclusively on the outer<flt-semantics>wrapper (role="none"when active), leaving the interactive<input role="slider">element without an accessible name in the browser's accessibility tree (name: ""in ChromeAccessibility.getFullAXTreeand"50%, slider"in VoiceOver).This change:
semanticsObject.labelto the inner<input role="slider">element'saria-labelattribute inSemanticIncrementable.update(), removing it when the label becomes empty._previousLabelinAriaLabelRepresentationso stalearia-labelattributes are cleaned up when a label is cleared.semantics_test.dart(_testIncrementables()) verifyingaria-labelpropagation and cleanup on<input role="slider">.Fixes http://b/463248173
Pre-launch Checklist
///).