Adds more customization options to the Chip widget (#11498)
* Adds more customization options to the Chip widget Includes: - Custom Tooltip message for the delete button; - Custom background color for the chip - Custom delete icon color - Custom label text style * Adds missing type annotations to tests and improves documentation. * Tweaks labelStyle field documentation
This commit is contained in:
parent
db88414131
commit
4da5e9b249
@ -19,7 +19,7 @@ const TextStyle _kLabelStyle = const TextStyle(
|
|||||||
fontSize: 13.0,
|
fontSize: 13.0,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
textBaseline: TextBaseline.alphabetic
|
textBaseline: TextBaseline.alphabetic,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// A material design chip.
|
/// A material design chip.
|
||||||
@ -57,6 +57,10 @@ class Chip extends StatelessWidget {
|
|||||||
this.avatar,
|
this.avatar,
|
||||||
@required this.label,
|
@required this.label,
|
||||||
this.onDeleted,
|
this.onDeleted,
|
||||||
|
this.labelStyle,
|
||||||
|
this.deleteButtonTooltipMessage,
|
||||||
|
this.backgroundColor,
|
||||||
|
this.deleteIconColor,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
/// A widget to display prior to the chip's label.
|
/// A widget to display prior to the chip's label.
|
||||||
@ -74,6 +78,30 @@ class Chip extends StatelessWidget {
|
|||||||
/// The delete button is included in the chip only if this callback is non-null.
|
/// The delete button is included in the chip only if this callback is non-null.
|
||||||
final VoidCallback onDeleted;
|
final VoidCallback onDeleted;
|
||||||
|
|
||||||
|
/// The style to be applied to the chip's label.
|
||||||
|
///
|
||||||
|
/// This only has effect on widgets that respect the [DefaultTextStyle],
|
||||||
|
/// such as [Text].
|
||||||
|
final TextStyle labelStyle;
|
||||||
|
|
||||||
|
/// Color to be used for the chip's background, the default being grey.
|
||||||
|
///
|
||||||
|
/// This color is used as the background of the container that will hold the
|
||||||
|
/// widget's label.
|
||||||
|
final Color backgroundColor;
|
||||||
|
|
||||||
|
/// Color for delete icon, the default being black.
|
||||||
|
///
|
||||||
|
/// This has no effect when [onDelete] is null since no delete icon will be
|
||||||
|
/// shown.
|
||||||
|
final Color deleteIconColor;
|
||||||
|
|
||||||
|
/// Message to be used for the chip delete button's tooltip.
|
||||||
|
///
|
||||||
|
/// This has no effect when [onDelete] is null since no delete icon will be
|
||||||
|
/// shown.
|
||||||
|
final String deleteButtonTooltipMessage;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
assert(debugCheckHasMaterial(context));
|
assert(debugCheckHasMaterial(context));
|
||||||
@ -90,14 +118,14 @@ class Chip extends StatelessWidget {
|
|||||||
margin: const EdgeInsets.only(right: 8.0),
|
margin: const EdgeInsets.only(right: 8.0),
|
||||||
width: _kAvatarDiamater,
|
width: _kAvatarDiamater,
|
||||||
height: _kAvatarDiamater,
|
height: _kAvatarDiamater,
|
||||||
child: avatar
|
child: avatar,
|
||||||
)
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
children.add(new DefaultTextStyle(
|
children.add(new DefaultTextStyle(
|
||||||
style: _kLabelStyle,
|
style: labelStyle ?? _kLabelStyle,
|
||||||
child: label
|
child: label,
|
||||||
));
|
));
|
||||||
|
|
||||||
if (deletable) {
|
if (deletable) {
|
||||||
@ -105,16 +133,16 @@ class Chip extends StatelessWidget {
|
|||||||
children.add(new GestureDetector(
|
children.add(new GestureDetector(
|
||||||
onTap: Feedback.wrapForTap(onDeleted, context),
|
onTap: Feedback.wrapForTap(onDeleted, context),
|
||||||
child: new Tooltip(
|
child: new Tooltip(
|
||||||
message: 'Delete "$label"',
|
message: deleteButtonTooltipMessage ?? 'Delete "$label"',
|
||||||
child: new Container(
|
child: new Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
child: const Icon(
|
child: new Icon(
|
||||||
Icons.cancel,
|
Icons.cancel,
|
||||||
size: 18.0,
|
size: 18.0,
|
||||||
color: Colors.black54
|
color: deleteIconColor ?? Colors.black54,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,14 +152,14 @@ class Chip extends StatelessWidget {
|
|||||||
height: _kChipHeight,
|
height: _kChipHeight,
|
||||||
padding: new EdgeInsets.only(left: leftPadding, right: rightPadding),
|
padding: new EdgeInsets.only(left: leftPadding, right: rightPadding),
|
||||||
decoration: new BoxDecoration(
|
decoration: new BoxDecoration(
|
||||||
color: Colors.grey.shade300,
|
color: backgroundColor ?? Colors.grey.shade300,
|
||||||
borderRadius: new BorderRadius.circular(16.0)
|
borderRadius: new BorderRadius.circular(16.0),
|
||||||
),
|
),
|
||||||
child: new Row(
|
child: new Row(
|
||||||
children: children,
|
children: children,
|
||||||
mainAxisSize: MainAxisSize.min
|
mainAxisSize: MainAxisSize.min,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,34 +10,56 @@ import 'feedback_tester.dart';
|
|||||||
void main() {
|
void main() {
|
||||||
testWidgets('Chip control test', (WidgetTester tester) async {
|
testWidgets('Chip control test', (WidgetTester tester) async {
|
||||||
final FeedbackTester feedback = new FeedbackTester();
|
final FeedbackTester feedback = new FeedbackTester();
|
||||||
bool didDeleteChip = false;
|
final List<String> deletedChipLabels = <String>[];
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
new MaterialApp(
|
new MaterialApp(
|
||||||
home: new Material(
|
home: new Material(
|
||||||
child: new Center(
|
child: new Column(
|
||||||
child: new Chip(
|
children: <Widget>[
|
||||||
avatar: const CircleAvatar(
|
new Chip(
|
||||||
child: const Text('C')
|
avatar: const CircleAvatar(
|
||||||
|
child: const Text('A')
|
||||||
|
),
|
||||||
|
label: const Text('Chip A'),
|
||||||
|
onDeleted: () {
|
||||||
|
deletedChipLabels.add('A');
|
||||||
|
},
|
||||||
|
deleteButtonTooltipMessage: 'Delete chip A',
|
||||||
),
|
),
|
||||||
label: const Text('Chip'),
|
new Chip(
|
||||||
onDeleted: () {
|
avatar: const CircleAvatar(
|
||||||
didDeleteChip = true;
|
child: const Text('B')
|
||||||
}
|
),
|
||||||
)
|
label: const Text('Chip B'),
|
||||||
|
onDeleted: () {
|
||||||
|
deletedChipLabels.add('B');
|
||||||
|
},
|
||||||
|
deleteButtonTooltipMessage: 'Delete chip B',
|
||||||
|
),
|
||||||
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect(tester.widget(find.byTooltip('Delete chip A')), isNotNull);
|
||||||
|
expect(tester.widget(find.byTooltip('Delete chip B')), isNotNull);
|
||||||
|
|
||||||
expect(feedback.clickSoundCount, 0);
|
expect(feedback.clickSoundCount, 0);
|
||||||
|
|
||||||
expect(didDeleteChip, isFalse);
|
expect(deletedChipLabels, isEmpty);
|
||||||
await tester.tap(find.byType(Tooltip));
|
await tester.tap(find.byTooltip('Delete chip A'));
|
||||||
expect(didDeleteChip, isTrue);
|
expect(deletedChipLabels, equals(<String>['A']));
|
||||||
|
|
||||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||||
expect(feedback.clickSoundCount, 1);
|
expect(feedback.clickSoundCount, 1);
|
||||||
|
|
||||||
|
await tester.tap(find.byTooltip('Delete chip B'));
|
||||||
|
expect(deletedChipLabels, equals(<String>['A', 'B']));
|
||||||
|
|
||||||
|
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||||
|
expect(feedback.clickSoundCount, 2);
|
||||||
|
|
||||||
feedback.dispose();
|
feedback.dispose();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user