[material_ui] Fixes SearchAnchor and SearchBar semantics - #12680
[material_ui] Fixes SearchAnchor and SearchBar semantics#12680chunhtai wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request addresses unlabeled tap target semantics in SearchBar and SearchAnchor by setting excludeFromSemantics: true on their internal interactive widgets and adding corresponding tests. Feedback suggests making excludeFromSemantics configurable on SearchAnchor to prevent accessibility regressions for custom builders, and adding an assertion in the new test to ensure the tap action nodes list is not empty.
| child: GestureDetector( | ||
| excludeFromSemantics: true, | ||
| onTap: _openView, | ||
| child: widget.builder(context, _searchController), | ||
| ), |
There was a problem hiding this comment.
Hardcoding excludeFromSemantics: true on the SearchAnchor's GestureDetector will cause an accessibility regression for custom builders. If a developer provides a custom non-tappable widget (like a simple Text or Icon) in widget.builder, it relies on this GestureDetector to provide the semantic tap action. With excludeFromSemantics: true, the widget will become completely non-interactive for screen readers.
To fix this while still resolving the duplicate semantics issue for SearchBar, we should introduce an excludeFromSemantics property to SearchAnchor (defaulting to false). Then, we can set it to true in the SearchAnchor.bar factory constructor.
child: GestureDetector(
excludeFromSemantics: widget.excludeFromSemantics,
onTap: _openView,
child: widget.builder(context, _searchController),
),There was a problem hiding this comment.
right, this is something I worry, but is this a common case? @QuncCccccc , if people indeed tend to provide passive component in the builder, we will have turn this into a widget parameter that something like SearchAnchor(automaticallyTapHandler:)
which will base on this parameter to build or not build a gesture recognizer. and user will need to be smart about when to set it to true or false
| for (final SemanticsNode node in semantics.nodesWith( | ||
| actions: <SemanticsAction>[SemanticsAction.tap], | ||
| )) { | ||
| final bool isTextField = node.hasFlag(SemanticsFlag.isTextField); | ||
| final bool hasLabel = node.label.isNotEmpty; | ||
| final bool hasTooltip = node.tooltip.isNotEmpty; | ||
| final bool hasValue = node.value.isNotEmpty; | ||
| expect(isTextField || hasLabel || hasTooltip || hasValue, isTrue); | ||
| } |
There was a problem hiding this comment.
The test currently iterates over the nodes returned by semantics.nodesWith. If nodesWith returns an empty list (for example, if all tap actions were accidentally removed), the loop will not execute and the test will pass vacuously. To make the test more robust, we should assert that the list of nodes with tap actions is not empty.
final List<SemanticsNode> tapNodes = semantics.nodesWith(
actions: <SemanticsAction>[SemanticsAction.tap],
);
expect(tapNodes, isNotEmpty);
for (final SemanticsNode node in tapNodes) {
final bool isTextField = node.hasFlag(SemanticsFlag.isTextField);
final bool hasLabel = node.label.isNotEmpty;
final bool hasTooltip = node.tooltip.isNotEmpty;
final bool hasValue = node.value.isNotEmpty;
expect(isTextField || hasLabel || hasTooltip || hasValue, isTrue);
}
fixes flutter/flutter#190884
Too many inkwell and gesture recognizer wrapping the searchAnchor subtree that all tries to provide the same semantics action. This is ok in in renderobject because gesture arena will pick a winer, but not going to work in semantics
Pre-Review Checklist
[shared_preferences]///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2