Skip to content

Feat: Add a11y for loading indicators #165173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

rkishan516
Copy link
Contributor

Feat: Add a11y for loading indicators
fixes: #161631

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • 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.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. engine flutter/engine repository. See also e: labels. f: material design flutter/packages/flutter/material repository. a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) platform-web Web applications specifically labels Mar 14, 2025
@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch 2 times, most recently from a4da150 to f6e5619 Compare March 15, 2025 08:09
@github-actions github-actions bot added the a: tests "flutter test", flutter_test, or one of our tests label Mar 15, 2025
@dkwingsmt dkwingsmt requested a review from chunhtai March 19, 2025 18:30
@@ -530,6 +530,8 @@ class SemanticsFlag {
static const int _kHasSelectedStateIndex = 1 << 28;
static const int _kHasRequiredStateIndex = 1 << 29;
static const int _kIsRequiredIndex = 1 << 30;
static const int _kIsProgressBarIndex = 1 << 31;
static const int _kIsLoadingSpinnerIndex = 1 << 32;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flag can at most fit 32 bit, so this is likely not going to work for platform that uses 32 bit int.

Also we already have progress bar and loadingspinner in https://main-api.flutter.dev/flutter/dart-ui/SemanticsRole.html
you can directly use that.

However these 2 enums are currently not wired up engine, so we will need to update the engine still

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually do we need these flags in this pr? it looks like they are not used

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I can remove these.

semanticsObject,
preferredLabelRepresentation: LabelRepresentation.ariaLabel,
) {
setAriaRole('loadingSpinner');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no loading spiner role in web

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I will remove this.

semanticsObject,
preferredLabelRepresentation: LabelRepresentation.ariaLabel,
) {
setAriaRole('progressbar');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

based on the https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/progressbar_role

we should add aria-valuemin, aria-valuemax, aria-valuenow if possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, i will add that.

return _buildIndicator(context, _controller.value, textDirection);
},
return Semantics(
role: SemanticsRole.loadingSpinner,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not a spinner, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is. Because if value is not given, it will be in loading mode else it will be in progreessbar mode.

enabled: widget.value != null,
role: SemanticsRole.progressBar,
child: Semantics(
enabled: widget.value == null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should probably only assign progressbar or loadingspinner but not both

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a time, it only assign one.
Because if value is not given its loadingSpinner else its progressBar.

@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch from f6e5619 to 0034f92 Compare March 20, 2025 03:27
@github-actions github-actions bot removed the a: tests "flutter test", flutter_test, or one of our tests label Mar 20, 2025
@dkwingsmt
Copy link
Contributor

Is this PR ready for another round of review? (from triage)

@chunhtai chunhtai self-requested a review April 2, 2025 18:33
@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch from 0034f92 to b7a864f Compare April 3, 2025 01:06
@rkishan516
Copy link
Contributor Author

Is this PR ready for another round of review? (from triage)

Yes @dkwingsmt.

}
}
return Semantics(
value: widget.value != null ? '${(widget.value ?? 0) * 100}%' : null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
value: widget.value != null ? '${(widget.value ?? 0) * 100}%' : null,
value: widget.value != null ? '${widget.value! * 100}%' : null,

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also should it have the % after the number?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed this.

setAriaRole('progressbar');

// Progress indicators in Flutter use values between 0.0 and 1.0
setAttribute('aria-valuemin', "0");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we may need a a new property for maxValue and minValue to propergate the value range. Hardcoded to 0 and 100 may be too opinionated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add new properties maxValue and minValue.

@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch from b7a864f to 3f35fa6 Compare April 4, 2025 01:30
@github-actions github-actions bot added a: tests "flutter test", flutter_test, or one of our tests platform-windows Building on or for Windows specifically a: desktop Running on desktop labels Apr 4, 2025
@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch 6 times, most recently from d61aae5 to 050ace5 Compare April 5, 2025 01:42
@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch from 050ace5 to cf1d583 Compare April 22, 2025 13:14
@chunhtai chunhtai self-requested a review April 22, 2025 16:54
@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch from cf1d583 to 99965e8 Compare April 23, 2025 01:09
@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch from 6d45f11 to 5e7af8b Compare May 8, 2025 09:03
Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this overall lgtm to me, just the property type should be string so that it matches the SemanticsProperties.value

@@ -1854,6 +1862,8 @@ base class _NativeSemanticsUpdateBuilder extends NativeFieldWrapperClass1
List<String>? controlsNodes,
int validationResultIndex,
int inputType,
double minValue,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably need to be string to match value

///
/// {@endtemplate}
///
/// {@macro flutter.semantics.SemanticsProperties.maxValue}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need to re macro here, the doc in @template in this section is still visible when compiling the doc. using macro here will cause it to duplicate the same doc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc should also mention this is used in conjunction with [value]. and a typical usage is a progress indicator

@chunhtai chunhtai requested a review from mdebbar May 8, 2025 18:52
@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch 4 times, most recently from 41174e0 to 6fca6dc Compare May 13, 2025 02:45
@chunhtai chunhtai self-requested a review May 21, 2025 21:41
label: semanticsLabel,
role:
expandedSemanticsValue != null ? SemanticsRole.progressBar : SemanticsRole.loadingSpinner,
minValue: '0.0',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be 0 and maxValue 100?

@@ -135,15 +135,15 @@ sealed class _DebugSemanticsRoleChecks {
SemanticsRole.status => _noLiveRegion,
SemanticsRole.list => _noCheckRequired,
SemanticsRole.listItem => _semanticsListItem,
SemanticsRole.loadingSpinner => _noCheckRequired,
SemanticsRole.progressBar => _noCheckRequired,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should check if it has value, minValue, maxvalue. and ideally value should be within min and max

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, let me push the change.

@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch 2 times, most recently from 6454d9d to d3c22fc Compare June 2, 2025 08:56
@chunhtai chunhtai self-requested a review June 4, 2025 21:47
@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch from d3c22fc to 8e7c200 Compare June 11, 2025 15:08
Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@chunhtai chunhtai requested a review from flutter-zl June 12, 2025 22:40
@chunhtai
Copy link
Contributor

Hi @flutter-zl, can you take a secondary review since this also touch some of the web engine code?

Also looks like this pr may need a rebase, the ci seems to act weird

@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch from 8e7c200 to 094acc9 Compare June 13, 2025 03:02
@rkishan516 rkishan516 force-pushed the a11y-loading-indicator branch from 094acc9 to b5abb59 Compare June 13, 2025 16:00
@flutter-zl
Copy link
Contributor

LGTM.

Copy link
Contributor

@flutter-zl flutter-zl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@chunhtai chunhtai added the autosubmit Merge PR when tree becomes green via auto submit App label Jun 13, 2025
Copy link
Contributor

auto-submit bot commented Jun 13, 2025

autosubmit label was removed for flutter/flutter/165173, because - The status or check suite Linux linux_android_debug_engine has failed. Please fix the issues identified (or deflake) before re-applying this label.

  • The status or check suite Linux linux_android_debug_engine_ddm has failed. Please fix the issues identified (or deflake) before re-applying this label.
  • The status or check suite Linux linux_fuchsia has failed. Please fix the issues identified (or deflake) before re-applying this label.

@auto-submit auto-submit bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jun 13, 2025
@rkishan516
Copy link
Contributor Author

@chunhtai I don't know why tests are failing, can you please have a look ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) a: desktop Running on desktop a: tests "flutter test", flutter_test, or one of our tests engine flutter/engine repository. See also e: labels. f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. platform-web Web applications specifically platform-windows Building on or for Windows specifically
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[a11y] loading indicator should have correct semantics role
4 participants