Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
Removed "if" on resolving text color at "SnackBarAction" (#120050)
Browse files Browse the repository at this point in the history
* 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"
  • Loading branch information
MarchMore committed Feb 8, 2023
1 parent 75ca31b commit 0588b92
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 9 deletions.
21 changes: 13 additions & 8 deletions packages/flutter/lib/src/material/snack_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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 ??
Expand Down
122 changes: 121 additions & 1 deletion packages/flutter/test/material/snack_bar_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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);
}
}

0 comments on commit 0588b92

Please sign in to comment.