diff --git a/packages/flutter/lib/src/material/material_button.dart b/packages/flutter/lib/src/material/material_button.dart index 4b05f08efb..17ed76bd2e 100644 --- a/packages/flutter/lib/src/material/material_button.dart +++ b/packages/flutter/lib/src/material/material_button.dart @@ -258,7 +258,10 @@ class MaterialButton extends StatelessWidget { elevation: buttonTheme.getElevation(this), highlightElevation: buttonTheme.getHighlightElevation(this), padding: buttonTheme.getPadding(this), - constraints: buttonTheme.constraints, + constraints: buttonTheme.getConstraints(this).copyWith( + minWidth: minWidth, + minHeight: height, + ), shape: buttonTheme.shape, clipBehavior: clipBehavior ?? Clip.none, animationDuration: buttonTheme.getAnimationDuration(this), diff --git a/packages/flutter/test/material/buttons_test.dart b/packages/flutter/test/material/buttons_test.dart index 8d4d7f2c5c..070f2e80be 100644 --- a/packages/flutter/test/material/buttons_test.dart +++ b/packages/flutter/test/material/buttons_test.dart @@ -330,7 +330,7 @@ void main() { expect(text.text.style.color, Colors.black38); }); - testWidgets('Disabled MaterialButton has same semantic size as enabled and exposes disabled semantics', (WidgetTester tester) async { + testWidgets('Disabled MaterialButton has same semantic size as enabled and exposes disabled semantics', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final Rect expectedButtonSize = Rect.fromLTRB(0.0, 0.0, 116.0, 48.0); @@ -409,6 +409,73 @@ void main() { semantics.dispose(); }); + testWidgets('MaterialButton minWidth and height parameters', (WidgetTester tester) async { + Widget buildFrame({ double minWidth, double height, EdgeInsets padding = EdgeInsets.zero, Widget child }) { + return Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: MaterialButton( + padding: padding, + minWidth: minWidth, + height: height, + onPressed: null, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + child: child, + ), + ), + ); + } + + await tester.pumpWidget(buildFrame(minWidth: 8.0, height: 24.0)); + expect(tester.getSize(find.byType(MaterialButton)), const Size(8.0, 24.0)); + + await tester.pumpWidget(buildFrame(minWidth: 8.0)); + // Default minHeight constraint is 36, see RawMaterialButton. + expect(tester.getSize(find.byType(MaterialButton)), const Size(8.0, 36.0)); + + await tester.pumpWidget(buildFrame(height: 8.0)); + // Default minWidth constraint is 88, see RawMaterialButton. + expect(tester.getSize(find.byType(MaterialButton)), const Size(88.0, 8.0)); + + await tester.pumpWidget(buildFrame()); + expect(tester.getSize(find.byType(MaterialButton)), const Size(88.0, 36.0)); + + await tester.pumpWidget(buildFrame(padding: const EdgeInsets.all(4.0))); + expect(tester.getSize(find.byType(MaterialButton)), const Size(88.0, 36.0)); + + // Size is defined by the padding. + await tester.pumpWidget( + buildFrame( + minWidth: 0.0, + height: 0.0, + padding: const EdgeInsets.all(4.0), + ), + ); + expect(tester.getSize(find.byType(MaterialButton)), const Size(8.0, 8.0)); + + // Size is defined by the padded child. + await tester.pumpWidget( + buildFrame( + minWidth: 0.0, + height: 0.0, + padding: const EdgeInsets.all(4.0), + child: const SizedBox(width: 8.0, height: 8.0), + ), + ); + expect(tester.getSize(find.byType(MaterialButton)), const Size(16.0, 16.0)); + + // Size is defined by the minWidth, height constraints. + await tester.pumpWidget( + buildFrame( + minWidth: 18.0, + height: 18.0, + padding: const EdgeInsets.all(4.0), + child: const SizedBox(width: 8.0, height: 8.0), + ), + ); + expect(tester.getSize(find.byType(MaterialButton)), const Size(18.0, 18.0)); + }); + testWidgets('MaterialButton size is configurable by ThemeData.materialTapTargetSize', (WidgetTester tester) async { final Key key1 = UniqueKey(); await tester.pumpWidget(