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,
md.comp.list.list-item.pressed.state-layer.color,
md.comp.list.list-item.pressed.state-layer.opacity,
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.trailing-icon.color,
md.comp.list.list-item.trailing-supporting-text.color,
md.comp.list.list-item.trailing-supporting-text.text-style,
md.comp.menu.container.color,
md.comp.menu.container.elevation,
......
......@@ -10,6 +10,8 @@ class ListTileTemplate extends TokenTemplate {
super.textThemePrefix = '_textTheme.',
});
static const String tokenGroup = 'md.comp.list.list-item';
@override
String generate() => '''
class _${blockName}DefaultsM3 extends ListTileThemeData {
......@@ -18,7 +20,7 @@ class _${blockName}DefaultsM3 extends ListTileThemeData {
contentPadding: const EdgeInsetsDirectional.only(start: 16.0, end: 24.0),
minLeadingWidth: 24,
minVerticalPadding: 8,
shape: ${shape("md.comp.list.list-item.container")},
shape: ${shape("$tokenGroup.container")},
);
final BuildContext context;
......@@ -30,19 +32,19 @@ class _${blockName}DefaultsM3 extends ListTileThemeData {
Color? get tileColor => Colors.transparent;
@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
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
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
Color? get selectedColor => ${componentColor('md.comp.list.list-item.selected.trailing-icon')};
Color? get selectedColor => ${componentColor('$tokenGroup.selected.trailing-icon')};
@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 {
///
/// If this property is null, then [ListTileThemeData.titleTextStyle] is used.
/// If that is also null and [ThemeData.useMaterial3] is true, [TextTheme.bodyLarge]
/// will be used. Otherwise, If ListTile style is [ListTileStyle.list],
/// [TextTheme.titleMedium] will be used and if ListTile style is [ListTileStyle.drawer],
/// [TextTheme.bodyLarge] will be used.
/// with [ColorScheme.onSurface] will be used. Otherwise, If ListTile style is
/// [ListTileStyle.list], [TextTheme.titleMedium] will be used and if ListTile style
/// is [ListTileStyle.drawer], [TextTheme.bodyLarge] will be used.
final TextStyle? titleTextStyle;
/// The text style for ListTile's [subtitle].
///
/// 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;
/// The text style for ListTile's [leading] and [trailing].
///
/// If this property is null, then [ListTileThemeData.leadingAndTrailingTextStyle] is used.
/// 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;
/// Defines the font used for the [title].
......@@ -798,7 +801,8 @@ class ListTile extends StatelessWidget {
subtitleStyle = subtitleTextStyle
?? tileTheme.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(
color: subtitleColor,
fontSize: _isDenseLayout(theme, tileTheme) ? 12.0 : null,
......@@ -1575,13 +1579,13 @@ class _LisTileDefaultsM3 extends ListTileThemeData {
Color? get tileColor => Colors.transparent;
@override
TextStyle? get titleTextStyle => _textTheme.bodyLarge;
TextStyle? get titleTextStyle => _textTheme.bodyLarge!.copyWith(color: _colors.onSurface);
@override
TextStyle? get subtitleTextStyle => _textTheme.bodyMedium;
TextStyle? get subtitleTextStyle => _textTheme.bodyMedium!.copyWith(color: _colors.onSurfaceVariant);
@override
TextStyle? get leadingAndTrailingTextStyle => _textTheme.labelSmall;
TextStyle? get leadingAndTrailingTextStyle => _textTheme.labelSmall!.copyWith(color: _colors.onSurfaceVariant);
@override
Color? get selectedColor => _colors.primary;
......
......@@ -1947,13 +1947,13 @@ void main() {
// ListTile default text colors.
await tester.pumpWidget(buildFrame());
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');
expect(title.text.style!.color, theme.textTheme.bodyLarge!.color);
expect(title.text.style!.color, theme.colorScheme.onSurface);
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');
expect(trailing.text.style!.color, theme.textTheme.labelSmall!.color);
expect(trailing.text.style!.color, theme.colorScheme.onSurfaceVariant);
});
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