mirror of
https://github.com/flutter/flutter
synced 2024-08-27 20:10:11 +00:00
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:
parent
fad8bda64a
commit
f65dd3bac0
|
@ -225,6 +225,7 @@ class ActionChip extends StatelessWidget implements ChipAttributes, TappableChip
|
|||
elevation: elevation,
|
||||
shadowColor: shadowColor,
|
||||
surfaceTintColor: surfaceTintColor,
|
||||
iconTheme: iconTheme,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -235,6 +235,7 @@ class FilterChip extends StatelessWidget
|
|||
showCheckmark: showCheckmark,
|
||||
checkmarkColor: checkmarkColor,
|
||||
avatarBorder: avatarBorder,
|
||||
iconTheme: iconTheme,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,6 +236,7 @@ class InputChip extends StatelessWidget
|
|||
checkmarkColor: checkmarkColor,
|
||||
isEnabled: isEnabled && (onSelected != null || onDeleted != null || onPressed != null),
|
||||
avatarBorder: avatarBorder,
|
||||
iconTheme: iconTheme,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue