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

Update `CircleAvatar` to support Material 3 (#114812)

parent 92f10ed7
...@@ -84,7 +84,8 @@ class CircleAvatar extends StatelessWidget { ...@@ -84,7 +84,8 @@ class CircleAvatar extends StatelessWidget {
/// The color with which to fill the circle. Changing the background /// The color with which to fill the circle. Changing the background
/// color will cause the avatar to animate to the new color. /// color will cause the avatar to animate to the new color.
/// ///
/// If a [backgroundColor] is not specified, the theme's /// If a [backgroundColor] is not specified and [ThemeData.useMaterial3] is true,
/// [ColorScheme.primaryContainer] will be used, otherwise the theme's
/// [ThemeData.primaryColorLight] is used with dark foreground colors, and /// [ThemeData.primaryColorLight] is used with dark foreground colors, and
/// [ThemeData.primaryColorDark] with light foreground colors. /// [ThemeData.primaryColorDark] with light foreground colors.
final Color? backgroundColor; final Color? backgroundColor;
...@@ -94,7 +95,9 @@ class CircleAvatar extends StatelessWidget { ...@@ -94,7 +95,9 @@ class CircleAvatar extends StatelessWidget {
/// Defaults to the primary text theme color if no [backgroundColor] is /// Defaults to the primary text theme color if no [backgroundColor] is
/// specified. /// specified.
/// ///
/// Defaults to [ThemeData.primaryColorLight] for dark background colors, and /// If a [foregroundColor] is not specified and [ThemeData.useMaterial3] is true,
/// [ColorScheme.onPrimaryContainer] will be used, otherwise the theme's
/// [ThemeData.primaryColorLight] for dark background colors, and
/// [ThemeData.primaryColorDark] for light background colors. /// [ThemeData.primaryColorDark] for light background colors.
final Color? foregroundColor; final Color? foregroundColor;
...@@ -192,8 +195,14 @@ class CircleAvatar extends StatelessWidget { ...@@ -192,8 +195,14 @@ class CircleAvatar extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context)); assert(debugCheckHasMediaQuery(context));
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
TextStyle textStyle = theme.primaryTextTheme.titleMedium!.copyWith(color: foregroundColor); final Color? effectiveForegroundColor = foregroundColor
Color? effectiveBackgroundColor = backgroundColor; ?? (theme.useMaterial3 ? theme.colorScheme.onPrimaryContainer : null);
final TextStyle effectiveTextStyle = theme.useMaterial3
? theme.textTheme.titleMedium!
: theme.primaryTextTheme.titleMedium!;
TextStyle textStyle = effectiveTextStyle.copyWith(color: effectiveForegroundColor);
Color? effectiveBackgroundColor = backgroundColor
?? (theme.useMaterial3 ? theme.colorScheme.primaryContainer : null);
if (effectiveBackgroundColor == null) { if (effectiveBackgroundColor == null) {
switch (ThemeData.estimateBrightnessForColor(textStyle.color!)) { switch (ThemeData.estimateBrightnessForColor(textStyle.color!)) {
case Brightness.dark: case Brightness.dark:
...@@ -203,7 +212,7 @@ class CircleAvatar extends StatelessWidget { ...@@ -203,7 +212,7 @@ class CircleAvatar extends StatelessWidget {
effectiveBackgroundColor = theme.primaryColorDark; effectiveBackgroundColor = theme.primaryColorDark;
break; break;
} }
} else if (foregroundColor == null) { } else if (effectiveForegroundColor == null) {
switch (ThemeData.estimateBrightnessForColor(backgroundColor!)) { switch (ThemeData.estimateBrightnessForColor(backgroundColor!)) {
case Brightness.dark: case Brightness.dark:
textStyle = textStyle.copyWith(color: theme.primaryColorLight); textStyle = textStyle.copyWith(color: theme.primaryColorLight);
......
...@@ -144,36 +144,8 @@ void main() { ...@@ -144,36 +144,8 @@ void main() {
expect(paragraph.text.style!.color, equals(foregroundColor)); expect(paragraph.text.style!.color, equals(foregroundColor));
}); });
testWidgets('CircleAvatar with light theme', (WidgetTester tester) async { testWidgets('CircleAvatar default colors', (WidgetTester tester) async {
final ThemeData theme = ThemeData( final ThemeData theme = ThemeData(useMaterial3: true);
primaryColor: Colors.grey.shade100,
primaryColorBrightness: Brightness.light,
);
await tester.pumpWidget(
wrap(
child: Theme(
data: theme,
child: const CircleAvatar(
child: Text('Z'),
),
),
),
);
final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar));
final RenderDecoratedBox child = box.child! as RenderDecoratedBox;
final BoxDecoration decoration = child.decoration as BoxDecoration;
expect(decoration.color, equals(theme.primaryColorLight));
final RenderParagraph paragraph = tester.renderObject(find.text('Z'));
expect(paragraph.text.style!.color, equals(theme.primaryTextTheme.titleLarge!.color));
});
testWidgets('CircleAvatar with dark theme', (WidgetTester tester) async {
final ThemeData theme = ThemeData(
primaryColor: Colors.grey.shade800,
primaryColorBrightness: Brightness.dark,
);
await tester.pumpWidget( await tester.pumpWidget(
wrap( wrap(
child: Theme( child: Theme(
...@@ -188,10 +160,10 @@ void main() { ...@@ -188,10 +160,10 @@ void main() {
final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar)); final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar));
final RenderDecoratedBox child = box.child! as RenderDecoratedBox; final RenderDecoratedBox child = box.child! as RenderDecoratedBox;
final BoxDecoration decoration = child.decoration as BoxDecoration; final BoxDecoration decoration = child.decoration as BoxDecoration;
expect(decoration.color, equals(theme.primaryColorDark)); expect(decoration.color, equals(theme.colorScheme.primaryContainer));
final RenderParagraph paragraph = tester.renderObject(find.text('Z')); final RenderParagraph paragraph = tester.renderObject(find.text('Z'));
expect(paragraph.text.style!.color, equals(theme.primaryTextTheme.titleLarge!.color)); expect(paragraph.text.style!.color, equals(theme.colorScheme.onPrimaryContainer));
}); });
testWidgets('CircleAvatar text does not expand with textScaleFactor', (WidgetTester tester) async { testWidgets('CircleAvatar text does not expand with textScaleFactor', (WidgetTester tester) async {
...@@ -306,6 +278,61 @@ void main() { ...@@ -306,6 +278,61 @@ void main() {
final RenderParagraph paragraph = tester.renderObject(find.text('Z')); final RenderParagraph paragraph = tester.renderObject(find.text('Z'));
expect(paragraph.text.style!.color, equals(ThemeData.fallback().primaryColorLight)); expect(paragraph.text.style!.color, equals(ThemeData.fallback().primaryColorLight));
}); });
group('Material 2', () {
// Tests that are only relevant for Material 2. Once ThemeData.useMaterial3
// is turned on by default, these tests can be removed.
testWidgets('CircleAvatar default colors with light theme', (WidgetTester tester) async {
final ThemeData theme = ThemeData(
primaryColor: Colors.grey.shade100,
primaryColorBrightness: Brightness.light,
);
await tester.pumpWidget(
wrap(
child: Theme(
data: theme,
child: const CircleAvatar(
child: Text('Z'),
),
),
),
);
final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar));
final RenderDecoratedBox child = box.child! as RenderDecoratedBox;
final BoxDecoration decoration = child.decoration as BoxDecoration;
expect(decoration.color, equals(theme.primaryColorLight));
final RenderParagraph paragraph = tester.renderObject(find.text('Z'));
expect(paragraph.text.style!.color, equals(theme.primaryTextTheme.titleLarge!.color));
});
testWidgets('CircleAvatar default colors with dark theme', (WidgetTester tester) async {
final ThemeData theme = ThemeData(
primaryColor: Colors.grey.shade800,
primaryColorBrightness: Brightness.dark,
);
await tester.pumpWidget(
wrap(
child: Theme(
data: theme,
child: const CircleAvatar(
child: Text('Z'),
),
),
),
);
final RenderConstrainedBox box = tester.renderObject(find.byType(CircleAvatar));
final RenderDecoratedBox child = box.child! as RenderDecoratedBox;
final BoxDecoration decoration = child.decoration as BoxDecoration;
expect(decoration.color, equals(theme.primaryColorDark));
final RenderParagraph paragraph = tester.renderObject(find.text('Z'));
expect(paragraph.text.style!.color, equals(theme.primaryTextTheme.titleLarge!.color));
});
});
} }
Widget wrap({ required Widget child }) { Widget wrap({ required Widget child }) {
......
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