Skip to content

Commit f65dd3b

Browse files
authored
Fix chip widgets don't the apply provided iconTheme (#135751)
fixes [`Chip.iconTheme` does not apply the icon theme](flutter/flutter#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)
1 parent fad8bda commit f65dd3b

File tree

10 files changed

+441
-39
lines changed

10 files changed

+441
-39
lines changed

packages/flutter/lib/src/material/action_chip.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ class ActionChip extends StatelessWidget implements ChipAttributes, TappableChip
225225
elevation: elevation,
226226
shadowColor: shadowColor,
227227
surfaceTintColor: surfaceTintColor,
228+
iconTheme: iconTheme,
228229
);
229230
}
230231
}

packages/flutter/lib/src/material/chip.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ class Chip extends StatelessWidget implements ChipAttributes, DeletableChipAttri
659659
elevation: elevation,
660660
shadowColor: shadowColor,
661661
surfaceTintColor: surfaceTintColor,
662+
iconTheme: iconTheme,
662663
);
663664
}
664665
}
@@ -1219,7 +1220,10 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
12191220
final Color? resolvedLabelColor = MaterialStateProperty.resolveAs<Color?>(effectiveLabelStyle.color, materialStates);
12201221
final TextStyle resolvedLabelStyle = effectiveLabelStyle.copyWith(color: resolvedLabelColor);
12211222
final Widget? avatar = iconTheme != null && hasAvatar
1222-
? IconTheme(data: iconTheme, child: widget.avatar!)
1223+
? IconTheme.merge(
1224+
data: theme.useMaterial3 ? chipDefaults.iconTheme!.merge(iconTheme) : iconTheme,
1225+
child: widget.avatar!,
1226+
)
12231227
: widget.avatar;
12241228

12251229
Widget result = Material(

packages/flutter/lib/src/material/filter_chip.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ class FilterChip extends StatelessWidget
235235
showCheckmark: showCheckmark,
236236
checkmarkColor: checkmarkColor,
237237
avatarBorder: avatarBorder,
238+
iconTheme: iconTheme,
238239
);
239240
}
240241
}

packages/flutter/lib/src/material/input_chip.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ class InputChip extends StatelessWidget
236236
checkmarkColor: checkmarkColor,
237237
isEnabled: isEnabled && (onSelected != null || onDeleted != null || onPressed != null),
238238
avatarBorder: avatarBorder,
239+
iconTheme: iconTheme,
239240
);
240241
}
241242
}

packages/flutter/test/material/action_chip_test.dart

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ Material getMaterial(WidgetTester tester) {
4444
);
4545
}
4646

47+
IconThemeData getIconData(WidgetTester tester) {
48+
final IconTheme iconTheme = tester.firstWidget(
49+
find.descendant(
50+
of: find.byType(RawChip),
51+
matching: find.byType(IconTheme),
52+
),
53+
);
54+
return iconTheme.data;
55+
}
56+
4757
DefaultTextStyle getLabelStyle(WidgetTester tester, String labelText) {
4858
return tester.widget(
4959
find.ancestor(
@@ -349,4 +359,29 @@ void main() {
349359
await tester.pumpWidget(wrapForChip(child: ActionChip(label: label, clipBehavior: Clip.antiAlias, onPressed: () { })));
350360
checkChipMaterialClipBehavior(tester, Clip.antiAlias);
351361
});
362+
363+
testWidgetsWithLeakTracking('ActionChip uses provided iconTheme', (WidgetTester tester) async {
364+
Widget buildChip({ IconThemeData? iconTheme }) {
365+
return MaterialApp(
366+
home: Material(
367+
child: ActionChip(
368+
iconTheme: iconTheme,
369+
avatar: const Icon(Icons.add),
370+
onPressed: () { },
371+
label: const Text('action chip'),
372+
),
373+
),
374+
);
375+
}
376+
377+
// Test default icon theme.
378+
await tester.pumpWidget(buildChip());
379+
380+
expect(getIconData(tester).color, ThemeData().colorScheme.primary);
381+
382+
// Test provided icon theme.
383+
await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff00ff00))));
384+
385+
expect(getIconData(tester).color, const Color(0xff00ff00));
386+
});
352387
}

packages/flutter/test/material/chip_test.dart

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3570,6 +3570,40 @@ void main() {
35703570
);
35713571
});
35723572

3573+
testWidgetsWithLeakTracking('Material3 - Chip.iconTheme respects default iconTheme.size', (WidgetTester tester) async {
3574+
Widget buildChip({ IconThemeData? iconTheme }) {
3575+
return MaterialApp(
3576+
theme: ThemeData(useMaterial3: true),
3577+
home: Directionality(
3578+
textDirection: TextDirection.ltr,
3579+
child: Material(
3580+
child: Center(
3581+
child: RawChip(
3582+
iconTheme: iconTheme,
3583+
avatar: const Icon(Icons.add),
3584+
label: const SizedBox(width: 100, height: 100),
3585+
onSelected: (bool newValue) { },
3586+
),
3587+
),
3588+
),
3589+
),
3590+
);
3591+
}
3592+
3593+
await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff332211))));
3594+
3595+
// Icon should have the default chip iconSize.
3596+
expect(getIconData(tester).size, 18.0);
3597+
expect(getIconData(tester).color, const Color(0xff332211));
3598+
3599+
// Icon should have the provided iconSize.
3600+
await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff112233), size: 23.0)));
3601+
await tester.pumpAndSettle();
3602+
3603+
expect(getIconData(tester).size, 23.0);
3604+
expect(getIconData(tester).color, const Color(0xff112233));
3605+
});
3606+
35733607
group('Material 2', () {
35743608
// These tests are only relevant for Material 2. Once Material 2
35753609
// support is deprecated and the APIs are removed, these tests

0 commit comments

Comments
 (0)