From 5a87890277afc1a5add38ac83145f2d37deedef3 Mon Sep 17 00:00:00 2001 From: Denis Bowen <42016383+DBowen33@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:25:01 -0500 Subject: [PATCH] add autofocus to fix a11y issue with dialog (#152637) Add autofocus=true to first TextButton in dialog so that focus automatically goes to an interactive element when dialog is opened. Before: https://screencast.googleplex.com/cast/NTYxNTczMTk2MDk3MTI2NHxlMjAyOTMzZi1lNw After: https://screencast.googleplex.com/cast/NTk1NzMxNjYxNTYwMjE3NnxlYWNlM2Q1MC1jYw fixes b/338656477 NOTE: This would be a good candidate to update the documentation for Dialogs and TextButtons to encourage the user to add autofocus=true on at least one button so that focus automatically goes to an interactive element instead of the actual Dialog element. --- dev/a11y_assessments/lib/use_cases/dialog.dart | 2 ++ dev/a11y_assessments/test/dialog_test.dart | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/dev/a11y_assessments/lib/use_cases/dialog.dart b/dev/a11y_assessments/lib/use_cases/dialog.dart index a3cfb24674..fa47216b15 100644 --- a/dev/a11y_assessments/lib/use_cases/dialog.dart +++ b/dev/a11y_assessments/lib/use_cases/dialog.dart @@ -42,6 +42,8 @@ class _MainWidget extends StatelessWidget { Row( children: [ TextButton( + key: const Key('OK Button'), + autofocus: true, onPressed: () { Navigator.pop(context); }, diff --git a/dev/a11y_assessments/test/dialog_test.dart b/dev/a11y_assessments/test/dialog_test.dart index 6ade54a6cf..38ea79b5ab 100644 --- a/dev/a11y_assessments/test/dialog_test.dart +++ b/dev/a11y_assessments/test/dialog_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:a11y_assessments/use_cases/dialog.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'test_utils.dart'; @@ -29,6 +30,19 @@ void main() { expect(find.text('This is a typical dialog.'), findsNothing); }); + testWidgets('ok button has autofocus when dialog opens', (WidgetTester tester) async { + await pumpsUseCase(tester, DialogUseCase()); + + Future invokeDialog() async { + await tester.tap(find.text('Show Dialog')); + await tester.pumpAndSettle(); + } + + await invokeDialog(); + final Finder okButton = find.byKey(const Key('OK Button')); + expect((okButton.evaluate().single.widget as TextButton).autofocus, true); + }); + testWidgets('dialog has one h1 tag', (WidgetTester tester) async { await pumpsUseCase(tester, DialogUseCase()); final Finder findHeadingLevelOnes = find.bySemanticsLabel('Dialog Demo');