diff --git a/packages/material_ui/lib/src/banner.dart b/packages/material_ui/lib/src/banner.dart index 482369255ee4..5ba0e947c86c 100644 --- a/packages/material_ui/lib/src/banner.dart +++ b/packages/material_ui/lib/src/banner.dart @@ -18,6 +18,8 @@ import 'scaffold.dart'; import 'text_theme.dart'; import 'theme.dart'; +part 'generated/banner_defaults_m3.g.dart'; + // Examples can assume: // late BuildContext context; @@ -489,35 +491,3 @@ class _BannerDefaultsM2 extends MaterialBannerThemeData { @override TextStyle? get contentTextStyle => _theme.textTheme.bodyMedium; } - -// BEGIN GENERATED TOKEN PROPERTIES - Banner - -// Do not edit by hand. The code between the "BEGIN GENERATED" and -// "END GENERATED" comments are generated from data in the Material -// Design token database by the script: -// dev/tools/gen_defaults/bin/gen_defaults.dart. - -// dart format off -class _BannerDefaultsM3 extends MaterialBannerThemeData { - _BannerDefaultsM3(this.context) - : super(elevation: 1.0); - - final BuildContext context; - late final ColorScheme _colors = Theme.of(context).colorScheme; - late final TextTheme _textTheme = Theme.of(context).textTheme; - - @override - Color? get backgroundColor => _colors.surfaceContainerLow; - - @override - Color? get surfaceTintColor => Colors.transparent; - - @override - Color? get dividerColor => _colors.outlineVariant; - - @override - TextStyle? get contentTextStyle => _textTheme.bodyMedium; -} -// dart format on - -// END GENERATED TOKEN PROPERTIES - Banner diff --git a/packages/material_ui/tool/gen_defaults/temporarily_excluded/generated/banner_defaults.g.dart b/packages/material_ui/lib/src/generated/banner_defaults_m3.g.dart similarity index 77% rename from packages/material_ui/tool/gen_defaults/temporarily_excluded/generated/banner_defaults.g.dart rename to packages/material_ui/lib/src/generated/banner_defaults_m3.g.dart index 1cb263cabca9..308539b9eb17 100644 --- a/packages/material_ui/tool/gen_defaults/temporarily_excluded/generated/banner_defaults.g.dart +++ b/packages/material_ui/lib/src/generated/banner_defaults_m3.g.dart @@ -2,6 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Do not edit by hand. The code is generated from data in the Material +// Design token database by the script: +// packages/material_ui/tool/gen_defaults/bin/gen_defaults.dart. +part of '../banner.dart'; + class _BannerDefaultsM3 extends MaterialBannerThemeData { _BannerDefaultsM3(this.context) : super(elevation: 1.0); diff --git a/packages/material_ui/tool/gen_defaults/bin/gen_defaults.dart b/packages/material_ui/tool/gen_defaults/bin/gen_defaults.dart index c7ab01c7e138..8a32b522e75e 100644 --- a/packages/material_ui/tool/gen_defaults/bin/gen_defaults.dart +++ b/packages/material_ui/tool/gen_defaults/bin/gen_defaults.dart @@ -15,7 +15,8 @@ import 'package:args/args.dart'; // import '../templates/action_chip_template.dart'; import '../templates/app_bar_template.dart'; // import '../templates/badge_template.dart'; -// import '../templates/banner_template.dart'; +import '../templates/banner_template.dart'; + // import '../templates/bottom_app_bar_template.dart'; // import '../templates/bottom_sheet_template.dart'; // import '../templates/button_template.dart'; @@ -66,7 +67,7 @@ Future main(List args) async { // const ActionChipTemplateM3().generateFile(verbose: verbose); const AppBarTemplateM3().generateFile(verbose: verbose); // const BadgeTemplateM3().generateFile(verbose: verbose); - // const BannerTemplateM3().generateFile(verbose: verbose); + const BannerTemplateM3().generateFile(verbose: verbose); // const BottomAppBarTemplateM3().generateFile(verbose: verbose); // const BottomSheetTemplateM3().generateFile(verbose: verbose); // const ButtonTemplateM3().generateFile(verbose: verbose); diff --git a/packages/material_ui/tool/gen_defaults/data/banner.dart b/packages/material_ui/tool/gen_defaults/data/banner.dart new file mode 100644 index 000000000000..0fadbc597127 --- /dev/null +++ b/packages/material_ui/tool/gen_defaults/data/banner.dart @@ -0,0 +1,63 @@ +// Copyright 2013 The Flutter Authors. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Version: 38.1.12 + +import 'color_role.dart'; +import 'shape_struct.dart'; +import 'typescale.dart'; +import 'typescale_struct.dart'; + +class TokenBanner { + /// md.comp.banner.container.color + static const TokenColorRole containerColor = TokenColorRole.surfaceContainerLow; + + /// md.comp.banner.container.elevation + static const double containerElevation = 1.00; + + /// md.comp.banner.container.shape + static const ShapeStruct containerShape = ShapeStruct( + family: 'SHAPE_FAMILY_ROUNDED_CORNERS', + topLeft: 0.00, + topRight: 0.00, + bottomLeft: 0.00, + bottomRight: 0.00, + ); + + /// md.comp.banner.desktop.with-single-line.container.height + static const double desktopWithSingleLineContainerHeight = 52.00; + + /// md.comp.banner.desktop.with-three-lines.container.height + static const double desktopWithThreeLinesContainerHeight = 90.00; + + /// md.comp.banner.desktop.with-two-lines.with-image.container.height + static const double desktopWithTwoLinesWithImageContainerHeight = 72.00; + + /// md.comp.banner.mobile.with-single-line.container.height + static const double mobileWithSingleLineContainerHeight = 54.00; + + /// md.comp.banner.mobile.with-two-lines.container.height + static const double mobileWithTwoLinesContainerHeight = 112.00; + + /// md.comp.banner.mobile.with-two-lines.with-image.container.height + static const double mobileWithTwoLinesWithImageContainerHeight = 120.00; + + /// md.comp.banner.supporting-text.color + static const TokenColorRole supportingTextColor = TokenColorRole.onSurfaceVariant; + + /// md.comp.banner.supporting-text.type + static const TypescaleStruct supportingTextType = TokenTypescale.bodyMedium; + + /// md.comp.banner.with-image.image.shape + static const ShapeStruct withImageImageShape = ShapeStruct( + family: 'SHAPE_FAMILY_CIRCULAR', + topLeft: 0.00, + topRight: 0.00, + bottomLeft: 0.00, + bottomRight: 0.00, + ); + + /// md.comp.banner.with-image.image.size + static const double withImageImageSize = 40.00; +} diff --git a/packages/material_ui/tool/gen_defaults/templates/banner_template.dart b/packages/material_ui/tool/gen_defaults/templates/banner_template.dart new file mode 100644 index 000000000000..ea023337414c --- /dev/null +++ b/packages/material_ui/tool/gen_defaults/templates/banner_template.dart @@ -0,0 +1,42 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import '../data/banner.dart'; +import '../data/divider.dart'; +import 'template.dart'; + +class BannerTemplateM3 extends TokenTemplateM3 { + const BannerTemplateM3(); + + @override + String get name => 'Banner'; + + @override + String get parentFilePath => 'banner.dart'; + + @override + String generateContents(String className) => + ''' +class $className extends MaterialBannerThemeData { + $className(this.context) + : super(elevation: ${number(TokenBanner.containerElevation)}); + + final BuildContext context; + late final ColorScheme _colors = Theme.of(context).colorScheme; + late final TextTheme _textTheme = Theme.of(context).textTheme; + + @override + Color? get backgroundColor => ${color(TokenBanner.containerColor, '_colors')}; + + @override + Color? get surfaceTintColor => Colors.transparent; + + @override + Color? get dividerColor => ${color(TokenDivider.color, '_colors')}; + + @override + TextStyle? get contentTextStyle => ${textStyle(TokenBanner.supportingTextType, '_textTheme')}; +} +'''; +} diff --git a/packages/material_ui/tool/gen_defaults/templates/template.dart b/packages/material_ui/tool/gen_defaults/templates/template.dart index 54c37d2e9a73..99167314791f 100644 --- a/packages/material_ui/tool/gen_defaults/templates/template.dart +++ b/packages/material_ui/tool/gen_defaults/templates/template.dart @@ -8,6 +8,8 @@ import 'package:meta/meta.dart'; import '../data/color_role.dart'; import '../data/shape_struct.dart'; +import '../data/typescale.dart'; +import '../data/typescale_struct.dart'; enum _MaterialVersion { material3, material3Expressive } @@ -110,6 +112,72 @@ abstract class TokenTemplate { return '${color(role, prefix)}.withOpacity(${number(opacity)})'; } + /// Generates a [TextTheme] expression for the given typescale token. + String textStyle(TypescaleStruct type, String prefix) { + final String? textStyleName = _textStyleName(type); + if (textStyleName == null) { + throw UnsupportedError('Unsupported typescale token.'); + } + return '$prefix.$textStyleName'; + } + + String? _textStyleName(TypescaleStruct type) { + if (_hasSameTypescaleValues(type, TokenTypescale.bodyLarge)) { + return 'bodyLarge'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.bodyMedium)) { + return 'bodyMedium'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.bodySmall)) { + return 'bodySmall'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.displayLarge)) { + return 'displayLarge'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.displayMedium)) { + return 'displayMedium'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.displaySmall)) { + return 'displaySmall'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.headlineLarge)) { + return 'headlineLarge'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.headlineMedium)) { + return 'headlineMedium'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.headlineSmall)) { + return 'headlineSmall'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.labelLarge)) { + return 'labelLarge'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.labelMedium)) { + return 'labelMedium'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.labelSmall)) { + return 'labelSmall'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.titleLarge)) { + return 'titleLarge'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.titleMedium)) { + return 'titleMedium'; + } + if (_hasSameTypescaleValues(type, TokenTypescale.titleSmall)) { + return 'titleSmall'; + } + return null; + } + + bool _hasSameTypescaleValues(TypescaleStruct a, TypescaleStruct b) { + return a.fontFamily == b.fontFamily && + a.fontSize == b.fontSize && + a.fontWeight == b.fontWeight && + a.lineHeight == b.lineHeight && + a.letterSpacing == b.letterSpacing; + } + /// Generates an [OutlinedBorder] expression for a shape token. /// /// Currently supports: diff --git a/packages/material_ui/tool/gen_defaults/temporarily_excluded/templates/banner_template.dart b/packages/material_ui/tool/gen_defaults/temporarily_excluded/templates/banner_template.dart deleted file mode 100644 index eb9bd75af2a7..000000000000 --- a/packages/material_ui/tool/gen_defaults/temporarily_excluded/templates/banner_template.dart +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'template.dart'; - -class BannerTemplate extends TokenTemplate { - const BannerTemplate( - super.blockName, - super.fileName, - super.tokens, { - super.colorSchemePrefix = '_colors.', - super.textThemePrefix = '_textTheme.', - }); - - @override - String generate() => ''' -class _${blockName}DefaultsM3 extends MaterialBannerThemeData { - _${blockName}DefaultsM3(this.context) - : super(elevation: ${elevation("md.comp.banner.container")}); - - final BuildContext context; - late final ColorScheme _colors = Theme.of(context).colorScheme; - late final TextTheme _textTheme = Theme.of(context).textTheme; - - @override - Color? get backgroundColor => ${componentColor("md.comp.banner.container")}; - - @override - Color? get surfaceTintColor => ${colorOrTransparent("md.comp.banner.container.surface-tint-layer.color")}; - - @override - Color? get dividerColor => ${color("md.comp.divider.color")}; - - @override - TextStyle? get contentTextStyle => ${textStyle("md.comp.banner.supporting-text")}; -} -'''; -} diff --git a/packages/material_ui/tool/gen_defaults/test/gen_defaults_test.dart b/packages/material_ui/tool/gen_defaults/test/gen_defaults_test.dart index 02f8d08fafca..5d0879ae2da4 100644 --- a/packages/material_ui/tool/gen_defaults/test/gen_defaults_test.dart +++ b/packages/material_ui/tool/gen_defaults/test/gen_defaults_test.dart @@ -7,7 +7,9 @@ import 'dart:io'; import 'package:test/test.dart'; import '../data/color_role.dart'; import '../data/shape_struct.dart'; +import '../data/typescale.dart'; import '../templates/app_bar_template.dart'; +import '../templates/banner_template.dart'; import '../templates/template.dart'; import 'test_fixtures/test_templates.dart'; @@ -148,6 +150,15 @@ void main() { ); }); + test('textStyle generates text theme expression', () { + final template = IconButtonTemplateM3(testPath()); + expect( + template.textStyle(TokenTypescale.labelSmall, 'Theme.of(context).textTheme'), + 'Theme.of(context).textTheme.labelSmall', + ); + expect(template.textStyle(TokenTypescale.bodyMedium, '_textTheme'), '_textTheme.bodyMedium'); + }); + test('ActionChipTemplateM3 emits M3 ActionChip defaults from tokens', () { // Intentionally empty, will be implemented during migration. See: // https://github.com/flutter/flutter/issues/187899 @@ -170,9 +181,14 @@ void main() { // https://github.com/flutter/flutter/issues/187899 }); - test('BannerTemplateM3 emits M3 Banner defaults from tokens', () { - // Intentionally empty, will be implemented during migration. See: - // https://github.com/flutter/flutter/issues/187899 + test('BannerTemplateM3 emits M3 Banner defaults from banner tokens', () { + final String contents = const BannerTemplateM3().generateContents('_BannerDefaultsM3'); + expect(contents, contains('class _BannerDefaultsM3 extends MaterialBannerThemeData')); + expect(contents, contains('elevation: 1.0')); + expect(contents, contains('Color? get backgroundColor => _colors.surfaceContainerLow')); + expect(contents, contains('Color? get surfaceTintColor => Colors.transparent')); + expect(contents, contains('Color? get dividerColor => _colors.outlineVariant')); + expect(contents, contains('TextStyle? get contentTextStyle => _textTheme.bodyMedium')); }); test('BottomAppBarTemplateM3 emits M3 BottomAppBar defaults from tokens', () {