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

### After
diff --git a/packages/flutter/lib/src/material/action_chip.dart b/packages/flutter/lib/src/material/action_chip.dart
index 142fc40..ab773e9 100644
--- a/packages/flutter/lib/src/material/action_chip.dart
+++ b/packages/flutter/lib/src/material/action_chip.dart
@@ -225,6 +225,7 @@
elevation: elevation,
shadowColor: shadowColor,
surfaceTintColor: surfaceTintColor,
+ iconTheme: iconTheme,
);
}
}
diff --git a/packages/flutter/lib/src/material/chip.dart b/packages/flutter/lib/src/material/chip.dart
index 757c642..5c785ae 100644
--- a/packages/flutter/lib/src/material/chip.dart
+++ b/packages/flutter/lib/src/material/chip.dart
@@ -659,6 +659,7 @@
elevation: elevation,
shadowColor: shadowColor,
surfaceTintColor: surfaceTintColor,
+ iconTheme: iconTheme,
);
}
}
@@ -1219,7 +1220,10 @@
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(
diff --git a/packages/flutter/lib/src/material/filter_chip.dart b/packages/flutter/lib/src/material/filter_chip.dart
index c56a183..317c945 100644
--- a/packages/flutter/lib/src/material/filter_chip.dart
+++ b/packages/flutter/lib/src/material/filter_chip.dart
@@ -235,6 +235,7 @@
showCheckmark: showCheckmark,
checkmarkColor: checkmarkColor,
avatarBorder: avatarBorder,
+ iconTheme: iconTheme,
);
}
}
diff --git a/packages/flutter/lib/src/material/input_chip.dart b/packages/flutter/lib/src/material/input_chip.dart
index 13c97d4..d3f7ba2 100644
--- a/packages/flutter/lib/src/material/input_chip.dart
+++ b/packages/flutter/lib/src/material/input_chip.dart
@@ -236,6 +236,7 @@
checkmarkColor: checkmarkColor,
isEnabled: isEnabled && (onSelected != null || onDeleted != null || onPressed != null),
avatarBorder: avatarBorder,
+ iconTheme: iconTheme,
);
}
}
diff --git a/packages/flutter/test/material/action_chip_test.dart b/packages/flutter/test/material/action_chip_test.dart
index 310db84..4aa5d61 100644
--- a/packages/flutter/test/material/action_chip_test.dart
+++ b/packages/flutter/test/material/action_chip_test.dart
@@ -44,6 +44,16 @@
);
}
+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 @@
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));
+ });
}
diff --git a/packages/flutter/test/material/chip_test.dart b/packages/flutter/test/material/chip_test.dart
index cfc57b5..879cce5 100644
--- a/packages/flutter/test/material/chip_test.dart
+++ b/packages/flutter/test/material/chip_test.dart
@@ -3570,6 +3570,40 @@
);
});
+ 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
diff --git a/packages/flutter/test/material/chip_theme_test.dart b/packages/flutter/test/material/chip_theme_test.dart
index d65cf69..82658d6 100644
--- a/packages/flutter/test/material/chip_theme_test.dart
+++ b/packages/flutter/test/material/chip_theme_test.dart
@@ -26,6 +26,16 @@
);
}
+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 @@
]));
});
- 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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) { },
),
@@ -276,11 +316,159 @@
);
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 @@
),
);
});
+
+ 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 {
diff --git a/packages/flutter/test/material/choice_chip_test.dart b/packages/flutter/test/material/choice_chip_test.dart
index 2f97610..faad789 100644
--- a/packages/flutter/test/material/choice_chip_test.dart
+++ b/packages/flutter/test/material/choice_chip_test.dart
@@ -24,6 +24,16 @@
);
}
+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 @@
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
diff --git a/packages/flutter/test/material/filter_chip_test.dart b/packages/flutter/test/material/filter_chip_test.dart
index 3d46afa..fd69291 100644
--- a/packages/flutter/test/material/filter_chip_test.dart
+++ b/packages/flutter/test/material/filter_chip_test.dart
@@ -104,6 +104,16 @@
);
}
+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 @@
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));
+ });
}
diff --git a/packages/flutter/test/material/input_chip_test.dart b/packages/flutter/test/material/input_chip_test.dart
index bb43b64..3c8b8db 100644
--- a/packages/flutter/test/material/input_chip_test.dart
+++ b/packages/flutter/test/material/input_chip_test.dart
@@ -90,6 +90,16 @@
);
}
+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 @@
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));
+ });
}