Skip to content

Commit

Permalink
Added ButtonStyle.maximumSize (flutter#80087)
Browse files Browse the repository at this point in the history
  • Loading branch information
HansMuller authored Apr 9, 2021
1 parent 1a36c18 commit 457985f
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 2 deletions.
23 changes: 21 additions & 2 deletions packages/flutter/lib/src/material/button_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class ButtonStyle with Diagnosticable {
this.padding,
this.minimumSize,
this.fixedSize,
this.maximumSize,
this.side,
this.shape,
this.mouseCursor,
Expand Down Expand Up @@ -159,18 +160,29 @@ class ButtonStyle with Diagnosticable {
///
/// The size of the rectangle the button lies within may be larger
/// per [tapTargetSize].
///
/// This value must be less than or equal to [maximumSize].
final MaterialStateProperty<Size?>? minimumSize;

/// The button's size.
///
/// This size is still constrained by the style's [minimumSize]. Fixed
/// size dimensions whose value is [double.infinity] are ignored.
/// This size is still constrained by the style's [minimumSize]
/// and [maximumSize]. Fixed size dimensions whose value is
/// [double.infinity] are ignored.
///
/// To specify buttons with a fixed width and the default height use
/// `fixedSize: Size.fromWidth(320)`. Similarly, to specify a fixed
/// height and the default width use `fixedSize: Size.fromHeight(100)`.
final MaterialStateProperty<Size?>? fixedSize;

/// The maximum size of the button itself.
///
/// A [Size.infinite] or null value for this property means that
/// the button's maximum size is not constrained.
///
/// This value must be greater than or equal to [minimumSize].
final MaterialStateProperty<Size?>? maximumSize;

/// The color and weight of the button's outline.
///
/// This value is combined with [shape] to create a shape decorated
Expand Down Expand Up @@ -259,6 +271,7 @@ class ButtonStyle with Diagnosticable {
MaterialStateProperty<EdgeInsetsGeometry?>? padding,
MaterialStateProperty<Size?>? minimumSize,
MaterialStateProperty<Size?>? fixedSize,
MaterialStateProperty<Size?>? maximumSize,
MaterialStateProperty<BorderSide?>? side,
MaterialStateProperty<OutlinedBorder?>? shape,
MaterialStateProperty<MouseCursor?>? mouseCursor,
Expand All @@ -279,6 +292,7 @@ class ButtonStyle with Diagnosticable {
padding: padding ?? this.padding,
minimumSize: minimumSize ?? this.minimumSize,
fixedSize: fixedSize ?? this.fixedSize,
maximumSize: maximumSize ?? this.maximumSize,
side: side ?? this.side,
shape: shape ?? this.shape,
mouseCursor: mouseCursor ?? this.mouseCursor,
Expand Down Expand Up @@ -309,6 +323,7 @@ class ButtonStyle with Diagnosticable {
padding: padding ?? style.padding,
minimumSize: minimumSize ?? style.minimumSize,
fixedSize: fixedSize ?? style.fixedSize,
maximumSize: maximumSize ?? style.maximumSize,
side: side ?? style.side,
shape: shape ?? style.shape,
mouseCursor: mouseCursor ?? style.mouseCursor,
Expand All @@ -333,6 +348,7 @@ class ButtonStyle with Diagnosticable {
padding,
minimumSize,
fixedSize,
maximumSize,
side,
shape,
mouseCursor,
Expand Down Expand Up @@ -361,6 +377,7 @@ class ButtonStyle with Diagnosticable {
&& other.padding == padding
&& other.minimumSize == minimumSize
&& other.fixedSize == fixedSize
&& other.maximumSize == maximumSize
&& other.side == side
&& other.shape == shape
&& other.mouseCursor == mouseCursor
Expand All @@ -384,6 +401,7 @@ class ButtonStyle with Diagnosticable {
properties.add(DiagnosticsProperty<MaterialStateProperty<EdgeInsetsGeometry?>>('padding', padding, defaultValue: null));
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<BorderSide?>>('side', side, defaultValue: null));
properties.add(DiagnosticsProperty<MaterialStateProperty<OutlinedBorder?>>('shape', shape, defaultValue: null));
properties.add(DiagnosticsProperty<MaterialStateProperty<MouseCursor?>>('mouseCursor', mouseCursor, defaultValue: null));
Expand All @@ -409,6 +427,7 @@ class ButtonStyle with Diagnosticable {
padding: _lerpProperties<EdgeInsetsGeometry?>(a?.padding, b?.padding, t, EdgeInsetsGeometry.lerp),
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),
side: _lerpSides(a?.side, b?.side, t),
shape: _lerpShapes(a?.shape, b?.shape, t),
mouseCursor: t < 0.5 ? a?.mouseCursor : b?.mouseCursor,
Expand Down
3 changes: 3 additions & 0 deletions packages/flutter/lib/src/material/button_style_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ class _ButtonStyleState extends State<ButtonStyleButton> with TickerProviderStat
final EdgeInsetsGeometry? resolvedPadding = resolve<EdgeInsetsGeometry?>((ButtonStyle? style) => style?.padding);
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 BorderSide? resolvedSide = resolve<BorderSide?>((ButtonStyle? style) => style?.side);
final OutlinedBorder? resolvedShape = resolve<OutlinedBorder?>((ButtonStyle? style) => style?.shape);

Expand All @@ -291,6 +292,8 @@ class _ButtonStyleState extends State<ButtonStyleButton> with TickerProviderStat
BoxConstraints(
minWidth: resolvedMinimumSize!.width,
minHeight: resolvedMinimumSize.height,
maxWidth: resolvedMaximumSize!.width,
maxHeight: resolvedMaximumSize.height,
),
);
if (resolvedFixedSize != null) {
Expand Down
4 changes: 4 additions & 0 deletions packages/flutter/lib/src/material/elevated_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ class ElevatedButton extends ButtonStyleButton {
EdgeInsetsGeometry? padding,
Size? minimumSize,
Size? fixedSize,
Size? maximumSize,
BorderSide? side,
OutlinedBorder? shape,
MouseCursor? enabledMouseCursor,
Expand Down Expand Up @@ -211,6 +212,7 @@ class ElevatedButton extends ButtonStyleButton {
padding: ButtonStyleButton.allOrNull<EdgeInsetsGeometry>(padding),
minimumSize: ButtonStyleButton.allOrNull<Size>(minimumSize),
fixedSize: ButtonStyleButton.allOrNull<Size>(fixedSize),
maximumSize: ButtonStyleButton.allOrNull<Size>(maximumSize),
side: ButtonStyleButton.allOrNull<BorderSide>(side),
shape: ButtonStyleButton.allOrNull<OutlinedBorder>(shape),
mouseCursor: mouseCursor,
Expand Down Expand Up @@ -270,6 +272,7 @@ class ElevatedButton extends ButtonStyleButton {
/// * `3 < textScaleFactor` - horizontal(4)
/// * `minimumSize` - Size(64, 36)
/// * `fixedSize` - null
/// * `maximumSize` - Size.infinite
/// * `side` - null
/// * `shape` - RoundedRectangleBorder(borderRadius: BorderRadius.circular(4))
/// * `mouseCursor`
Expand Down Expand Up @@ -315,6 +318,7 @@ class ElevatedButton extends ButtonStyleButton {
textStyle: theme.textTheme.button,
padding: scaledPadding,
minimumSize: const Size(64, 36),
maximumSize: Size.infinite,
side: null,
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4))),
enabledMouseCursor: SystemMouseCursors.click,
Expand Down
4 changes: 4 additions & 0 deletions packages/flutter/lib/src/material/outlined_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class OutlinedButton extends ButtonStyleButton {
EdgeInsetsGeometry? padding,
Size? minimumSize,
Size? fixedSize,
Size? maximumSize,
BorderSide? side,
OutlinedBorder? shape,
MouseCursor? enabledMouseCursor,
Expand Down Expand Up @@ -180,6 +181,7 @@ class OutlinedButton extends ButtonStyleButton {
padding: ButtonStyleButton.allOrNull<EdgeInsetsGeometry>(padding),
minimumSize: ButtonStyleButton.allOrNull<Size>(minimumSize),
fixedSize: ButtonStyleButton.allOrNull<Size>(fixedSize),
maximumSize: ButtonStyleButton.allOrNull<Size>(maximumSize),
side: ButtonStyleButton.allOrNull<BorderSide>(side),
shape: ButtonStyleButton.allOrNull<OutlinedBorder>(shape),
mouseCursor: mouseCursor,
Expand Down Expand Up @@ -232,6 +234,7 @@ class OutlinedButton extends ButtonStyleButton {
/// * `3 < textScaleFactor` - horizontal(4)
/// * `minimumSize` - Size(64, 36)
/// * `fixedSize` - null
/// * `maximumSize` - Size.infinite
/// * `side` - BorderSide(width: 1, color: Theme.colorScheme.onSurface(0.12))
/// * `shape` - RoundedRectangleBorder(borderRadius: BorderRadius.circular(4))
/// * `mouseCursor`
Expand Down Expand Up @@ -264,6 +267,7 @@ class OutlinedButton extends ButtonStyleButton {
textStyle: theme.textTheme.button,
padding: scaledPadding,
minimumSize: const Size(64, 36),
maximumSize: Size.infinite,
side: BorderSide(
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.12),
width: 1,
Expand Down
4 changes: 4 additions & 0 deletions packages/flutter/lib/src/material/text_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ class TextButton extends ButtonStyleButton {
EdgeInsetsGeometry? padding,
Size? minimumSize,
Size? fixedSize,
Size? maximumSize,
BorderSide? side,
OutlinedBorder? shape,
MouseCursor? enabledMouseCursor,
Expand Down Expand Up @@ -234,6 +235,7 @@ class TextButton extends ButtonStyleButton {
padding: ButtonStyleButton.allOrNull<EdgeInsetsGeometry>(padding),
minimumSize: ButtonStyleButton.allOrNull<Size>(minimumSize),
fixedSize: ButtonStyleButton.allOrNull<Size>(fixedSize),
maximumSize: ButtonStyleButton.allOrNull<Size>(maximumSize),
side: ButtonStyleButton.allOrNull<BorderSide>(side),
shape: ButtonStyleButton.allOrNull<OutlinedBorder>(shape),
mouseCursor: mouseCursor,
Expand Down Expand Up @@ -289,6 +291,7 @@ class TextButton extends ButtonStyleButton {
/// * `3 < textScaleFactor` - horizontal(4)
/// * `minimumSize` - Size(64, 36)
/// * `fixedSize` - null
/// * `maximumSize` - Size.infinite
/// * `side` - null
/// * `shape` - RoundedRectangleBorder(borderRadius: BorderRadius.circular(4))
/// * `mouseCursor`
Expand Down Expand Up @@ -333,6 +336,7 @@ class TextButton extends ButtonStyleButton {
textStyle: theme.textTheme.button,
padding: scaledPadding,
minimumSize: const Size(64, 36),
maximumSize: Size.infinite,
side: null,
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4))),
enabledMouseCursor: SystemMouseCursors.click,
Expand Down
6 changes: 6 additions & 0 deletions packages/flutter/test/material/button_style_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ void main() {
expect(style.padding, null);
expect(style.minimumSize, null);
expect(style.fixedSize, null);
expect(style.maximumSize, null);
expect(style.side, null);
expect(style.shape, null);
expect(style.mouseCursor, null);
Expand Down Expand Up @@ -56,6 +57,7 @@ void main() {
padding: MaterialStateProperty.all<EdgeInsets>(const EdgeInsets.all(1.0)),
minimumSize: MaterialStateProperty.all<Size>(const Size(1.0, 2.0)),
side: MaterialStateProperty.all<BorderSide>(const BorderSide(width: 4.0, color: Color(0xfffffff4))),
maximumSize: MaterialStateProperty.all<Size>(const Size(100.0, 200.0)),
shape: MaterialStateProperty.all<OutlinedBorder>(const StadiumBorder()),
mouseCursor: MaterialStateProperty.all<MouseCursor>(SystemMouseCursors.forbidden),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
Expand All @@ -76,6 +78,7 @@ void main() {
'elevation: MaterialStateProperty.all(1.5)',
'padding: MaterialStateProperty.all(EdgeInsets.all(1.0))',
'minimumSize: MaterialStateProperty.all(Size(1.0, 2.0))',
'maximumSize: MaterialStateProperty.all(Size(100.0, 200.0))',
'side: MaterialStateProperty.all(BorderSide(Color(0xfffffff4), 4.0, BorderStyle.solid))',
'shape: MaterialStateProperty.all(StadiumBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none)))',
'mouseCursor: MaterialStateProperty.all(SystemMouseCursor(forbidden))',
Expand All @@ -94,6 +97,7 @@ void main() {
final MaterialStateProperty<EdgeInsets> padding = MaterialStateProperty.all<EdgeInsets>(const EdgeInsets.all(1));
final MaterialStateProperty<Size> minimumSize = MaterialStateProperty.all<Size>(const Size(1, 2));
final MaterialStateProperty<Size> fixedSize = MaterialStateProperty.all<Size>(const Size(3, 4));
final MaterialStateProperty<Size> maximumSize = MaterialStateProperty.all<Size>(const Size(5, 6));
final MaterialStateProperty<BorderSide> side = MaterialStateProperty.all<BorderSide>(const BorderSide());
final MaterialStateProperty<OutlinedBorder> shape = MaterialStateProperty.all<OutlinedBorder>(const StadiumBorder());
final MaterialStateProperty<MouseCursor> mouseCursor = MaterialStateProperty.all<MouseCursor>(SystemMouseCursors.forbidden);
Expand All @@ -111,6 +115,7 @@ void main() {
padding: padding,
minimumSize: minimumSize,
fixedSize: fixedSize,
maximumSize: maximumSize,
side: side,
shape: shape,
mouseCursor: mouseCursor,
Expand All @@ -131,6 +136,7 @@ void main() {
padding: padding,
minimumSize: minimumSize,
fixedSize: fixedSize,
maximumSize: maximumSize,
side: side,
shape: shape,
mouseCursor: mouseCursor,
Expand Down
71 changes: 71 additions & 0 deletions packages/flutter/test/material/elevated_button_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,77 @@ void main() {
expect(tester.getRect(find.byKey(iconKey)), const Rect.fromLTRB(46.0, 0.0, 96.0, 100.0));
expect(tester.getRect(find.byKey(labelKey)), const Rect.fromLTRB(104.0, 0.0, 154.0, 100.0));
});

testWidgets('ElevatedButton maximumSize', (WidgetTester tester) async {
final Key key0 = UniqueKey();
final Key key1 = UniqueKey();

await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ElevatedButton(
key: key0,
style: TextButton.styleFrom(
minimumSize: const Size(24, 36),
maximumSize: const Size.fromWidth(64),
),
onPressed: () { },
child: const Text('A B C D E F G H I J K L M N O P'),
),
ElevatedButton.icon(
key: key1,
style: TextButton.styleFrom(
minimumSize: const Size(24, 36),
maximumSize: const Size.fromWidth(104),
),
onPressed: () {},
icon: Container(color: Colors.red, width: 32, height: 32),
label: const Text('A B C D E F G H I J K L M N O P'),
),
],
),
),
),
),
);

expect(tester.getSize(find.byKey(key0)), const Size(64.0, 224.0));
expect(tester.getSize(find.byKey(key1)), const Size(104.0, 224.0));
});

testWidgets('Fixed size ElevatedButton, same as minimumSize == maximumSize', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ElevatedButton(
style: ElevatedButton.styleFrom(fixedSize: const Size(200, 200)),
onPressed: () { },
child: const Text('200x200'),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: const Size(200, 200),
maximumSize: const Size(200, 200),
),
onPressed: () { },
child: const Text('200,200'),
),
],
),
),
),
);

expect(tester.getSize(find.widgetWithText(ElevatedButton, '200x200')), const Size(200, 200));
expect(tester.getSize(find.widgetWithText(ElevatedButton, '200,200')), const Size(200, 200));
});
}

TextStyle _iconStyle(WidgetTester tester, IconData icon) {
Expand Down
Loading

0 comments on commit 457985f

Please sign in to comment.