Unverified Commit ca5aa232 authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Update `ListTile` text defaults to use `ColorScheme` (#128581)

fixes https://github.com/flutter/flutter/issues/128569

<details> 
<summary>code sample</summary> 

```dart
import 'package:flutter/material.dart';

void main() {
  runApp(const ListTileApp());
}

class ListTileApp extends StatelessWidget {
  const ListTileApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.red).copyWith(
          onSurface: Colors.yellow,
          onSurfaceVariant: Colors.green,
        ),
      ),
      home: const Scaffold(
        body: Center(
          child: ListTile(
            title: Text('title'),
            subtitle: Text('subtitle'),
          ),
        ),
      ),
    );
  }
}

``` 
	
</details>

# Description
M3 ListTile couldn't be customized using `ColorScheme` colors. 

- This PR updates the list tile text defaults to `ColorScheme` text color tokens.
- Improved the `ListTile` template to use the token group.
- Update docs and tests.

```dart
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.red).copyWith(
          onSurface: Colors.yellow,
          onSurfaceVariant: Colors.green,
        ),
```

### Before

![Screenshot 2023-06-09 at 17 47 04](https://github.com/flutter/flutter/assets/48603081/c0130371-3c7c-428c-bb57-504822cf64b5)

### After

![Screenshot 2023-06-09 at 17 46 17](https://github.com/flutter/flutter/assets/48603081/3b4d6f8c-7fdd-4546-a6f0-00dd34cb5a96)
parent 6f2118be
...@@ -397,8 +397,10 @@ md.comp.list.list-item.pressed.leading-icon.icon.color, ...@@ -397,8 +397,10 @@ md.comp.list.list-item.pressed.leading-icon.icon.color,
md.comp.list.list-item.pressed.state-layer.color, md.comp.list.list-item.pressed.state-layer.color,
md.comp.list.list-item.pressed.state-layer.opacity, md.comp.list.list-item.pressed.state-layer.opacity,
md.comp.list.list-item.selected.trailing-icon.color, md.comp.list.list-item.selected.trailing-icon.color,
md.comp.list.list-item.supporting-text.color,
md.comp.list.list-item.supporting-text.text-style, md.comp.list.list-item.supporting-text.text-style,
md.comp.list.list-item.trailing-icon.color, md.comp.list.list-item.trailing-icon.color,
md.comp.list.list-item.trailing-supporting-text.color,
md.comp.list.list-item.trailing-supporting-text.text-style, md.comp.list.list-item.trailing-supporting-text.text-style,
md.comp.menu.container.color, md.comp.menu.container.color,
md.comp.menu.container.elevation, md.comp.menu.container.elevation,
......
...@@ -10,6 +10,8 @@ class ListTileTemplate extends TokenTemplate { ...@@ -10,6 +10,8 @@ class ListTileTemplate extends TokenTemplate {
super.textThemePrefix = '_textTheme.', super.textThemePrefix = '_textTheme.',
}); });
static const String tokenGroup = 'md.comp.list.list-item';
@override @override
String generate() => ''' String generate() => '''
class _${blockName}DefaultsM3 extends ListTileThemeData { class _${blockName}DefaultsM3 extends ListTileThemeData {
...@@ -18,7 +20,7 @@ class _${blockName}DefaultsM3 extends ListTileThemeData { ...@@ -18,7 +20,7 @@ class _${blockName}DefaultsM3 extends ListTileThemeData {
contentPadding: const EdgeInsetsDirectional.only(start: 16.0, end: 24.0), contentPadding: const EdgeInsetsDirectional.only(start: 16.0, end: 24.0),
minLeadingWidth: 24, minLeadingWidth: 24,
minVerticalPadding: 8, minVerticalPadding: 8,
shape: ${shape("md.comp.list.list-item.container")}, shape: ${shape("$tokenGroup.container")},
); );
final BuildContext context; final BuildContext context;
...@@ -30,19 +32,19 @@ class _${blockName}DefaultsM3 extends ListTileThemeData { ...@@ -30,19 +32,19 @@ class _${blockName}DefaultsM3 extends ListTileThemeData {
Color? get tileColor => Colors.transparent; Color? get tileColor => Colors.transparent;
@override @override
TextStyle? get titleTextStyle => ${textStyle("md.comp.list.list-item.label-text")}; TextStyle? get titleTextStyle => ${textStyle("$tokenGroup.label-text")}!.copyWith(color: ${componentColor('$tokenGroup.label-text')});
@override @override
TextStyle? get subtitleTextStyle => ${textStyle("md.comp.list.list-item.supporting-text")}; TextStyle? get subtitleTextStyle => ${textStyle("$tokenGroup.supporting-text")}!.copyWith(color: ${componentColor('$tokenGroup.supporting-text')});
@override @override
TextStyle? get leadingAndTrailingTextStyle => ${textStyle("md.comp.list.list-item.trailing-supporting-text")}; TextStyle? get leadingAndTrailingTextStyle => ${textStyle("$tokenGroup.trailing-supporting-text")}!.copyWith(color: ${componentColor('$tokenGroup.trailing-supporting-text')});
@override @override
Color? get selectedColor => ${componentColor('md.comp.list.list-item.selected.trailing-icon')}; Color? get selectedColor => ${componentColor('$tokenGroup.selected.trailing-icon')};
@override @override
Color? get iconColor => ${componentColor('md.comp.list.list-item.trailing-icon')}; Color? get iconColor => ${componentColor('$tokenGroup.trailing-icon')};
} }
'''; ''';
} }
...@@ -509,22 +509,25 @@ class ListTile extends StatelessWidget { ...@@ -509,22 +509,25 @@ class ListTile extends StatelessWidget {
/// ///
/// If this property is null, then [ListTileThemeData.titleTextStyle] is used. /// If this property is null, then [ListTileThemeData.titleTextStyle] is used.
/// If that is also null and [ThemeData.useMaterial3] is true, [TextTheme.bodyLarge] /// If that is also null and [ThemeData.useMaterial3] is true, [TextTheme.bodyLarge]
/// will be used. Otherwise, If ListTile style is [ListTileStyle.list], /// with [ColorScheme.onSurface] will be used. Otherwise, If ListTile style is
/// [TextTheme.titleMedium] will be used and if ListTile style is [ListTileStyle.drawer], /// [ListTileStyle.list], [TextTheme.titleMedium] will be used and if ListTile style
/// [TextTheme.bodyLarge] will be used. /// is [ListTileStyle.drawer], [TextTheme.bodyLarge] will be used.
final TextStyle? titleTextStyle; final TextStyle? titleTextStyle;
/// The text style for ListTile's [subtitle]. /// The text style for ListTile's [subtitle].
/// ///
/// If this property is null, then [ListTileThemeData.subtitleTextStyle] is used. /// If this property is null, then [ListTileThemeData.subtitleTextStyle] is used.
/// If that is also null, [TextTheme.bodyMedium] will be used. /// If that is also null and [ThemeData.useMaterial3] is true, [TextTheme.bodyMedium]
/// with [ColorScheme.onSurfaceVariant] will be used, otherwise [TextTheme.bodyMedium]
/// with [TextTheme.bodySmall] color will be used.
final TextStyle? subtitleTextStyle; final TextStyle? subtitleTextStyle;
/// The text style for ListTile's [leading] and [trailing]. /// The text style for ListTile's [leading] and [trailing].
/// ///
/// If this property is null, then [ListTileThemeData.leadingAndTrailingTextStyle] is used. /// If this property is null, then [ListTileThemeData.leadingAndTrailingTextStyle] is used.
/// If that is also null and [ThemeData.useMaterial3] is true, [TextTheme.labelSmall] /// If that is also null and [ThemeData.useMaterial3] is true, [TextTheme.labelSmall]
/// will be used, otherwise [TextTheme.bodyMedium] will be used. /// with [ColorScheme.onSurfaceVariant] will be used, otherwise [TextTheme.bodyMedium]
/// will be used.
final TextStyle? leadingAndTrailingTextStyle; final TextStyle? leadingAndTrailingTextStyle;
/// Defines the font used for the [title]. /// Defines the font used for the [title].
...@@ -798,7 +801,8 @@ class ListTile extends StatelessWidget { ...@@ -798,7 +801,8 @@ class ListTile extends StatelessWidget {
subtitleStyle = subtitleTextStyle subtitleStyle = subtitleTextStyle
?? tileTheme.subtitleTextStyle ?? tileTheme.subtitleTextStyle
?? defaults.subtitleTextStyle!; ?? defaults.subtitleTextStyle!;
final Color? subtitleColor = effectiveColor ?? theme.textTheme.bodySmall!.color; final Color? subtitleColor = effectiveColor
?? (theme.useMaterial3 ? null : theme.textTheme.bodySmall!.color);
subtitleStyle = subtitleStyle.copyWith( subtitleStyle = subtitleStyle.copyWith(
color: subtitleColor, color: subtitleColor,
fontSize: _isDenseLayout(theme, tileTheme) ? 12.0 : null, fontSize: _isDenseLayout(theme, tileTheme) ? 12.0 : null,
...@@ -1575,13 +1579,13 @@ class _LisTileDefaultsM3 extends ListTileThemeData { ...@@ -1575,13 +1579,13 @@ class _LisTileDefaultsM3 extends ListTileThemeData {
Color? get tileColor => Colors.transparent; Color? get tileColor => Colors.transparent;
@override @override
TextStyle? get titleTextStyle => _textTheme.bodyLarge; TextStyle? get titleTextStyle => _textTheme.bodyLarge!.copyWith(color: _colors.onSurface);
@override @override
TextStyle? get subtitleTextStyle => _textTheme.bodyMedium; TextStyle? get subtitleTextStyle => _textTheme.bodyMedium!.copyWith(color: _colors.onSurfaceVariant);
@override @override
TextStyle? get leadingAndTrailingTextStyle => _textTheme.labelSmall; TextStyle? get leadingAndTrailingTextStyle => _textTheme.labelSmall!.copyWith(color: _colors.onSurfaceVariant);
@override @override
Color? get selectedColor => _colors.primary; Color? get selectedColor => _colors.primary;
......
...@@ -1947,13 +1947,13 @@ void main() { ...@@ -1947,13 +1947,13 @@ void main() {
// ListTile default text colors. // ListTile default text colors.
await tester.pumpWidget(buildFrame()); await tester.pumpWidget(buildFrame());
final RenderParagraph leading = _getTextRenderObject(tester, 'leading'); final RenderParagraph leading = _getTextRenderObject(tester, 'leading');
expect(leading.text.style!.color, theme.textTheme.labelSmall!.color); expect(leading.text.style!.color, theme.colorScheme.onSurfaceVariant);
final RenderParagraph title = _getTextRenderObject(tester, 'title'); final RenderParagraph title = _getTextRenderObject(tester, 'title');
expect(title.text.style!.color, theme.textTheme.bodyLarge!.color); expect(title.text.style!.color, theme.colorScheme.onSurface);
final RenderParagraph subtitle = _getTextRenderObject(tester, 'subtitle'); final RenderParagraph subtitle = _getTextRenderObject(tester, 'subtitle');
expect(subtitle.text.style!.color, theme.textTheme.bodyMedium!.color); expect(subtitle.text.style!.color, theme.colorScheme.onSurfaceVariant);
final RenderParagraph trailing = _getTextRenderObject(tester, 'trailing'); final RenderParagraph trailing = _getTextRenderObject(tester, 'trailing');
expect(trailing.text.style!.color, theme.textTheme.labelSmall!.color); expect(trailing.text.style!.color, theme.colorScheme.onSurfaceVariant);
}); });
testWidgets('Default ListTile debugFillProperties', (WidgetTester tester) async { testWidgets('Default ListTile debugFillProperties', (WidgetTester tester) async {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment