Unverified Commit 0588b925 authored by MarchMore's avatar MarchMore Committed by GitHub

Removed "if" on resolving text color at "SnackBarAction" (#120050)

* Removed "if" on resolving text color at "SnackBarAction"

Removed multiple "if" for "resolveForegroundColor" method at "SnackBarAction". At least one of the multiple "if" ("defaults.actionTextColor is MaterialStateColor") led to not applying a custom set color (e.g. MaterialColor "Colors.red") for the action text when using Material 3.

The second "if" ("snackBarTheme.actionTextColor is MaterialStateColor") also makes no sense then as the set color of the Theme would lead to the same blocking behaviour of manual color assignment.

The last remaining "if" ("widget.textColor is MaterialStateColor") will be unnecessary if the other "if" will be removed, as it will be resolved in the code right afterwards.

The three "if" also seems to block the usage of the custom text color or the color at all if the widget is in the "MaterialState.disabled" state.

* Adjusted recent modifications to SnackBarAction's text color resolution

* Now the "widget.textColor" is checked if it is set.
  * If it is a MaterialStateColor, it will be used
  * Otherwise continue with normal resolution (It will be used in the resolution anyways because it's set)

* Repeat same steps with "snackBarTheme.actionTextColor" if previous was not set

* Repeat same steps with "defaults.actionTextColor" if previous was not set

* Reverted the auto formatting changes

* Added two test cases to "snack_bar_test"

 * Test for setting a MaterialColor to a SnackBarAction' label (M3)
 * Test for setting a MaterialStateColor to a SnackBarAction' label (M3)

* Renamed test cases "Snackbar labels can be colored"
parent 75ca31b0
......@@ -140,15 +140,20 @@ class _SnackBarActionState extends State<SnackBarAction> {
final SnackBarThemeData snackBarTheme = Theme.of(context).snackBarTheme;
MaterialStateColor resolveForegroundColor() {
if (widget.textColor is MaterialStateColor) {
return widget.textColor! as MaterialStateColor;
}
if (snackBarTheme.actionTextColor is MaterialStateColor) {
return snackBarTheme.actionTextColor! as MaterialStateColor;
}
if (defaults.actionTextColor is MaterialStateColor) {
return defaults.actionTextColor! as MaterialStateColor;
if (widget.textColor != null) {
if (widget.textColor is MaterialStateColor) {
return widget.textColor! as MaterialStateColor;
}
} else if (snackBarTheme.actionTextColor != null) {
if (snackBarTheme.actionTextColor is MaterialStateColor) {
return snackBarTheme.actionTextColor! as MaterialStateColor;
}
} else if (defaults.actionTextColor != null) {
if (defaults.actionTextColor is MaterialStateColor) {
return defaults.actionTextColor! as MaterialStateColor;
}
}
return MaterialStateColor.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return widget.disabledTextColor ??
......
......@@ -812,7 +812,7 @@ void main() {
expect(snackBarBottomRight.dx, (800 + widgetWidth) / 2); // Device width is 800.
});
testWidgets('Snackbar labels can be colored', (WidgetTester tester) async {
testWidgets('Snackbar labels can be colored as MaterialColor (Material 2)', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
......@@ -856,6 +856,110 @@ void main() {
}
});
testWidgets('Snackbar labels can be colored as MaterialColor (Material 3)',
(WidgetTester tester) async {
const MaterialColor usedColor = Colors.teal;
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(useMaterial3: true),
home: Scaffold(
body: Builder(
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('I am a snack bar.'),
duration: const Duration(seconds: 2),
action: SnackBarAction(
textColor: usedColor,
label: 'ACTION',
onPressed: () {},
),
),
);
},
child: const Text('X'),
);
},
),
),
),
);
await tester.tap(find.text('X'));
await tester.pump(); // start animation
await tester.pump(const Duration(milliseconds: 750));
final Element actionTextButton =
tester.element(find.widgetWithText(TextButton, 'ACTION'));
final Widget textButton = actionTextButton.widget;
if (textButton is TextButton) {
final ButtonStyle buttonStyle = textButton.style!;
if (buttonStyle.foregroundColor is MaterialStateColor) {
// Same color when resolved
expect(buttonStyle.foregroundColor!.resolve(<MaterialState>{}), usedColor);
} else {
expect(false, true);
}
} else {
expect(false, true);
}
});
testWidgets('Snackbar labels can be colored as MaterialStateColor (Material 3)',
(WidgetTester tester) async {
const _TestMaterialStateColor usedColor = _TestMaterialStateColor();
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(useMaterial3: true),
home: Scaffold(
body: Builder(
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('I am a snack bar.'),
duration: const Duration(seconds: 2),
action: SnackBarAction(
textColor: usedColor,
label: 'ACTION',
onPressed: () {},
),
),
);
},
child: const Text('X'),
);
},
),
),
),
);
await tester.tap(find.text('X'));
await tester.pump(); // start animation
await tester.pump(const Duration(milliseconds: 750));
final Element actionTextButton =
tester.element(find.widgetWithText(TextButton, 'ACTION'));
final Widget textButton = actionTextButton.widget;
if (textButton is TextButton) {
final ButtonStyle buttonStyle = textButton.style!;
if (buttonStyle.foregroundColor is MaterialStateColor) {
// Exactly the same object
expect(buttonStyle.foregroundColor, usedColor);
} else {
expect(false, true);
}
} else {
expect(false, true);
}
});
testWidgets('SnackBar button text alignment', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: MediaQuery(
......@@ -2588,3 +2692,19 @@ Map<DismissDirection, List<Offset>> _getDragGesturesOfDismissDirections(double s
return dragGestures;
}
class _TestMaterialStateColor extends MaterialStateColor {
const _TestMaterialStateColor() : super(_colorRed);
static const int _colorRed = 0xFFF44336;
static const int _colorBlue = 0xFF2196F3;
@override
Color resolve(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) {
return const Color(_colorBlue);
}
return const Color(_colorRed);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment