diff --git a/packages/flutter/lib/src/material/icon_button.dart b/packages/flutter/lib/src/material/icon_button.dart index 517a25cf8b..8fea4c9461 100644 --- a/packages/flutter/lib/src/material/icon_button.dart +++ b/packages/flutter/lib/src/material/icon_button.dart @@ -874,7 +874,10 @@ class _SelectableIconButtonState extends State<_SelectableIconButton> { onPressed: widget.onPressed, variant: widget.variant, toggleable: toggleable, - child: widget.child, + child: Semantics( + selected: widget.isSelected, + child: widget.child, + ), ); } } diff --git a/packages/flutter/test/material/icon_button_test.dart b/packages/flutter/test/material/icon_button_test.dart index 3ff46df1e7..6ca92b500e 100644 --- a/packages/flutter/test/material/icon_button_test.dart +++ b/packages/flutter/test/material/icon_button_test.dart @@ -653,6 +653,62 @@ void main() { semantics.dispose(); }); + testWidgets('IconButton Semantics (selected) - M3', (WidgetTester tester) async { + final SemanticsTester semantics = SemanticsTester(tester); + + await tester.pumpWidget( + wrap( + useMaterial3: true, + child: IconButton( + onPressed: mockOnPressedFunction.handler, + isSelected: true, + icon: const Icon(Icons.link, semanticLabel: 'link'), + ), + ), + ); + + expect( + semantics, + hasSemantics( + TestSemantics.root( + children: [ + TestSemantics( + textDirection: TextDirection.ltr, + children: [ + TestSemantics( + children: [ + TestSemantics( + flags: [SemanticsFlag.scopesRoute], + children: [ + TestSemantics( + actions: [ + SemanticsAction.tap, + ], + flags: [ + SemanticsFlag.hasEnabledState, + SemanticsFlag.isButton, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocusable, + SemanticsFlag.isSelected, + ], + label: 'link', + ), + ], + ), + ], + ), + ], + ), + ], + ), + ignoreId: true, + ignoreRect: true, + ignoreTransform: true, + ), + ); + semantics.dispose(); + }); + testWidgets('IconButton loses focus when disabled.', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(debugLabel: 'IconButton'); await tester.pumpWidget(