Commit d0ff41ec authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Add accentTextTheme and accentIconTheme to ThemeData (#6808)

These define a TextTheme and IconTheme that contrast with the accent
colour brightness. Also adjust default accentColorBrightness to match
Material spec examples (dark text/icons on teal in Dark theme).

Update material components to use accentTextTheme, accentIconTheme:
* DatePicker selection
* Floating action button icon
* TimePicker selection
* Slider label text
parent f172f067
...@@ -224,9 +224,7 @@ class DayPicker extends StatelessWidget { ...@@ -224,9 +224,7 @@ class DayPicker extends StatelessWidget {
if (selectedDate.year == year && selectedDate.month == month && selectedDate.day == day) { if (selectedDate.year == year && selectedDate.month == month && selectedDate.day == day) {
// The selected day gets a circle background highlight, and a contrasting text color. // The selected day gets a circle background highlight, and a contrasting text color.
itemStyle = themeData.textTheme.body2.copyWith( itemStyle = themeData.accentTextTheme.body2;
color: (themeData.brightness == Brightness.light) ? Colors.white : Colors.black87
);
decoration = new BoxDecoration( decoration = new BoxDecoration(
backgroundColor: themeData.accentColor, backgroundColor: themeData.accentColor,
shape: BoxShape.circle shape: BoxShape.circle
......
...@@ -120,7 +120,7 @@ class _FloatingActionButtonState extends State<FloatingActionButton> { ...@@ -120,7 +120,7 @@ class _FloatingActionButtonState extends State<FloatingActionButton> {
if (materialColor == null) { if (materialColor == null) {
final ThemeData themeData = Theme.of(context); final ThemeData themeData = Theme.of(context);
materialColor = themeData.accentColor; materialColor = themeData.accentColor;
iconColor = themeData.accentColorBrightness == Brightness.dark ? Colors.white : Colors.black; iconColor = themeData.accentIconTheme.color;
} }
Widget result = new Center( Widget result = new Center(
......
...@@ -145,7 +145,7 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin { ...@@ -145,7 +145,7 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin {
divisions: config.divisions, divisions: config.divisions,
label: config.label, label: config.label,
activeColor: config.activeColor ?? theme.accentColor, activeColor: config.activeColor ?? theme.accentColor,
textTheme: theme.primaryTextTheme, textTheme: theme.accentTextTheme,
onChanged: config.onChanged != null ? _handleChanged : null, onChanged: config.onChanged != null ? _handleChanged : null,
vsync: this, vsync: this,
); );
......
...@@ -93,8 +93,10 @@ class ThemeData { ...@@ -93,8 +93,10 @@ class ThemeData {
Color errorColor, Color errorColor,
TextTheme textTheme, TextTheme textTheme,
TextTheme primaryTextTheme, TextTheme primaryTextTheme,
TextTheme accentTextTheme,
IconThemeData iconTheme, IconThemeData iconTheme,
IconThemeData primaryIconTheme, IconThemeData primaryIconTheme,
IconThemeData accentIconTheme,
TargetPlatform platform TargetPlatform platform
}) { }) {
brightness ??= Brightness.light; brightness ??= Brightness.light;
...@@ -104,7 +106,8 @@ class ThemeData { ...@@ -104,7 +106,8 @@ class ThemeData {
primaryColorBrightness ??= Brightness.dark; primaryColorBrightness ??= Brightness.dark;
final bool primaryIsDark = primaryColorBrightness == Brightness.dark; final bool primaryIsDark = primaryColorBrightness == Brightness.dark;
accentColor ??= isDark ? Colors.tealAccent[200] : primarySwatch[500]; accentColor ??= isDark ? Colors.tealAccent[200] : primarySwatch[500];
accentColorBrightness ??= Brightness.dark; accentColorBrightness ??= isDark ? Brightness.light : Brightness.dark;
final bool accentIsDark = accentColorBrightness == Brightness.dark;
canvasColor ??= isDark ? Colors.grey[850] : Colors.grey[50]; canvasColor ??= isDark ? Colors.grey[850] : Colors.grey[50];
cardColor ??= isDark ? Colors.grey[800] : Colors.white; cardColor ??= isDark ? Colors.grey[800] : Colors.white;
dividerColor ??= isDark ? const Color(0x1FFFFFFF) : const Color(0x1F000000); dividerColor ??= isDark ? const Color(0x1FFFFFFF) : const Color(0x1F000000);
...@@ -124,11 +127,12 @@ class ThemeData { ...@@ -124,11 +127,12 @@ class ThemeData {
errorColor ??= Colors.red[700]; errorColor ??= Colors.red[700];
iconTheme ??= isDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black); iconTheme ??= isDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
primaryIconTheme ??= primaryIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black); primaryIconTheme ??= primaryIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
accentIconTheme ??= accentIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
platform ??= defaultTargetPlatform; platform ??= defaultTargetPlatform;
final Typography typography = new Typography(platform: platform); final Typography typography = new Typography(platform: platform);
primaryTextTheme ??= primaryIsDark ? typography.white : typography.black;
textTheme ??= isDark ? typography.white : typography.black; textTheme ??= isDark ? typography.white : typography.black;
primaryTextTheme ??= primaryIsDark ? typography.white : typography.black;
accentTextTheme ??= accentIsDark ? typography.white : typography.black;
return new ThemeData.raw( return new ThemeData.raw(
brightness: brightness, brightness: brightness,
primaryColor: primaryColor, primaryColor: primaryColor,
...@@ -153,8 +157,10 @@ class ThemeData { ...@@ -153,8 +157,10 @@ class ThemeData {
errorColor: errorColor, errorColor: errorColor,
textTheme: textTheme, textTheme: textTheme,
primaryTextTheme: primaryTextTheme, primaryTextTheme: primaryTextTheme,
accentTextTheme: accentTextTheme,
iconTheme: iconTheme, iconTheme: iconTheme,
primaryIconTheme: primaryIconTheme, primaryIconTheme: primaryIconTheme,
accentIconTheme: accentIconTheme,
platform: platform platform: platform
); );
} }
...@@ -189,8 +195,10 @@ class ThemeData { ...@@ -189,8 +195,10 @@ class ThemeData {
this.errorColor, this.errorColor,
this.textTheme, this.textTheme,
this.primaryTextTheme, this.primaryTextTheme,
this.accentTextTheme,
this.iconTheme, this.iconTheme,
this.primaryIconTheme, this.primaryIconTheme,
this.accentIconTheme,
this.platform this.platform
}) { }) {
assert(brightness != null); assert(brightness != null);
...@@ -216,8 +224,10 @@ class ThemeData { ...@@ -216,8 +224,10 @@ class ThemeData {
assert(errorColor != null); assert(errorColor != null);
assert(textTheme != null); assert(textTheme != null);
assert(primaryTextTheme != null); assert(primaryTextTheme != null);
assert(accentTextTheme != null);
assert(iconTheme != null); assert(iconTheme != null);
assert(primaryIconTheme != null); assert(primaryIconTheme != null);
assert(accentIconTheme != null);
assert(platform != null); assert(platform != null);
} }
...@@ -325,12 +335,18 @@ class ThemeData { ...@@ -325,12 +335,18 @@ class ThemeData {
/// A text theme that contrasts with the primary color. /// A text theme that contrasts with the primary color.
final TextTheme primaryTextTheme; final TextTheme primaryTextTheme;
/// A text theme that contrasts with the accent color.
final TextTheme accentTextTheme;
/// An icon theme that contrasts with the card and canvas colors. /// An icon theme that contrasts with the card and canvas colors.
final IconThemeData iconTheme; final IconThemeData iconTheme;
/// An icon theme that contrasts with the primary color. /// An icon theme that contrasts with the primary color.
final IconThemeData primaryIconTheme; final IconThemeData primaryIconTheme;
/// An icon theme that contrasts with the accent color.
final IconThemeData accentIconTheme;
/// The platform the material widgets should adapt to target. /// The platform the material widgets should adapt to target.
/// ///
/// Defaults to the current platform. /// Defaults to the current platform.
...@@ -362,8 +378,10 @@ class ThemeData { ...@@ -362,8 +378,10 @@ class ThemeData {
Color errorColor, Color errorColor,
TextTheme textTheme, TextTheme textTheme,
TextTheme primaryTextTheme, TextTheme primaryTextTheme,
TextTheme accentTextTheme,
IconThemeData iconTheme, IconThemeData iconTheme,
IconThemeData primaryIconTheme, IconThemeData primaryIconTheme,
IconThemeData accentIconTheme,
TargetPlatform platform, TargetPlatform platform,
}) { }) {
return new ThemeData( return new ThemeData(
...@@ -390,8 +408,10 @@ class ThemeData { ...@@ -390,8 +408,10 @@ class ThemeData {
errorColor: errorColor ?? this.errorColor, errorColor: errorColor ?? this.errorColor,
textTheme: textTheme ?? this.textTheme, textTheme: textTheme ?? this.textTheme,
primaryTextTheme: primaryTextTheme ?? this.primaryTextTheme, primaryTextTheme: primaryTextTheme ?? this.primaryTextTheme,
accentTextTheme: accentTextTheme ?? this.accentTextTheme,
iconTheme: iconTheme ?? this.iconTheme, iconTheme: iconTheme ?? this.iconTheme,
primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme, primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme,
accentIconTheme: accentIconTheme ?? this.accentIconTheme,
platform: platform ?? this.platform, platform: platform ?? this.platform,
); );
} }
...@@ -422,8 +442,10 @@ class ThemeData { ...@@ -422,8 +442,10 @@ class ThemeData {
errorColor: Color.lerp(begin.errorColor, end.errorColor, t), errorColor: Color.lerp(begin.errorColor, end.errorColor, t),
textTheme: TextTheme.lerp(begin.textTheme, end.textTheme, t), textTheme: TextTheme.lerp(begin.textTheme, end.textTheme, t),
primaryTextTheme: TextTheme.lerp(begin.primaryTextTheme, end.primaryTextTheme, t), primaryTextTheme: TextTheme.lerp(begin.primaryTextTheme, end.primaryTextTheme, t),
accentTextTheme: TextTheme.lerp(begin.accentTextTheme, end.accentTextTheme, t),
iconTheme: IconThemeData.lerp(begin.iconTheme, end.iconTheme, t), iconTheme: IconThemeData.lerp(begin.iconTheme, end.iconTheme, t),
primaryIconTheme: IconThemeData.lerp(begin.primaryIconTheme, end.primaryIconTheme, t), primaryIconTheme: IconThemeData.lerp(begin.primaryIconTheme, end.primaryIconTheme, t),
accentIconTheme: IconThemeData.lerp(begin.accentIconTheme, end.accentIconTheme, t),
platform: t < 0.5 ? begin.platform : end.platform platform: t < 0.5 ? begin.platform : end.platform
); );
} }
...@@ -456,8 +478,10 @@ class ThemeData { ...@@ -456,8 +478,10 @@ class ThemeData {
(otherData.errorColor == errorColor) && (otherData.errorColor == errorColor) &&
(otherData.textTheme == textTheme) && (otherData.textTheme == textTheme) &&
(otherData.primaryTextTheme == primaryTextTheme) && (otherData.primaryTextTheme == primaryTextTheme) &&
(otherData.accentTextTheme == accentTextTheme) &&
(otherData.iconTheme == iconTheme) && (otherData.iconTheme == iconTheme) &&
(otherData.primaryIconTheme == primaryIconTheme) && (otherData.primaryIconTheme == primaryIconTheme) &&
(otherData.accentIconTheme == accentIconTheme) &&
(otherData.platform == platform); (otherData.platform == platform);
} }
...@@ -488,8 +512,10 @@ class ThemeData { ...@@ -488,8 +512,10 @@ class ThemeData {
errorColor, errorColor,
textTheme, textTheme,
primaryTextTheme, primaryTextTheme,
accentTextTheme,
iconTheme, iconTheme,
primaryIconTheme, primaryIconTheme,
accentIconTheme,
platform, platform,
) )
); );
......
...@@ -595,11 +595,11 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin { ...@@ -595,11 +595,11 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
switch (config.mode) { switch (config.mode) {
case _TimePickerMode.hour: case _TimePickerMode.hour:
primaryLabels = _initHours(theme.textTheme); primaryLabels = _initHours(theme.textTheme);
secondaryLabels = _initHours(theme.primaryTextTheme); secondaryLabels = _initHours(theme.accentTextTheme);
break; break;
case _TimePickerMode.minute: case _TimePickerMode.minute:
primaryLabels = _initMinutes(theme.textTheme); primaryLabels = _initMinutes(theme.textTheme);
secondaryLabels = _initMinutes(theme.primaryTextTheme); secondaryLabels = _initMinutes(theme.accentTextTheme);
break; break;
} }
......
...@@ -13,4 +13,58 @@ void main() { ...@@ -13,4 +13,58 @@ void main() {
expect(theme.textTheme, typography.black, reason: 'Not using default typography for $platform'); expect(theme.textTheme, typography.black, reason: 'Not using default typography for $platform');
} }
}); });
test('Default text theme contrasts with brightness', () {
ThemeData lightTheme = new ThemeData(brightness: Brightness.light);
ThemeData darkTheme = new ThemeData(brightness: Brightness.dark);
Typography typography = new Typography(platform: lightTheme.platform);
expect(lightTheme.textTheme.title.color, typography.black.title.color);
expect(darkTheme.textTheme.title.color, typography.white.title.color);
});
test('Default primary text theme contrasts with primary brightness', () {
ThemeData lightTheme = new ThemeData(primaryColorBrightness: Brightness.light);
ThemeData darkTheme = new ThemeData(primaryColorBrightness: Brightness.dark);
Typography typography = new Typography(platform: lightTheme.platform);
expect(lightTheme.primaryTextTheme.title.color, typography.black.title.color);
expect(darkTheme.primaryTextTheme.title.color, typography.white.title.color);
});
test('Default accent text theme contrasts with accent brightness', () {
ThemeData lightTheme = new ThemeData(accentColorBrightness: Brightness.light);
ThemeData darkTheme = new ThemeData(accentColorBrightness: Brightness.dark);
Typography typography = new Typography(platform: lightTheme.platform);
expect(lightTheme.accentTextTheme.title.color, typography.black.title.color);
expect(darkTheme.accentTextTheme.title.color, typography.white.title.color);
});
test('Default icon theme contrasts with brightness', () {
ThemeData lightTheme = new ThemeData(brightness: Brightness.light);
ThemeData darkTheme = new ThemeData(brightness: Brightness.dark);
Typography typography = new Typography(platform: lightTheme.platform);
expect(lightTheme.textTheme.title.color, typography.black.title.color);
expect(darkTheme.textTheme.title.color, typography.white.title.color);
});
test('Default primary icon theme contrasts with primary brightness', () {
ThemeData lightTheme = new ThemeData(primaryColorBrightness: Brightness.light);
ThemeData darkTheme = new ThemeData(primaryColorBrightness: Brightness.dark);
Typography typography = new Typography(platform: lightTheme.platform);
expect(lightTheme.primaryTextTheme.title.color, typography.black.title.color);
expect(darkTheme.primaryTextTheme.title.color, typography.white.title.color);
});
test('Default accent icon theme contrasts with accent brightness', () {
ThemeData lightTheme = new ThemeData(accentColorBrightness: Brightness.light);
ThemeData darkTheme = new ThemeData(accentColorBrightness: Brightness.dark);
Typography typography = new Typography(platform: lightTheme.platform);
expect(lightTheme.accentTextTheme.title.color, typography.black.title.color);
expect(darkTheme.accentTextTheme.title.color, typography.white.title.color);
});
} }
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