diff --git a/dev/tools/gen_defaults/bin/gen_defaults.dart b/dev/tools/gen_defaults/bin/gen_defaults.dart index 1b46653e81..ce3b468bc3 100644 --- a/dev/tools/gen_defaults/bin/gen_defaults.dart +++ b/dev/tools/gen_defaults/bin/gen_defaults.dart @@ -18,6 +18,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:gen_defaults/fab_template.dart'; +import 'package:gen_defaults/typography_template.dart'; Map _readTokenFile(String fileName) { return jsonDecode(File('dev/tools/gen_defaults/data/$fileName').readAsStringSync()) as Map; @@ -70,4 +71,5 @@ Future main(List args) async { } FABTemplate('$materialLib/floating_action_button.dart', tokens).updateFile(); + TypographyTemplate('$materialLib/typography.dart', tokens).updateFile(); } diff --git a/dev/tools/gen_defaults/lib/template.dart b/dev/tools/gen_defaults/lib/template.dart index bdaa4127a8..b920a5b983 100644 --- a/dev/tools/gen_defaults/lib/template.dart +++ b/dev/tools/gen_defaults/lib/template.dart @@ -86,7 +86,6 @@ abstract class TokenTemplate { } String textStyle(String tokenName) { - final String fontName = '$tokenName.text-style'; - return tokens[fontName]!.toString(); + return tokens['$tokenName.text-style']!.toString(); } } diff --git a/dev/tools/gen_defaults/lib/typography_template.dart b/dev/tools/gen_defaults/lib/typography_template.dart new file mode 100644 index 0000000000..c8b123a4b6 --- /dev/null +++ b/dev/tools/gen_defaults/lib/typography_template.dart @@ -0,0 +1,76 @@ +// 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 TypographyTemplate extends TokenTemplate { + const TypographyTemplate(String fileName, Map tokens) : super(fileName, tokens); + + @override + String generate() => ''' +// Generated version ${tokens["version"]} +class _M3Typography { + _M3Typography._(); + + ${_textTheme('englishLike', 'alphabetic')} + + ${_textTheme('dense', 'ideographic')} + + ${_textTheme('tall', 'alphabetic')} +} +'''; + + String _textTheme(String name, String baseline) { + final StringBuffer theme = StringBuffer('static const TextTheme $name = TextTheme(\n'); + theme.writeln(' displayLarge: ${_textStyleDef('md.sys.typescale.display-large', '$name displayLarge 2021', baseline)},'); + theme.writeln(' displayMedium: ${_textStyleDef('md.sys.typescale.display-medium', '$name displayMedium 2021', baseline)},'); + theme.writeln(' displaySmall: ${_textStyleDef('md.sys.typescale.display-small', '$name displaySmall 2021', baseline)},'); + theme.writeln(' headlineLarge: ${_textStyleDef('md.sys.typescale.headline-large', '$name headlineLarge 2021', baseline)},'); + theme.writeln(' headlineMedium: ${_textStyleDef('md.sys.typescale.headline-medium', '$name headlineMedium 2021', baseline)},'); + theme.writeln(' headlineSmall: ${_textStyleDef('md.sys.typescale.headline-small', '$name headlineSmall 2021', baseline)},'); + theme.writeln(' titleLarge: ${_textStyleDef('md.sys.typescale.title-large', '$name titleLarge 2021', baseline)},'); + theme.writeln(' titleMedium: ${_textStyleDef('md.sys.typescale.title-medium', '$name titleMedium 2021', baseline)},'); + theme.writeln(' titleSmall: ${_textStyleDef('md.sys.typescale.title-small', '$name titleSmall 2021', baseline)},'); + theme.writeln(' labelLarge: ${_textStyleDef('md.sys.typescale.label-large', '$name labelLarge 2021', baseline)},'); + theme.writeln(' labelMedium: ${_textStyleDef('md.sys.typescale.label-medium', '$name labelMedium 2021', baseline)},'); + theme.writeln(' labelSmall: ${_textStyleDef('md.sys.typescale.label-small', '$name labelSmall 2021', baseline)},'); + theme.writeln(' bodyLarge: ${_textStyleDef('md.sys.typescale.body-large', '$name bodyLarge 2021', baseline)},'); + theme.writeln(' bodyMedium: ${_textStyleDef('md.sys.typescale.body-medium', '$name bodyMedium 2021', baseline)},'); + theme.writeln(' bodySmall: ${_textStyleDef('md.sys.typescale.body-small', '$name bodySmall 2021', baseline)},'); + theme.write(' );'); + return theme.toString(); + } + + String _textStyleDef(String tokenName, String debugLabel, String baseline) { + final StringBuffer style = StringBuffer("TextStyle(debugLabel: '$debugLabel'"); + style.write(', inherit: false'); + style.write(', fontSize: ${_fontSize(tokenName)}'); + style.write(', fontWeight: ${_fontWeight(tokenName)}'); + style.write(', letterSpacing: ${_fontSpacing(tokenName)}'); + style.write(', height: ${_fontHeight(tokenName)}'); + style.write(', textBaseline: TextBaseline.$baseline'); + style.write(', leadingDistribution: TextLeadingDistribution.even'); + style.write(')'); + return style.toString(); + } + + String _fontSize(String textStyleTokenName) { + return tokens['$textStyleTokenName.size']!.toString(); + } + + String _fontWeight(String textStyleTokenName) { + final String weightValue = tokens[tokens['$textStyleTokenName.weight']!]!.toString(); + return 'FontWeight.w$weightValue'; + } + + String _fontSpacing(String textStyleTokenName) { + return tokens['$textStyleTokenName.tracking']!.toString(); + } + + String _fontHeight(String textStyleTokenName) { + final double size = tokens['$textStyleTokenName.size']! as double; + final double lineHeight = tokens['$textStyleTokenName.line-height']! as double; + return (lineHeight / size).toStringAsFixed(2); + } +} diff --git a/packages/flutter/lib/src/material/theme_data.dart b/packages/flutter/lib/src/material/theme_data.dart index bcb609b78a..c742b01123 100644 --- a/packages/flutter/lib/src/material/theme_data.dart +++ b/packages/flutter/lib/src/material/theme_data.dart @@ -495,7 +495,7 @@ class ThemeData with Diagnosticable { splashColor ??= isDark ? _kDarkThemeSplashColor : _kLightThemeSplashColor; // TYPOGRAPHY & ICONOGRAPHY - typography ??= Typography.material2014(platform: platform); + typography ??= useMaterial3 ? Typography.material2021(platform: platform) : Typography.material2014(platform: platform); TextTheme defaultTextTheme = isDark ? typography.white : typography.black; TextTheme defaultPrimaryTextTheme = primaryIsDark ? typography.white : typography.black; TextTheme defaultAccentTextTheme = accentIsDark ? typography.white : typography.black; @@ -1134,6 +1134,9 @@ class ThemeData with Diagnosticable { /// start using new colors, typography and other features of Material 3. /// If false, they will use the Material 2 look and feel. /// + /// If true, the default Typography will be [Typography.material2021], + /// otherwise it will default to [Typography.material2014]. + /// /// During the migration to Material 3, turning this on may yield /// inconsistent look and feel in your app. Some components will be migrated /// before others and typography changes will be coming in stages. diff --git a/packages/flutter/lib/src/material/typography.dart b/packages/flutter/lib/src/material/typography.dart index 35cc0dc259..ec674c022e 100644 --- a/packages/flutter/lib/src/material/typography.dart +++ b/packages/flutter/lib/src/material/typography.dart @@ -147,6 +147,34 @@ class Typography with Diagnosticable { ); } + /// Creates a typography instance using Material Design 3 2021 defaults. + /// + /// If [platform] is [TargetPlatform.iOS] or [TargetPlatform.macOS], the + /// default values for [black] and [white] are [blackCupertino] and + /// [whiteCupertino] respectively. Otherwise they are [blackMountainView] and + /// [whiteMountainView]. If [platform] is null then both [black] and [white] + /// must be specified. + /// + /// The default values for [englishLike], [dense], and [tall] are + /// [englishLike2021], [dense2021], and [tall2021]. + factory Typography.material2021({ + TargetPlatform? platform = TargetPlatform.android, + TextTheme? black, + TextTheme? white, + TextTheme? englishLike, + TextTheme? dense, + TextTheme? tall, + }) { + assert(platform != null || (black != null && white != null)); + return Typography._withPlatform( + platform, + black, white, + englishLike ?? englishLike2021, + dense ?? dense2021, + tall ?? tall2021, + ); + } + factory Typography._withPlatform( TargetPlatform? platform, TextTheme? black, @@ -675,4 +703,91 @@ class Typography with Diagnosticable { labelMedium : TextStyle(debugLabel: 'tall labelMedium 2018', fontSize: 12.0, fontWeight: FontWeight.w400, textBaseline: TextBaseline.alphabetic), labelSmall : TextStyle(debugLabel: 'tall labelSmall 2018', fontSize: 11.0, fontWeight: FontWeight.w400, textBaseline: TextBaseline.alphabetic), ); + + /// Defines text geometry for [ScriptCategory.englishLike] scripts, such as + /// English, French, Russian, etc. + /// + /// The font sizes, weights, and letter spacings in this version match the + /// [2021 Material Design 3 specification](https://m3.material.io/styles/typography/overview). + static const TextTheme englishLike2021 = _M3Typography.englishLike; + + /// Defines text geometry for dense scripts, such as Chinese, Japanese + /// and Korean. + /// + /// The Material Design 3 specification does not include 'dense' text themes, + /// so this is just here to be consistent with the API. + static const TextTheme dense2021 = _M3Typography.dense; + + /// Defines text geometry for tall scripts, such as Farsi, Hindi, and Thai. + /// + /// The Material Design 3 specification does not include 'tall' text themes, + /// so this is just here to be consistent with the API. + static const TextTheme tall2021 = _M3Typography.tall; } + +// BEGIN GENERATED TOKEN PROPERTIES + +// Generated code to the end of this file. Do not edit by hand. +// These defaults are generated from the Material Design Token +// database by the script dev/tools/gen_defaults/bin/gen_defaults.dart. + +// Generated version v0_76 +class _M3Typography { + _M3Typography._(); + + static const TextTheme englishLike = TextTheme( + displayLarge: TextStyle(debugLabel: 'englishLike displayLarge 2021', inherit: false, fontSize: 57.0, fontWeight: FontWeight.w400, letterSpacing: -0.25, height: 1.12, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + displayMedium: TextStyle(debugLabel: 'englishLike displayMedium 2021', inherit: false, fontSize: 45.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.16, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + displaySmall: TextStyle(debugLabel: 'englishLike displaySmall 2021', inherit: false, fontSize: 36.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.22, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + headlineLarge: TextStyle(debugLabel: 'englishLike headlineLarge 2021', inherit: false, fontSize: 32.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.25, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + headlineMedium: TextStyle(debugLabel: 'englishLike headlineMedium 2021', inherit: false, fontSize: 28.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.29, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + headlineSmall: TextStyle(debugLabel: 'englishLike headlineSmall 2021', inherit: false, fontSize: 24.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.33, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + titleLarge: TextStyle(debugLabel: 'englishLike titleLarge 2021', inherit: false, fontSize: 22.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.27, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + titleMedium: TextStyle(debugLabel: 'englishLike titleMedium 2021', inherit: false, fontSize: 16.0, fontWeight: FontWeight.w500, letterSpacing: 0.15, height: 1.50, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + titleSmall: TextStyle(debugLabel: 'englishLike titleSmall 2021', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, letterSpacing: 0.1, height: 1.43, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + labelLarge: TextStyle(debugLabel: 'englishLike labelLarge 2021', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, letterSpacing: 0.1, height: 1.43, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + labelMedium: TextStyle(debugLabel: 'englishLike labelMedium 2021', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w500, letterSpacing: 0.5, height: 1.33, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + labelSmall: TextStyle(debugLabel: 'englishLike labelSmall 2021', inherit: false, fontSize: 11.0, fontWeight: FontWeight.w500, letterSpacing: 0.5, height: 1.45, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + bodyLarge: TextStyle(debugLabel: 'englishLike bodyLarge 2021', inherit: false, fontSize: 16.0, fontWeight: FontWeight.w400, letterSpacing: 0.5, height: 1.50, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + bodyMedium: TextStyle(debugLabel: 'englishLike bodyMedium 2021', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w400, letterSpacing: 0.25, height: 1.43, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + bodySmall: TextStyle(debugLabel: 'englishLike bodySmall 2021', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w400, letterSpacing: 0.4, height: 1.33, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + ); + + static const TextTheme dense = TextTheme( + displayLarge: TextStyle(debugLabel: 'dense displayLarge 2021', inherit: false, fontSize: 57.0, fontWeight: FontWeight.w400, letterSpacing: -0.25, height: 1.12, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + displayMedium: TextStyle(debugLabel: 'dense displayMedium 2021', inherit: false, fontSize: 45.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.16, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + displaySmall: TextStyle(debugLabel: 'dense displaySmall 2021', inherit: false, fontSize: 36.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.22, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + headlineLarge: TextStyle(debugLabel: 'dense headlineLarge 2021', inherit: false, fontSize: 32.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.25, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + headlineMedium: TextStyle(debugLabel: 'dense headlineMedium 2021', inherit: false, fontSize: 28.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.29, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + headlineSmall: TextStyle(debugLabel: 'dense headlineSmall 2021', inherit: false, fontSize: 24.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.33, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + titleLarge: TextStyle(debugLabel: 'dense titleLarge 2021', inherit: false, fontSize: 22.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.27, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + titleMedium: TextStyle(debugLabel: 'dense titleMedium 2021', inherit: false, fontSize: 16.0, fontWeight: FontWeight.w500, letterSpacing: 0.15, height: 1.50, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + titleSmall: TextStyle(debugLabel: 'dense titleSmall 2021', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, letterSpacing: 0.1, height: 1.43, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + labelLarge: TextStyle(debugLabel: 'dense labelLarge 2021', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, letterSpacing: 0.1, height: 1.43, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + labelMedium: TextStyle(debugLabel: 'dense labelMedium 2021', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w500, letterSpacing: 0.5, height: 1.33, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + labelSmall: TextStyle(debugLabel: 'dense labelSmall 2021', inherit: false, fontSize: 11.0, fontWeight: FontWeight.w500, letterSpacing: 0.5, height: 1.45, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + bodyLarge: TextStyle(debugLabel: 'dense bodyLarge 2021', inherit: false, fontSize: 16.0, fontWeight: FontWeight.w400, letterSpacing: 0.5, height: 1.50, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + bodyMedium: TextStyle(debugLabel: 'dense bodyMedium 2021', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w400, letterSpacing: 0.25, height: 1.43, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + bodySmall: TextStyle(debugLabel: 'dense bodySmall 2021', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w400, letterSpacing: 0.4, height: 1.33, textBaseline: TextBaseline.ideographic, leadingDistribution: TextLeadingDistribution.even), + ); + + static const TextTheme tall = TextTheme( + displayLarge: TextStyle(debugLabel: 'tall displayLarge 2021', inherit: false, fontSize: 57.0, fontWeight: FontWeight.w400, letterSpacing: -0.25, height: 1.12, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + displayMedium: TextStyle(debugLabel: 'tall displayMedium 2021', inherit: false, fontSize: 45.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.16, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + displaySmall: TextStyle(debugLabel: 'tall displaySmall 2021', inherit: false, fontSize: 36.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.22, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + headlineLarge: TextStyle(debugLabel: 'tall headlineLarge 2021', inherit: false, fontSize: 32.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.25, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + headlineMedium: TextStyle(debugLabel: 'tall headlineMedium 2021', inherit: false, fontSize: 28.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.29, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + headlineSmall: TextStyle(debugLabel: 'tall headlineSmall 2021', inherit: false, fontSize: 24.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.33, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + titleLarge: TextStyle(debugLabel: 'tall titleLarge 2021', inherit: false, fontSize: 22.0, fontWeight: FontWeight.w400, letterSpacing: 0.0, height: 1.27, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + titleMedium: TextStyle(debugLabel: 'tall titleMedium 2021', inherit: false, fontSize: 16.0, fontWeight: FontWeight.w500, letterSpacing: 0.15, height: 1.50, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + titleSmall: TextStyle(debugLabel: 'tall titleSmall 2021', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, letterSpacing: 0.1, height: 1.43, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + labelLarge: TextStyle(debugLabel: 'tall labelLarge 2021', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w500, letterSpacing: 0.1, height: 1.43, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + labelMedium: TextStyle(debugLabel: 'tall labelMedium 2021', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w500, letterSpacing: 0.5, height: 1.33, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + labelSmall: TextStyle(debugLabel: 'tall labelSmall 2021', inherit: false, fontSize: 11.0, fontWeight: FontWeight.w500, letterSpacing: 0.5, height: 1.45, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + bodyLarge: TextStyle(debugLabel: 'tall bodyLarge 2021', inherit: false, fontSize: 16.0, fontWeight: FontWeight.w400, letterSpacing: 0.5, height: 1.50, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + bodyMedium: TextStyle(debugLabel: 'tall bodyMedium 2021', inherit: false, fontSize: 14.0, fontWeight: FontWeight.w400, letterSpacing: 0.25, height: 1.43, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + bodySmall: TextStyle(debugLabel: 'tall bodySmall 2021', inherit: false, fontSize: 12.0, fontWeight: FontWeight.w400, letterSpacing: 0.4, height: 1.33, textBaseline: TextBaseline.alphabetic, leadingDistribution: TextLeadingDistribution.even), + ); +} + +// END GENERATED TOKEN PROPERTIES diff --git a/packages/flutter/test/material/theme_test.dart b/packages/flutter/test/material/theme_test.dart index 8b23057c01..170bd174c6 100644 --- a/packages/flutter/test/material/theme_test.dart +++ b/packages/flutter/test/material/theme_test.dart @@ -84,6 +84,11 @@ void main() { ); }); + testWidgets('ThemeData with null typography uses proper defaults', (WidgetTester tester) async { + expect(ThemeData().typography, Typography.material2014()); + expect(ThemeData(useMaterial3: true).typography, Typography.material2021()); + }); + testWidgets('PopupMenu inherits shadowed app theme', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/5572 final Key popupMenuButtonKey = UniqueKey(); diff --git a/packages/flutter/test/material/typography_test.dart b/packages/flutter/test/material/typography_test.dart index 703e67bf95..92b7bc300b 100644 --- a/packages/flutter/test/material/typography_test.dart +++ b/packages/flutter/test/material/typography_test.dart @@ -200,4 +200,147 @@ void main() { expect(theme.labelSmall!.fontSize, 10); expect(theme.labelSmall!.letterSpacing, 1.5); }); + + test('englishLike2021 TextTheme matches Material Design 3 spec', () { + // Check the default material text theme against the style values + // shown https://m3.material.io/styles/typography/tokens. + // + // This may need to be updated if the token values change. + final TextTheme theme = Typography.englishLike2021.merge(Typography.blackMountainView); + + // Display large + expect(theme.displayLarge!.fontFamily, 'Roboto'); + expect(theme.displayLarge!.fontSize, 57.0); + expect(theme.displayLarge!.fontWeight, FontWeight.w400); + expect(theme.displayLarge!.letterSpacing, -0.25); + expect(theme.displayLarge!.height, 1.12); + expect(theme.displayLarge!.textBaseline, TextBaseline.alphabetic); + expect(theme.displayLarge!.leadingDistribution, TextLeadingDistribution.even); + + // Display medium + expect(theme.displayMedium!.fontFamily, 'Roboto'); + expect(theme.displayMedium!.fontSize, 45.0); + expect(theme.displayMedium!.fontWeight, FontWeight.w400); + expect(theme.displayMedium!.letterSpacing, 0.0); + expect(theme.displayMedium!.height, 1.16); + expect(theme.displayMedium!.textBaseline, TextBaseline.alphabetic); + expect(theme.displayMedium!.leadingDistribution, TextLeadingDistribution.even); + + // Display small + expect(theme.displaySmall!.fontFamily, 'Roboto'); + expect(theme.displaySmall!.fontSize, 36.0); + expect(theme.displaySmall!.fontWeight, FontWeight.w400); + expect(theme.displaySmall!.letterSpacing, 0.0); + expect(theme.displaySmall!.height, 1.22); + expect(theme.displaySmall!.textBaseline, TextBaseline.alphabetic); + expect(theme.displaySmall!.leadingDistribution, TextLeadingDistribution.even); + + // Headline large + expect(theme.headlineLarge!.fontFamily, 'Roboto'); + expect(theme.headlineLarge!.fontSize, 32.0); + expect(theme.headlineLarge!.fontWeight, FontWeight.w400); + expect(theme.headlineLarge!.letterSpacing, 0.0); + expect(theme.headlineLarge!.height, 1.25); + expect(theme.headlineLarge!.textBaseline, TextBaseline.alphabetic); + expect(theme.headlineLarge!.leadingDistribution, TextLeadingDistribution.even); + + // Headline medium + expect(theme.headlineMedium!.fontFamily, 'Roboto'); + expect(theme.headlineMedium!.fontSize, 28.0); + expect(theme.headlineMedium!.fontWeight, FontWeight.w400); + expect(theme.headlineMedium!.letterSpacing, 0.0); + expect(theme.headlineMedium!.height, 1.29); + expect(theme.headlineMedium!.textBaseline, TextBaseline.alphabetic); + expect(theme.headlineMedium!.leadingDistribution, TextLeadingDistribution.even); + + // Headline small + expect(theme.headlineSmall!.fontFamily, 'Roboto'); + expect(theme.headlineSmall!.fontSize, 24.0); + expect(theme.headlineSmall!.fontWeight, FontWeight.w400); + expect(theme.headlineSmall!.letterSpacing, 0.0); + expect(theme.headlineSmall!.height, 1.33); + expect(theme.headlineSmall!.textBaseline, TextBaseline.alphabetic); + expect(theme.headlineSmall!.leadingDistribution, TextLeadingDistribution.even); + + // Title large + expect(theme.titleLarge!.fontFamily, 'Roboto'); + expect(theme.titleLarge!.fontSize, 22.0); + expect(theme.titleLarge!.fontWeight, FontWeight.w400); + expect(theme.titleLarge!.letterSpacing, 0.0); + expect(theme.titleLarge!.height, 1.27); + expect(theme.titleLarge!.textBaseline, TextBaseline.alphabetic); + expect(theme.titleLarge!.leadingDistribution, TextLeadingDistribution.even); + + // Title medium + expect(theme.titleMedium!.fontFamily, 'Roboto'); + expect(theme.titleMedium!.fontSize, 16.0); + expect(theme.titleMedium!.fontWeight, FontWeight.w500); + expect(theme.titleMedium!.letterSpacing, 0.15); + expect(theme.titleMedium!.height, 1.50); + expect(theme.titleMedium!.textBaseline, TextBaseline.alphabetic); + expect(theme.titleMedium!.leadingDistribution, TextLeadingDistribution.even); + + // Title small + expect(theme.titleSmall!.fontFamily, 'Roboto'); + expect(theme.titleSmall!.fontSize, 14.0); + expect(theme.titleSmall!.fontWeight, FontWeight.w500); + expect(theme.titleSmall!.letterSpacing, 0.1); + expect(theme.titleSmall!.height, 1.43); + expect(theme.titleSmall!.textBaseline, TextBaseline.alphabetic); + expect(theme.titleSmall!.leadingDistribution, TextLeadingDistribution.even); + + // Label large + expect(theme.labelLarge!.fontFamily, 'Roboto'); + expect(theme.labelLarge!.fontSize, 14.0); + expect(theme.labelLarge!.fontWeight, FontWeight.w500); + expect(theme.labelLarge!.letterSpacing, 0.1); + expect(theme.labelLarge!.height, 1.43); + expect(theme.labelLarge!.textBaseline, TextBaseline.alphabetic); + expect(theme.labelLarge!.leadingDistribution, TextLeadingDistribution.even); + + // Label medium + expect(theme.labelMedium!.fontFamily, 'Roboto'); + expect(theme.labelMedium!.fontSize, 12.0); + expect(theme.labelMedium!.fontWeight, FontWeight.w500); + expect(theme.labelMedium!.letterSpacing, 0.5); + expect(theme.labelMedium!.height, 1.33); + expect(theme.labelMedium!.textBaseline, TextBaseline.alphabetic); + expect(theme.labelMedium!.leadingDistribution, TextLeadingDistribution.even); + + // Label small + expect(theme.labelSmall!.fontFamily, 'Roboto'); + expect(theme.labelSmall!.fontSize, 11.0); + expect(theme.labelSmall!.fontWeight, FontWeight.w500); + expect(theme.labelSmall!.letterSpacing, 0.5); + expect(theme.labelSmall!.height, 1.45); + expect(theme.labelSmall!.textBaseline, TextBaseline.alphabetic); + expect(theme.labelSmall!.leadingDistribution, TextLeadingDistribution.even); + + // Body large + expect(theme.bodyLarge!.fontFamily, 'Roboto'); + expect(theme.bodyLarge!.fontSize, 16.0); + expect(theme.bodyLarge!.fontWeight, FontWeight.w400); + expect(theme.bodyLarge!.letterSpacing, 0.5); + expect(theme.bodyLarge!.height, 1.50); + expect(theme.bodyLarge!.textBaseline, TextBaseline.alphabetic); + expect(theme.bodyLarge!.leadingDistribution, TextLeadingDistribution.even); + + // Body medium + expect(theme.bodyMedium!.fontFamily, 'Roboto'); + expect(theme.bodyMedium!.fontSize, 14.0); + expect(theme.bodyMedium!.fontWeight, FontWeight.w400); + expect(theme.bodyMedium!.letterSpacing, 0.25); + expect(theme.bodyMedium!.height, 1.43); + expect(theme.bodyMedium!.textBaseline, TextBaseline.alphabetic); + expect(theme.bodyMedium!.leadingDistribution, TextLeadingDistribution.even); + + // Body small + expect(theme.bodySmall!.fontFamily, 'Roboto'); + expect(theme.bodySmall!.fontSize, 12.0); + expect(theme.bodySmall!.fontWeight, FontWeight.w400); + expect(theme.bodySmall!.letterSpacing, 0.4); + expect(theme.bodySmall!.height, 1.33); + expect(theme.bodySmall!.textBaseline, TextBaseline.alphabetic); + expect(theme.bodySmall!.leadingDistribution, TextLeadingDistribution.even); + }); }