Unverified Commit 4c8fc781 authored by Darren Austin's avatar Darren Austin Committed by GitHub

Added ThemeData.from() method to construct a Theme from a ColorScheme (#37355)

Provide a new ThemeData.from() method that constructs a Theme based off the colors in a given ColorScheme.
parent 7c25328b
...@@ -221,7 +221,7 @@ class ThemeData extends Diagnosticable { ...@@ -221,7 +221,7 @@ class ThemeData extends Diagnosticable {
backgroundColor ??= isDark ? Colors.grey[700] : primarySwatch[200]; backgroundColor ??= isDark ? Colors.grey[700] : primarySwatch[200];
dialogBackgroundColor ??= isDark ? Colors.grey[800] : Colors.white; dialogBackgroundColor ??= isDark ? Colors.grey[800] : Colors.white;
indicatorColor ??= accentColor == primaryColor ? Colors.white : accentColor; indicatorColor ??= accentColor == primaryColor ? Colors.white : accentColor;
hintColor ??= isDark ? const Color(0x80FFFFFF) : const Color(0x8A000000); hintColor ??= isDark ? const Color(0x80FFFFFF) : const Color(0x8A000000);
errorColor ??= Colors.red[700]; errorColor ??= Colors.red[700];
inputDecorationTheme ??= const InputDecorationTheme(); inputDecorationTheme ??= const InputDecorationTheme();
pageTransitionsTheme ??= const PageTransitionsTheme(); pageTransitionsTheme ??= const PageTransitionsTheme();
...@@ -476,9 +476,65 @@ class ThemeData extends Diagnosticable { ...@@ -476,9 +476,65 @@ class ThemeData extends Diagnosticable {
assert(popupMenuTheme != null), assert(popupMenuTheme != null),
assert(bannerTheme != null); assert(bannerTheme != null);
// Warning: make sure these properties are in the exact same order as in /// Create a [ThemeData] based on the colors in the given [colorScheme] and
// hashValues() and in the raw constructor and in the order of fields in /// text styles of the optional [textTheme].
// the class and in the lerp() method. ///
/// The [colorScheme] can not be null.
///
/// If [colorScheme.brightness] is [Brightness.dark] then
/// [ThemeData.applyElevationOverlayColor] will be set to true to support
/// the Material dark theme method for indicating elevation by overlaying
/// a semi-transparent white color on top of the surface color.
///
/// This is the recommended method to theme your application. As we move
/// forward we will be converting all the widget implementations to only use
/// colors or colors derived from those in [ColorScheme].
///
/// {@tool sample}
/// This example will set up an application to use the baseline Material
/// Design light and dark themes.
///
/// ```dart
/// MaterialApp(
/// theme: ThemeData.from(colorScheme: ColorScheme.light()),
/// darkTheme: ThemeData.from(colorScheme: ColorScheme.dark()),
/// )
/// ```
/// {@end-tool}
///
/// See <https://material.io/design/color/> for
/// more discussion on how to pick the right colors.
factory ThemeData.from({
@required ColorScheme colorScheme,
TextTheme textTheme,
}) {
assert(colorScheme != null);
final bool isDark = colorScheme.brightness == Brightness.dark;
// 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;
return ThemeData(
brightness: colorScheme.brightness,
primaryColor: primarySurfaceColor,
primaryColorBrightness: ThemeData.estimateBrightnessForColor(primarySurfaceColor),
canvasColor: colorScheme.background,
accentColor: colorScheme.secondary,
accentColorBrightness: ThemeData.estimateBrightnessForColor(colorScheme.secondary),
scaffoldBackgroundColor: colorScheme.background,
cardColor: colorScheme.surface,
dividerColor: colorScheme.onSurface.withOpacity(0.12),
backgroundColor: colorScheme.background,
dialogBackgroundColor: colorScheme.background,
errorColor: colorScheme.error,
textTheme: textTheme,
indicatorColor: onPrimarySurfaceColor,
applyElevationOverlayColor: isDark,
colorScheme: colorScheme,
);
}
/// A default light blue theme. /// A default light blue theme.
/// ///
...@@ -503,6 +559,10 @@ class ThemeData extends Diagnosticable { ...@@ -503,6 +559,10 @@ class ThemeData extends Diagnosticable {
/// text geometry. /// text geometry.
factory ThemeData.fallback() => ThemeData.light(); factory ThemeData.fallback() => ThemeData.light();
// Warning: make sure these properties are in the exact same order as in
// hashValues() and in the raw constructor and in the order of fields in
// the class and in the lerp() method.
/// The brightness of the overall theme of the application. Used by widgets /// The brightness of the overall theme of the application. Used by widgets
/// like buttons to determine what color to pick when not using the primary or /// like buttons to determine what color to pick when not using the primary or
/// accent color. /// accent color.
......
...@@ -136,4 +136,38 @@ void main() { ...@@ -136,4 +136,38 @@ void main() {
test('cursorColor', () { test('cursorColor', () {
expect(ThemeData(cursorColor: Colors.red).cursorColor, Colors.red); expect(ThemeData(cursorColor: Colors.red).cursorColor, Colors.red);
}); });
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);
expect(theme.brightness, equals(Brightness.light));
expect(theme.primaryColor, equals(lightColors.primary));
expect(theme.accentColor, equals(lightColors.secondary));
expect(theme.cardColor, equals(lightColors.surface));
expect(theme.backgroundColor, equals(lightColors.background));
expect(theme.canvasColor, equals(lightColors.background));
expect(theme.scaffoldBackgroundColor, equals(lightColors.background));
expect(theme.dialogBackgroundColor, equals(lightColors.background));
expect(theme.errorColor, equals(lightColors.error));
expect(theme.applyElevationOverlayColor, isFalse);
});
testWidgets('ThemeData.from a dark color scheme sets appropriate values', (WidgetTester tester) async {
const ColorScheme darkColors = ColorScheme.dark();
final ThemeData theme = ThemeData.from(colorScheme: darkColors);
expect(theme.brightness, equals(Brightness.dark));
// in dark theme's the color used for main components is surface instead of primary
expect(theme.primaryColor, equals(darkColors.surface));
expect(theme.accentColor, equals(darkColors.secondary));
expect(theme.cardColor, equals(darkColors.surface));
expect(theme.backgroundColor, equals(darkColors.background));
expect(theme.canvasColor, equals(darkColors.background));
expect(theme.scaffoldBackgroundColor, equals(darkColors.background));
expect(theme.dialogBackgroundColor, equals(darkColors.background));
expect(theme.errorColor, equals(darkColors.error));
expect(theme.applyElevationOverlayColor, isTrue);
});
} }
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