From cc435d673eaf055d4e9549d846747b28091098e6 Mon Sep 17 00:00:00 2001 From: Qun Cheng <36861262+QuncCccccc@users.noreply.github.com> Date: Fri, 28 Oct 2022 10:30:59 -0700 Subject: [PATCH] Fix Color Scheme Defaults in Material 3 (#112666) --- dev/tools/gen_defaults/bin/gen_defaults.dart | 2 + .../lib/color_scheme_template.dart | 88 +++++++++++ .../flutter/lib/src/material/theme_data.dart | 96 ++++++++++- .../test/material/banner_theme_test.dart | 16 +- .../test/material/card_theme_test.dart | 9 +- .../flutter/test/material/checkbox_test.dart | 15 +- .../flutter/test/material/dialog_test.dart | 2 +- .../test/material/dialog_theme_test.dart | 2 +- .../test/material/divider_theme_test.dart | 8 +- .../test/material/navigation_rail_test.dart | 2 +- .../test/material/popup_menu_theme_test.dart | 2 +- .../test/material/theme_data_test.dart | 149 ++++++++++++++++++ 12 files changed, 359 insertions(+), 32 deletions(-) create mode 100644 dev/tools/gen_defaults/lib/color_scheme_template.dart diff --git a/dev/tools/gen_defaults/bin/gen_defaults.dart b/dev/tools/gen_defaults/bin/gen_defaults.dart index 0eba0f113d3..21b76bf6cb1 100644 --- a/dev/tools/gen_defaults/bin/gen_defaults.dart +++ b/dev/tools/gen_defaults/bin/gen_defaults.dart @@ -24,6 +24,7 @@ import 'package:gen_defaults/bottom_sheet_template.dart'; import 'package:gen_defaults/button_template.dart'; import 'package:gen_defaults/card_template.dart'; import 'package:gen_defaults/checkbox_template.dart'; +import 'package:gen_defaults/color_scheme_template.dart'; import 'package:gen_defaults/dialog_template.dart'; import 'package:gen_defaults/divider_template.dart'; import 'package:gen_defaults/fab_template.dart'; @@ -127,6 +128,7 @@ Future main(List args) async { ButtonTemplate('md.comp.text-button', 'TextButton', '$materialLib/text_button.dart', tokens).updateFile(); CardTemplate('Card', '$materialLib/card.dart', tokens).updateFile(); CheckboxTemplate('Checkbox', '$materialLib/checkbox.dart', tokens).updateFile(); + ColorSchemeTemplate('ColorScheme', '$materialLib/theme_data.dart', tokens).updateFile(); DialogFullscreenTemplate('DialogFullscreen', '$materialLib/dialog.dart', tokens).updateFile(); DialogTemplate('Dialog', '$materialLib/dialog.dart', tokens).updateFile(); DividerTemplate('Divider', '$materialLib/divider.dart', tokens).updateFile(); diff --git a/dev/tools/gen_defaults/lib/color_scheme_template.dart b/dev/tools/gen_defaults/lib/color_scheme_template.dart new file mode 100644 index 00000000000..1e5ccd94a4c --- /dev/null +++ b/dev/tools/gen_defaults/lib/color_scheme_template.dart @@ -0,0 +1,88 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'template.dart'; + +class ColorSchemeTemplate extends TokenTemplate { + ColorSchemeTemplate(super.blockName, super.fileName, super.tokens); + + // Map of light color scheme token data from tokens. + late Map colorTokensLight = tokens['colorsLight'] as Map; + + // Map of dark color scheme token data from tokens. + late Map colorTokensDark = tokens['colorsDark'] as Map; + + @override + String generate() => ''' +const ColorScheme _colorSchemeLightM3 = ColorScheme( + brightness: Brightness.light, + primary: Color(${tokens[colorTokensLight['md.sys.color.primary']]}), + onPrimary: Color(${tokens[colorTokensLight['md.sys.color.on-primary']]}), + primaryContainer: Color(${tokens[colorTokensLight['md.sys.color.primary-container']]}), + onPrimaryContainer: Color(${tokens[colorTokensLight['md.sys.color.on-primary-container']]}), + secondary: Color(${tokens[colorTokensLight['md.sys.color.secondary']]}), + onSecondary: Color(${tokens[colorTokensLight['md.sys.color.on-secondary']]}), + secondaryContainer: Color(${tokens[colorTokensLight['md.sys.color.secondary-container']]}), + onSecondaryContainer: Color(${tokens[colorTokensLight['md.sys.color.on-secondary-container']]}), + tertiary: Color(${tokens[colorTokensLight['md.sys.color.tertiary']]}), + onTertiary: Color(${tokens[colorTokensLight['md.sys.color.on-tertiary']]}), + tertiaryContainer: Color(${tokens[colorTokensLight['md.sys.color.tertiary-container']]}), + onTertiaryContainer: Color(${tokens[colorTokensLight['md.sys.color.on-tertiary-container']]}), + error: Color(${tokens[colorTokensLight['md.sys.color.error']]}), + onError: Color(${tokens[colorTokensLight['md.sys.color.on-error']]}), + errorContainer: Color(${tokens[colorTokensLight['md.sys.color.error-container']]}), + onErrorContainer: Color(${tokens[colorTokensLight['md.sys.color.on-error-container']]}), + background: Color(${tokens[colorTokensLight['md.sys.color.background']]}), + onBackground: Color(${tokens[colorTokensLight['md.sys.color.on-background']]}), + surface: Color(${tokens[colorTokensLight['md.sys.color.surface']]}), + onSurface: Color(${tokens[colorTokensLight['md.sys.color.on-surface']]}), + surfaceVariant: Color(${tokens[colorTokensLight['md.sys.color.surface-variant']]}), + onSurfaceVariant: Color(${tokens[colorTokensLight['md.sys.color.on-surface-variant']]}), + outline: Color(${tokens[colorTokensLight['md.sys.color.outline']]}), + outlineVariant: Color(${tokens[colorTokensLight['md.sys.color.outline-variant']]}), + shadow: Color(${tokens[colorTokensLight['md.sys.color.shadow']]}), + scrim: Color(${tokens[colorTokensLight['md.sys.color.scrim']]}), + inverseSurface: Color(${tokens[colorTokensLight['md.sys.color.inverse-surface']]}), + onInverseSurface: Color(${tokens[colorTokensLight['md.sys.color.inverse-on-surface']]}), + inversePrimary: Color(${tokens[colorTokensLight['md.sys.color.inverse-primary']]}), + // The surfaceTint color is set to the same color as the primary. + surfaceTint: Color(${tokens[colorTokensLight['md.sys.color.primary']]}), +); + +const ColorScheme _colorSchemeDarkM3 = ColorScheme( + brightness: Brightness.dark, + primary: Color(${tokens[colorTokensDark['md.sys.color.primary']]}), + onPrimary: Color(${tokens[colorTokensDark['md.sys.color.on-primary']]}), + primaryContainer: Color(${tokens[colorTokensDark['md.sys.color.primary-container']]}), + onPrimaryContainer: Color(${tokens[colorTokensDark['md.sys.color.on-primary-container']]}), + secondary: Color(${tokens[colorTokensDark['md.sys.color.secondary']]}), + onSecondary: Color(${tokens[colorTokensDark['md.sys.color.on-secondary']]}), + secondaryContainer: Color(${tokens[colorTokensDark['md.sys.color.secondary-container']]}), + onSecondaryContainer: Color(${tokens[colorTokensDark['md.sys.color.on-secondary-container']]}), + tertiary: Color(${tokens[colorTokensDark['md.sys.color.tertiary']]}), + onTertiary: Color(${tokens[colorTokensDark['md.sys.color.on-tertiary']]}), + tertiaryContainer: Color(${tokens[colorTokensDark['md.sys.color.tertiary-container']]}), + onTertiaryContainer: Color(${tokens[colorTokensDark['md.sys.color.on-tertiary-container']]}), + error: Color(${tokens[colorTokensDark['md.sys.color.error']]}), + onError: Color(${tokens[colorTokensDark['md.sys.color.on-error']]}), + errorContainer: Color(${tokens[colorTokensDark['md.sys.color.error-container']]}), + onErrorContainer: Color(${tokens[colorTokensDark['md.sys.color.on-error-container']]}), + background: Color(${tokens[colorTokensDark['md.sys.color.background']]}), + onBackground: Color(${tokens[colorTokensDark['md.sys.color.on-background']]}), + surface: Color(${tokens[colorTokensDark['md.sys.color.surface']]}), + onSurface: Color(${tokens[colorTokensDark['md.sys.color.on-surface']]}), + surfaceVariant: Color(${tokens[colorTokensDark['md.sys.color.surface-variant']]}), + onSurfaceVariant: Color(${tokens[colorTokensDark['md.sys.color.on-surface-variant']]}), + outline: Color(${tokens[colorTokensDark['md.sys.color.outline']]}), + outlineVariant: Color(${tokens[colorTokensDark['md.sys.color.outline-variant']]}), + shadow: Color(${tokens[colorTokensDark['md.sys.color.shadow']]}), + scrim: Color(${tokens[colorTokensDark['md.sys.color.scrim']]}), + inverseSurface: Color(${tokens[colorTokensDark['md.sys.color.inverse-surface']]}), + onInverseSurface: Color(${tokens[colorTokensDark['md.sys.color.inverse-on-surface']]}), + inversePrimary: Color(${tokens[colorTokensDark['md.sys.color.inverse-primary']]}), + // The surfaceTint color is set to the same color as the primary. + surfaceTint: Color(${tokens[colorTokensDark['md.sys.color.primary']]}), +); +'''; +} diff --git a/packages/flutter/lib/src/material/theme_data.dart b/packages/flutter/lib/src/material/theme_data.dart index cb7b837a7fd..cde51645d61 100644 --- a/packages/flutter/lib/src/material/theme_data.dart +++ b/packages/flutter/lib/src/material/theme_data.dart @@ -478,15 +478,18 @@ class ThemeData with Diagnosticable { assert(colorSchemeSeed == null || primaryColor == null); final Brightness effectiveBrightness = brightness ?? colorScheme?.brightness ?? Brightness.light; final bool isDark = effectiveBrightness == Brightness.dark; - if (colorSchemeSeed != null) { - colorScheme = ColorScheme.fromSeed(seedColor: colorSchemeSeed, brightness: effectiveBrightness); + if (colorSchemeSeed != null || useMaterial3) { + if (colorSchemeSeed != null) { + colorScheme = ColorScheme.fromSeed(seedColor: colorSchemeSeed, brightness: effectiveBrightness); + } + colorScheme ??= isDark ? _colorSchemeDarkM3 : _colorSchemeLightM3; // For surfaces that use primary color in light themes and surface color in dark final Color primarySurfaceColor = isDark ? colorScheme.surface : colorScheme.primary; final Color onPrimarySurfaceColor = isDark ? colorScheme.onSurface : colorScheme.onPrimary; // Default some of the color settings to values from the color scheme - primaryColor = primarySurfaceColor; + primaryColor ??= primarySurfaceColor; primaryColorBrightness = ThemeData.estimateBrightnessForColor(primarySurfaceColor); canvasColor ??= colorScheme.background; accentColor ??= colorScheme.secondary; @@ -1243,8 +1246,10 @@ class ThemeData with Diagnosticable { /// A temporary flag used to opt-in to Material 3 features. /// /// If true, then widgets that have been migrated to Material 3 will - /// use new colors, typography and other features of Material 3. - /// If false, they will use the Material 2 look and feel. + /// use new colors, typography and other features of Material 3. A new + /// purple-based [ColorScheme] will be created and applied to the updated + /// widgets, as long as this is set to true. If false, they will use the + /// Material 2 look and feel. /// /// During the migration to Material 3, turning this on may yield /// inconsistent look and feel in your app as some widgets are migrated @@ -2950,3 +2955,84 @@ class VisualDensity with Diagnosticable { return '${super.toStringShort()}(h: ${debugFormatDouble(horizontal)}, v: ${debugFormatDouble(vertical)})'; } } + +// BEGIN GENERATED TOKEN PROPERTIES - ColorScheme + +// Do not edit by hand. The code between the "BEGIN GENERATED" and +// "END GENERATED" comments are generated from data in the Material +// Design token database by the script: +// dev/tools/gen_defaults/bin/gen_defaults.dart. + +// Token database version: v0_132 + +const ColorScheme _colorSchemeLightM3 = ColorScheme( + brightness: Brightness.light, + primary: Color(0xFF6750A4), + onPrimary: Color(0xFFFFFFFF), + primaryContainer: Color(0xFFEADDFF), + onPrimaryContainer: Color(0xFF21005D), + secondary: Color(0xFF625B71), + onSecondary: Color(0xFFFFFFFF), + secondaryContainer: Color(0xFFE8DEF8), + onSecondaryContainer: Color(0xFF1D192B), + tertiary: Color(0xFF7D5260), + onTertiary: Color(0xFFFFFFFF), + tertiaryContainer: Color(0xFFFFD8E4), + onTertiaryContainer: Color(0xFF31111D), + error: Color(0xFFB3261E), + onError: Color(0xFFFFFFFF), + errorContainer: Color(0xFFF9DEDC), + onErrorContainer: Color(0xFF410E0B), + background: Color(0xFFFFFBFE), + onBackground: Color(0xFF1C1B1F), + surface: Color(0xFFFFFBFE), + onSurface: Color(0xFF1C1B1F), + surfaceVariant: Color(0xFFE7E0EC), + onSurfaceVariant: Color(0xFF49454F), + outline: Color(0xFF79747E), + outlineVariant: Color(0xFFCAC4D0), + shadow: Color(0xFF000000), + scrim: Color(0xFF000000), + inverseSurface: Color(0xFF313033), + onInverseSurface: Color(0xFFF4EFF4), + inversePrimary: Color(0xFFD0BCFF), + // The surfaceTint color is set to the same color as the primary. + surfaceTint: Color(0xFF6750A4), +); + +const ColorScheme _colorSchemeDarkM3 = ColorScheme( + brightness: Brightness.dark, + primary: Color(0xFFD0BCFF), + onPrimary: Color(0xFF381E72), + primaryContainer: Color(0xFF4F378B), + onPrimaryContainer: Color(0xFFEADDFF), + secondary: Color(0xFFCCC2DC), + onSecondary: Color(0xFF332D41), + secondaryContainer: Color(0xFF4A4458), + onSecondaryContainer: Color(0xFFE8DEF8), + tertiary: Color(0xFFEFB8C8), + onTertiary: Color(0xFF492532), + tertiaryContainer: Color(0xFF633B48), + onTertiaryContainer: Color(0xFFFFD8E4), + error: Color(0xFFF2B8B5), + onError: Color(0xFF601410), + errorContainer: Color(0xFF8C1D18), + onErrorContainer: Color(0xFFF9DEDC), + background: Color(0xFF1C1B1F), + onBackground: Color(0xFFE6E1E5), + surface: Color(0xFF1C1B1F), + onSurface: Color(0xFFE6E1E5), + surfaceVariant: Color(0xFF49454F), + onSurfaceVariant: Color(0xFFCAC4D0), + outline: Color(0xFF938F99), + outlineVariant: Color(0xFF49454F), + shadow: Color(0xFF000000), + scrim: Color(0xFF000000), + inverseSurface: Color(0xFFE6E1E5), + onInverseSurface: Color(0xFF313033), + inversePrimary: Color(0xFF6750A4), + // The surfaceTint color is set to the same color as the primary. + surfaceTint: Color(0xFFD0BCFF), +); + +// END GENERATED TOKEN PROPERTIES - ColorScheme diff --git a/packages/flutter/test/material/banner_theme_test.dart b/packages/flutter/test/material/banner_theme_test.dart index 0cf5654c1a3..e419a86bd8d 100644 --- a/packages/flutter/test/material/banner_theme_test.dart +++ b/packages/flutter/test/material/banner_theme_test.dart @@ -67,11 +67,11 @@ void main() { }); testWidgets('Passing no MaterialBannerThemeData returns defaults', (WidgetTester tester) async { - final ThemeData theme = ThemeData(); + final ThemeData theme = ThemeData(useMaterial3: true); const String contentText = 'Content'; await tester.pumpWidget(MaterialApp( - theme: ThemeData(useMaterial3: true), + theme: theme, home: Scaffold( body: MaterialBanner( content: const Text(contentText), @@ -87,7 +87,7 @@ void main() { )); final Material material = _getMaterialFromText(tester, contentText); - expect(material.color, const Color(0xffffffff)); + expect(material.color, theme.colorScheme.surface); expect(material.surfaceTintColor, theme.colorScheme.surfaceTint); expect(material.shadowColor, null); expect(material.elevation, 0.0); @@ -110,16 +110,16 @@ void main() { expect(leadingTopLeft.dx - materialTopLeft.dx, 16); // Default leading padding. final Divider divider = tester.widget(find.byType(Divider)); - expect(divider.color, theme.colorScheme.surfaceVariant); + expect(divider.color, theme.colorScheme.outlineVariant); }); testWidgets('Passing no MaterialBannerThemeData returns defaults when presented by ScaffoldMessenger', (WidgetTester tester) async { - final ThemeData theme = ThemeData(); + final ThemeData theme = ThemeData(useMaterial3: true); const String contentText = 'Content'; const Key tapTarget = Key('tap-target'); await tester.pumpWidget(MaterialApp( - theme: ThemeData(useMaterial3: true), + theme: theme, home: Scaffold( body: Builder( builder: (BuildContext context) { @@ -151,7 +151,7 @@ void main() { await tester.pumpAndSettle(); final Material material = _getMaterialFromText(tester, contentText); - expect(material.color, const Color(0xffffffff)); + expect(material.color, theme.colorScheme.surface); expect(material.surfaceTintColor, theme.colorScheme.surfaceTint); expect(material.shadowColor, null); expect(material.elevation, 0.0); @@ -174,7 +174,7 @@ void main() { expect(leadingTopLeft.dx - materialTopLeft.dx, 16); // Default leading padding. final Divider divider = tester.widget(find.byType(Divider)); - expect(divider.color, theme.colorScheme.surfaceVariant); + expect(divider.color, theme.colorScheme.outlineVariant); }); testWidgets('MaterialBanner uses values from MaterialBannerThemeData', (WidgetTester tester) async { diff --git a/packages/flutter/test/material/card_theme_test.dart b/packages/flutter/test/material/card_theme_test.dart index 4103884d17d..11db02fa452 100644 --- a/packages/flutter/test/material/card_theme_test.dart +++ b/packages/flutter/test/material/card_theme_test.dart @@ -16,8 +16,9 @@ void main() { }); testWidgets('Passing no CardTheme returns defaults', (WidgetTester tester) async { + final ThemeData theme = ThemeData(useMaterial3: true); await tester.pumpWidget(MaterialApp( - theme: ThemeData(useMaterial3: true), + theme: theme, home: const Scaffold( body: Card(), ), @@ -27,9 +28,9 @@ void main() { final Material material = _getCardMaterial(tester); expect(material.clipBehavior, Clip.none); - expect(material.color, Colors.white); - expect(material.shadowColor, Colors.black); - expect(material.surfaceTintColor, Colors.blue); // Default primary color + expect(material.color, theme.colorScheme.surface); + expect(material.shadowColor, theme.colorScheme.shadow); + expect(material.surfaceTintColor, theme.colorScheme.surfaceTint); // Default primary color expect(material.elevation, 1.0); expect(container.margin, const EdgeInsets.all(4.0)); expect(material.shape, const RoundedRectangleBorder( diff --git a/packages/flutter/test/material/checkbox_test.dart b/packages/flutter/test/material/checkbox_test.dart index 9ca7cc3634f..ec589841fce 100644 --- a/packages/flutter/test/material/checkbox_test.dart +++ b/packages/flutter/test/material/checkbox_test.dart @@ -1587,11 +1587,12 @@ void main() { testWidgets('Checkbox has default error color when isError is set to true - M3', (WidgetTester tester) async { final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox'); + final ThemeData themeData = ThemeData(useMaterial3: true); tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; bool? value = true; Widget buildApp({bool autoFocus = true}) { return MaterialApp( - theme: ThemeData(useMaterial3: true), + theme: themeData, home: Material( child: Center( child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) { @@ -1617,7 +1618,7 @@ void main() { expect(focusNode.hasPrimaryFocus, isTrue); expect( Material.of(tester.element(find.byType(Checkbox))), - paints..circle(color: theme.colorScheme.error.withOpacity(0.12))..path(color: theme.colorScheme.error)..path(color: theme.colorScheme.onError) + paints..circle(color: themeData.colorScheme.error.withOpacity(0.12))..path(color: themeData.colorScheme.error)..path(color: themeData.colorScheme.onError) ); // Default color @@ -1627,7 +1628,7 @@ void main() { expect(focusNode.hasPrimaryFocus, isFalse); expect( Material.of(tester.element(find.byType(Checkbox))), - paints..path(color: theme.colorScheme.error)..path(color: theme.colorScheme.onError) + paints..path(color: themeData.colorScheme.error)..path(color: themeData.colorScheme.onError) ); // Start hovering @@ -1639,8 +1640,8 @@ void main() { expect( Material.of(tester.element(find.byType(Checkbox))), paints - ..circle(color: theme.colorScheme.error.withOpacity(0.08)) - ..path(color: theme.colorScheme.error) + ..circle(color: themeData.colorScheme.error.withOpacity(0.08)) + ..path(color: themeData.colorScheme.error) ); // Start pressing @@ -1649,8 +1650,8 @@ void main() { expect( Material.of(tester.element(find.byType(Checkbox))), paints - ..circle(color: theme.colorScheme.error.withOpacity(0.12)) - ..path(color: theme.colorScheme.error) + ..circle(color: themeData.colorScheme.error.withOpacity(0.12)) + ..path(color: themeData.colorScheme.error) ); await gestureLongPress.up(); await tester.pump(); diff --git a/packages/flutter/test/material/dialog_test.dart b/packages/flutter/test/material/dialog_test.dart index 091f64e6231..17e7855f378 100644 --- a/packages/flutter/test/material/dialog_test.dart +++ b/packages/flutter/test/material/dialog_test.dart @@ -134,7 +134,7 @@ void main() { await tester.pumpAndSettle(); final Material material3Widget = _getMaterialFromDialog(tester); - expect(material3Widget.color, const Color(0xff424242)); + expect(material3Widget.color, material3Theme.colorScheme.surface); expect(material3Widget.shape, _defaultM3DialogShape); expect(material3Widget.elevation, 6.0); }); diff --git a/packages/flutter/test/material/dialog_theme_test.dart b/packages/flutter/test/material/dialog_theme_test.dart index a7a3c7d1f06..f08917f73d0 100644 --- a/packages/flutter/test/material/dialog_theme_test.dart +++ b/packages/flutter/test/material/dialog_theme_test.dart @@ -269,7 +269,7 @@ void main() { // first is Text('X') final RichText text = tester.widget(find.byType(RichText).last); - expect(text.text.style!.color, ThemeData().colorScheme.secondary); + expect(text.text.style!.color, theme.colorScheme.secondary); }); testWidgets('Custom Title Text Style - Constructor Param', (WidgetTester tester) async { diff --git a/packages/flutter/test/material/divider_theme_test.dart b/packages/flutter/test/material/divider_theme_test.dart index 29bfd810318..5f18f3b655b 100644 --- a/packages/flutter/test/material/divider_theme_test.dart +++ b/packages/flutter/test/material/divider_theme_test.dart @@ -59,8 +59,9 @@ void main() { group('Horizontal Divider', () { testWidgets('Passing no DividerThemeData returns defaults', (WidgetTester tester) async { + final ThemeData theme = ThemeData(useMaterial3: true); await tester.pumpWidget(MaterialApp( - theme: ThemeData(useMaterial3: true), + theme: theme, home: const Scaffold( body: Divider(), ), @@ -73,7 +74,6 @@ void main() { final BoxDecoration decoration = container.decoration! as BoxDecoration; expect(decoration.border!.bottom.width, 1.0); - final ThemeData theme = ThemeData(); expect(decoration.border!.bottom.color, theme.colorScheme.outlineVariant); final Rect dividerRect = tester.getRect(find.byType(Divider)); @@ -161,8 +161,9 @@ void main() { group('Vertical Divider', () { testWidgets('Passing no DividerThemeData returns defaults', (WidgetTester tester) async { + final ThemeData theme = ThemeData(useMaterial3: true); await tester.pumpWidget(MaterialApp( - theme: ThemeData(useMaterial3: true), + theme: theme, home: const Scaffold( body: VerticalDivider(), ), @@ -176,7 +177,6 @@ void main() { final Border border = decoration.border! as Border; expect(border.left.width, 1.0); - final ThemeData theme = ThemeData(); expect(border.left.color, theme.colorScheme.outlineVariant); final Rect dividerRect = tester.getRect(find.byType(VerticalDivider)); diff --git a/packages/flutter/test/material/navigation_rail_test.dart b/packages/flutter/test/material/navigation_rail_test.dart index a0b567f1da8..53207a40060 100644 --- a/packages/flutter/test/material/navigation_rail_test.dart +++ b/packages/flutter/test/material/navigation_rail_test.dart @@ -78,7 +78,7 @@ void main() { ), ); - expect(_railMaterial(tester).color, equals(Colors.white)); + expect(_railMaterial(tester).color, equals(const Color(0xFFFFFBFE))); // default surface color in M3 colorScheme await _pumpNavigationRail( tester, diff --git a/packages/flutter/test/material/popup_menu_theme_test.dart b/packages/flutter/test/material/popup_menu_theme_test.dart index f8f64e8adc2..77587936312 100644 --- a/packages/flutter/test/material/popup_menu_theme_test.dart +++ b/packages/flutter/test/material/popup_menu_theme_test.dart @@ -180,7 +180,7 @@ void main() { ).last, ); expect(enabledText.style.fontFamily, 'Roboto'); - expect(enabledText.style.color, const Color(0xff000000)); + expect(enabledText.style.color, theme.colorScheme.onSurface); /// Test disabled text color final DefaultTextStyle disabledText = tester.widget( find.descendant( diff --git a/packages/flutter/test/material/theme_data_test.dart b/packages/flutter/test/material/theme_data_test.dart index e0e4a71d5a4..01fb19472eb 100644 --- a/packages/flutter/test/material/theme_data_test.dart +++ b/packages/flutter/test/material/theme_data_test.dart @@ -251,6 +251,155 @@ void main() { expect(theme.applyElevationOverlayColor, true); }); + test('ThemeData can generate a default M3 light colorScheme when useMaterial3 is true', () { + final ThemeData theme = ThemeData(useMaterial3: true); + + expect(theme.colorScheme.primary, const Color(0xFF6750A4)); + expect(theme.colorScheme.onPrimary, const Color(0xFFFFFFFF)); + expect(theme.colorScheme.primaryContainer, const Color(0xFFEADDFF)); + expect(theme.colorScheme.onPrimaryContainer, const Color(0xFF21005D)); + expect(theme.colorScheme.secondary, const Color(0xFF625B71)); + expect(theme.colorScheme.onSecondary, const Color(0xFFFFFFFF)); + expect(theme.colorScheme.secondaryContainer, const Color(0xFFE8DEF8)); + expect(theme.colorScheme.onSecondaryContainer, const Color(0xFF1D192B)); + expect(theme.colorScheme.tertiary, const Color(0xFF7D5260)); + expect(theme.colorScheme.onTertiary, const Color(0xFFFFFFFF)); + expect(theme.colorScheme.tertiaryContainer, const Color(0xFFFFD8E4)); + expect(theme.colorScheme.onTertiaryContainer, const Color(0xFF31111D)); + expect(theme.colorScheme.error, const Color(0xFFB3261E)); + expect(theme.colorScheme.onError, const Color(0xFFFFFFFF)); + expect(theme.colorScheme.errorContainer, const Color(0xFFF9DEDC)); + expect(theme.colorScheme.onErrorContainer, const Color(0xFF410E0B)); + expect(theme.colorScheme.outline, const Color(0xFF79747E)); + expect(theme.colorScheme.background, const Color(0xFFFFFBFE)); + expect(theme.colorScheme.onBackground, const Color(0xFF1C1B1F)); + expect(theme.colorScheme.surface, const Color(0xFFFFFBFE)); + expect(theme.colorScheme.onSurface, const Color(0xFF1C1B1F)); + expect(theme.colorScheme.surfaceVariant, const Color(0xFFE7E0EC)); + expect(theme.colorScheme.onSurfaceVariant, const Color(0xFF49454F)); + expect(theme.colorScheme.inverseSurface, const Color(0xFF313033)); + expect(theme.colorScheme.onInverseSurface, const Color(0xFFF4EFF4)); + expect(theme.colorScheme.inversePrimary, const Color(0xFFD0BCFF)); + expect(theme.colorScheme.shadow, const Color(0xFF000000)); + expect(theme.colorScheme.surfaceTint, const Color(0xFF6750A4)); + expect(theme.colorScheme.brightness, Brightness.light); + + expect(theme.primaryColor, theme.colorScheme.primary); + expect(theme.primaryColorBrightness, Brightness.dark); + expect(theme.canvasColor, theme.colorScheme.background); + expect(theme.accentColor, theme.colorScheme.secondary); + expect(theme.accentColorBrightness, Brightness.dark); + expect(theme.scaffoldBackgroundColor, theme.colorScheme.background); + expect(theme.bottomAppBarColor, theme.colorScheme.surface); + expect(theme.cardColor, theme.colorScheme.surface); + expect(theme.dividerColor, theme.colorScheme.outline); + expect(theme.backgroundColor, theme.colorScheme.background); + expect(theme.dialogBackgroundColor, theme.colorScheme.background); + expect(theme.indicatorColor, theme.colorScheme.onPrimary); + expect(theme.errorColor, theme.colorScheme.error); + expect(theme.applyElevationOverlayColor, false); + }); + + + test('ThemeData.light() can generate a default M3 light colorScheme when useMaterial3 is true', () { + final ThemeData theme = ThemeData.light(useMaterial3: true); + + expect(theme.colorScheme.primary, const Color(0xFF6750A4)); + expect(theme.colorScheme.onPrimary, const Color(0xFFFFFFFF)); + expect(theme.colorScheme.primaryContainer, const Color(0xFFEADDFF)); + expect(theme.colorScheme.onPrimaryContainer, const Color(0xFF21005D)); + expect(theme.colorScheme.secondary, const Color(0xFF625B71)); + expect(theme.colorScheme.onSecondary, const Color(0xFFFFFFFF)); + expect(theme.colorScheme.secondaryContainer, const Color(0xFFE8DEF8)); + expect(theme.colorScheme.onSecondaryContainer, const Color(0xFF1D192B)); + expect(theme.colorScheme.tertiary, const Color(0xFF7D5260)); + expect(theme.colorScheme.onTertiary, const Color(0xFFFFFFFF)); + expect(theme.colorScheme.tertiaryContainer, const Color(0xFFFFD8E4)); + expect(theme.colorScheme.onTertiaryContainer, const Color(0xFF31111D)); + expect(theme.colorScheme.error, const Color(0xFFB3261E)); + expect(theme.colorScheme.onError, const Color(0xFFFFFFFF)); + expect(theme.colorScheme.errorContainer, const Color(0xFFF9DEDC)); + expect(theme.colorScheme.onErrorContainer, const Color(0xFF410E0B)); + expect(theme.colorScheme.outline, const Color(0xFF79747E)); + expect(theme.colorScheme.background, const Color(0xFFFFFBFE)); + expect(theme.colorScheme.onBackground, const Color(0xFF1C1B1F)); + expect(theme.colorScheme.surface, const Color(0xFFFFFBFE)); + expect(theme.colorScheme.onSurface, const Color(0xFF1C1B1F)); + expect(theme.colorScheme.surfaceVariant, const Color(0xFFE7E0EC)); + expect(theme.colorScheme.onSurfaceVariant, const Color(0xFF49454F)); + expect(theme.colorScheme.inverseSurface, const Color(0xFF313033)); + expect(theme.colorScheme.onInverseSurface, const Color(0xFFF4EFF4)); + expect(theme.colorScheme.inversePrimary, const Color(0xFFD0BCFF)); + expect(theme.colorScheme.shadow, const Color(0xFF000000)); + expect(theme.colorScheme.surfaceTint, const Color(0xFF6750A4)); + expect(theme.colorScheme.brightness, Brightness.light); + + expect(theme.primaryColor, theme.colorScheme.primary); + expect(theme.primaryColorBrightness, Brightness.dark); + expect(theme.canvasColor, theme.colorScheme.background); + expect(theme.accentColor, theme.colorScheme.secondary); + expect(theme.accentColorBrightness, Brightness.dark); + expect(theme.scaffoldBackgroundColor, theme.colorScheme.background); + expect(theme.bottomAppBarColor, theme.colorScheme.surface); + expect(theme.cardColor, theme.colorScheme.surface); + expect(theme.dividerColor, theme.colorScheme.outline); + expect(theme.backgroundColor, theme.colorScheme.background); + expect(theme.dialogBackgroundColor, theme.colorScheme.background); + expect(theme.indicatorColor, theme.colorScheme.onPrimary); + expect(theme.errorColor, theme.colorScheme.error); + expect(theme.applyElevationOverlayColor, false); + }); + + + test('ThemeData.dark() can generate a default M3 dark colorScheme when useMaterial3 is true', () { + final ThemeData theme = ThemeData.dark(useMaterial3: true); + + expect(theme.colorScheme.primary, const Color(0xFFD0BCFF)); + expect(theme.colorScheme.onPrimary, const Color(0xFF381E72)); + expect(theme.colorScheme.primaryContainer, const Color(0xFF4F378B)); + expect(theme.colorScheme.onPrimaryContainer, const Color(0xFFEADDFF)); + expect(theme.colorScheme.secondary, const Color(0xFFCCC2DC)); + expect(theme.colorScheme.onSecondary, const Color(0xFF332D41)); + expect(theme.colorScheme.secondaryContainer, const Color(0xFF4A4458)); + expect(theme.colorScheme.onSecondaryContainer, const Color(0xFFE8DEF8)); + expect(theme.colorScheme.tertiary, const Color(0xFFEFB8C8)); + expect(theme.colorScheme.onTertiary, const Color(0xFF492532)); + expect(theme.colorScheme.tertiaryContainer, const Color(0xFF633B48)); + expect(theme.colorScheme.onTertiaryContainer, const Color(0xFFFFD8E4)); + expect(theme.colorScheme.error, const Color(0xFFF2B8B5)); + expect(theme.colorScheme.onError, const Color(0xFF601410)); + expect(theme.colorScheme.errorContainer, const Color(0xFF8C1D18)); + expect(theme.colorScheme.onErrorContainer, const Color(0xFFF9DEDC)); + expect(theme.colorScheme.outline, const Color(0xFF938F99)); + expect(theme.colorScheme.background, const Color(0xFF1C1B1F)); + expect(theme.colorScheme.onBackground, const Color(0xFFE6E1E5)); + expect(theme.colorScheme.surface, const Color(0xFF1C1B1F)); + expect(theme.colorScheme.onSurface, const Color(0xFFE6E1E5)); + expect(theme.colorScheme.surfaceVariant, const Color(0xFF49454F)); + expect(theme.colorScheme.onSurfaceVariant, const Color(0xFFCAC4D0)); + expect(theme.colorScheme.inverseSurface, const Color(0xFFE6E1E5)); + expect(theme.colorScheme.onInverseSurface, const Color(0xFF313033)); + expect(theme.colorScheme.inversePrimary, const Color(0xFF6750A4)); + expect(theme.colorScheme.shadow, const Color(0xFF000000)); + expect(theme.colorScheme.surfaceTint, const Color(0xFFD0BCFF)); + expect(theme.colorScheme.brightness, Brightness.dark); + + expect(theme.primaryColor, theme.colorScheme.surface); + expect(theme.primaryColorBrightness, Brightness.dark); + expect(theme.canvasColor, theme.colorScheme.background); + expect(theme.accentColor, theme.colorScheme.secondary); + expect(theme.accentColorBrightness, Brightness.light); + expect(theme.scaffoldBackgroundColor, theme.colorScheme.background); + expect(theme.bottomAppBarColor, theme.colorScheme.surface); + expect(theme.cardColor, theme.colorScheme.surface); + expect(theme.dividerColor, theme.colorScheme.outline); + expect(theme.backgroundColor, theme.colorScheme.background); + expect(theme.dialogBackgroundColor, theme.colorScheme.background); + expect(theme.indicatorColor, theme.colorScheme.onSurface); + expect(theme.errorColor, theme.colorScheme.error); + expect(theme.applyElevationOverlayColor, true); + }); + testWidgets('ThemeData.from a light color scheme sets appropriate values', (WidgetTester tester) async { const ColorScheme lightColors = ColorScheme.light(); final ThemeData theme = ThemeData.from(colorScheme: lightColors);