Skip to content

Commit

Permalink
feat: Add autofocus for MenuItemButton (#139396)
Browse files Browse the repository at this point in the history
MenuAnchor for Material 3 is great for contextual menus but there are some minor issues related to accessibility.
This PR aims to close the gap by adding `autofocus` to the menu item button so keyboard navigation is more intuitive. Otherwise, it becomes a mess to navigate through just keyboards.

Partially resolves #139395

## Additional Notes

I should mention, I have not written tests for this due to it's trivial nature. I also lack the experience of writing Flutter tests in general, so if someone feels inclined to take over this PR and add it they're welcome to.
  • Loading branch information
Fernthedev authored Jun 27, 2024
1 parent def5a38 commit e706d7d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
5 changes: 5 additions & 0 deletions packages/flutter/lib/src/material/menu_anchor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,7 @@ class MenuItemButton extends StatefulWidget {
this.requestFocusOnHover = true,
this.onFocusChange,
this.focusNode,
this.autofocus = false,
this.shortcut,
this.semanticsLabel,
this.style,
Expand Down Expand Up @@ -897,6 +898,9 @@ class MenuItemButton extends StatefulWidget {
/// {@macro flutter.widgets.Focus.focusNode}
final FocusNode? focusNode;

/// {@macro flutter.widgets.Focus.autofocus}
final bool autofocus;

/// The optional shortcut that selects this [MenuItemButton].
///
/// {@macro flutter.material.MenuBar.shortcuts_note}
Expand Down Expand Up @@ -1140,6 +1144,7 @@ class _MenuItemButtonState extends State<MenuItemButton> {
onFocusChange: widget.enabled ? widget.onFocusChange : null,
focusNode: _focusNode,
style: mergedStyle,
autofocus: widget.enabled && widget.autofocus,
statesController: widget.statesController,
clipBehavior: widget.clipBehavior,
isSemanticButton: null,
Expand Down
39 changes: 39 additions & 0 deletions packages/flutter/test/material/menu_anchor_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2229,6 +2229,45 @@ void main() {
expect(find.text('leadingIcon'), findsOneWidget);
});

testWidgets('autofocus is used when set and widget is enabled',
(WidgetTester tester) async {

listenForFocusChanges();

await tester.pumpWidget(
MaterialApp(
home: Material(
child: Column(
children: <Widget>[
MenuAnchor(
controller: controller,
menuChildren: <Widget>[
MenuItemButton(
autofocus: true,
// Required for clickability.
onPressed: () {},
child: Text(TestMenu.mainMenu0.label),
),
MenuItemButton(
onPressed: () {},
child: Text(TestMenu.mainMenu1.label),
),
],
),
const Expanded(child: Placeholder()),
],
),
),
),
);

controller.open();
await tester.pump();

expect(controller.isOpen, equals(true));
expect(focusedMenu, equals('MenuItemButton(Text("${TestMenu.mainMenu0.label}"))'));
});

testWidgets('trailingIcon is used when set', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
Expand Down

0 comments on commit e706d7d

Please sign in to comment.