From 3001faa227ba2db79ee95d41b9027839dbdc826e Mon Sep 17 00:00:00 2001 From: Qun Cheng Date: Tue, 8 Sep 2026 18:12:01 -0700 Subject: [PATCH] Migrate M3 Checkbox defaults to new gen_defaults --- packages/material_ui/lib/src/checkbox.dart | 141 +--------------- .../generated/checkbox_defaults_m3.g.dart} | 5 + .../tool/gen_defaults/bin/gen_defaults.dart | 4 +- .../templates/checkbox_template.dart | 150 ++++++++++++++++++ .../templates/checkbox_template.dart | 146 ----------------- .../gen_defaults/test/gen_defaults_test.dart | 33 +++- 6 files changed, 189 insertions(+), 290 deletions(-) rename packages/material_ui/{tool/gen_defaults/temporarily_excluded/generated/checkbox_defaults.g.dart => lib/src/generated/checkbox_defaults_m3.g.dart} (95%) create mode 100644 packages/material_ui/tool/gen_defaults/templates/checkbox_template.dart delete mode 100644 packages/material_ui/tool/gen_defaults/temporarily_excluded/templates/checkbox_template.dart diff --git a/packages/material_ui/lib/src/checkbox.dart b/packages/material_ui/lib/src/checkbox.dart index 59660b5991e4..22f2936bed26 100644 --- a/packages/material_ui/lib/src/checkbox.dart +++ b/packages/material_ui/lib/src/checkbox.dart @@ -20,6 +20,8 @@ import 'debug.dart'; import 'theme.dart'; import 'theme_data.dart'; +part 'generated/checkbox_defaults_m3.g.dart'; + // Examples can assume: // bool _throwShotAway = false; // late StateSetter setState; @@ -928,142 +930,3 @@ class _CheckboxDefaultsM2 extends CheckboxThemeData { OutlinedBorder get shape => const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(1.0))); } - -// BEGIN GENERATED TOKEN PROPERTIES - Checkbox - -// 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 _CheckboxDefaultsM3 extends CheckboxThemeData { - _CheckboxDefaultsM3(BuildContext context) - : _theme = Theme.of(context), - _colors = Theme.of(context).colorScheme; - - final ThemeData _theme; - final ColorScheme _colors; - - @override - WidgetStateBorderSide? get side { - return WidgetStateBorderSide.resolveWith((Set states) { - if (states.contains(WidgetState.disabled)) { - if (states.contains(WidgetState.selected)) { - return const BorderSide(width: 2.0, color: Colors.transparent); - } - return BorderSide(width: 2.0, color: _colors.onSurface.withOpacity(0.38)); - } - if (states.contains(WidgetState.selected)) { - return const BorderSide(width: 0.0, color: Colors.transparent); - } - if (states.contains(WidgetState.error)) { - return BorderSide(width: 2.0, color: _colors.error); - } - if (states.contains(WidgetState.pressed)) { - return BorderSide(width: 2.0, color: _colors.onSurface); - } - if (states.contains(WidgetState.hovered)) { - return BorderSide(width: 2.0, color: _colors.onSurface); - } - if (states.contains(WidgetState.focused)) { - return BorderSide(width: 2.0, color: _colors.onSurface); - } - return BorderSide(width: 2.0, color: _colors.onSurfaceVariant); - }); - } - - @override - WidgetStateProperty get fillColor { - return WidgetStateProperty.resolveWith((Set states) { - if (states.contains(WidgetState.disabled)) { - if (states.contains(WidgetState.selected)) { - return _colors.onSurface.withOpacity(0.38); - } - return Colors.transparent; - } - if (states.contains(WidgetState.selected)) { - if (states.contains(WidgetState.error)) { - return _colors.error; - } - return _colors.primary; - } - return Colors.transparent; - }); - } - - @override - WidgetStateProperty get checkColor { - return WidgetStateProperty.resolveWith((Set states) { - if (states.contains(WidgetState.disabled)) { - if (states.contains(WidgetState.selected)) { - return _colors.surface; - } - return Colors.transparent; // No icons available when the checkbox is unselected. - } - if (states.contains(WidgetState.selected)) { - if (states.contains(WidgetState.error)) { - return _colors.onError; - } - return _colors.onPrimary; - } - return Colors.transparent; // No icons available when the checkbox is unselected. - }); - } - - @override - WidgetStateProperty get overlayColor { - return WidgetStateProperty.resolveWith((Set states) { - if (states.contains(WidgetState.error)) { - if (states.contains(WidgetState.pressed)) { - return _colors.error.withOpacity(0.1); - } - if (states.contains(WidgetState.hovered)) { - return _colors.error.withOpacity(0.08); - } - if (states.contains(WidgetState.focused)) { - return _colors.error.withOpacity(0.1); - } - } - if (states.contains(WidgetState.selected)) { - if (states.contains(WidgetState.pressed)) { - return _colors.onSurface.withOpacity(0.1); - } - if (states.contains(WidgetState.hovered)) { - return _colors.primary.withOpacity(0.08); - } - if (states.contains(WidgetState.focused)) { - return _colors.primary.withOpacity(0.1); - } - return Colors.transparent; - } - if (states.contains(WidgetState.pressed)) { - return _colors.primary.withOpacity(0.1); - } - if (states.contains(WidgetState.hovered)) { - return _colors.onSurface.withOpacity(0.08); - } - if (states.contains(WidgetState.focused)) { - return _colors.onSurface.withOpacity(0.1); - } - return Colors.transparent; - }); - } - - @override - double get splashRadius => 40.0 / 2; - - @override - MaterialTapTargetSize get materialTapTargetSize => _theme.materialTapTargetSize; - - @override - VisualDensity get visualDensity => VisualDensity.standard; - - @override - OutlinedBorder get shape => const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(2.0)), - ); -} -// dart format on - -// END GENERATED TOKEN PROPERTIES - Checkbox diff --git a/packages/material_ui/tool/gen_defaults/temporarily_excluded/generated/checkbox_defaults.g.dart b/packages/material_ui/lib/src/generated/checkbox_defaults_m3.g.dart similarity index 95% rename from packages/material_ui/tool/gen_defaults/temporarily_excluded/generated/checkbox_defaults.g.dart rename to packages/material_ui/lib/src/generated/checkbox_defaults_m3.g.dart index b92eb235e81e..64a7ec72dee4 100644 --- a/packages/material_ui/tool/gen_defaults/temporarily_excluded/generated/checkbox_defaults.g.dart +++ b/packages/material_ui/lib/src/generated/checkbox_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 '../checkbox.dart'; + class _CheckboxDefaultsM3 extends CheckboxThemeData { _CheckboxDefaultsM3(BuildContext context) : _theme = Theme.of(context), 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 849621e5b575..b4c73d874490 100644 --- a/packages/material_ui/tool/gen_defaults/bin/gen_defaults.dart +++ b/packages/material_ui/tool/gen_defaults/bin/gen_defaults.dart @@ -20,8 +20,8 @@ import '../templates/banner_template.dart'; import '../templates/bottom_sheet_template.dart'; import '../templates/button_template.dart'; import '../templates/card_template.dart'; +import '../templates/checkbox_template.dart'; -// import '../templates/checkbox_template.dart'; // import '../templates/chip_template.dart'; // import '../templates/color_scheme_template.dart'; // import '../templates/date_picker_template.dart'; @@ -78,7 +78,7 @@ Future main(List args) async { const CardTemplateM3('Card').generateFile(verbose: verbose); const CardTemplateM3('Filled Card').generateFile(verbose: verbose); const CardTemplateM3('Outlined Card').generateFile(verbose: verbose); - // const CheckboxTemplateM3().generateFile(verbose: verbose); + const CheckboxTemplateM3().generateFile(verbose: verbose); // const ChipTemplateM3().generateFile(verbose: verbose); // const ColorSchemeTemplateM3().generateFile(verbose: verbose); // const DatePickerTemplateM3().generateFile(verbose: verbose); diff --git a/packages/material_ui/tool/gen_defaults/templates/checkbox_template.dart b/packages/material_ui/tool/gen_defaults/templates/checkbox_template.dart new file mode 100644 index 000000000000..f418cc7060a7 --- /dev/null +++ b/packages/material_ui/tool/gen_defaults/templates/checkbox_template.dart @@ -0,0 +1,150 @@ +// 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/checkbox.dart'; +import 'template.dart'; + +class CheckboxTemplateM3 extends TokenTemplateM3 { + const CheckboxTemplateM3(); + + @override + String get name => 'Checkbox'; + + @override + String get parentFilePath => 'checkbox.dart'; + + String _borderSide(double width, String color, {bool isConst = false}) { + return '${isConst ? 'const ' : ''}BorderSide(width: ${number(width)}, color: $color)'; + } + + @override + String generateContents(String className) => + ''' +class $className extends CheckboxThemeData { + $className(BuildContext context) + : _theme = Theme.of(context), + _colors = Theme.of(context).colorScheme; + + final ThemeData _theme; + final ColorScheme _colors; + + @override + WidgetStateBorderSide? get side { + return WidgetStateBorderSide.resolveWith((Set states) { + if (states.contains(WidgetState.disabled)) { + if (states.contains(WidgetState.selected)) { + return ${_borderSide(TokenCheckbox.unselectedDisabledOutlineWidth, 'Colors.transparent', isConst: true)}; + } + return ${_borderSide(TokenCheckbox.unselectedDisabledOutlineWidth, colorWithOpacity(TokenCheckbox.unselectedDisabledOutlineColor, TokenCheckbox.unselectedDisabledContainerOpacity, '_colors'))}; + } + if (states.contains(WidgetState.selected)) { + return ${_borderSide(TokenCheckbox.selectedOutlineWidth, 'Colors.transparent', isConst: true)}; + } + if (states.contains(WidgetState.error)) { + return ${_borderSide(TokenCheckbox.unselectedOutlineWidth, color(TokenCheckbox.unselectedErrorOutlineColor, '_colors'))}; + } + if (states.contains(WidgetState.pressed)) { + return ${_borderSide(TokenCheckbox.unselectedPressedOutlineWidth, color(TokenCheckbox.unselectedPressedOutlineColor, '_colors'))}; + } + if (states.contains(WidgetState.hovered)) { + return ${_borderSide(TokenCheckbox.unselectedHoverOutlineWidth, color(TokenCheckbox.unselectedHoverOutlineColor, '_colors'))}; + } + if (states.contains(WidgetState.focused)) { + return ${_borderSide(TokenCheckbox.unselectedFocusOutlineWidth, color(TokenCheckbox.unselectedFocusOutlineColor, '_colors'))}; + } + return ${_borderSide(TokenCheckbox.unselectedOutlineWidth, color(TokenCheckbox.unselectedOutlineColor, '_colors'))}; + }); + } + + @override + WidgetStateProperty get fillColor { + return WidgetStateProperty.resolveWith((Set states) { + if (states.contains(WidgetState.disabled)) { + if (states.contains(WidgetState.selected)) { + return ${colorWithOpacity(TokenCheckbox.selectedDisabledContainerColor, TokenCheckbox.selectedDisabledContainerOpacity, '_colors')}; + } + return Colors.transparent; + } + if (states.contains(WidgetState.selected)) { + if (states.contains(WidgetState.error)) { + return ${color(TokenCheckbox.selectedErrorContainerColor, '_colors')}; + } + return ${color(TokenCheckbox.selectedContainerColor, '_colors')}; + } + return Colors.transparent; + }); + } + + @override + WidgetStateProperty get checkColor { + return WidgetStateProperty.resolveWith((Set states) { + if (states.contains(WidgetState.disabled)) { + if (states.contains(WidgetState.selected)) { + return ${color(TokenCheckbox.selectedDisabledIconColor, '_colors')}; + } + return Colors.transparent; // No icons available when the checkbox is unselected. + } + if (states.contains(WidgetState.selected)) { + if (states.contains(WidgetState.error)) { + return ${color(TokenCheckbox.selectedErrorIconColor, '_colors')}; + } + return ${color(TokenCheckbox.selectedIconColor, '_colors')}; + } + return Colors.transparent; // No icons available when the checkbox is unselected. + }); + } + + @override + WidgetStateProperty get overlayColor { + return WidgetStateProperty.resolveWith((Set states) { + if (states.contains(WidgetState.error)) { + if (states.contains(WidgetState.pressed)) { + return ${colorWithOpacity(TokenCheckbox.errorPressedStateLayerColor, TokenCheckbox.errorPressedStateLayerOpacity, '_colors')}; + } + if (states.contains(WidgetState.hovered)) { + return ${colorWithOpacity(TokenCheckbox.errorHoverStateLayerColor, TokenCheckbox.errorHoverStateLayerOpacity, '_colors')}; + } + if (states.contains(WidgetState.focused)) { + return ${colorWithOpacity(TokenCheckbox.errorFocusStateLayerColor, TokenCheckbox.errorFocusStateLayerOpacity, '_colors')}; + } + } + if (states.contains(WidgetState.selected)) { + if (states.contains(WidgetState.pressed)) { + return ${colorWithOpacity(TokenCheckbox.selectedPressedStateLayerColor, TokenCheckbox.selectedPressedStateLayerOpacity, '_colors')}; + } + if (states.contains(WidgetState.hovered)) { + return ${colorWithOpacity(TokenCheckbox.selectedHoverStateLayerColor, TokenCheckbox.selectedHoverStateLayerOpacity, '_colors')}; + } + if (states.contains(WidgetState.focused)) { + return ${colorWithOpacity(TokenCheckbox.selectedFocusStateLayerColor, TokenCheckbox.selectedFocusStateLayerOpacity, '_colors')}; + } + return Colors.transparent; + } + if (states.contains(WidgetState.pressed)) { + return ${colorWithOpacity(TokenCheckbox.unselectedPressedStateLayerColor, TokenCheckbox.unselectedPressedStateLayerOpacity, '_colors')}; + } + if (states.contains(WidgetState.hovered)) { + return ${colorWithOpacity(TokenCheckbox.unselectedHoverStateLayerColor, TokenCheckbox.unselectedHoverStateLayerOpacity, '_colors')}; + } + if (states.contains(WidgetState.focused)) { + return ${colorWithOpacity(TokenCheckbox.unselectedFocusStateLayerColor, TokenCheckbox.unselectedFocusStateLayerOpacity, '_colors')}; + } + return Colors.transparent; + }); + } + + @override + double get splashRadius => ${number(TokenCheckbox.stateLayerSize)} / 2; + + @override + MaterialTapTargetSize get materialTapTargetSize => _theme.materialTapTargetSize; + + @override + VisualDensity get visualDensity => VisualDensity.standard; + + @override + OutlinedBorder get shape => ${shape(TokenCheckbox.containerShape)}; +} +'''; +} diff --git a/packages/material_ui/tool/gen_defaults/temporarily_excluded/templates/checkbox_template.dart b/packages/material_ui/tool/gen_defaults/temporarily_excluded/templates/checkbox_template.dart deleted file mode 100644 index 43f21ba1e53f..000000000000 --- a/packages/material_ui/tool/gen_defaults/temporarily_excluded/templates/checkbox_template.dart +++ /dev/null @@ -1,146 +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 CheckboxTemplate extends TokenTemplate { - const CheckboxTemplate( - super.blockName, - super.fileName, - super.tokens, { - super.colorSchemePrefix = '_colors.', - }); - - @override - String generate() => - ''' -class _${blockName}DefaultsM3 extends CheckboxThemeData { - _${blockName}DefaultsM3(BuildContext context) - : _theme = Theme.of(context), - _colors = Theme.of(context).colorScheme; - - final ThemeData _theme; - final ColorScheme _colors; - - @override - WidgetStateBorderSide? get side { - return WidgetStateBorderSide.resolveWith((Set states) { - if (states.contains(WidgetState.disabled)) { - if (states.contains(WidgetState.selected)) { - return const BorderSide(width: ${getToken('md.comp.checkbox.unselected.disabled.outline.width')}, color: Colors.transparent); - } - return BorderSide(width: ${getToken('md.comp.checkbox.unselected.disabled.outline.width')}, color: ${componentColor('md.comp.checkbox.unselected.disabled.outline')}.withOpacity(${getToken('md.comp.checkbox.unselected.disabled.container.opacity')})); - } - if (states.contains(WidgetState.selected)) { - return const BorderSide(width: ${getToken('md.comp.checkbox.selected.outline.width')}, color: Colors.transparent); - } - if (states.contains(WidgetState.error)) { - return BorderSide(width: ${getToken('md.comp.checkbox.unselected.disabled.outline.width')}, color: ${componentColor('md.comp.checkbox.unselected.error.outline')}); - } - if (states.contains(WidgetState.pressed)) { - return BorderSide(width: ${getToken('md.comp.checkbox.unselected.pressed.outline.width')}, color: ${componentColor('md.comp.checkbox.unselected.pressed.outline')}); - } - if (states.contains(WidgetState.hovered)) { - return BorderSide(width: ${getToken('md.comp.checkbox.unselected.hover.outline.width')}, color: ${componentColor('md.comp.checkbox.unselected.hover.outline')}); - } - if (states.contains(WidgetState.focused)) { - return BorderSide(width: ${getToken('md.comp.checkbox.unselected.focus.outline.width')}, color: ${componentColor('md.comp.checkbox.unselected.focus.outline')}); - } - return BorderSide(width: ${getToken('md.comp.checkbox.unselected.outline.width')}, color: ${componentColor('md.comp.checkbox.unselected.outline')}); - }); - } - - @override - WidgetStateProperty get fillColor { - return WidgetStateProperty.resolveWith((Set states) { - if (states.contains(WidgetState.disabled)) { - if (states.contains(WidgetState.selected)) { - return ${componentColor('md.comp.checkbox.selected.disabled.container')}; - } - return Colors.transparent; - } - if (states.contains(WidgetState.selected)) { - if (states.contains(WidgetState.error)) { - return ${componentColor('md.comp.checkbox.selected.error.container')}; - } - return ${componentColor('md.comp.checkbox.selected.container')}; - } - return Colors.transparent; - }); - } - - @override - WidgetStateProperty get checkColor { - return WidgetStateProperty.resolveWith((Set states) { - if (states.contains(WidgetState.disabled)) { - if (states.contains(WidgetState.selected)) { - return ${componentColor('md.comp.checkbox.selected.disabled.icon')}; - } - return Colors.transparent; // No icons available when the checkbox is unselected. - } - if (states.contains(WidgetState.selected)) { - if (states.contains(WidgetState.error)) { - return ${componentColor('md.comp.checkbox.selected.error.icon')}; - } - return ${componentColor('md.comp.checkbox.selected.icon')}; - } - return Colors.transparent; // No icons available when the checkbox is unselected. - }); - } - - @override - WidgetStateProperty get overlayColor { - return WidgetStateProperty.resolveWith((Set states) { - if (states.contains(WidgetState.error)) { - if (states.contains(WidgetState.pressed)) { - return ${componentColor('md.comp.checkbox.error.pressed.state-layer')}; - } - if (states.contains(WidgetState.hovered)) { - return ${componentColor('md.comp.checkbox.error.hover.state-layer')}; - } - if (states.contains(WidgetState.focused)) { - return ${componentColor('md.comp.checkbox.error.focus.state-layer')}; - } - } - if (states.contains(WidgetState.selected)) { - if (states.contains(WidgetState.pressed)) { - return ${componentColor('md.comp.checkbox.selected.pressed.state-layer')}; - } - if (states.contains(WidgetState.hovered)) { - return ${componentColor('md.comp.checkbox.selected.hover.state-layer')}; - } - if (states.contains(WidgetState.focused)) { - return ${componentColor('md.comp.checkbox.selected.focus.state-layer')}; - } - return Colors.transparent; - } - if (states.contains(WidgetState.pressed)) { - return ${componentColor('md.comp.checkbox.unselected.pressed.state-layer')}; - } - if (states.contains(WidgetState.hovered)) { - return ${componentColor('md.comp.checkbox.unselected.hover.state-layer')}; - } - if (states.contains(WidgetState.focused)) { - return ${componentColor('md.comp.checkbox.unselected.focus.state-layer')}; - } - return Colors.transparent; - }); - } - - @override - double get splashRadius => ${getToken('md.comp.checkbox.state-layer.size')} / 2; - - @override - MaterialTapTargetSize get materialTapTargetSize => _theme.materialTapTargetSize; - - @override - VisualDensity get visualDensity => VisualDensity.standard; - - @override - OutlinedBorder get shape => const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(${getToken('md.comp.checkbox.unselected.outline.width')})), - ); -} -'''; -} 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 58c4b8619a16..a51ce512d309 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 @@ -17,7 +17,7 @@ import '../templates/banner_template.dart'; import '../templates/bottom_sheet_template.dart'; import '../templates/button_template.dart'; import '../templates/card_template.dart'; -// import '../templates/checkbox_template.dart'; +import '../templates/checkbox_template.dart'; // import '../templates/chip_template.dart'; // import '../templates/color_scheme_template.dart'; // import '../templates/date_picker_template.dart'; @@ -444,8 +444,35 @@ void main() { }); test('CheckboxTemplateM3 emits M3 Checkbox defaults from tokens', () { - // Intentionally empty, will be implemented during migration. See: - // https://github.com/flutter/flutter/issues/187899 + final String contents = _generateContents(const CheckboxTemplateM3()); + expect(contents, contains('class _CheckboxDefaultsM3 extends CheckboxThemeData')); + expect(contents, contains('WidgetStateBorderSide? get side')); + expect(contents, contains('return const BorderSide(width: 2.0, color: Colors.transparent);')); + expect( + contents, + contains('return BorderSide(width: 2.0, color: _colors.onSurface.withOpacity(0.38));'), + ); + expect(contents, contains('return const BorderSide(width: 0.0, color: Colors.transparent);')); + expect(contents, contains('return BorderSide(width: 2.0, color: _colors.error);')); + expect(contents, contains('WidgetStateProperty get fillColor')); + expect(contents, contains('return _colors.onSurface.withOpacity(0.38);')); + expect(contents, contains('return _colors.primary;')); + expect(contents, contains('WidgetStateProperty get checkColor')); + expect(contents, contains('return _colors.surface;')); + expect(contents, contains('return _colors.onError;')); + expect(contents, contains('return _colors.onPrimary;')); + expect(contents, contains('WidgetStateProperty get overlayColor')); + expect(contents, contains('return _colors.error.withOpacity(0.1);')); + expect(contents, contains('return _colors.primary.withOpacity(0.08);')); + expect(contents, contains('return _colors.onSurface.withOpacity(0.1);')); + expect(contents, contains('double get splashRadius => 40.0 / 2')); + expect(contents, contains('VisualDensity get visualDensity => VisualDensity.standard')); + expect( + contents, + contains( + 'const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0)))', + ), + ); }); test('ChipTemplateM3 emits M3 Chip defaults from tokens', () {