flutter icon indicating copy to clipboard operation
flutter copied to clipboard

[web:a11y] implement the "selected" semantic property

Open rami-a opened this issue 5 years ago • 9 comments
trafficstars

Internal: b/258949931

Using the Semantics widget and setting the selected property to true does not currently cause any sort of additional announcement in flutter web. This gets read out as "selected" on iOS and Android. There is likely some sort of mechanism in ARIA that can be utilized for this.

rami-a avatar Sep 25 '20 19:09 rami-a

cc @nturgut

rami-a avatar Sep 25 '20 19:09 rami-a

Any reproducible steps?

pedromassangocode avatar Sep 29 '20 09:09 pedromassangocode

@nturgut and I confirmed that this is currently the case. You can reproduce by creating a simple widget such as this, and then trying to use a screen reader with it on flutter web. It will end up reading out as "text, button". Compared to iOS/android where it will read "selected, text, button".

Semantics(
  selected: true,
  button: true,
  child: Center(
    child: Text(
      'Text',
    ),
  ),
)

rami-a avatar Sep 29 '20 13:09 rami-a

Setting to P2 to reflect b/246006912

xster avatar Sep 22 '22 04:09 xster

Dropping back to P4. A workaround confirmed by the customer is to use toggled instead of selected.

yjbanov avatar Sep 27 '22 23:09 yjbanov

Received another report for this issue b/258949931.

yjbanov avatar Sep 19 '23 17:09 yjbanov

This issue is marked P1 but has had no recent status updates.

The P1 label indicates high-priority issues that are at the top of the work list. This is the highest priority level a bug can have if it isn't affecting a top-tier customer or breaking the build. Bugs marked P1 are generally actively being worked on unless the assignee is dealing with a P0 bug (or another P1 bug). Issues at this level should be resolved in a matter of months and should have monthly updates on GitHub.

Please consider where this bug really falls in our current priorities, and label it or assign it accordingly. This allows people to have a clearer picture of what work is actually planned. Thanks!

flutter-triage-bot[bot] avatar Feb 08 '24 01:02 flutter-triage-bot[bot]

We're drowning in flutter triage bot traffic. Resetting the triage bot timer.

yjbanov avatar Feb 15 '24 19:02 yjbanov

The way isSelected flag works right now doesn't work well for the web. On the web, we need to have two pieces of information about the node/widget:

  1. Does the widget have the quality of being selected (let's call it "selectable widget"). If not, whether it's selected or not is irrelevant to that widget. Currently this information is not communicated to the engine (but there's something; more details below).
  2. If the widget is selectable, then we need to know whether it is currently selected or not (i.e. the value of SemanticsFlag.isSelected).

SemanticsFlag.isSelected is driven by the SemanticsProperties.selected property. Interestingly, the dartdocs on that property imply that the "is selectable" vs "is selected" distinction already exists, and is expressed by the nullability of the selected property. If it's null, then the widget is not selectable. If it's true or false, then the widget is selected and is currently selected or not. This is also expressible on the web as follows:

  • selected == null => aria-selected attribute is missing.
  • selected == true => aria-selected="true".
  • selected == false => aria-selected="false".

It seems, however, that this information is lost after translation to engine semantics, as there's no way to express it using one bit of information. Instead, what the engine sees is that the widget is selected (isSelected flag is set), or that it's either not selectable or not selected (isSelected flag is not set).

A natural fix in Flutter is to introduce SemanticsFlag.hasSelectedState, similar to hasCheckedState and hasEnabledState. Together with SemanticsFlag.isSelected we'll have all the information we need.

This will have to be a multi-step process (unless the repos merge before then, and it could take fewer PRs):

  • [x] Introduce a hasSelectedState flag in the engine. The flag will initially be a noop. The goal of this step is to adjust the downstream code to the mere presence of the new flag, but not yet to its functionality. For example, there are tests that enumerate all flags and verify their values.
  • [x] Roll the new flag into the framework and beyond, fixing code as it lands downstream.
  • [x] Change all widgets in the framework that use isSelected to also supply the hasSelectedState.
  • [x] Implement the engine functionality. In the web case, when hasSelectedState is set, the engine will set aria-selected to "true" or "false" according to the value of the isSelected flag. If hasSelectedState is unset, then isSelected is ignored, and aria-selected attribute is not added to the DOM tree.
  • [x] Let the new functionality roll downstream again, fixing code as necessary.

yjbanov avatar Oct 09 '24 17:10 yjbanov

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

github-actions[bot] avatar Nov 04 '24 21:11 github-actions[bot]