Description
Issue description
ColorScheme based themes create ThemeData that is inconsistent with the provided ColorScheme. Some sub themes are also incomplete when using ColorScheme based themes because Theme.from(colorScheme)
does not set all Theme() color properties used by sub themes.
For broader adoption of ColorScheme based theming, it would be useful if it behaved as might be expected and did not leave remnants of the default colors from Theme() factory in the resulting theme from a Theme.from(colorScheme) factory, where one would expect there should be colors from the colorScheme in use.
This issue demo uses ColorScheme.light()
and ColorScheme.dark()
and Theme.from(colorscheme)
for each of them to demonstrate incompleteness and inconsistencies in the resulting light and dark themes and to show that many Theme() color properties do not get any colors from the used ColorScheme applied. This makes the resulting ThemeData inconsistent with the ColorScheme used to create the ThemeData. In some cases this also affects default colors on some widgets, making the situation potentially even more confusing.
Since the issue can easily be remedied with additional manual custom theming e.g. with copyWith
, after creating a ColorScheme based theme with Theme.from(colorScheme)
, it is not a big issue, but the current situation does seem like an oversight and the incomplete and conflicting results may be confusing to new developers.
It would be useful and more elegant if when using ColorScheme and Theme.from(colorScheme) it created more complete matching ThemeData results, were none of its color properties were left with Theme() factory defaults that potentially conflict with the used ColorScheme and also that no widgets were left with default colors that do not match the ColorScheme used to create ThemeData from ColorScheme.
Steps to Reproduce
This issue applies to all current Flutter versions and all channels.
The source code for the issue demo can be found here:
https://gist.github.com/rydmike/b59cea071eefdbe7c1332b2d014bc156
And the issues can easily be demonstrated and tried with this DartPad:
https://www.dartpad.dev/b59cea071eefdbe7c1332b2d014bc156
Results and description of gaps and issues with ColorScheme based themes
toggleableActiveColor
ColorScheme based themes will get the default dark theme based toggleable color and not the secondary color from the dark
ColorScheme. The resulting color may or may not fit with the used colors in ColorScheme based theme. The default dark theme color is close to ColorScheme.dark() so it works fairly well for the default values, but not for general usage.
Proposed fix:
ThemeData.from() should also set:
toggleableActiveColor: colorScheme.secondary
for better backwards compatibility and so that the dark mode toggleableActiveColor also matches the ColorScheme based theme in dark mode and not only light mode.
primaryColorDark
ColorScheme based themes do not set any color at all for the Theme() color primaryColorDark. It only gets default value from default Theme factory for both light and dark mode. The resulting color may or may not fit with the used colors in ColorScheme based theme.
Proposed fix:
For a better fit with legacy themes and to match the colors in the ColorScheme the ThemeData.from() should set primaryColorDark to a slightly darker hue based on colorScheme.primary for light themes.
primaryColorLight
ColorScheme based themes do not set any color at all for the Theme() color primaryColorLight. It only gets default value from default Theme factory for both light and dark mode. The resulting color may or may not fit with the used colors in ColorScheme based theme.
Proposed fix:
For a better fit with legacy themes and to match the colors in the ColorScheme the ThemeData.from() should set primaryColorLight to a lighter hue based on colorScheme.primary for light themes.
secondaryHeaderColor
ColorScheme based themes do not set any color at all for the Theme() color secondaryHeaderColor. It only gets default value from default Theme factory for both light and dark mode. The resulting color may or may not fit with the used colors in ColorScheme based theme.
Proposed fix:
For a better fit with legacy themes and to match the colors in the ColorScheme the ThemeData.from() should set secondaryHeaderColor to a much lighter hue based on colorScheme.primary for light themes.
Text selection when using ColorScheme based themes
The new "TextSelectionThemeData" and "useTextSelectionTheme" address the issues below, but only when used in TextField()
and SelectableText()
. Still the color properties in the resulting ThemeData are left at their default values, which may be confusing and they also do not match the applied ColorScheme based theme.
The useTextSelectionTheme
cannot be set with ColorScheme directly, an extra copyWith (inconvenient) is required and even then the ThemeData result values are left at their Theme() defaults, this may be confusing as they do not match the applied ColorScheme colors.
textSelectionColor
ColorScheme based themes do not set any color at all for the Theme() color textSelectionColor. It only gets default value from default Theme factory for both light and dark mode. The resulting color may or may not fit with the used colors in ColorScheme based theme.
Proposed fix:
For a better fit with legacy themes and to match the colors in the ColorScheme the ThemeData.from() should set textSelectionColor to a lighter hue based on colorScheme.primary for light themes and to colorScheme.secondary for dark themes.
Alternatively:
ColorScheme based themes could set the Theme() property to the colorScheme.primary based colors introduced with TextSelectionThemeData, this would not break older Theme() based themes and would make the property correctly ColorScheme based for themes based on ColorScheme.
textSelectionHandleColor
ColorScheme based themes do not set any color at all for the Theme() color textSelectionHandleColor. It only gets default value from default Theme factory for both light and dark mode. The resulting color may or may not fit with the used colors in ColorScheme based theme.
Proposed fix:
For a better fit with legacy themes and to match the colors in the ColorScheme the ThemeData.from() should set textSelectionHandleColor to a lighter hue based on colorScheme.primary for light themes and to a darker hue of colorScheme.secondary for dark themes.
Alternatively:
ColorScheme based themes could set the Theme() property to the colorScheme.primary based colors introduced with TextSelectionThemeData, this would not break older Theme() based themes and would make the property correctly ColorScheme based for themes based on ColorScheme and it would match the TextSelectionThemeData defaults.
cursorColor
ColorScheme based themes do not set any color at all for the Theme() color cursorColor. It only gets default value from default Theme factory for both light and dark mode. The resulting color may or may not fit with the used colors in ColorScheme based theme.
Proposed fix:
For a better fit with legacy themes and to match the colors in the ColorScheme the ThemeData.from() should set cursorColor to colorScheme.primary or some hue of it.
Alternatively:
ColorScheme based themes could set the Theme() property to the colorScheme.primary based colors introduced with TextSelectionThemeData, this would not break older Theme() based themes and would make the property correctly ColorScheme based for themes based on ColorScheme and it would match the TextSelectionThemeData defaults.
Note:
It is worth noticing that default Theme() uses the same fixed blue color for light and dark mode and that this blue color is not any variant of the default blue colors used in the default blue primary swatch, which is a bit odd. It is very close to the default blue hues in default Theme() and thus works well with the the default Theme(), but it does not work well with ColorScheme themes or any other none default and none blue based theme.
Flutter doctor
flutter doctor -v
[√] Flutter (Channel master, 1.22.0-10.0.pre.161, on Microsoft Windows [Version 10.0.18363.1016], locale en-US)
• Flutter version 1.22.0-10.0.pre.161 at C:\Users\mryds\fvm\versions\master
• Framework revision cba91c97d0 (20 hours ago), 2020-09-13 18:57:03 -0400
• Engine revision 2fc054147e
• Dart version 2.10.0 (build 2.10.0-121.0.dev)
[√] Android toolchain - develop for Android devices (Android SDK version 29.0.1)
• Android SDK at C:\Users\mryds\AppData\Local\Android\sdk
• Platform android-29, build-tools 29.0.1
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
• All Android licenses accepted.
[√] Chrome - develop for the web
• Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.6.5)
• Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
• Visual Studio Community 2019 version 16.6.30320.27
• Windows 10 SDK version 10.0.18362.0
[√] Android Studio (version 4.0)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin version 47.1.2
• Dart plugin version 193.7361
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
[√] IntelliJ IDEA Community Edition (version 2019.2)
• IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.3.1
• Flutter plugin version 35.3.3
• Dart plugin version 192.7402
[√] VS Code (version 1.49.0)
• VS Code at C:\Users\mryds\AppData\Local\Programs\Microsoft VS Code
• Flutter extension version 3.14.1
[√] Connected device (4 available)
• Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.18363.1016]
• Web Server (web) • web-server • web-javascript • Flutter Tools
• Chrome (web) • chrome • web-javascript • Google Chrome 85.0.4183.102
• Edge (web) • edge • web-javascript • Microsoft Edge 85.0.564.44
• No issues found!