Fix chip widgets don't the apply provided iconTheme (#135751)

fixes [`Chip.iconTheme` does not apply the icon theme](https://github.com/flutter/flutter/issues/111828)

### Description
- Fix chip widgets that don't utilize the provided `iconTheme`.
- Prevent `iconTheme` with just color from overriding the default icon size.
- Add some missing M3 tests for the chip and chip theme properties.

### Code sample

<details>
<summary>expand to view the code sample</summary> 

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

void main() => runApp(const MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(useMaterial3: true),
      home: const Example(),
    );
  }
}

class Example extends StatefulWidget {
  const Example({super.key});

  @override
  State<Example> createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  final bool _isEnable = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            RawChip(
              iconTheme: const IconThemeData(color: Colors.amber),
              avatar: const Icon(Icons.favorite_rounded),
              label: const Text('RawChip'),
              onPressed: () {},
              isEnabled: _isEnable,
            ),
            const Chip(
              iconTheme: IconThemeData(color: Colors.amber),
              avatar: Icon(Icons.favorite_rounded),
              label: Text('Chip'),
              // onDeleted: () {},
            ),
            FilterChip(
              iconTheme: const IconThemeData(color: Colors.amber),
              avatar: const Icon(Icons.favorite_rounded),
              label: const Text('FilterChip'),
              selected: false,
              onSelected: _isEnable ? (bool value) {} : null,
            ),
            InputChip(
              iconTheme: const IconThemeData(color: Colors.amber),
              avatar: const Icon(Icons.favorite_rounded),
              label: const Text('InputChip'),
              isEnabled: _isEnable,
              onPressed: () {},
            ),
            ActionChip(
              iconTheme: const IconThemeData(color: Colors.amber),
              avatar: const Icon(Icons.favorite_rounded),
              label: const Text('ActionChip'),
              onPressed: _isEnable ? () {} : null,
            ),
            ChoiceChip(
              iconTheme: const IconThemeData(color: Colors.amber),
              avatar: const Icon(Icons.favorite_rounded),
              label: const Text('ChoiceChip'),
              selected: false,
              onSelected: _isEnable ? (bool value) {} : null,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: const Icon(Icons.add),
      ),
    );
  }
}

```

</details>

### Before
![Screenshot 2023-09-29 at 16 59 39](https://github.com/flutter/flutter/assets/48603081/4bc32032-cff3-4237-812f-86f17ed95337)

### After

![Screenshot 2023-09-29 at 16 55 24](https://github.com/flutter/flutter/assets/48603081/05a1fc52-fb31-4790-a840-18f2e9718241)
This commit is contained in:
Taha Tesser 2023-10-12 17:17:56 +03:00 committed by GitHub
parent fad8bda64a
commit f65dd3bac0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 443 additions and 41 deletions

View file

@ -225,6 +225,7 @@ class ActionChip extends StatelessWidget implements ChipAttributes, TappableChip
elevation: elevation,
shadowColor: shadowColor,
surfaceTintColor: surfaceTintColor,
iconTheme: iconTheme,
);
}
}

View file

@ -659,6 +659,7 @@ class Chip extends StatelessWidget implements ChipAttributes, DeletableChipAttri
elevation: elevation,
shadowColor: shadowColor,
surfaceTintColor: surfaceTintColor,
iconTheme: iconTheme,
);
}
}
@ -1219,7 +1220,10 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
final Color? resolvedLabelColor = MaterialStateProperty.resolveAs<Color?>(effectiveLabelStyle.color, materialStates);
final TextStyle resolvedLabelStyle = effectiveLabelStyle.copyWith(color: resolvedLabelColor);
final Widget? avatar = iconTheme != null && hasAvatar
? IconTheme(data: iconTheme, child: widget.avatar!)
? IconTheme.merge(
data: theme.useMaterial3 ? chipDefaults.iconTheme!.merge(iconTheme) : iconTheme,
child: widget.avatar!,
)
: widget.avatar;
Widget result = Material(

View file

@ -235,6 +235,7 @@ class FilterChip extends StatelessWidget
showCheckmark: showCheckmark,
checkmarkColor: checkmarkColor,
avatarBorder: avatarBorder,
iconTheme: iconTheme,
);
}
}

View file

@ -236,6 +236,7 @@ class InputChip extends StatelessWidget
checkmarkColor: checkmarkColor,
isEnabled: isEnabled && (onSelected != null || onDeleted != null || onPressed != null),
avatarBorder: avatarBorder,
iconTheme: iconTheme,
);
}
}

View file

@ -44,6 +44,16 @@ Material getMaterial(WidgetTester tester) {
);
}
IconThemeData getIconData(WidgetTester tester) {
final IconTheme iconTheme = tester.firstWidget(
find.descendant(
of: find.byType(RawChip),
matching: find.byType(IconTheme),
),
);
return iconTheme.data;
}
DefaultTextStyle getLabelStyle(WidgetTester tester, String labelText) {
return tester.widget(
find.ancestor(
@ -349,4 +359,29 @@ void main() {
await tester.pumpWidget(wrapForChip(child: ActionChip(label: label, clipBehavior: Clip.antiAlias, onPressed: () { })));
checkChipMaterialClipBehavior(tester, Clip.antiAlias);
});
testWidgetsWithLeakTracking('ActionChip uses provided iconTheme', (WidgetTester tester) async {
Widget buildChip({ IconThemeData? iconTheme }) {
return MaterialApp(
home: Material(
child: ActionChip(
iconTheme: iconTheme,
avatar: const Icon(Icons.add),
onPressed: () { },
label: const Text('action chip'),
),
),
);
}
// Test default icon theme.
await tester.pumpWidget(buildChip());
expect(getIconData(tester).color, ThemeData().colorScheme.primary);
// Test provided icon theme.
await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff00ff00))));
expect(getIconData(tester).color, const Color(0xff00ff00));
});
}

View file

@ -3570,6 +3570,40 @@ void main() {
);
});
testWidgetsWithLeakTracking('Material3 - Chip.iconTheme respects default iconTheme.size', (WidgetTester tester) async {
Widget buildChip({ IconThemeData? iconTheme }) {
return MaterialApp(
theme: ThemeData(useMaterial3: true),
home: Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: RawChip(
iconTheme: iconTheme,
avatar: const Icon(Icons.add),
label: const SizedBox(width: 100, height: 100),
onSelected: (bool newValue) { },
),
),
),
),
);
}
await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff332211))));
// Icon should have the default chip iconSize.
expect(getIconData(tester).size, 18.0);
expect(getIconData(tester).color, const Color(0xff332211));
// Icon should have the provided iconSize.
await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff112233), size: 23.0)));
await tester.pumpAndSettle();
expect(getIconData(tester).size, 23.0);
expect(getIconData(tester).color, const Color(0xff112233));
});
group('Material 2', () {
// These tests are only relevant for Material 2. Once Material 2
// support is deprecated and the APIs are removed, these tests

View file

@ -26,6 +26,16 @@ Material getMaterial(WidgetTester tester) {
);
}
IconThemeData getIconData(WidgetTester tester) {
final IconTheme iconTheme = tester.firstWidget(
find.descendant(
of: find.byType(RawChip),
matching: find.byType(IconTheme),
),
);
return iconTheme.data;
}
DefaultTextStyle getLabelStyle(WidgetTester tester) {
return tester.widget(
find.descendant(
@ -140,7 +150,7 @@ void main() {
]));
});
testWidgetsWithLeakTracking('Chip uses ThemeData chip theme', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Material3 - Chip uses ThemeData chip theme', (WidgetTester tester) async {
const ChipThemeData chipTheme = ChipThemeData(
backgroundColor: Color(0xff112233),
elevation: 4,
@ -148,18 +158,19 @@ void main() {
labelPadding: EdgeInsets.all(25),
shape: RoundedRectangleBorder(),
labelStyle: TextStyle(fontSize: 32),
iconTheme: IconThemeData(color: Color(0xff332211)),
);
final ThemeData theme = ThemeData(chipTheme: chipTheme, useMaterial3: true);
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(useMaterial3: false).copyWith(
chipTheme: chipTheme,
),
theme: ThemeData(chipTheme: chipTheme, useMaterial3: true),
home: Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: RawChip(
avatar: const Icon(Icons.add),
label: const SizedBox(width: 100, height: 100),
onSelected: (bool newValue) { },
),
@ -172,12 +183,54 @@ void main() {
final RenderBox materialBox = getMaterialBox(tester);
expect(materialBox, paints..rect(color: chipTheme.backgroundColor));
expect(getMaterial(tester).elevation, chipTheme.elevation);
expect(tester.getSize(find.byType(RawChip)), const Size(250, 250)); // label + padding + labelPadding
expect(getMaterial(tester).shape, chipTheme.shape);
expect(tester.getSize(find.byType(RawChip)), const Size(402, 252)); // label + padding + labelPadding
expect(
getMaterial(tester).shape,
chipTheme.shape?.copyWith(side: BorderSide(color: theme.colorScheme.outline)),
);
expect(getLabelStyle(tester).style.fontSize, 32);
expect(getIconData(tester).color, chipTheme.iconTheme!.color);
});
testWidgetsWithLeakTracking('Chip uses ChipTheme', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Material2 - Chip uses ThemeData chip theme', (WidgetTester tester) async {
const ChipThemeData chipTheme = ChipThemeData(
backgroundColor: Color(0xff112233),
elevation: 4,
padding: EdgeInsets.all(50),
labelPadding: EdgeInsets.all(25),
shape: RoundedRectangleBorder(),
labelStyle: TextStyle(fontSize: 32),
iconTheme: IconThemeData(color: Color(0xff332211)),
);
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(chipTheme: chipTheme, useMaterial3: false),
home: Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: RawChip(
avatar: const Icon(Icons.add),
label: const SizedBox(width: 100, height: 100),
onSelected: (bool newValue) { },
),
),
),
),
),
);
final RenderBox materialBox = getMaterialBox(tester);
expect(materialBox, paints..rect(color: chipTheme.backgroundColor));
expect(getMaterial(tester).elevation, chipTheme.elevation);
expect(tester.getSize(find.byType(RawChip)), const Size(400, 250)); // label + padding + labelPadding
expect(getMaterial(tester).shape, chipTheme.shape);
expect(getLabelStyle(tester).style.fontSize, 32);
expect(getIconData(tester).color, chipTheme.iconTheme!.color);
});
testWidgetsWithLeakTracking('Material3 - Chip uses local ChipTheme', (WidgetTester tester) async {
const ChipThemeData chipTheme = ChipThemeData(
backgroundColor: Color(0xff112233),
elevation: 4,
@ -185,22 +238,13 @@ void main() {
labelPadding: EdgeInsets.all(25),
labelStyle: TextStyle(fontSize: 32),
shape: RoundedRectangleBorder(),
iconTheme: IconThemeData(color: Color(0xff332211)),
);
const ChipThemeData shadowedChipTheme = ChipThemeData(
backgroundColor: Color(0xff332211),
elevation: 3,
padding: EdgeInsets.all(5),
labelPadding: EdgeInsets.all(10),
labelStyle: TextStyle(fontSize: 64),
shape: CircleBorder(),
);
final ThemeData theme = ThemeData(chipTheme: const ChipThemeData(), useMaterial3: true);
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(useMaterial3: false).copyWith(
chipTheme: shadowedChipTheme,
),
theme: theme,
home: ChipTheme(
data: chipTheme,
child: Builder(
@ -210,6 +254,7 @@ void main() {
child: Material(
child: Center(
child: RawChip(
avatar: const Icon(Icons.add),
label: const SizedBox(width: 100, height: 100),
onSelected: (bool newValue) { },
),
@ -224,32 +269,32 @@ void main() {
final RenderBox materialBox = getMaterialBox(tester);
expect(materialBox, paints..rect(color: chipTheme.backgroundColor));
expect(tester.getSize(find.byType(RawChip)), const Size(250, 250)); // label + padding + labelPadding
expect(tester.getSize(find.byType(RawChip)), const Size(402, 252)); // label + padding + labelPadding
expect(getMaterial(tester).elevation, chipTheme.elevation);
expect(getMaterial(tester).shape, chipTheme.shape);
expect(
getMaterial(tester).shape,
chipTheme.shape?.copyWith(side: BorderSide(color: theme.colorScheme.outline)),
);
expect(getLabelStyle(tester).style.fontSize, 32);
expect(getIconData(tester).color, chipTheme.iconTheme!.color);
});
testWidgetsWithLeakTracking('Chip uses constructor parameters', (WidgetTester tester) async {
const ChipThemeData shadowedChipTheme = ChipThemeData(
testWidgetsWithLeakTracking('Material2 - Chip uses local ChipTheme', (WidgetTester tester) async {
const ChipThemeData chipTheme = ChipThemeData(
backgroundColor: Color(0xff112233),
elevation: 4,
padding: EdgeInsets.all(5),
labelPadding: EdgeInsets.all(2),
labelStyle: TextStyle(),
padding: EdgeInsets.all(50),
labelPadding: EdgeInsets.all(25),
labelStyle: TextStyle(fontSize: 32),
shape: RoundedRectangleBorder(),
iconTheme: IconThemeData(color: Color(0xff332211)),
);
const Color backgroundColor = Color(0xff332211);
const double elevation = 3;
const double fontSize = 32;
const OutlinedBorder shape = CircleBorder();
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(useMaterial3: false),
theme: ThemeData(chipTheme: const ChipThemeData(), useMaterial3: false),
home: ChipTheme(
data: shadowedChipTheme,
data: chipTheme,
child: Builder(
builder: (BuildContext context) {
return Directionality(
@ -257,12 +302,7 @@ void main() {
child: Material(
child: Center(
child: RawChip(
backgroundColor: backgroundColor,
elevation: elevation,
padding: const EdgeInsets.all(50),
labelPadding:const EdgeInsets.all(25),
labelStyle: const TextStyle(fontSize: fontSize),
shape: shape,
avatar: const Icon(Icons.add),
label: const SizedBox(width: 100, height: 100),
onSelected: (bool newValue) { },
),
@ -275,12 +315,160 @@ void main() {
),
);
final RenderBox materialBox = getMaterialBox(tester);
expect(materialBox, paints..rect(color: chipTheme.backgroundColor));
expect(tester.getSize(find.byType(RawChip)), const Size(400, 250)); // label + padding + labelPadding
expect(getMaterial(tester).elevation, chipTheme.elevation);
expect(getMaterial(tester).shape, chipTheme.shape);
expect(getLabelStyle(tester).style.fontSize, 32);
expect(getIconData(tester).color, chipTheme.iconTheme!.color);
});
testWidgetsWithLeakTracking('Chip properties overrides ChipTheme', (WidgetTester tester) async {
const ChipThemeData chipTheme = ChipThemeData(
backgroundColor: Color(0xff112233),
elevation: 4,
padding: EdgeInsets.all(50),
labelPadding: EdgeInsets.all(25),
labelStyle: TextStyle(fontSize: 32),
shape: RoundedRectangleBorder(),
iconTheme: IconThemeData(color: Color(0xff332211)),
);
const Color backgroundColor = Color(0xff000000);
const double elevation = 6.0;
const EdgeInsets padding = EdgeInsets.all(10);
const EdgeInsets labelPadding = EdgeInsets.all(5);
const TextStyle labelStyle = TextStyle(fontSize: 20);
const RoundedRectangleBorder shape = RoundedRectangleBorder(side: BorderSide(color: Color(0xff0000ff)));
const IconThemeData iconTheme = IconThemeData(color: Color(0xff00ff00));
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(chipTheme: chipTheme),
home: Builder(
builder: (BuildContext context) {
return Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: RawChip(
backgroundColor: backgroundColor,
elevation: elevation,
padding: padding,
labelPadding: labelPadding,
labelStyle: labelStyle,
shape: shape,
iconTheme: iconTheme,
avatar: const Icon(Icons.add),
label: const SizedBox(width: 100, height: 100),
onSelected: (bool newValue) { },
),
),
),
);
},
),
),
);
final RenderBox materialBox = getMaterialBox(tester);
expect(materialBox, paints..rect(color: backgroundColor));
expect(tester.getSize(find.byType(RawChip)), const Size(242, 132)); // label + padding + labelPadding
expect(getMaterial(tester).elevation, elevation);
expect(getMaterial(tester).shape, shape);
expect(getLabelStyle(tester).style.fontSize, labelStyle.fontSize);
expect(getIconData(tester).color, iconTheme.color);
});
testWidgetsWithLeakTracking('Material3 - Chip uses constructor parameters', (WidgetTester tester) async {
const Color backgroundColor = Color(0xff332211);
const double elevation = 3;
const double fontSize = 32;
const OutlinedBorder shape = CircleBorder(side: BorderSide(color: Color(0xff0000ff)));
const IconThemeData iconTheme = IconThemeData(color: Color(0xff443322));
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(useMaterial3: true),
home: Builder(
builder: (BuildContext context) {
return Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: RawChip(
backgroundColor: backgroundColor,
elevation: elevation,
padding: const EdgeInsets.all(50),
labelPadding:const EdgeInsets.all(25),
labelStyle: const TextStyle(fontSize: fontSize),
shape: shape,
iconTheme: iconTheme,
avatar: const Icon(Icons.add),
label: const SizedBox(width: 100, height: 100),
onSelected: (bool newValue) { },
),
),
),
);
},
),
),
);
final RenderBox materialBox = getMaterialBox(tester);
expect(materialBox, paints..circle(color: backgroundColor));
expect(tester.getSize(find.byType(RawChip)), const Size(250, 250)); // label + padding + labelPadding
expect(tester.getSize(find.byType(RawChip)), const Size(402, 252)); // label + padding + labelPadding
expect(getMaterial(tester).elevation, elevation);
expect(getMaterial(tester).shape, shape);
expect(getLabelStyle(tester).style.fontSize, 32);
expect(getIconData(tester).color, iconTheme.color);
});
testWidgetsWithLeakTracking('Material2 - Chip uses constructor parameters', (WidgetTester tester) async {
const Color backgroundColor = Color(0xff332211);
const double elevation = 3;
const double fontSize = 32;
const OutlinedBorder shape = CircleBorder();
const IconThemeData iconTheme = IconThemeData(color: Color(0xff443322));
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Builder(
builder: (BuildContext context) {
return Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: RawChip(
backgroundColor: backgroundColor,
elevation: elevation,
padding: const EdgeInsets.all(50),
labelPadding:const EdgeInsets.all(25),
labelStyle: const TextStyle(fontSize: fontSize),
shape: shape,
iconTheme: iconTheme,
avatar: const Icon(Icons.add),
label: const SizedBox(width: 100, height: 100),
onSelected: (bool newValue) { },
),
),
),
);
},
),
),
);
final RenderBox materialBox = getMaterialBox(tester);
expect(materialBox, paints..circle(color: backgroundColor));
expect(tester.getSize(find.byType(RawChip)), const Size(400, 250)); // label + padding + labelPadding
expect(getMaterial(tester).elevation, elevation);
expect(getMaterial(tester).shape, shape);
expect(getLabelStyle(tester).style.fontSize, 32);
expect(getIconData(tester).color, iconTheme.color);
});
testWidgetsWithLeakTracking('ChipTheme.fromDefaults', (WidgetTester tester) async {
@ -986,6 +1174,39 @@ void main() {
),
);
});
testWidgetsWithLeakTracking('Material3 - ChipThemeData.iconTheme respects default iconTheme.size', (WidgetTester tester) async {
Widget buildChip({ IconThemeData? iconTheme }) {
return MaterialApp(
theme: ThemeData(useMaterial3: true, chipTheme: ChipThemeData(iconTheme: iconTheme)),
home: Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: RawChip(
avatar: const Icon(Icons.add),
label: const SizedBox(width: 100, height: 100),
onSelected: (bool newValue) { },
),
),
),
),
);
}
await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff332211))));
// Icon should have the default chip iconSize.
expect(getIconData(tester).size, 18.0);
expect(getIconData(tester).color, const Color(0xff332211));
// Icon should have the provided iconSize.
await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff112233), size: 23.0)));
await tester.pumpAndSettle();
expect(getIconData(tester).size, 23.0);
expect(getIconData(tester).color, const Color(0xff112233));
});
}
class _MaterialStateOutlinedBorder extends StadiumBorder implements MaterialStateOutlinedBorder {

View file

@ -24,6 +24,16 @@ Material getMaterial(WidgetTester tester) {
);
}
IconThemeData getIconData(WidgetTester tester) {
final IconTheme iconTheme = tester.firstWidget(
find.descendant(
of: find.byType(RawChip),
matching: find.byType(IconTheme),
),
);
return iconTheme.data;
}
DefaultTextStyle getLabelStyle(WidgetTester tester, String labelText) {
return tester.widget(
find.ancestor(
@ -575,6 +585,32 @@ void main() {
expect(rawChip.checkmarkColor, checkmarkColor);
});
testWidgetsWithLeakTracking('ChoiceChip uses provided iconTheme', (WidgetTester tester) async {
Widget buildChip({ IconThemeData? iconTheme }) {
return MaterialApp(
home: Material(
child: ChoiceChip(
iconTheme: iconTheme,
avatar: const Icon(Icons.add),
label: const Text('Test'),
selected: false,
onSelected: (bool _) {},
),
),
);
}
// Test default icon theme.
await tester.pumpWidget(buildChip());
expect(getIconData(tester).color, ThemeData().iconTheme.color);
// Test provided icon theme.
await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff00ff00))));
expect(getIconData(tester).color, const Color(0xff00ff00));
});
group('Material 2', () {
// These tests are only relevant for Material 2. Once Material 2
// support is deprecated and the APIs are removed, these tests

View file

@ -104,6 +104,16 @@ Material getMaterial(WidgetTester tester) {
);
}
IconThemeData getIconData(WidgetTester tester) {
final IconTheme iconTheme = tester.firstWidget(
find.descendant(
of: find.byType(RawChip),
matching: find.byType(IconTheme),
),
);
return iconTheme.data;
}
DefaultTextStyle getLabelStyle(WidgetTester tester, String labelText) {
return tester.widget(
find.ancestor(
@ -687,4 +697,29 @@ void main() {
await tester.pumpAndSettle();
expect(tester.getSize(find.byType(FilterChip)).width, expectedWidth);
});
testWidgetsWithLeakTracking('FilterChip uses provided iconTheme', (WidgetTester tester) async {
Widget buildChip({ IconThemeData? iconTheme }) {
return MaterialApp(
home: Material(
child: FilterChip(
iconTheme: iconTheme,
avatar: const Icon(Icons.add),
label: const Text('FilterChip'),
onSelected: (bool _) {},
),
),
);
}
// Test default icon theme.
await tester.pumpWidget(buildChip());
expect(getIconData(tester).color, ThemeData().iconTheme.color);
// Test provided icon theme.
await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff00ff00))));
expect(getIconData(tester).color, const Color(0xff00ff00));
});
}

View file

@ -90,6 +90,16 @@ RenderBox getMaterialBox(WidgetTester tester) {
);
}
IconThemeData getIconData(WidgetTester tester) {
final IconTheme iconTheme = tester.firstWidget(
find.descendant(
of: find.byType(RawChip),
matching: find.byType(IconTheme),
),
);
return iconTheme.data;
}
void checkChipMaterialClipBehavior(WidgetTester tester, Clip clipBehavior) {
final Iterable<Material> materials = tester.widgetList<Material>(find.byType(Material));
// There should be two Material widgets, first Material is from the "_wrapForChip" and
@ -377,4 +387,28 @@ void main() {
final RenderBox materialBox = getMaterialBox(tester);
expect(materialBox, paints..path(color: material3ChipDefaults.disabledColor));
});
testWidgetsWithLeakTracking('InputChip uses provided iconTheme', (WidgetTester tester) async {
Widget buildChip({ IconThemeData? iconTheme }) {
return MaterialApp(
home: Material(
child: InputChip(
iconTheme: iconTheme,
avatar: const Icon(Icons.add),
label: const Text('Test'),
),
),
);
}
// Test default icon theme.
await tester.pumpWidget(buildChip());
expect(getIconData(tester).color, ThemeData().iconTheme.color);
// Test provided icon theme.
await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff00ff00))));
expect(getIconData(tester).color, const Color(0xff00ff00));
});
}