Issues have been solved, we can now have the tests back
## 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].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.
## Description
Please check comment:
https://github.com/flutter/flutter/pull/171040#issuecomment-3014250567.
This PR adds `SemanticsLabelBuilder`, a new utility class for creating
accessible concatenated labels with proper text direction handling and
spacing. Currently, developers manually concatenate semantic labels
using string interpolation, which is error-prone and leads to
accessibility issues like missing spaces, incorrect text direction for
RTL languages. The new builder provides automatic spacing, Unicode
bidirectional text embedding for mixed LTR/RTL content.
### Before (error-prone manual concatenation):
```dart
// Missing space
String label = "$firstName$lastName"; // "JohnDoe"
String englishText = "Welcome";
String arabicText = "مرحبا"; // Arabic "Hello"
// Manual Concatenation (WITHOUT Unicode embedding):
aria-label="Welcome 欢迎 مرحبا स्वागत है to our global app"
// Problem: Arabic does not have proper text direction handling
```
### After (automatic and accessible):
Demo app after the change: https://label-0702.web.app/
```dart
// Automatic spacing and text direction handling
final label = (SemanticsLabelBuilder()
..addPart(firstName)
..addPart(lastName)).build();
// Result: "John Doe" with proper aria-label generation
// SemanticsLabelBuilder (WITH Unicode embedding):
aria-label="Welcome 欢迎 [U+202B]مرحبا[U+202C] स्वागत है to our global app"
// Result: Arabic has proper text direction handling
```
## Issues Fixed
This fixes https://github.com/flutter/flutter/issues/162094.
This PR addresses the general accessibility problem of error-prone
manual label concatenation that affects screen reader users. While not
fixing a specific filed issue, it provides a robust solution for the
common pattern of building complex semantic labels that are critical for
accessibility compliance, particularly for multilingual applications and
complex UI components like contact cards, dashboards, and e-commerce
listings.
## Breaking Changes
No breaking changes were made. This is a purely additive API that
doesn't modify existing behavior or require any migration.
## Key Features Added
- **SemanticsLabelBuilder**: Main builder class for concatenating text
parts
- **Automatic spacing**: Configurable separators with intelligent empty
part handling
- **Text direction support**: Unicode bidirectional embedding for
RTL/LTR mixed content
## Example Usage
```dart
// Basic usage
final label = (SemanticsLabelBuilder()
..addPart('Contact')
..addPart('John Doe')
..addPart('Phone: +1-555-0123')).build();
// Result: "Contact John Doe Phone: +1-555-0123"
// Custom separator
final label = (SemanticsLabelBuilder(separator: ', ')
..addPart('Name: Alice')
..addPart('Status: Online')).build();
// Result: "Name: Alice, Status: Online"
// Multilingual support
final label = (SemanticsLabelBuilder(textDirection: TextDirection.ltr)
..addPart('Welcome', textDirection: TextDirection.ltr)
..addPart('مرحبا', textDirection: TextDirection.rtl)
..addPart('to our app')).build();
// Result: "Welcome مرحبا to our app" (with proper RTL embedding)
```
```
## 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: Mouad Debbar <mouad.debbar@gmail.com>
<!-- start_original_pr_link -->
Reverts: flutter/flutter#165531
<!-- end_original_pr_link -->
<!-- start_initiating_author -->
Initiated by: matanlurey
<!-- end_initiating_author -->
<!-- start_revert_reason -->
Reason for reverting: Breaks google client tests
<!-- end_revert_reason -->
<!-- start_original_pr_author -->
Original PR Author: ash2moon
<!-- end_original_pr_author -->
<!-- start_reviewers -->
Reviewed By: {chunhtai, reidbaker, hannah-hyj}
<!-- end_reviewers -->
<!-- start_revert_body -->
This change reverts the following previous change:
Resolves partly https://github.com/flutter/flutter/issues/165510
**Context:** This issue originates from
https://github.com/flutter/flutter/issues/99715, where it was reported
that `liveRegion` alone was insufficient for announcing form validation
errors. While `liveRegion` announces the first error encountered,
subsequent submissions with the same error message on Android would not
trigger a re-announcement.
**Original Solution:** Pull request
https://github.com/flutter/flutter/pull/123373 addressed this by
implementing the `announce` event to ensure error messages were
consistently announced, even for repeated submissions.
**Native Android Behavior (Jetpack Compose):** In native Android
development using Jetpack Compose, setting the `isError` property of a
`TextField` to `true` triggers Talkback to announce "Error invalid
input." This announcement occurs *only* on the initial change to the
error state. Subsequent errors, even if the `isError` property remains
`true`, are not re-announced. This behavior closely mirrors the
functionality of `liveRegion`, with the key difference being that
`liveRegion` also announces the specific error text, in addition to the
general error state. Testing in a native Jetpack Compose application
confirms this behavior and provides a valuable comparison point against
the current Flutter form example.
**Suggested Action:** **Fork** the behavior in
https://github.com/flutter/flutter/pull/123373. Reinstate the use of
`liveRegion` for error announcements within `widgets/Form` for Android
and keep other platforms the same.
## 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.
If you need help, consider asking for advice on the #hackers-new channel
on [Discord].
<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
<!-- end_revert_body -->
Co-authored-by: auto-submit[bot] <flutter-engprod-team@google.com>
Fixes https://github.com/flutter/flutter/issues/163576
In `updateWith()` method, `_replaceChildren()` is called to generate
`_children` list. `_children` list is used to generate the hit test
order (`childrenInHitTestOrder`).
In `_replaceChildren()`, `childrenIn**Inverse**PaintOrder` is directly
assigned to _children, so _children itself follows hit test order. So
when we generate the `childrenInHitTestOrder`, we don't need to reverse
the children again.
https://github.com/user-attachments/assets/df9d852f-231e-4480-8d8b-10c1d406f120
## 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.
Unfortunately `10_google3_bug.yml` comes before `2_bug.yml`.
This changes the name (slightly) of the issue templates based on the
instructions from GitHub on what to do when you have 10+ issue templates
(as a side-note: I wonder if we need/still use umbrella bugs for the
feature tracker, or two types of performance bugs)
Fixes https://github.com/flutter/flutter/issues/162577
### Description
- Adds `role` check in
`SemanticsNode._isDifferentFromCurrentSemanticAnnotation` function.
- Adds `SemanticsNode.debugIsDirty` property to check in tests whether
the node is marked as dirty.
## 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.
- [ ] 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.
This auto-formats all *.dart files in the repository outside of the
`engine` subdirectory and enforces that these files stay formatted with
a presubmit check.
**Reviewers:** Please carefully review all the commits except for the
one titled "formatted". The "formatted" commit was auto-generated by
running `dev/tools/format.sh -a -f`. The other commits were hand-crafted
to prepare the repo for the formatting change. I recommend reviewing the
commits one-by-one via the "Commits" tab and avoiding Github's "Files
changed" tab as it will likely slow down your browser because of the
size of this PR.
---------
Co-authored-by: Kate Lovett <katelovett@google.com>
Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
Set the `hasSelectedState` flag in all selectable widgets. This happens automatically because only selectable widgets have `Semantics.selected` set to a non-null value. When the value is propagated to `SemanticsConfiguration.isSelected`, it sets both `hasSelectedState` to true and `isSelected` as appropriate.
More progress towards https://github.com/flutter/flutter/issues/66673
Multiple fixes related to heading levels:
* Fix heading level absorption. Heading level would get erased when a semantics config is absorbed into another. With this change the highest heading level wins.
* Add `headingLevel` to the diagnostics of `SemanticsNode`.
* Add unit-tests for heading levels.
* Add an a11y use-case for headings.
Improves https://github.com/flutter/flutter/issues/46789 and general accessibility of headings.
The purpose of this PR is to temporarily skip one integration test that is blocking the changes indicated below:
(This change adds a new property in Semantics widget that would take an integer corresponding to the heading levels defined by the ARIA heading role. This is necessary in order to get proper accessibility and usability in a website for users who rely on screen readers and other assistive technologies.)
Issue fixed by this PR:
https://github.com/flutter/flutter/issues/97894
Engine part:
https://github.com/flutter/engine/pull/41435
Framework part:
https://github.com/flutter/flutter/pull/125771
When a `TextField` is rendered before a `Navigator`, it breaks in semantics mode. This is because the framework generates the incorrect semantics tree (excludes the TextField) and when that tree gets sent to the engine, we don't get the signal to create the corresponding `<input>` element.
This happens for a few reasons:
* `ModalBarrier` uses `BlockSemantics` to drop the semantics of routes beneath the current route in `Navigator`
* `ModalBarrier` mistakenly recognizes the widget outside of the `Navigator` to be its sibling
* So we end up dropping the semantics node of the `TextField` rendered before it.
The fix is to let `Navigator` generate a semantics node so that `ModalBarrier` doesn't mistakenly think widgets outside of `Navigator` are its siblings.
`Navigator` doesn't currently do this, which causes all the nodes generated from its widget subtree to be directly attached to the parent semantics node above `Navigator` - since this is also the parent of `TextField`, it considers them siblings.
Fixes https://github.com/flutter/flutter/issues/129324
Much nicer calling API and simplifies evolving this API in the future.
I wish we could write a dart fix for this, but that's blocked on https://github.com/dart-lang/sdk/issues/54668.
This PR adds `String? identifier` to `Semantics` and `SemanticsProperties`. The `identifier` will be exposed on Android as `resource-id` and on iOS as `accessibilityIdentifier`.
Mainly targeted at #17988
Initial Engine PR with Android support: https://github.com/flutter/engine/pull/47961
iOS Engine PR: https://github.com/flutter/engine/pull/48858
### Migration
This change breaks the SemanticsUpdateBuilder API which is on the Framework<-->Engine border. For more details see [engine PR](https://github.com/flutter/engine/pull/47961).
Steps:
part 1: [engine] add `SemanticsUpdateBuilderNew` https://github.com/flutter/engine/pull/47961
**part 2: [flutter] use `SemanticsUpdateBuilderNew`** <-- we are here
part 3: [engine] update `SemanticsUpdateBuilder` to be the same as `SemanticsUpdateBuilderNew`*
part 4: [flutter] use (now updated) `SemanticsUpdateBuilder` again.
part 5: [engine] remove `SemanticsBuilderNew`