From 322dd06d6e1149bf78d72963344a67682ee5f7bf Mon Sep 17 00:00:00 2001 From: Darren Austin Date: Tue, 29 Nov 2022 18:03:33 -0800 Subject: [PATCH] Updated the M3 textTheme to use `onSurface` color for all styles. (#116125) --- .../flutter/lib/src/material/theme_data.dart | 4 +- .../flutter/lib/src/material/typography.dart | 22 +++++++++- .../test/material/banner_theme_test.dart | 21 +++++----- .../flutter/test/material/list_tile_test.dart | 2 +- .../test/material/theme_data_test.dart | 6 +-- .../flutter/test/material/theme_test.dart | 3 +- .../test/material/typography_test.dart | 42 +++++++++++++++++++ 7 files changed, 83 insertions(+), 17 deletions(-) diff --git a/packages/flutter/lib/src/material/theme_data.dart b/packages/flutter/lib/src/material/theme_data.dart index 20a5ea78220..02da234fac0 100644 --- a/packages/flutter/lib/src/material/theme_data.dart +++ b/packages/flutter/lib/src/material/theme_data.dart @@ -565,7 +565,9 @@ class ThemeData with Diagnosticable { splashColor ??= isDark ? _kDarkThemeSplashColor : _kLightThemeSplashColor; // TYPOGRAPHY & ICONOGRAPHY - typography ??= useMaterial3 ? Typography.material2021(platform: platform) : Typography.material2014(platform: platform); + typography ??= useMaterial3 + ? Typography.material2021(platform: platform, colorScheme: colorScheme) + : Typography.material2014(platform: platform); TextTheme defaultTextTheme = isDark ? typography.white : typography.black; TextTheme defaultPrimaryTextTheme = primaryIsDark ? typography.white : typography.black; TextTheme defaultAccentTextTheme = accentIsDark ? typography.white : typography.black; diff --git a/packages/flutter/lib/src/material/typography.dart b/packages/flutter/lib/src/material/typography.dart index e15513e06ae..3d573451e6e 100644 --- a/packages/flutter/lib/src/material/typography.dart +++ b/packages/flutter/lib/src/material/typography.dart @@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/painting.dart'; +import 'color_scheme.dart'; import 'colors.dart'; import 'text_theme.dart'; @@ -166,6 +167,7 @@ class Typography with Diagnosticable { /// * factory Typography.material2021({ TargetPlatform? platform = TargetPlatform.android, + ColorScheme colorScheme = const ColorScheme.light(), TextTheme? black, TextTheme? white, TextTheme? englishLike, @@ -173,13 +175,31 @@ class Typography with Diagnosticable { TextTheme? tall, }) { assert(platform != null || (black != null && white != null)); - return Typography._withPlatform( + final Typography base = Typography._withPlatform( platform, black, white, englishLike ?? englishLike2021, dense ?? dense2021, tall ?? tall2021, ); + + // Ensure they are all uniformly dark or light, with + // no color variation based on style as it was in previous + // versions of Material Design. + final Color dark = colorScheme.brightness == Brightness.light ? colorScheme.onSurface : colorScheme.surface; + final Color light = colorScheme.brightness == Brightness.light ? colorScheme.surface : colorScheme.onSurface; + return base.copyWith( + black: base.black.apply( + displayColor: dark, + bodyColor: dark, + decorationColor: dark + ), + white: base.white.apply( + displayColor: light, + bodyColor: light, + decorationColor: light + ), + ); } factory Typography._withPlatform( diff --git a/packages/flutter/test/material/banner_theme_test.dart b/packages/flutter/test/material/banner_theme_test.dart index e419a86bd8d..0c12b929649 100644 --- a/packages/flutter/test/material/banner_theme_test.dart +++ b/packages/flutter/test/material/banner_theme_test.dart @@ -67,11 +67,16 @@ void main() { }); testWidgets('Passing no MaterialBannerThemeData returns defaults', (WidgetTester tester) async { - final ThemeData theme = ThemeData(useMaterial3: true); const String contentText = 'Content'; + final ThemeData theme = ThemeData(useMaterial3: true); + late final ThemeData localizedTheme; await tester.pumpWidget(MaterialApp( theme: theme, + builder:(BuildContext context, Widget? child) { + localizedTheme = Theme.of(context); + return child!; + }, home: Scaffold( body: MaterialBanner( content: const Text(contentText), @@ -93,12 +98,9 @@ void main() { expect(material.elevation, 0.0); final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText); - // Default value for ThemeData.typography is Typography.material2021() expect( content.text.style, - Typography.material2021().englishLike.bodyMedium!.merge( - Typography.material2021().black.bodyMedium, - ), + localizedTheme.textTheme.bodyMedium, ); final Offset rowTopLeft = tester.getTopLeft(find.byType(Row)); @@ -114,15 +116,17 @@ void main() { }); testWidgets('Passing no MaterialBannerThemeData returns defaults when presented by ScaffoldMessenger', (WidgetTester tester) async { - final ThemeData theme = ThemeData(useMaterial3: true); const String contentText = 'Content'; const Key tapTarget = Key('tap-target'); + final ThemeData theme = ThemeData(useMaterial3: true); + late final ThemeData localizedTheme; await tester.pumpWidget(MaterialApp( theme: theme, home: Scaffold( body: Builder( builder: (BuildContext context) { + localizedTheme = Theme.of(context); return GestureDetector( key: tapTarget, onTap: () { @@ -157,12 +161,9 @@ void main() { expect(material.elevation, 0.0); final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText); - // Default value for ThemeData.typography is Typography.material2021() expect( content.text.style, - Typography.material2021().englishLike.bodyMedium!.merge( - Typography.material2021().black.bodyMedium, - ), + localizedTheme.textTheme.bodyMedium, ); final Offset rowTopLeft = tester.getTopLeft(find.byType(Row)); diff --git a/packages/flutter/test/material/list_tile_test.dart b/packages/flutter/test/material/list_tile_test.dart index ec360171297..7cbba67314c 100644 --- a/packages/flutter/test/material/list_tile_test.dart +++ b/packages/flutter/test/material/list_tile_test.dart @@ -2230,7 +2230,7 @@ void main() { ); } - final ThemeData theme = ThemeData(); + final ThemeData theme = ThemeData(useMaterial3: true); // ListTile - ListTileStyle.list (default). await tester.pumpWidget(buildFrame()); diff --git a/packages/flutter/test/material/theme_data_test.dart b/packages/flutter/test/material/theme_data_test.dart index dd2407b23b6..88513bd4773 100644 --- a/packages/flutter/test/material/theme_data_test.dart +++ b/packages/flutter/test/material/theme_data_test.dart @@ -72,15 +72,15 @@ void main() { test('light, dark and fallback constructors support useMaterial3', () { final ThemeData lightTheme = ThemeData.light(useMaterial3: true); expect(lightTheme.useMaterial3, true); - expect(lightTheme.typography, Typography.material2021()); + expect(lightTheme.typography, Typography.material2021(colorScheme: lightTheme.colorScheme)); final ThemeData darkTheme = ThemeData.dark(useMaterial3: true); expect(darkTheme.useMaterial3, true); - expect(darkTheme.typography, Typography.material2021()); + expect(darkTheme.typography, Typography.material2021(colorScheme: darkTheme.colorScheme)); final ThemeData fallbackTheme = ThemeData.light(useMaterial3: true); expect(fallbackTheme.useMaterial3, true); - expect(fallbackTheme.typography, Typography.material2021()); + expect(fallbackTheme.typography, Typography.material2021(colorScheme: fallbackTheme.colorScheme)); }); testWidgets('Defaults to MaterialTapTargetBehavior.padded on mobile platforms and MaterialTapTargetBehavior.shrinkWrap on desktop', (WidgetTester tester) async { diff --git a/packages/flutter/test/material/theme_test.dart b/packages/flutter/test/material/theme_test.dart index 7f917f6fddb..02fb5893976 100644 --- a/packages/flutter/test/material/theme_test.dart +++ b/packages/flutter/test/material/theme_test.dart @@ -134,7 +134,8 @@ void main() { testWidgets('ThemeData with null typography uses proper defaults', (WidgetTester tester) async { expect(ThemeData().typography, Typography.material2014()); - expect(ThemeData(useMaterial3: true).typography, Typography.material2021()); + final ThemeData m3Theme = ThemeData(useMaterial3: true); + expect(m3Theme.typography, Typography.material2021(colorScheme: m3Theme.colorScheme)); }); testWidgets('PopupMenu inherits shadowed app theme', (WidgetTester tester) async { diff --git a/packages/flutter/test/material/typography_test.dart b/packages/flutter/test/material/typography_test.dart index 6071c3ffb10..562b4301f26 100644 --- a/packages/flutter/test/material/typography_test.dart +++ b/packages/flutter/test/material/typography_test.dart @@ -363,4 +363,46 @@ void main() { expect(theme.bodySmall!.textBaseline, TextBaseline.alphabetic); expect(theme.bodySmall!.leadingDistribution, TextLeadingDistribution.even); }); + + test('Default M3 light textTheme styles all use onSurface', () { + final ThemeData theme = ThemeData(useMaterial3: true); + final TextTheme textTheme = theme.textTheme; + final Color dark = theme.colorScheme.onSurface; + expect(textTheme.displayLarge!.color, dark); + expect(textTheme.displayMedium!.color, dark); + expect(textTheme.displaySmall!.color, dark); + expect(textTheme.headlineLarge!.color, dark); + expect(textTheme.headlineMedium!.color, dark); + expect(textTheme.headlineSmall!.color, dark); + expect(textTheme.titleLarge!.color, dark); + expect(textTheme.titleMedium!.color, dark); + expect(textTheme.titleSmall!.color, dark); + expect(textTheme.bodyLarge!.color, dark); + expect(textTheme.bodyMedium!.color, dark); + expect(textTheme.bodySmall!.color, dark); + expect(textTheme.labelLarge!.color, dark); + expect(textTheme.labelMedium!.color, dark); + expect(textTheme.labelSmall!.color, dark); + }); + + test('Default M3 dark textTheme styles all use onSurface', () { + final ThemeData theme = ThemeData(useMaterial3: true, brightness: Brightness.dark); + final TextTheme textTheme = theme.textTheme; + final Color light = theme.colorScheme.onSurface; + expect(textTheme.displayLarge!.color, light); + expect(textTheme.displayMedium!.color, light); + expect(textTheme.displaySmall!.color, light); + expect(textTheme.headlineLarge!.color, light); + expect(textTheme.headlineMedium!.color, light); + expect(textTheme.headlineSmall!.color, light); + expect(textTheme.titleLarge!.color, light); + expect(textTheme.titleMedium!.color, light); + expect(textTheme.titleSmall!.color, light); + expect(textTheme.bodyLarge!.color, light); + expect(textTheme.bodyMedium!.color, light); + expect(textTheme.bodySmall!.color, light); + expect(textTheme.labelLarge!.color, light); + expect(textTheme.labelMedium!.color, light); + expect(textTheme.labelSmall!.color, light); + }); }