From 12f1e4a0748346e526fa1d0d4e24be99bf3df13b Mon Sep 17 00:00:00 2001 From: Qun Cheng <36861262+QuncCccccc@users.noreply.github.com> Date: Thu, 16 Jul 2026 10:06:14 -0700 Subject: [PATCH] [material_ui] Migrate AppBar M3 template to use new gen_defaults script (#12122) ~Will land https://github.com/flutter/packages/pull/12209 first.~ Fixes https://github.com/flutter/flutter/issues/188397 Initially gen_defaults script and its templates were used to handle JSON tokens. After we fix the token pipeline and make it possible to get M3E tokens, we use Dart constants and re-created the gen_defaults in material_ui. After decoupling, the old gen_defaults will be deprecated soon. This PR is to: * create a template for M3 `AppBar` so we can use new script to generate M3 defaults. * move the generated code to `generated/` folder so all M3 and M3E generated code will be in the same location. - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [x] I read the [Tree Hygiene] page, which explains my responsibilities. - [x] I read and followed the [relevant style guides] and ran [the auto-formatter]. - [x] I signed the [CLA]. - [x] The title of the PR starts with the name of the package surrounded by square brackets, e.g. `[shared_preferences]` - [x] I [linked to at least one issue that this PR fixes] in the description above. - [ ] I followed [the version and CHANGELOG instructions], using [semantic versioning] and the [repository CHANGELOG style], or I have commented below to indicate which documented exception this PR falls under[^1]. - [x] I updated/added any relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or I have commented below to indicate which [test exemption] this PR falls under[^1]. - [ ] All existing and new tests are passing. --- packages/material_ui/lib/src/app_bar.dart | 111 +--------------- .../src/generated/app_bar_defaults_m3.g.dart} | 5 + .../tool/gen_defaults/bin/gen_defaults.dart | 7 +- .../templates/app_bar_template.dart | 121 ++++++++++++++++++ .../templates/app_bar_template.dart | 112 ---------------- .../gen_defaults/test/gen_defaults_test.dart | 13 ++ 6 files changed, 143 insertions(+), 226 deletions(-) rename packages/material_ui/{tool/gen_defaults/temporarily_excluded/generated/app_bar_defaults.g.dart => lib/src/generated/app_bar_defaults_m3.g.dart} (93%) create mode 100644 packages/material_ui/tool/gen_defaults/templates/app_bar_template.dart delete mode 100644 packages/material_ui/tool/gen_defaults/temporarily_excluded/templates/app_bar_template.dart diff --git a/packages/material_ui/lib/src/app_bar.dart b/packages/material_ui/lib/src/app_bar.dart index 7997ed4c39b7..523053651ef7 100644 --- a/packages/material_ui/lib/src/app_bar.dart +++ b/packages/material_ui/lib/src/app_bar.dart @@ -34,6 +34,8 @@ import 'tabs.dart'; import 'text_theme.dart'; import 'theme.dart'; +part 'generated/app_bar_defaults_m3.g.dart'; + // Examples can assume: // late String _logoAsset; // double _myToolbarHeight = 250.0; @@ -2576,112 +2578,3 @@ class _AppBarDefaultsM2 extends AppBarThemeData { @override EdgeInsets? get actionsPadding => EdgeInsets.zero; } - -// BEGIN GENERATED TOKEN PROPERTIES - AppBar - -// 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 _AppBarDefaultsM3 extends AppBarThemeData { - _AppBarDefaultsM3(this.context) - : super( - elevation: 0.0, - scrolledUnderElevation: 3.0, - titleSpacing: NavigationToolbar.kMiddleSpacing, - toolbarHeight: 64.0, - ); - - final BuildContext context; - late final ThemeData _theme = Theme.of(context); - late final ColorScheme _colors = _theme.colorScheme; - late final TextTheme _textTheme = _theme.textTheme; - - @override - Color? get backgroundColor => _colors.surface; - - @override - Color? get foregroundColor => _colors.onSurface; - - @override - Color? get shadowColor => Colors.transparent; - - @override - Color? get surfaceTintColor => Colors.transparent; - - @override - IconThemeData? get iconTheme => IconThemeData( - color: _colors.onSurface, - size: 24.0, - ); - - @override - IconThemeData? get actionsIconTheme => IconThemeData( - color: _colors.onSurfaceVariant, - size: 24.0, - ); - - @override - TextStyle? get toolbarTextStyle => _textTheme.bodyMedium; - - @override - TextStyle? get titleTextStyle => _textTheme.titleLarge; - - // TODO(Craftplacer): Consider using EdgeInsets.only(right: 8.0) instead of - // EdgeInsets.zero for Material 3 in the future, - // https://github.com/flutter/flutter/issues/155747 - @override - EdgeInsets? get actionsPadding => EdgeInsets.zero; -} - -// Variant configuration -class _MediumScrollUnderFlexibleConfig with _ScrollUnderFlexibleConfig { - _MediumScrollUnderFlexibleConfig(this.context); - - final BuildContext context; - late final ThemeData _theme = Theme.of(context); - late final ColorScheme _colors = _theme.colorScheme; - late final TextTheme _textTheme = _theme.textTheme; - - static const double collapsedHeight = 64.0; - static const double expandedHeight = 112.0; - - @override - TextStyle? get collapsedTextStyle => - _textTheme.titleLarge?.apply(color: _colors.onSurface); - - @override - TextStyle? get expandedTextStyle => - _textTheme.headlineSmall?.apply(color: _colors.onSurface); - - @override - EdgeInsetsGeometry get expandedTitlePadding => const EdgeInsets.fromLTRB(16, 0, 16, 20); -} - -class _LargeScrollUnderFlexibleConfig with _ScrollUnderFlexibleConfig { - _LargeScrollUnderFlexibleConfig(this.context); - - final BuildContext context; - late final ThemeData _theme = Theme.of(context); - late final ColorScheme _colors = _theme.colorScheme; - late final TextTheme _textTheme = _theme.textTheme; - - static const double collapsedHeight = 64.0; - static const double expandedHeight = 152.0; - - @override - TextStyle? get collapsedTextStyle => - _textTheme.titleLarge?.apply(color: _colors.onSurface); - - @override - TextStyle? get expandedTextStyle => - _textTheme.headlineMedium?.apply(color: _colors.onSurface); - - @override - EdgeInsetsGeometry get expandedTitlePadding => const EdgeInsets.fromLTRB(16, 0, 16, 28); -} -// dart format on - -// END GENERATED TOKEN PROPERTIES - AppBar diff --git a/packages/material_ui/tool/gen_defaults/temporarily_excluded/generated/app_bar_defaults.g.dart b/packages/material_ui/lib/src/generated/app_bar_defaults_m3.g.dart similarity index 93% rename from packages/material_ui/tool/gen_defaults/temporarily_excluded/generated/app_bar_defaults.g.dart rename to packages/material_ui/lib/src/generated/app_bar_defaults_m3.g.dart index 016534430147..e50453c58df7 100644 --- a/packages/material_ui/tool/gen_defaults/temporarily_excluded/generated/app_bar_defaults.g.dart +++ b/packages/material_ui/lib/src/generated/app_bar_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 '../app_bar.dart'; + class _AppBarDefaultsM3 extends AppBarThemeData { _AppBarDefaultsM3(this.context) : super( 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 2da295bc4e99..bcfe06fba9db 100644 --- a/packages/material_ui/tool/gen_defaults/bin/gen_defaults.dart +++ b/packages/material_ui/tool/gen_defaults/bin/gen_defaults.dart @@ -12,8 +12,7 @@ import 'package:args/args.dart'; -// TODO(elliette): Import template files. -// import '../templates/x_template.dart'; +import '../templates/app_bar_template.dart'; Future main(List args) async { // Parse arguments @@ -21,8 +20,6 @@ Future main(List args) async { parser.addFlag('verbose', abbr: 'v', help: 'Enable verbose output', negatable: false); final ArgResults argResults = parser.parse(args); // TODO(elliette): Add token logger when verbose flag is used. - // ignore: unused_local_variable final verbose = argResults['verbose'] as bool; - // TODO(elliette): Invoke template generators. - // const XTemplate().generateFile(verbose: verbose); + const AppBarTemplateM3().generateFile(verbose: verbose); } diff --git a/packages/material_ui/tool/gen_defaults/templates/app_bar_template.dart b/packages/material_ui/tool/gen_defaults/templates/app_bar_template.dart new file mode 100644 index 000000000000..b4963b2aabfb --- /dev/null +++ b/packages/material_ui/tool/gen_defaults/templates/app_bar_template.dart @@ -0,0 +1,121 @@ +// 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/app_bar.dart'; +import '../data/app_bar_large.dart'; +import '../data/app_bar_medium.dart'; +import '../data/app_bar_small.dart'; +import 'template.dart'; + +class AppBarTemplateM3 extends TokenTemplateM3 { + const AppBarTemplateM3(); + + @override + String get name => 'App Bar'; + + @override + String get parentFilePath => 'app_bar.dart'; + + @override + String generateContents(String className) => + ''' +class $className extends AppBarThemeData { + $className(this.context) + : super( + elevation: ${number(TokenAppBar.containerElevation)}, + scrolledUnderElevation: ${number(TokenAppBar.onScrollContainerElevation)}, + titleSpacing: NavigationToolbar.kMiddleSpacing, + toolbarHeight: ${number(TokenAppBarSmall.containerHeight)}, + ); + + final BuildContext context; + late final ThemeData _theme = Theme.of(context); + late final ColorScheme _colors = _theme.colorScheme; + late final TextTheme _textTheme = _theme.textTheme; + + @override + Color? get backgroundColor => ${color(TokenAppBar.containerColor, '_colors')}; + + @override + Color? get foregroundColor => ${color(TokenAppBar.titleColor, '_colors')}; + + @override + Color? get shadowColor => Colors.transparent; + + @override + Color? get surfaceTintColor => Colors.transparent; + + @override + IconThemeData? get iconTheme => IconThemeData( + color: ${color(TokenAppBar.leadingIconColor, '_colors')}, + size: ${number(TokenAppBar.iconSize)}, + ); + + @override + IconThemeData? get actionsIconTheme => IconThemeData( + color: ${color(TokenAppBar.trailingIconColor, '_colors')}, + size: ${number(TokenAppBar.iconSize)}, + ); + + @override + TextStyle? get toolbarTextStyle => _textTheme.bodyMedium; + + @override + TextStyle? get titleTextStyle => _textTheme.titleLarge; + + // TODO(Craftplacer): Consider using EdgeInsets.only(right: 8.0) instead of + // EdgeInsets.zero for Material 3 in the future, + // https://github.com/flutter/flutter/issues/155747 + @override + EdgeInsets? get actionsPadding => EdgeInsets.zero; +} + +// Variant configuration +class _MediumScrollUnderFlexibleConfig with _ScrollUnderFlexibleConfig { + _MediumScrollUnderFlexibleConfig(this.context); + + final BuildContext context; + late final ThemeData _theme = Theme.of(context); + late final ColorScheme _colors = _theme.colorScheme; + late final TextTheme _textTheme = _theme.textTheme; + + static const double collapsedHeight = ${number(TokenAppBarSmall.containerHeight)}; + static const double expandedHeight = ${number(TokenAppBarMedium.containerHeight)}; + + @override + TextStyle? get collapsedTextStyle => + _textTheme.titleLarge?.apply(color: ${color(TokenAppBar.titleColor, '_colors')}); + + @override + TextStyle? get expandedTextStyle => + _textTheme.headlineSmall?.apply(color: ${color(TokenAppBar.titleColor, '_colors')}); + + @override + EdgeInsetsGeometry get expandedTitlePadding => const EdgeInsets.fromLTRB(16, 0, 16, 20); +} + +class _LargeScrollUnderFlexibleConfig with _ScrollUnderFlexibleConfig { + _LargeScrollUnderFlexibleConfig(this.context); + + final BuildContext context; + late final ThemeData _theme = Theme.of(context); + late final ColorScheme _colors = _theme.colorScheme; + late final TextTheme _textTheme = _theme.textTheme; + + static const double collapsedHeight = ${number(TokenAppBarSmall.containerHeight)}; + static const double expandedHeight = ${number(TokenAppBarLarge.containerHeight)}; + + @override + TextStyle? get collapsedTextStyle => + _textTheme.titleLarge?.apply(color: ${color(TokenAppBar.titleColor, '_colors')}); + + @override + TextStyle? get expandedTextStyle => + _textTheme.headlineMedium?.apply(color: ${color(TokenAppBar.titleColor, '_colors')}); + + @override + EdgeInsetsGeometry get expandedTitlePadding => const EdgeInsets.fromLTRB(16, 0, 16, 28); +} +'''; +} diff --git a/packages/material_ui/tool/gen_defaults/temporarily_excluded/templates/app_bar_template.dart b/packages/material_ui/tool/gen_defaults/temporarily_excluded/templates/app_bar_template.dart deleted file mode 100644 index fa13fa14f19b..000000000000 --- a/packages/material_ui/tool/gen_defaults/temporarily_excluded/templates/app_bar_template.dart +++ /dev/null @@ -1,112 +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 AppBarTemplate extends TokenTemplate { - const AppBarTemplate(super.blockName, super.fileName, super.tokens) - : super(colorSchemePrefix: '_colors.', textThemePrefix: '_textTheme.'); - - @override - String generate() => - ''' -class _${blockName}DefaultsM3 extends AppBarThemeData { - _${blockName}DefaultsM3(this.context) - : super( - elevation: ${elevation('md.comp.top-app-bar.small.container')}, - scrolledUnderElevation: ${elevation('md.comp.top-app-bar.small.on-scroll.container')}, - titleSpacing: NavigationToolbar.kMiddleSpacing, - toolbarHeight: ${getToken('md.comp.top-app-bar.small.container.height')}, - ); - - final BuildContext context; - late final ThemeData _theme = Theme.of(context); - late final ColorScheme _colors = _theme.colorScheme; - late final TextTheme _textTheme = _theme.textTheme; - - @override - Color? get backgroundColor => ${componentColor('md.comp.top-app-bar.small.container')}; - - @override - Color? get foregroundColor => ${color('md.comp.top-app-bar.small.headline.color')}; - - @override - Color? get shadowColor => ${colorOrTransparent('md.comp.top-app-bar.small.container.shadow-color')}; - - @override - Color? get surfaceTintColor => ${colorOrTransparent('md.comp.top-app-bar.small.container.surface-tint-layer.color')}; - - @override - IconThemeData? get iconTheme => IconThemeData( - color: ${componentColor('md.comp.top-app-bar.small.leading-icon')}, - size: ${getToken('md.comp.top-app-bar.small.leading-icon.size')}, - ); - - @override - IconThemeData? get actionsIconTheme => IconThemeData( - color: ${componentColor('md.comp.top-app-bar.small.trailing-icon')}, - size: ${getToken('md.comp.top-app-bar.small.trailing-icon.size')}, - ); - - @override - TextStyle? get toolbarTextStyle => _textTheme.bodyMedium; - - @override - TextStyle? get titleTextStyle => ${textStyle('md.comp.top-app-bar.small.headline')}; - - // TODO(Craftplacer): Consider using EdgeInsets.only(right: 8.0) instead of - // EdgeInsets.zero for Material 3 in the future, - // https://github.com/flutter/flutter/issues/155747 - @override - EdgeInsets? get actionsPadding => EdgeInsets.zero; -} - -// Variant configuration -class _MediumScrollUnderFlexibleConfig with _ScrollUnderFlexibleConfig { - _MediumScrollUnderFlexibleConfig(this.context); - - final BuildContext context; - late final ThemeData _theme = Theme.of(context); - late final ColorScheme _colors = _theme.colorScheme; - late final TextTheme _textTheme = _theme.textTheme; - - static const double collapsedHeight = ${getToken('md.comp.top-app-bar.small.container.height')}; - static const double expandedHeight = ${getToken('md.comp.top-app-bar.medium.container.height')}; - - @override - TextStyle? get collapsedTextStyle => - ${textStyle('md.comp.top-app-bar.small.headline')}?.apply(color: ${color('md.comp.top-app-bar.small.headline.color')}); - - @override - TextStyle? get expandedTextStyle => - ${textStyle('md.comp.top-app-bar.medium.headline')}?.apply(color: ${color('md.comp.top-app-bar.medium.headline.color')}); - - @override - EdgeInsetsGeometry get expandedTitlePadding => const EdgeInsets.fromLTRB(16, 0, 16, 20); -} - -class _LargeScrollUnderFlexibleConfig with _ScrollUnderFlexibleConfig { - _LargeScrollUnderFlexibleConfig(this.context); - - final BuildContext context; - late final ThemeData _theme = Theme.of(context); - late final ColorScheme _colors = _theme.colorScheme; - late final TextTheme _textTheme = _theme.textTheme; - - static const double collapsedHeight = ${getToken('md.comp.top-app-bar.small.container.height')}; - static const double expandedHeight = ${getToken('md.comp.top-app-bar.large.container.height')}; - - @override - TextStyle? get collapsedTextStyle => - ${textStyle('md.comp.top-app-bar.small.headline')}?.apply(color: ${color('md.comp.top-app-bar.small.headline.color')}); - - @override - TextStyle? get expandedTextStyle => - ${textStyle('md.comp.top-app-bar.large.headline')}?.apply(color: ${color('md.comp.top-app-bar.large.headline.color')}); - - @override - EdgeInsetsGeometry get expandedTitlePadding => const EdgeInsets.fromLTRB(16, 0, 16, 28); -} -'''; -} 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 26eaf485c53c..90063d5cdbe2 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,6 +7,7 @@ import 'dart:io'; import 'package:test/test.dart'; import '../data/color_role.dart'; import '../data/shape_struct.dart'; +import '../templates/app_bar_template.dart'; import '../templates/template.dart'; import 'test_fixtures/test_templates.dart'; @@ -146,6 +147,18 @@ void main() { ), ); }); + + test('AppBarTemplateM3 emits M3 AppBar defaults from app bar tokens', () { + final String contents = const AppBarTemplateM3().generateContents('_AppBarDefaultsM3'); + expect(contents, contains('class _AppBarDefaultsM3 extends AppBarThemeData')); + expect(contents, contains('scrolledUnderElevation: 3.0')); + expect(contents, contains('toolbarHeight: 64.0')); + expect(contents, contains('Color? get backgroundColor => _colors.surface')); + expect(contents, contains('Color? get foregroundColor => _colors.onSurface')); + expect(contents, contains('color: _colors.onSurfaceVariant')); + expect(contents, contains('static const double expandedHeight = 112.0')); + expect(contents, contains('static const double expandedHeight = 152.0')); + }); test('will run dart format over the generated file', () { final template = UnformattedTemplate(testPath()); template.generateFile();