From 8a4812a6dae7b654438a5a0f2504e0c143986785 Mon Sep 17 00:00:00 2001 From: hangyu Date: Thu, 1 Aug 2024 15:06:28 -0700 Subject: [PATCH] Add more widgets to a11y assessment app (#152662) ## 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. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. [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 --- .../lib/use_cases/action_chip.dart | 54 ++++++++++++++ dev/a11y_assessments/lib/use_cases/card.dart | 51 +++++++++++++ .../lib/use_cases/expansion_tile.dart | 74 +++++++++++++++++++ .../lib/use_cases/snack_bar.dart | 67 +++++++++++++++++ .../lib/use_cases/switch_list_tile.dart | 66 +++++++++++++++++ .../lib/use_cases/use_cases.dart | 10 +++ .../test/action_chip_test.dart | 16 ++++ dev/a11y_assessments/test/card_test.dart | 16 ++++ .../test/expansion_tile_test.dart | 16 ++++ dev/a11y_assessments/test/snack_bar_test.dart | 20 +++++ .../test/switch_list_tile_test.dart | 16 ++++ 11 files changed, 406 insertions(+) create mode 100644 dev/a11y_assessments/lib/use_cases/action_chip.dart create mode 100644 dev/a11y_assessments/lib/use_cases/card.dart create mode 100644 dev/a11y_assessments/lib/use_cases/expansion_tile.dart create mode 100644 dev/a11y_assessments/lib/use_cases/snack_bar.dart create mode 100644 dev/a11y_assessments/lib/use_cases/switch_list_tile.dart create mode 100644 dev/a11y_assessments/test/action_chip_test.dart create mode 100644 dev/a11y_assessments/test/card_test.dart create mode 100644 dev/a11y_assessments/test/expansion_tile_test.dart create mode 100644 dev/a11y_assessments/test/snack_bar_test.dart create mode 100644 dev/a11y_assessments/test/switch_list_tile_test.dart diff --git a/dev/a11y_assessments/lib/use_cases/action_chip.dart b/dev/a11y_assessments/lib/use_cases/action_chip.dart new file mode 100644 index 0000000000..9d269f8fe9 --- /dev/null +++ b/dev/a11y_assessments/lib/use_cases/action_chip.dart @@ -0,0 +1,54 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import 'use_cases.dart'; + +class ActionChipUseCase extends UseCase { + @override + String get name => 'ActionChip'; + + @override + String get route => '/action-chip'; + + @override + Widget build(BuildContext context) => const MainWidget(); +} + +class MainWidget extends StatefulWidget { + const MainWidget({super.key}); + + @override + State createState() => MainWidgetState(); +} + +class MainWidgetState extends State { + bool favorite = false; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + title: const Text('ActionChip'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ActionChip( + avatar: const Icon(Icons.favorite), + label: const Text('Action'), + onPressed: () {}, + ), + const ActionChip( + avatar: Icon(Icons.favorite), + label: Text('Action'), + ), + ], + ), + ), + ); + } +} diff --git a/dev/a11y_assessments/lib/use_cases/card.dart b/dev/a11y_assessments/lib/use_cases/card.dart new file mode 100644 index 0000000000..81b4723a99 --- /dev/null +++ b/dev/a11y_assessments/lib/use_cases/card.dart @@ -0,0 +1,51 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import 'use_cases.dart'; + +class CardUseCase extends UseCase { + @override + String get name => 'Card'; + + @override + String get route => '/card'; + + @override + Widget build(BuildContext context) => const MainWidget(); +} + +class MainWidget extends StatefulWidget { + const MainWidget({super.key}); + + @override + State createState() => MainWidgetState(); +} + +class MainWidgetState extends State { + bool favorite = false; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + title: const Text('Card'), + ), + body: const Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Card( + child: Padding( + padding: EdgeInsets.all(16), + child: Text('Card'), + ), + ), + ], + ), + ), + ); + } +} diff --git a/dev/a11y_assessments/lib/use_cases/expansion_tile.dart b/dev/a11y_assessments/lib/use_cases/expansion_tile.dart new file mode 100644 index 0000000000..2a4cc8d137 --- /dev/null +++ b/dev/a11y_assessments/lib/use_cases/expansion_tile.dart @@ -0,0 +1,74 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import 'use_cases.dart'; + +class ExpansionTileUseCase extends UseCase { + @override + String get name => 'ExpansionTile'; + + @override + String get route => '/expansion-tile'; + + @override + Widget build(BuildContext context) => const ExpansionTileExample(); +} + + +class ExpansionTileExample extends StatefulWidget { + const ExpansionTileExample({super.key}); + + @override + State createState() => _ExpansionTileExampleState(); +} + +class _ExpansionTileExampleState extends State { + bool _customTileExpanded = false; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + title: const Text('ExpansionTile'), + ), + body: Column( + children: [ + const ExpansionTile( + title: Text('ExpansionTile 1'), + subtitle: Text('Trailing expansion arrow icon'), + children: [ + ListTile(title: Text('This is tile number 1')), + ], + ), + ExpansionTile( + title: const Text('ExpansionTile 2'), + subtitle: const Text('Custom expansion arrow icon'), + trailing: Icon( + _customTileExpanded ? Icons.arrow_drop_down_circle : Icons.arrow_drop_down, + ), + children: const [ + ListTile(title: Text('This is tile number 2')), + ], + onExpansionChanged: (bool expanded) { + setState(() { + _customTileExpanded = expanded; + }); + }, + ), + const ExpansionTile( + title: Text('ExpansionTile 3'), + subtitle: Text('Leading expansion arrow icon'), + controlAffinity: ListTileControlAffinity.leading, + children: [ + ListTile(title: Text('This is tile number 3')), + ], + ), + ], + ), + ); + } +} diff --git a/dev/a11y_assessments/lib/use_cases/snack_bar.dart b/dev/a11y_assessments/lib/use_cases/snack_bar.dart new file mode 100644 index 0000000000..d27abbe389 --- /dev/null +++ b/dev/a11y_assessments/lib/use_cases/snack_bar.dart @@ -0,0 +1,67 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import 'use_cases.dart'; + +class SnackBarUseCase extends UseCase { + @override + String get name => 'SnackBar'; + + @override + String get route => '/snack-bar'; + + @override + Widget build(BuildContext context) => const MainWidget(); +} + +class MainWidget extends StatefulWidget { + const MainWidget({super.key}); + + @override + State createState() => MainWidgetState(); +} + +class MainWidgetState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + title: const Text('SnackBar'), + ), + body: Center( + child: Column( + children: [ + ElevatedButton( + child: const Text('Show Snackbar'), + onPressed: () { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Awesome Snackbar!'), + ), + ); + }, + ), + ElevatedButton( + child: const Text('Show Snackbar with action '), + onPressed: () { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Awesome Snackbar!'), + action: SnackBarAction( + label: 'Action', + onPressed: () {}, + ), + ), + ); + }, + ), + ], + ), + ), + ); + } +} diff --git a/dev/a11y_assessments/lib/use_cases/switch_list_tile.dart b/dev/a11y_assessments/lib/use_cases/switch_list_tile.dart new file mode 100644 index 0000000000..653ee10738 --- /dev/null +++ b/dev/a11y_assessments/lib/use_cases/switch_list_tile.dart @@ -0,0 +1,66 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import 'use_cases.dart'; + +class SwitchListTileUseCase extends UseCase { + @override + String get name => 'SwitchListTile'; + + @override + String get route => '/switch-list-tile'; + + @override + Widget build(BuildContext context) => const SwitchListTileExample(); +} + +class SwitchListTileExample extends StatefulWidget { + const SwitchListTileExample({super.key}); + + @override + State createState() => _SwitchListTileExampleState(); +} + +class _SwitchListTileExampleState extends State { + bool _lights1 = false; + bool _lights2 = false; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).colorScheme.inversePrimary, + title: const Text('SwitchListTile'), + ), + body: Center( + child: Column( + children: [ + SwitchListTile( + title: const Text('Lights'), + value: _lights1, + onChanged: (bool value) { + setState(() { + _lights1 = value; + }); + }, + secondary: const Icon(Icons.lightbulb_outline), + ), + SwitchListTile( + title: const Text('Lights'), + subtitle: const Text('Subtitle'), + value: _lights2, + onChanged: (bool value) { + setState(() { + _lights2 = value; + }); + }, + secondary: const Icon(Icons.lightbulb_outline), + ), + ], + ), + ), + ); + } +} diff --git a/dev/a11y_assessments/lib/use_cases/use_cases.dart b/dev/a11y_assessments/lib/use_cases/use_cases.dart index 094fdbb469..f6d8e1bc58 100644 --- a/dev/a11y_assessments/lib/use_cases/use_cases.dart +++ b/dev/a11y_assessments/lib/use_cases/use_cases.dart @@ -4,15 +4,20 @@ import 'package:flutter/widgets.dart'; +import 'action_chip.dart'; import 'auto_complete.dart'; import 'badge.dart'; +import 'card.dart'; import 'check_box_list_tile.dart'; import 'date_picker.dart'; import 'dialog.dart'; +import 'expansion_tile.dart'; import 'material_banner.dart'; import 'navigation_bar.dart'; import 'radio_list_tile.dart'; import 'slider.dart'; +import 'snack_bar.dart'; +import 'switch_list_tile.dart'; import 'text_button.dart'; import 'text_field.dart'; import 'text_field_password.dart'; @@ -36,4 +41,9 @@ final List useCases = [ NavigationBarUseCase(), TextButtonUseCase(), RadioListTileUseCase(), + ActionChipUseCase(), + SnackBarUseCase(), + SwitchListTileUseCase(), + ExpansionTileUseCase(), + CardUseCase(), ]; diff --git a/dev/a11y_assessments/test/action_chip_test.dart b/dev/a11y_assessments/test/action_chip_test.dart new file mode 100644 index 0000000000..0a3a349df9 --- /dev/null +++ b/dev/a11y_assessments/test/action_chip_test.dart @@ -0,0 +1,16 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:a11y_assessments/use_cases/action_chip.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_utils.dart'; + +void main() { + testWidgets('action chip can run', (WidgetTester tester) async { + await pumpsUseCase(tester, ActionChipUseCase()); + expect(find.byType(ActionChip), findsExactly(2)); + }); +} diff --git a/dev/a11y_assessments/test/card_test.dart b/dev/a11y_assessments/test/card_test.dart new file mode 100644 index 0000000000..c8237b0223 --- /dev/null +++ b/dev/a11y_assessments/test/card_test.dart @@ -0,0 +1,16 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:a11y_assessments/use_cases/card.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_utils.dart'; + +void main() { + testWidgets('card can run', (WidgetTester tester) async { + await pumpsUseCase(tester, CardUseCase()); + expect(find.byType(Card), findsExactly(1)); + }); +} diff --git a/dev/a11y_assessments/test/expansion_tile_test.dart b/dev/a11y_assessments/test/expansion_tile_test.dart new file mode 100644 index 0000000000..5882488a5e --- /dev/null +++ b/dev/a11y_assessments/test/expansion_tile_test.dart @@ -0,0 +1,16 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:a11y_assessments/use_cases/expansion_tile.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_utils.dart'; + +void main() { + testWidgets('action chip can run', (WidgetTester tester) async { + await pumpsUseCase(tester, ExpansionTileUseCase()); + expect(find.byType(ExpansionTile), findsExactly(3)); + }); +} diff --git a/dev/a11y_assessments/test/snack_bar_test.dart b/dev/a11y_assessments/test/snack_bar_test.dart new file mode 100644 index 0000000000..21a8a9cc59 --- /dev/null +++ b/dev/a11y_assessments/test/snack_bar_test.dart @@ -0,0 +1,20 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:a11y_assessments/use_cases/snack_bar.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_utils.dart'; + +void main() { + testWidgets('snack bar can run', (WidgetTester tester) async { + await pumpsUseCase(tester, SnackBarUseCase()); + const String snackBarText = 'Awesome Snackbar!'; + expect(find.text(snackBarText), findsNothing); + await tester.tap(find.text('Show Snackbar')); + expect(find.text(snackBarText), findsNothing); + await tester.pump(); + expect(find.text(snackBarText), findsOneWidget); + }); +} diff --git a/dev/a11y_assessments/test/switch_list_tile_test.dart b/dev/a11y_assessments/test/switch_list_tile_test.dart new file mode 100644 index 0000000000..c272ec97ff --- /dev/null +++ b/dev/a11y_assessments/test/switch_list_tile_test.dart @@ -0,0 +1,16 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:a11y_assessments/use_cases/switch_list_tile.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_utils.dart'; + +void main() { + testWidgets('action chip can run', (WidgetTester tester) async { + await pumpsUseCase(tester, SwitchListTileUseCase()); + expect(find.byType(SwitchListTile), findsExactly(2)); + }); +}