Fix chips use square delete button InkWell
shape instead of circular (#144319)
fixes [Chips delete button hover style is square, not circular](https://github.com/flutter/flutter/issues/141335) ### Code sample <details> <summary>expand to view the code sample</summary> ```dart import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: RawChip( label: const Text('Test'), onPressed: null, deleteIcon: const Icon(Icons.clear, size: 18), onDeleted: () {}, ), ), ), ); } } ``` </details> ### Preview | Before | After | | --------------- | --------------- | | <img src="https://github.com/flutter/flutter/assets/48603081/c5d62c57-97b3-4f94-b83d-df13559ee3a8" /> | <img src="https://github.com/flutter/flutter/assets/48603081/b76edaab-73e0-4aa9-8ca2-127eedd77814" /> |
This commit is contained in:
parent
e8f8a8dc17
commit
cfabdca9ca
@ -1191,6 +1191,7 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
|
|||||||
radius: (_kChipHeight + (widget.padding?.vertical ?? 0.0)) * .45,
|
radius: (_kChipHeight + (widget.padding?.vertical ?? 0.0)) * .45,
|
||||||
// Keeps the splash from being constrained to the icon alone.
|
// Keeps the splash from being constrained to the icon alone.
|
||||||
splashFactory: _UnconstrainedInkSplashFactory(Theme.of(context).splashFactory),
|
splashFactory: _UnconstrainedInkSplashFactory(Theme.of(context).splashFactory),
|
||||||
|
customBorder: const CircleBorder(),
|
||||||
onTap: widget.isEnabled ? widget.onDeleted : null,
|
onTap: widget.isEnabled ? widget.onDeleted : null,
|
||||||
child: IconTheme(
|
child: IconTheme(
|
||||||
data: theme.iconTheme.copyWith(
|
data: theme.iconTheme.copyWith(
|
||||||
|
@ -144,6 +144,7 @@ Widget chipWithOptionalDeleteButton({
|
|||||||
TextDirection textDirection = TextDirection.ltr,
|
TextDirection textDirection = TextDirection.ltr,
|
||||||
String? chipTooltip,
|
String? chipTooltip,
|
||||||
String? deleteButtonTooltipMessage,
|
String? deleteButtonTooltipMessage,
|
||||||
|
double? size,
|
||||||
VoidCallback? onPressed = doNothing,
|
VoidCallback? onPressed = doNothing,
|
||||||
ThemeData? themeData,
|
ThemeData? themeData,
|
||||||
}) {
|
}) {
|
||||||
@ -156,7 +157,11 @@ Widget chipWithOptionalDeleteButton({
|
|||||||
tooltip: chipTooltip,
|
tooltip: chipTooltip,
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
onDeleted: deletable ? doNothing : null,
|
onDeleted: deletable ? doNothing : null,
|
||||||
deleteIcon: Icon(Icons.close, key: deleteButtonKey),
|
deleteIcon: Icon(
|
||||||
|
key: deleteButtonKey,
|
||||||
|
size: size,
|
||||||
|
Icons.close,
|
||||||
|
),
|
||||||
deleteButtonTooltipMessage: deleteButtonTooltipMessage,
|
deleteButtonTooltipMessage: deleteButtonTooltipMessage,
|
||||||
label: Text(
|
label: Text(
|
||||||
deletable
|
deletable
|
||||||
@ -1852,6 +1857,7 @@ void main() {
|
|||||||
labelKey: labelKey,
|
labelKey: labelKey,
|
||||||
deleteButtonKey: deleteButtonKey,
|
deleteButtonKey: deleteButtonKey,
|
||||||
deletable: true,
|
deletable: true,
|
||||||
|
size: 18.0,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1957,6 +1963,7 @@ void main() {
|
|||||||
onPressed: null,
|
onPressed: null,
|
||||||
deleteButtonKey: deleteButtonKey,
|
deleteButtonKey: deleteButtonKey,
|
||||||
deletable: true,
|
deletable: true,
|
||||||
|
size: 18.0,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -5385,6 +5392,62 @@ void main() {
|
|||||||
expect(labelTopRight.dx, deleteIconCenter.dx - (iconSize / 2) - labelPadding);
|
expect(labelTopRight.dx, deleteIconCenter.dx - (iconSize / 2) - labelPadding);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Default delete button InkWell shape', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(wrapForChip(
|
||||||
|
child: Center(
|
||||||
|
child: RawChip(
|
||||||
|
onDeleted: () { },
|
||||||
|
label: const Text('RawChip'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
final InkWell deleteButtonInkWell = tester.widget<InkWell>(find.ancestor(
|
||||||
|
of: find.byIcon(Icons.cancel),
|
||||||
|
matching: find.byType(InkWell).last,
|
||||||
|
));
|
||||||
|
expect(deleteButtonInkWell.customBorder, const CircleBorder());
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Default delete button overlay', (WidgetTester tester) async {
|
||||||
|
final ThemeData theme = ThemeData();
|
||||||
|
await tester.pumpWidget(wrapForChip(
|
||||||
|
child: Center(
|
||||||
|
child: RawChip(
|
||||||
|
onDeleted: () { },
|
||||||
|
label: const Text('RawChip'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
theme: theme,
|
||||||
|
));
|
||||||
|
|
||||||
|
RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||||
|
expect(inkFeatures, isNot(paints..rect(color: theme.hoverColor)));
|
||||||
|
expect(inkFeatures, paintsExactlyCountTimes(#clipPath, 0));
|
||||||
|
|
||||||
|
// Hover over the delete icon.
|
||||||
|
final Offset centerOfDeleteButton = tester.getCenter(find.byType(Icon));
|
||||||
|
final TestGesture hoverGesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
||||||
|
await hoverGesture.moveTo(centerOfDeleteButton);
|
||||||
|
addTearDown(hoverGesture.removePointer);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
||||||
|
expect(inkFeatures, paints..rect(color: theme.hoverColor));
|
||||||
|
expect(inkFeatures, paintsExactlyCountTimes(#clipPath, 1));
|
||||||
|
|
||||||
|
const Rect expectedClipRect = Rect.fromLTRB(124.7, 10.0, 142.7, 28.0);
|
||||||
|
final Path expectedClipPath = Path()..addRect(expectedClipRect);
|
||||||
|
expect(
|
||||||
|
inkFeatures,
|
||||||
|
paints..clipPath(pathMatcher: coversSameAreaAs(
|
||||||
|
expectedClipPath,
|
||||||
|
areaToCompare: expectedClipRect.inflate(48.0),
|
||||||
|
sampleSize: 100,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
group('Material 2', () {
|
group('Material 2', () {
|
||||||
// These tests are only relevant for Material 2. Once Material 2
|
// These tests are only relevant for Material 2. Once Material 2
|
||||||
// support is deprecated and the APIs are removed, these tests
|
// support is deprecated and the APIs are removed, these tests
|
||||||
|
Loading…
x
Reference in New Issue
Block a user