-
Notifications
You must be signed in to change notification settings - Fork 150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using GoogleFonts TextThemes as input in ThemeData produces wrong default text colors #401
Comments
PTAL @rodydavis |
Yep I have seen this. Will look into it. Usually you will want to call apply to the text theme to override the color to on surface with the correct brightness |
Yes you can do apply with onSurface and onPrimary for primaryTextTheme, but if you use M2 you would have to do a copyWith black/white with the correct opacities per TextStyle as well. Very tedious. Generally it feels surprising and a bit poor dev experience that when you give a TextTheme from GoogleFonts as input to ThemeData textTheme and primaryTextTheme, that the only case when it is correct is if you happen make and want a black Typography2014 text theme. For everything else it is just wrong. Definitely confusing for many users and they probably don't even know what the correct contrast colors should be in what mode M2/M3 light/dark. In the sample I made, I included a utility class that sets color to null in all styles (apply can't do that). Just used this to test that if I override an incoming text theme, when it has the fingerprint of a GoogleFonts default TextTheme for colors in it, to have all null colors, that then we can handover the setting of the default colors to ThemeData and get correct M2/M3 light/dark colors assigned by the factory. Changing current GoogleFonts text theme method to deliver such TextThemes is potentially breaking, not sure how bad and if it would matter to most use cases, but it might. Thus an alternative solution would be to add a new TextTheme method where color is null in all styles (like font sizes actually also are now), and document that using it is recommended when applying a GoogleFonts text theme directly to ThemeData textTheme and primaryTextTheme properties. Just a thought. 😀 |
As a Flutter begginer, I stumbled on this on day 2. |
I am having a similar issue, When using custom GoogleFonts throughout the app in dark mode the text color is black instead of white. Wonder if I am missing anything, this is how I am applying the fonts throughout the app return MaterialApp(
...
darkTheme: ThemeData.dark(
useMaterial3: true,
).copyWith(
textTheme: GoogleFonts.quicksandTextTheme(), // text is black in darkmode
brightness: Brightness.dark),
),
theme: ThemeData(
textTheme: GoogleFonts.quicksandTextTheme(), // this works fine in light mode
)),
...
) |
Hi @maheshmnj, what your are doing with the Since you are using Material3, the light My reproduction code sample contains a work-around you can use to fix this issue. You can use the helper that the reproduction sample includes and uses, to correct the colors to get the expected results: /// A utility class to set the color of the font color to null in all
/// [TextStyle]s in a [TextTheme].
class TextThemeColor {
/// Set font color to null in all styles in passed in [TextTheme] and
/// return the new [TextTheme] other properties remain unchanged.
static TextTheme nullFontColor(TextTheme textTheme) {
/// Set font color to null in all styles in passed in [TextTheme] and
return TextTheme(
displayLarge: nullColor(textTheme.displayLarge!),
displayMedium: nullColor(textTheme.displayMedium!),
displaySmall: nullColor(textTheme.displaySmall!),
//
headlineLarge: nullColor(textTheme.headlineLarge!),
headlineMedium: nullColor(textTheme.headlineMedium!),
headlineSmall: nullColor(textTheme.headlineSmall!),
//
titleLarge: nullColor(textTheme.titleLarge!),
titleMedium: nullColor(textTheme.titleMedium!),
titleSmall: nullColor(textTheme.titleSmall!),
//
bodyLarge: nullColor(textTheme.bodyLarge!),
bodyMedium: nullColor(textTheme.bodyMedium!),
bodySmall: nullColor(textTheme.bodySmall!),
//
labelLarge: nullColor(textTheme.labelLarge!),
labelMedium: nullColor(textTheme.labelMedium!),
labelSmall: nullColor(textTheme.labelSmall!),
);
}
/// Set font color to null in passed in [TextStyle] and
/// return the new [TextStyle], other properties remain unchanged.
static TextStyle nullColor(TextStyle style) {
return TextStyle(
color: null, // Set color to NULL, let ThemeData handle default.
backgroundColor: style.backgroundColor,
fontSize: style.fontSize,
fontWeight: style.fontWeight,
fontStyle: style.fontStyle,
letterSpacing: style.letterSpacing,
wordSpacing: style.wordSpacing,
textBaseline: style.textBaseline,
height: style.height,
leadingDistribution: style.leadingDistribution,
locale: style.locale,
foreground: style.foreground,
background: style.background,
shadows: style.shadows,
fontFeatures: style.fontFeatures,
fontVariations: style.fontVariations,
decoration: style.decoration,
decorationColor: style.decorationColor,
decorationStyle: style.decorationStyle,
decorationThickness: style.decorationThickness,
debugLabel: style.debugLabel,
fontFamily: style.fontFamily,
fontFamilyFallback: style.fontFamilyFallback,
overflow: style.overflow,
);
}
} and then using your example theme and return MaterialApp(
...
theme: ThemeData(
brightness: Brightness.light,
colorScheme: ...,
useMaterial3: true,
textTheme: TextThemeColor.nullFontColor(GoogleFonts.quicksandTextTheme()),
primaryTextTheme: TextThemeColor.nullFontColor(GoogleFonts.quicksandTextTheme()),
),
darkTheme: ThemeData(
brightness: Brightness.dark,
colorScheme: ...,
useMaterial3: true,
textTheme: TextThemeColor.nullFontColor(GoogleFonts.quicksandTextTheme()),
primaryTextTheme: TextThemeColor.nullFontColor(GoogleFonts.quicksandTextTheme()),
),
...
) This will give you correct default contrast colors for both It all works by setting the hard coded black text color in the GoogleFonts.textTheme back to null for all its The If you are interested in more details about this you can read this answer: rydmike/flex_color_scheme#160 (comment). As seen in this example, if/when you want to use a custom I have no idea why this issue has not been fixed by just making the font color default to null, or providing another TextTheme getter where it is so, and recommending its usage for |
Thanks for the detailed insights @rydmike |
Package
google_fonts
Existing issue?
What happened?
GoogleFonts TextTheme Color defined to always use M2 light mode color
GoogleFonts TextTheme have their TextStyle colors hard coded to M2 light mode colors.
When using a GoogleFonts text theme, like e.g.
GoogleFonts.notoSansTextTheme()
it always comes with the colors fromThemeData.light().textTheme
baked in as default color.These TextTheme colors are only appropriate in
ThemeData(textTheme: ..., ...)
for M2 light mode. They are wrong default colors for all other modes, like dark M2, light or dark M3 and primaryTextTheme. Thus, when used for such cases asTextTheme
inThemeData
, the colors have to be overridden for every TextStyle in the TextTheme to get mode correct or even usable contrast color.If the used
TextStyle
colors in all the GoogleFonts TextThemes were null,ThemeData
would add M2/M3 mode and light/dark appropriate colors to the GoogleFonts TextThemes when used in a theme.The GoogleFonts TextThemes already have NO font sizes defined, since
ThemeData.light().textTheme
used as default does not yet resolve sizes, they are all null and get applied later in the localization step, this fact gives us M2/M3 mode correct sizes, but not colors.Letting
Color
remain null in allGoogleFonts
text themes and be applied byThemeData
to appropriate colors would be similar behavior for color and make the default GoogleFonts TextTheme get correct M2 (opacity based) based contrast colors in M2 and M3 (onSurface based) colors in M3 mode as well as correct contrast colors for light/dark mode.Even when used as
primaryTextTheme
, color would be resolved based onThemeData
modes, with the known issue and limitationprimaryTextTheme
has see Flutter issue #118146.Build the attached sample app to see the result. Toggle the switch ON to see expected results, keep OFF to see issues as presented below.
Expected results
Expect to get M2/M3 mode and light/dark mode correct contrast color on the text when using
GoogleFonts
asTextTheme
inThemeData
when used astextTheme
andprimaryTextTheme
.Actual results
In M3 light mode, the
textTheme
colors get M2 light mode based colors with its different opacities for different styles. This is incorrect, they should all beonSurface
color with no opacity.The
primaryTextTheme
is also M2 light mode text theme based, not only is it incorrect, it is also incorrect contrast for the usedprimary
color.In M3 dark mode, the same M2 light mode colors are used, they are not usable at all as colors on a dark mode
textTheme
.Ironically, in dark mode, the light M2 theme mode font colors happen to work better on
primary
color than whatThemeData
actually makes when colors are null. As mentioned, the reason for this is issue #118146 and unrelated to this case.In M2 light mode, the colors are actually correct for
textTheme
.In M2 dark mode, the
textTheme
uses the M2 light mode colors, and they are of course not legible at all. Again, in this case due mentioned unrelated issue, the dark modeprimaryTextTheme
is better than whatThemeData
would actually make if colors were null.Proposal
Keep
color
null in all returned GoogleFonts TextThemes and all their TextStyles, and letThemeData
apply appropriate default colors. Users can still apply their own colors as needed.The change is potentially breaking, but it makes
GoogleFonts
default TextThemes better in allThemeData
modes in Flutter. Importantly, it also gives us correct M3 mode font colors by default when we use M3.If the hard coded M2 light mode colors for some reason are critical in the current
TextThemes
returned byGoogleFonts
, maybe consider adding another newTextTheme
getter where allTextStyle
colors are null. This, as a more suitable optional/new defaultTextTheme
more usable and suitable forThemeData
consumption.Currently, I'm using a version of the fix presented in the attached sample in FlexColorScheme. As seen, I found a "reasonably" safe way to check when a given passed
TextTheme
is using a default GoogleFonts TextTheme, and only set colors to null then. It would be nice to not need this workaround. but I can of course continue to use it. Still it might also be nice to not have all users of GoogleFonts that use vanillaThemeData
struggle with this issue.Issue sample code
The reproduction sample code is attached below.
Sample build requirements
Add GoogleFonts to pubspec yaml.
If using macOS add:
To at least the macOS debug mode entitlements file.
Code sample
Used versions
Relevant log output
Flutter doctor
The text was updated successfully, but these errors were encountered: