Unverified Commit ad62645f authored by neko-andrew's avatar neko-andrew Committed by GitHub

Fix intrinsic width of input decorator (#138074)

Fix min intrinsic width of input decorator by removing left or right padding when `prefixIcon` or `suffixIcon` are used.

Fixes #137937.
parent e49cc812
......@@ -1224,25 +1224,25 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
@override
double computeMinIntrinsicWidth(double height) {
return _minWidth(icon, height)
+ contentPadding.left
+ (prefixIcon != null ? 0.0 : (textDirection == TextDirection.ltr ? contentPadding.left : contentPadding.right))
+ _minWidth(prefixIcon, height)
+ _minWidth(prefix, height)
+ math.max(_minWidth(input, height), _minWidth(hint, height))
+ _minWidth(suffix, height)
+ _minWidth(suffixIcon, height)
+ contentPadding.right;
+ (suffixIcon != null ? 0.0 : (textDirection == TextDirection.ltr ? contentPadding.right : contentPadding.left));
}
@override
double computeMaxIntrinsicWidth(double height) {
return _maxWidth(icon, height)
+ contentPadding.left
+ (prefixIcon != null ? 0.0 : (textDirection == TextDirection.ltr ? contentPadding.left : contentPadding.right))
+ _maxWidth(prefixIcon, height)
+ _maxWidth(prefix, height)
+ math.max(_maxWidth(input, height), _maxWidth(hint, height))
+ _maxWidth(suffix, height)
+ _maxWidth(suffixIcon, height)
+ contentPadding.right;
+ (suffixIcon != null ? 0.0 : (textDirection == TextDirection.ltr ? contentPadding.right : contentPadding.left));
}
double _lineHeight(double width, List<RenderBox?> boxes) {
......
......@@ -26,6 +26,7 @@ Widget buildInputDecorator({
bool isFocused = false,
bool isHovering = false,
bool useMaterial3 = false,
bool useIntrinsicWidth = false,
TextStyle? baseStyle,
TextAlignVertical? textAlignVertical,
VisualDensity? visualDensity,
......@@ -34,6 +35,21 @@ Widget buildInputDecorator({
style: TextStyle(fontSize: 16.0),
),
}) {
Widget widget = InputDecorator(
expands: expands,
decoration: decoration,
isEmpty: isEmpty,
isFocused: isFocused,
isHovering: isHovering,
baseStyle: baseStyle,
textAlignVertical: textAlignVertical,
child: child,
);
if (useIntrinsicWidth) {
widget = IntrinsicWidth(child: widget);
}
return MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Material(
......@@ -50,16 +66,7 @@ Widget buildInputDecorator({
alignment: Alignment.topLeft,
child: Directionality(
textDirection: textDirection,
child: InputDecorator(
expands: expands,
decoration: decoration,
isEmpty: isEmpty,
isFocused: isFocused,
isHovering: isHovering,
baseStyle: baseStyle,
textAlignVertical: textAlignVertical,
child: child,
),
child: widget,
),
),
);
......@@ -6890,6 +6897,48 @@ testWidgetsWithLeakTracking('OutlineInputBorder with BorderRadius.zero should dr
expect(decoratorRight, lessThanOrEqualTo(prefixRight));
});
testWidgetsWithLeakTracking('instrinic width with prefixIcon/suffixIcon', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/137937
for (final TextDirection direction in TextDirection.values) {
Future<Size> measureText(InputDecoration decoration) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
// isEmpty: false (default)
// isFocused: false (default)
decoration: decoration,
useIntrinsicWidth: true,
textDirection: direction,
),
);
await tester.pumpAndSettle();
expect(find.text('text'), findsOneWidget);
return tester.renderObject<RenderBox>(find.text('text')).size;
}
const EdgeInsetsGeometry padding = EdgeInsetsDirectional.only(end: 24, start: 12);
final Size textSizeWithoutIcons = await measureText(const InputDecoration(
contentPadding: padding,
));
final Size textSizeWithPrefixIcon = await measureText(const InputDecoration(
contentPadding: padding,
prefixIcon: Focus(child: Icon(Icons.search)),
));
final Size textSizeWithSuffixIcon = await measureText(const InputDecoration(
contentPadding: padding,
suffixIcon: Focus(child: Icon(Icons.search)),
));
expect(textSizeWithPrefixIcon.width, equals(textSizeWithoutIcons.width), reason: 'text width is different with prefixIcon and $direction');
expect(textSizeWithSuffixIcon.width, equals(textSizeWithoutIcons.width), reason: 'text width is different with prefixIcon and $direction');
}
});
testWidgetsWithLeakTracking('InputDecorator with counter does not crash when given a 0 size', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/129611
const InputDecoration decoration = InputDecoration(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment