Unverified Commit 91663376 authored by rami-a's avatar rami-a Committed by GitHub

Allow for customizing SnackBar's content TextStyle in its theme (#35075)

* Allow for customizing Snackbar's content TextStyle in its theme

* Address PR feedback

* Fix analyzer issues

* Address more PR feedback
parent 8532f4d0
......@@ -253,6 +253,7 @@ class SnackBar extends StatelessWidget {
accentColorBrightness: theme.accentColorBrightness,
snackBarTheme: snackBarTheme,
);
final TextStyle contentTextStyle = snackBarTheme.contentTextStyle ?? darkTheme.textTheme.subhead;
final SnackBarBehavior snackBarBehavior = behavior ?? snackBarTheme.behavior ?? SnackBarBehavior.fixed;
final bool isFloatingSnackBar = snackBarBehavior == SnackBarBehavior.floating;
final double snackBarPadding = isFloatingSnackBar ? 16.0 : 24.0;
......@@ -263,7 +264,7 @@ class SnackBar extends StatelessWidget {
child: Container(
padding: const EdgeInsets.symmetric(vertical: _singleLineVerticalPadding),
child: DefaultTextStyle(
style: darkTheme.textTheme.subhead,
style: contentTextStyle,
child: content,
),
),
......
......@@ -55,6 +55,7 @@ class SnackBarThemeData extends Diagnosticable {
this.backgroundColor,
this.actionTextColor,
this.disabledActionTextColor,
this.contentTextStyle,
this.elevation,
this.shape,
this.behavior,
......@@ -77,6 +78,11 @@ class SnackBarThemeData extends Diagnosticable {
/// otherwise.
final Color disabledActionTextColor;
/// Used to configure the [DefaultTextStyle] for the [SnackBar.content] widget.
///
/// If null, [SnackBar] defines its default.
final TextStyle contentTextStyle;
/// Default value for [SnackBar.elevation].
///
/// If null, [SnackBar] uses a default of 6.0.
......@@ -102,6 +108,7 @@ class SnackBarThemeData extends Diagnosticable {
Color backgroundColor,
Color actionTextColor,
Color disabledActionTextColor,
TextStyle contentTextStyle,
double elevation,
ShapeBorder shape,
SnackBarBehavior behavior,
......@@ -110,6 +117,7 @@ class SnackBarThemeData extends Diagnosticable {
backgroundColor: backgroundColor ?? this.backgroundColor,
actionTextColor: actionTextColor ?? this.actionTextColor,
disabledActionTextColor: disabledActionTextColor ?? this.disabledActionTextColor,
contentTextStyle: contentTextStyle ?? this.contentTextStyle,
elevation: elevation ?? this.elevation,
shape: shape ?? this.shape,
behavior: behavior ?? this.behavior,
......@@ -127,6 +135,7 @@ class SnackBarThemeData extends Diagnosticable {
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
actionTextColor: Color.lerp(a?.actionTextColor, b?.actionTextColor, t),
disabledActionTextColor: Color.lerp(a?.disabledActionTextColor, b?.disabledActionTextColor, t),
contentTextStyle: TextStyle.lerp(a?.contentTextStyle, b?.contentTextStyle, t),
elevation: lerpDouble(a?.elevation, b?.elevation, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
behavior: t < 0.5 ? a.behavior : b.behavior,
......@@ -139,6 +148,7 @@ class SnackBarThemeData extends Diagnosticable {
backgroundColor,
actionTextColor,
disabledActionTextColor,
contentTextStyle,
elevation,
shape,
behavior,
......@@ -155,6 +165,7 @@ class SnackBarThemeData extends Diagnosticable {
return typedOther.backgroundColor == backgroundColor
&& typedOther.actionTextColor == actionTextColor
&& typedOther.disabledActionTextColor == disabledActionTextColor
&& typedOther.contentTextStyle == contentTextStyle
&& typedOther.elevation == elevation
&& typedOther.shape == shape
&& typedOther.behavior == behavior;
......@@ -166,6 +177,7 @@ class SnackBarThemeData extends Diagnosticable {
properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
properties.add(ColorProperty('actionTextColor', actionTextColor, defaultValue: null));
properties.add(ColorProperty('disabledActionTextColor', disabledActionTextColor, defaultValue: null));
properties.add(DiagnosticsProperty<TextStyle>('contentTextStyle', contentTextStyle, defaultValue: null));
properties.add(DoubleProperty('elevation', elevation, defaultValue: null));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
properties.add(DiagnosticsProperty<SnackBarBehavior>('behavior', behavior, defaultValue: null));
......
......@@ -17,6 +17,7 @@ void main() {
expect(snackBarTheme.backgroundColor, null);
expect(snackBarTheme.actionTextColor, null);
expect(snackBarTheme.disabledActionTextColor, null);
expect(snackBarTheme.contentTextStyle, null);
expect(snackBarTheme.elevation, null);
expect(snackBarTheme.shape, null);
expect(snackBarTheme.behavior, null);
......@@ -40,6 +41,7 @@ void main() {
backgroundColor: const Color(0xFFFFFFFF),
actionTextColor: const Color(0xFF0000AA),
disabledActionTextColor: const Color(0xFF00AA00),
contentTextStyle: const TextStyle(color: Color(0xFF123456)),
elevation: 2.0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0)),
behavior: SnackBarBehavior.floating,
......@@ -54,6 +56,7 @@ void main() {
'backgroundColor: Color(0xffffffff)',
'actionTextColor: Color(0xff0000aa)',
'disabledActionTextColor: Color(0xff00aa00)',
'contentTextStyle: TextStyle(inherit: true, color: Color(0xff123456))',
'elevation: 2.0',
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.circular(2.0))',
'behavior: SnackBarBehavior.floating'
......@@ -61,6 +64,7 @@ void main() {
});
testWidgets('Passing no SnackBarThemeData returns defaults', (WidgetTester tester) async {
const String text = 'I am a snack bar.';
await tester.pumpWidget(MaterialApp(
home: Scaffold(
body: Builder(
......@@ -68,7 +72,7 @@ void main() {
return GestureDetector(
onTap: () {
Scaffold.of(context).showSnackBar(SnackBar(
content: const Text('I am a snack bar.'),
content: const Text(text),
duration: const Duration(seconds: 2),
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
));
......@@ -85,13 +89,16 @@ void main() {
await tester.pump(const Duration(milliseconds: 750));
final Material material = _getSnackBarMaterial(tester);
final RenderParagraph content = _getSnackBarTextRenderObject(tester, text);
expect(content.text.style, Typography().white.subhead);
expect(material.color, const Color(0xFF323232));
expect(material.elevation, 6.0);
expect(material.shape, null);
});
testWidgets('SnackBar uses values from SnackBarThemeData', (WidgetTester tester) async {
const String text = 'I am a snack bar.';
final SnackBarThemeData snackBarTheme = _snackBarTheme();
await tester.pumpWidget(MaterialApp(
......@@ -102,7 +109,7 @@ void main() {
return GestureDetector(
onTap: () {
Scaffold.of(context).showSnackBar(SnackBar(
content: const Text('I am a snack bar.'),
content: const Text(text),
duration: const Duration(seconds: 2),
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
));
......@@ -120,7 +127,9 @@ void main() {
final Material material = _getSnackBarMaterial(tester);
final RawMaterialButton button = _getSnackBarButton(tester);
final RenderParagraph content = _getSnackBarTextRenderObject(tester, text);
expect(content.text.style, snackBarTheme.contentTextStyle);
expect(material.color, snackBarTheme.backgroundColor);
expect(material.elevation, snackBarTheme.elevation);
expect(material.shape, snackBarTheme.shape);
......@@ -265,9 +274,10 @@ void main() {
SnackBarThemeData _snackBarTheme() {
return SnackBarThemeData(
backgroundColor: Colors.orange,
actionTextColor: Colors.green,
contentTextStyle: const TextStyle(color: Colors.blue),
elevation: 12.0,
shape: BeveledRectangleBorder(borderRadius: BorderRadius.circular(12)),
actionTextColor: Colors.green,
);
}
......@@ -288,3 +298,10 @@ RawMaterialButton _getSnackBarButton(WidgetTester tester) {
).first,
);
}
RenderParagraph _getSnackBarTextRenderObject(WidgetTester tester, String text) {
return tester.renderObject(find.descendant(
of: find.byType(SnackBar),
matching: find.text(text),
));
}
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