From 38c7c2fe93b3c6bea85dd6ea69f8c74c33994911 Mon Sep 17 00:00:00 2001 From: Taha Tesser Date: Tue, 25 Apr 2023 00:41:06 +0300 Subject: [PATCH] Fix `OutlinedButton`, `TextButton`, and `IconButton` throw exception when passing only one cursor to `styleFrom` (#125204) fixes https://github.com/flutter/flutter/issues/118071 --- .../lib/src/material/elevated_button.dart | 4 +--- .../lib/src/material/filled_button.dart | 5 +---- .../flutter/lib/src/material/icon_button.dart | 12 +++++------ .../lib/src/material/outlined_button.dart | 12 +++++------ .../flutter/lib/src/material/text_button.dart | 12 +++++------ .../test/material/elevated_button_test.dart | 1 - .../test/material/icon_button_test.dart | 20 +++++++++++++++++++ .../test/material/outlined_button_test.dart | 18 +++++++++++++++++ .../test/material/text_button_test.dart | 18 +++++++++++++++++ 9 files changed, 73 insertions(+), 29 deletions(-) diff --git a/packages/flutter/lib/src/material/elevated_button.dart b/packages/flutter/lib/src/material/elevated_button.dart index 7f44da76f509..3bae64133505 100644 --- a/packages/flutter/lib/src/material/elevated_button.dart +++ b/packages/flutter/lib/src/material/elevated_button.dart @@ -207,9 +207,7 @@ class ElevatedButton extends ButtonStyleButton { final MaterialStateProperty? elevationValue = (elevation == null) ? null : _ElevatedButtonDefaultElevation(elevation); - final MaterialStateProperty? mouseCursor = (enabledMouseCursor == null && disabledMouseCursor == null) - ? null - : _ElevatedButtonDefaultMouseCursor(enabledMouseCursor, disabledMouseCursor); + final MaterialStateProperty mouseCursor = _ElevatedButtonDefaultMouseCursor(enabledMouseCursor, disabledMouseCursor); return ButtonStyle( textStyle: MaterialStatePropertyAll(textStyle), diff --git a/packages/flutter/lib/src/material/filled_button.dart b/packages/flutter/lib/src/material/filled_button.dart index bd7b0070b7fe..f4b92e28e9b0 100644 --- a/packages/flutter/lib/src/material/filled_button.dart +++ b/packages/flutter/lib/src/material/filled_button.dart @@ -240,10 +240,7 @@ class FilledButton extends ButtonStyleButton { final MaterialStateProperty? overlayColor = (foreground == null) ? null : _FilledButtonDefaultOverlay(foreground); - final MaterialStateProperty? mouseCursor = - (enabledMouseCursor == null && disabledMouseCursor == null) - ? null - : _FilledButtonDefaultMouseCursor(enabledMouseCursor, disabledMouseCursor); + final MaterialStateProperty mouseCursor = _FilledButtonDefaultMouseCursor(enabledMouseCursor, disabledMouseCursor); return ButtonStyle( textStyle: MaterialStatePropertyAll(textStyle), diff --git a/packages/flutter/lib/src/material/icon_button.dart b/packages/flutter/lib/src/material/icon_button.dart index e821dff80f6f..569a40e64740 100644 --- a/packages/flutter/lib/src/material/icon_button.dart +++ b/packages/flutter/lib/src/material/icon_button.dart @@ -638,9 +638,7 @@ class IconButton extends StatelessWidget { final MaterialStateProperty? overlayColor = (foregroundColor == null && hoverColor == null && focusColor == null && highlightColor == null) ? null : _IconButtonDefaultOverlay(foregroundColor, focusColor, hoverColor, highlightColor); - final MaterialStateProperty? mouseCursor = (enabledMouseCursor == null && disabledMouseCursor == null) - ? null - : _IconButtonDefaultMouseCursor(enabledMouseCursor!, disabledMouseCursor!); + final MaterialStateProperty mouseCursor = _IconButtonDefaultMouseCursor(enabledMouseCursor, disabledMouseCursor); return ButtonStyle( backgroundColor: buttonBackgroundColor, @@ -1061,14 +1059,14 @@ class _IconButtonDefaultOverlay extends MaterialStateProperty { } @immutable -class _IconButtonDefaultMouseCursor extends MaterialStateProperty with Diagnosticable { +class _IconButtonDefaultMouseCursor extends MaterialStateProperty with Diagnosticable { _IconButtonDefaultMouseCursor(this.enabledCursor, this.disabledCursor); - final MouseCursor enabledCursor; - final MouseCursor disabledCursor; + final MouseCursor? enabledCursor; + final MouseCursor? disabledCursor; @override - MouseCursor resolve(Set states) { + MouseCursor? resolve(Set states) { if (states.contains(MaterialState.disabled)) { return disabledCursor; } diff --git a/packages/flutter/lib/src/material/outlined_button.dart b/packages/flutter/lib/src/material/outlined_button.dart index c30260005986..77e67322ef49 100644 --- a/packages/flutter/lib/src/material/outlined_button.dart +++ b/packages/flutter/lib/src/material/outlined_button.dart @@ -186,9 +186,7 @@ class OutlinedButton extends ButtonStyleButton { final MaterialStateProperty? overlayColor = (foreground == null) ? null : _OutlinedButtonDefaultOverlay(foreground); - final MaterialStateProperty? mouseCursor = (enabledMouseCursor == null && disabledMouseCursor == null) - ? null - : _OutlinedButtonDefaultMouseCursor(enabledMouseCursor!, disabledMouseCursor!); + final MaterialStateProperty mouseCursor = _OutlinedButtonDefaultMouseCursor(enabledMouseCursor, disabledMouseCursor); return ButtonStyle( textStyle: ButtonStyleButton.allOrNull(textStyle), @@ -395,14 +393,14 @@ class _OutlinedButtonDefaultOverlay extends MaterialStateProperty with D } @immutable -class _OutlinedButtonDefaultMouseCursor extends MaterialStateProperty with Diagnosticable { +class _OutlinedButtonDefaultMouseCursor extends MaterialStateProperty with Diagnosticable { _OutlinedButtonDefaultMouseCursor(this.enabledCursor, this.disabledCursor); - final MouseCursor enabledCursor; - final MouseCursor disabledCursor; + final MouseCursor? enabledCursor; + final MouseCursor? disabledCursor; @override - MouseCursor resolve(Set states) { + MouseCursor? resolve(Set states) { if (states.contains(MaterialState.disabled)) { return disabledCursor; } diff --git a/packages/flutter/lib/src/material/text_button.dart b/packages/flutter/lib/src/material/text_button.dart index fd339c1b7c40..2ea151b1ecb8 100644 --- a/packages/flutter/lib/src/material/text_button.dart +++ b/packages/flutter/lib/src/material/text_button.dart @@ -200,9 +200,7 @@ class TextButton extends ButtonStyleButton { : disabledIconColor == null ? ButtonStyleButton.allOrNull(iconColor) : _TextButtonDefaultIconColor(iconColor, disabledIconColor); - final MaterialStateProperty? mouseCursor = (enabledMouseCursor == null && disabledMouseCursor == null) - ? null - : _TextButtonDefaultMouseCursor(enabledMouseCursor!, disabledMouseCursor!); + final MaterialStateProperty mouseCursor = _TextButtonDefaultMouseCursor(enabledMouseCursor, disabledMouseCursor); return ButtonStyle( textStyle: ButtonStyleButton.allOrNull(textStyle), @@ -456,14 +454,14 @@ class _TextButtonDefaultIconColor extends MaterialStateProperty { } @immutable -class _TextButtonDefaultMouseCursor extends MaterialStateProperty with Diagnosticable { +class _TextButtonDefaultMouseCursor extends MaterialStateProperty with Diagnosticable { _TextButtonDefaultMouseCursor(this.enabledCursor, this.disabledCursor); - final MouseCursor enabledCursor; - final MouseCursor disabledCursor; + final MouseCursor? enabledCursor; + final MouseCursor? disabledCursor; @override - MouseCursor resolve(Set states) { + MouseCursor? resolve(Set states) { if (states.contains(MaterialState.disabled)) { return disabledCursor; } diff --git a/packages/flutter/test/material/elevated_button_test.dart b/packages/flutter/test/material/elevated_button_test.dart index 2304d51c5c42..434045b8e884 100644 --- a/packages/flutter/test/material/elevated_button_test.dart +++ b/packages/flutter/test/material/elevated_button_test.dart @@ -1835,7 +1835,6 @@ void main() { expect(controller.value, {MaterialState.disabled}); expect(count, 1); }); - } TextStyle _iconStyle(WidgetTester tester, IconData icon) { diff --git a/packages/flutter/test/material/icon_button_test.dart b/packages/flutter/test/material/icon_button_test.dart index ed59901ad464..9463ee326af3 100644 --- a/packages/flutter/test/material/icon_button_test.dart +++ b/packages/flutter/test/material/icon_button_test.dart @@ -2482,6 +2482,26 @@ void main() { testWidgets('black87 icon color defined by users shows correctly in Material3', (WidgetTester tester) async { }); + + testWidgets("IconButton.styleFrom doesn't throw exception on passing only one cursor", (WidgetTester tester) async { + // This is a regression test for https://github.com/flutter/flutter/issues/118071. + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: Material( + child: IconButton( + style: OutlinedButton.styleFrom( + enabledMouseCursor: SystemMouseCursors.text, + ), + onPressed: () {}, + icon: const Icon(Icons.add), + ), + ), + ), + ); + + expect(tester.takeException(), isNull); + }); }); } diff --git a/packages/flutter/test/material/outlined_button_test.dart b/packages/flutter/test/material/outlined_button_test.dart index cb06d8a359ec..97da07b2c516 100644 --- a/packages/flutter/test/material/outlined_button_test.dart +++ b/packages/flutter/test/material/outlined_button_test.dart @@ -1947,6 +1947,24 @@ void main() { expect(controller.value, {MaterialState.disabled}); expect(count, 1); }); + + testWidgets("OutlinedButton.styleFrom doesn't throw exception on passing only one cursor", (WidgetTester tester) async { + // This is a regression test for https://github.com/flutter/flutter/issues/118071. + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: OutlinedButton( + style: OutlinedButton.styleFrom( + enabledMouseCursor: SystemMouseCursors.text, + ), + onPressed: () {}, + child: const Text('button'), + ), + ), + ); + + expect(tester.takeException(), isNull); + }); } TextStyle _iconStyle(WidgetTester tester, IconData icon) { diff --git a/packages/flutter/test/material/text_button_test.dart b/packages/flutter/test/material/text_button_test.dart index c16f5beb7274..02748406744d 100644 --- a/packages/flutter/test/material/text_button_test.dart +++ b/packages/flutter/test/material/text_button_test.dart @@ -1809,6 +1809,24 @@ void main() { expect(material.textStyle!.color, colorScheme.onSurface.withOpacity(0.38)); expect(iconColor(), equals(Colors.blue)); }); + + testWidgets("TextButton.styleFrom doesn't throw exception on passing only one cursor", (WidgetTester tester) async { + // This is a regression test for https://github.com/flutter/flutter/issues/118071. + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: TextButton( + style: TextButton.styleFrom( + enabledMouseCursor: SystemMouseCursors.text, + ), + onPressed: () {}, + child: const Text('button'), + ), + ), + ); + + expect(tester.takeException(), isNull); + }); } TextStyle? _iconStyle(WidgetTester tester, IconData icon) {