diff --git a/packages/flutter/lib/src/material/text_field.dart b/packages/flutter/lib/src/material/text_field.dart index 8293369de3e..ca5ce230549 100644 --- a/packages/flutter/lib/src/material/text_field.dart +++ b/packages/flutter/lib/src/material/text_field.dart @@ -575,7 +575,7 @@ class _TextFieldState extends State with AutomaticKeepAliveClientMixi ); final ThemeData themeData = Theme.of(context); - final TextStyle style = widget.style ?? themeData.textTheme.subhead; + final TextStyle style = themeData.textTheme.subhead.merge(widget.style); final Brightness keyboardAppearance = widget.keyboardAppearance ?? themeData.primaryColorBrightness; final TextEditingController controller = _effectiveController; final FocusNode focusNode = _effectiveFocusNode; diff --git a/packages/flutter/test/material/text_field_test.dart b/packages/flutter/test/material/text_field_test.dart index 75526ea66ef..64ff26242c1 100644 --- a/packages/flutter/test/material/text_field_test.dart +++ b/packages/flutter/test/material/text_field_test.dart @@ -3420,6 +3420,56 @@ void main() { expect(tapCount, 0); }); + testWidgets('TextField style is merged with theme', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/23994 + + final ThemeData themeData = ThemeData( + textTheme: TextTheme( + subhead: TextStyle( + color: Colors.blue[500], + ), + ), + ); + + Widget buildFrame(TextStyle style) { + return MaterialApp( + theme: themeData, + home: Material( + child: Center( + child: TextField( + style: style, + ), + ), + ), + ); + } + + // Empty TextStyle is overridden by theme + await tester.pumpWidget(buildFrame(const TextStyle())); + EditableText editableText = tester.widget(find.byType(EditableText)); + expect(editableText.style.color, themeData.textTheme.subhead.color); + expect(editableText.style.background, themeData.textTheme.subhead.background); + expect(editableText.style.shadows, themeData.textTheme.subhead.shadows); + expect(editableText.style.decoration, themeData.textTheme.subhead.decoration); + expect(editableText.style.locale, themeData.textTheme.subhead.locale); + expect(editableText.style.wordSpacing, themeData.textTheme.subhead.wordSpacing); + + // Properties set on TextStyle override theme + const Color setColor = Colors.red; + await tester.pumpWidget(buildFrame(const TextStyle(color: setColor))); + editableText = tester.widget(find.byType(EditableText)); + expect(editableText.style.color, setColor); + + // inherit: false causes nothing to be merged in from theme + await tester.pumpWidget(buildFrame(const TextStyle( + fontSize: 24.0, + textBaseline: TextBaseline.alphabetic, + inherit: false, + ))); + editableText = tester.widget(find.byType(EditableText)); + expect(editableText.style.color, isNull); + }); + testWidgets('style enforces required fields', (WidgetTester tester) async { Widget buildFrame(TextStyle style) { return MaterialApp(