Added iconSize parameter in ButtonStyle (#108268)

* Added iconSize parameter in ButtonStyle

Co-authored-by: Qun Cheng <quncheng@google.com>
diff --git a/packages/flutter/lib/src/material/button_style.dart b/packages/flutter/lib/src/material/button_style.dart
index 216c5c7..51736ad 100644
--- a/packages/flutter/lib/src/material/button_style.dart
+++ b/packages/flutter/lib/src/material/button_style.dart
@@ -132,6 +132,7 @@
     this.minimumSize,
     this.fixedSize,
     this.maximumSize,
+    this.iconSize,
     this.side,
     this.shape,
     this.mouseCursor,
@@ -210,6 +211,9 @@
   /// This value must be greater than or equal to [minimumSize].
   final MaterialStateProperty<Size?>? maximumSize;
 
+  /// The icon's size inside of the button.
+  final MaterialStateProperty<double?>? iconSize;
+
   /// The color and weight of the button's outline.
   ///
   /// This value is combined with [shape] to create a shape decorated
@@ -300,6 +304,7 @@
     MaterialStateProperty<Size?>? minimumSize,
     MaterialStateProperty<Size?>? fixedSize,
     MaterialStateProperty<Size?>? maximumSize,
+    MaterialStateProperty<double?>? iconSize,
     MaterialStateProperty<BorderSide?>? side,
     MaterialStateProperty<OutlinedBorder?>? shape,
     MaterialStateProperty<MouseCursor?>? mouseCursor,
@@ -322,6 +327,7 @@
       minimumSize: minimumSize ?? this.minimumSize,
       fixedSize: fixedSize ?? this.fixedSize,
       maximumSize: maximumSize ?? this.maximumSize,
+      iconSize: iconSize ?? this.iconSize,
       side: side ?? this.side,
       shape: shape ?? this.shape,
       mouseCursor: mouseCursor ?? this.mouseCursor,
@@ -355,6 +361,7 @@
       minimumSize: minimumSize ?? style.minimumSize,
       fixedSize: fixedSize ?? style.fixedSize,
       maximumSize: maximumSize ?? style.maximumSize,
+      iconSize: iconSize ?? style.iconSize,
       side: side ?? style.side,
       shape: shape ?? style.shape,
       mouseCursor: mouseCursor ?? style.mouseCursor,
@@ -368,28 +375,32 @@
   }
 
   @override
-  int get hashCode => Object.hash(
-    textStyle,
-    backgroundColor,
-    foregroundColor,
-    overlayColor,
-    shadowColor,
-    surfaceTintColor,
-    elevation,
-    padding,
-    minimumSize,
-    fixedSize,
-    maximumSize,
-    side,
-    shape,
-    mouseCursor,
-    visualDensity,
-    tapTargetSize,
-    animationDuration,
-    enableFeedback,
-    alignment,
-    splashFactory,
-  );
+  int get hashCode {
+    final List<Object?> values = <Object?>[
+      textStyle,
+      backgroundColor,
+      foregroundColor,
+      overlayColor,
+      shadowColor,
+      surfaceTintColor,
+      elevation,
+      padding,
+      minimumSize,
+      fixedSize,
+      maximumSize,
+      iconSize,
+      side,
+      shape,
+      mouseCursor,
+      visualDensity,
+      tapTargetSize,
+      animationDuration,
+      enableFeedback,
+      alignment,
+      splashFactory,
+    ];
+    return Object.hashAll(values);
+  }
 
   @override
   bool operator ==(Object other) {
@@ -411,6 +422,7 @@
         && other.minimumSize == minimumSize
         && other.fixedSize == fixedSize
         && other.maximumSize == maximumSize
+        && other.iconSize == iconSize
         && other.side == side
         && other.shape == shape
         && other.mouseCursor == mouseCursor
@@ -436,6 +448,7 @@
     properties.add(DiagnosticsProperty<MaterialStateProperty<Size?>>('minimumSize', minimumSize, defaultValue: null));
     properties.add(DiagnosticsProperty<MaterialStateProperty<Size?>>('fixedSize', fixedSize, defaultValue: null));
     properties.add(DiagnosticsProperty<MaterialStateProperty<Size?>>('maximumSize', maximumSize, defaultValue: null));
+    properties.add(DiagnosticsProperty<MaterialStateProperty<double?>>('iconSize', iconSize, defaultValue: null));
     properties.add(DiagnosticsProperty<MaterialStateProperty<BorderSide?>>('side', side, defaultValue: null));
     properties.add(DiagnosticsProperty<MaterialStateProperty<OutlinedBorder?>>('shape', shape, defaultValue: null));
     properties.add(DiagnosticsProperty<MaterialStateProperty<MouseCursor?>>('mouseCursor', mouseCursor, defaultValue: null));
@@ -464,6 +477,7 @@
       minimumSize: _lerpProperties<Size?>(a?.minimumSize, b?.minimumSize, t, Size.lerp),
       fixedSize: _lerpProperties<Size?>(a?.fixedSize, b?.fixedSize, t, Size.lerp),
       maximumSize: _lerpProperties<Size?>(a?.maximumSize, b?.maximumSize, t, Size.lerp),
+      iconSize: _lerpProperties<double?>(a?.iconSize, b?.iconSize, t, lerpDouble),
       side: _lerpSides(a?.side, b?.side, t),
       shape: MaterialStateProperty.lerp<OutlinedBorder?>(a?.shape, b?.shape, t, OutlinedBorder.lerp),
       mouseCursor: t < 0.5 ? a?.mouseCursor : b?.mouseCursor,
diff --git a/packages/flutter/lib/src/material/button_style_button.dart b/packages/flutter/lib/src/material/button_style_button.dart
index 3a22b19..3dd671b 100644
--- a/packages/flutter/lib/src/material/button_style_button.dart
+++ b/packages/flutter/lib/src/material/button_style_button.dart
@@ -281,6 +281,7 @@
     final Size? resolvedMinimumSize = resolve<Size?>((ButtonStyle? style) => style?.minimumSize);
     final Size? resolvedFixedSize = resolve<Size?>((ButtonStyle? style) => style?.fixedSize);
     final Size? resolvedMaximumSize = resolve<Size?>((ButtonStyle? style) => style?.maximumSize);
+    final double? resolvedIconSize = resolve<double?>((ButtonStyle? style) => style?.iconSize);
     final BorderSide? resolvedSide = resolve<BorderSide?>((ButtonStyle? style) => style?.side);
     final OutlinedBorder? resolvedShape = resolve<OutlinedBorder?>((ButtonStyle? style) => style?.shape);
 
@@ -393,7 +394,7 @@
           customBorder: resolvedShape.copyWith(side: resolvedSide),
           statesController: statesController,
           child: IconTheme.merge(
-            data: IconThemeData(color: resolvedForegroundColor),
+            data: IconThemeData(color: resolvedForegroundColor, size: resolvedIconSize),
             child: Padding(
               padding: padding,
               child: Align(
diff --git a/packages/flutter/test/material/button_style_test.dart b/packages/flutter/test/material/button_style_test.dart
index 0bd0baa..11de84c 100644
--- a/packages/flutter/test/material/button_style_test.dart
+++ b/packages/flutter/test/material/button_style_test.dart
@@ -27,6 +27,7 @@
     expect(style.minimumSize, null);
     expect(style.fixedSize, null);
     expect(style.maximumSize, null);
+    expect(style.iconSize, null);
     expect(style.side, null);
     expect(style.shape, null);
     expect(style.mouseCursor, null);
@@ -62,6 +63,7 @@
       minimumSize: MaterialStatePropertyAll<Size>(Size(1.0, 2.0)),
       side: MaterialStatePropertyAll<BorderSide>(BorderSide(width: 4.0, color: Color(0xfffffff6))),
       maximumSize: MaterialStatePropertyAll<Size>(Size(100.0, 200.0)),
+      iconSize: MaterialStatePropertyAll<double>(48.1),
       shape: MaterialStatePropertyAll<OutlinedBorder>(StadiumBorder()),
       mouseCursor: MaterialStatePropertyAll<MouseCursor>(SystemMouseCursors.forbidden),
       tapTargetSize: MaterialTapTargetSize.shrinkWrap,
@@ -85,6 +87,7 @@
       'padding: MaterialStatePropertyAll(EdgeInsets.all(1.0))',
       'minimumSize: MaterialStatePropertyAll(Size(1.0, 2.0))',
       'maximumSize: MaterialStatePropertyAll(Size(100.0, 200.0))',
+      'iconSize: MaterialStatePropertyAll(48.1)',
       'side: MaterialStatePropertyAll(BorderSide(Color(0xfffffff6), 4.0, BorderStyle.solid))',
       'shape: MaterialStatePropertyAll(StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none)))',
       'mouseCursor: MaterialStatePropertyAll(SystemMouseCursor(forbidden))',
@@ -106,6 +109,7 @@
     const MaterialStateProperty<Size> minimumSize = MaterialStatePropertyAll<Size>(Size(1, 2));
     const MaterialStateProperty<Size> fixedSize = MaterialStatePropertyAll<Size>(Size(3, 4));
     const MaterialStateProperty<Size> maximumSize = MaterialStatePropertyAll<Size>(Size(5, 6));
+    const MaterialStateProperty<double> iconSize = MaterialStatePropertyAll<double>(48.0);
     const MaterialStateProperty<BorderSide> side = MaterialStatePropertyAll<BorderSide>(BorderSide());
     const MaterialStateProperty<OutlinedBorder> shape = MaterialStatePropertyAll<OutlinedBorder>(StadiumBorder());
     const MaterialStateProperty<MouseCursor> mouseCursor = MaterialStatePropertyAll<MouseCursor>(SystemMouseCursors.forbidden);
@@ -126,6 +130,7 @@
       minimumSize: minimumSize,
       fixedSize: fixedSize,
       maximumSize: maximumSize,
+      iconSize: iconSize,
       side: side,
       shape: shape,
       mouseCursor: mouseCursor,
@@ -149,6 +154,7 @@
         minimumSize: minimumSize,
         fixedSize: fixedSize,
         maximumSize: maximumSize,
+        iconSize: iconSize,
         side: side,
         shape: shape,
         mouseCursor: mouseCursor,