Text field height fix (#55911)
diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart
index b08f986..9898505 100644
--- a/packages/flutter/lib/src/material/input_decorator.dart
+++ b/packages/flutter/lib/src/material/input_decorator.dart
@@ -1075,7 +1075,7 @@
+ contentPadding.bottom
+ densityOffset.dy,
);
- final double minContainerHeight = decoration.isDense || expands
+ final double minContainerHeight = decoration.isDense || decoration.isCollapsed || expands
? 0.0
: kMinInteractiveDimension + densityOffset.dy;
final double maxContainerHeight = boxConstraints.maxHeight - bottomHeight + densityOffset.dy;
@@ -2511,6 +2511,7 @@
)
this.hasFloatingPlaceholder = true, // ignore: deprecated_member_use_from_same_package
this.floatingLabelBehavior = FloatingLabelBehavior.auto,
+ this.isCollapsed = false,
this.isDense,
this.contentPadding,
this.prefixIcon,
@@ -2541,8 +2542,7 @@
this.alignLabelWithHint,
}) : assert(enabled != null),
assert(!(prefix != null && prefixText != null), 'Declaring both prefix and prefixText is not supported.'),
- assert(!(suffix != null && suffixText != null), 'Declaring both suffix and suffixText is not supported.'),
- isCollapsed = false;
+ assert(!(suffix != null && suffixText != null), 'Declaring both suffix and suffixText is not supported.');
/// Defines an [InputDecorator] that is the same size as the input field.
///
@@ -3303,8 +3303,6 @@
/// Creates a copy of this input decoration with the given fields replaced
/// by the new values.
- ///
- /// Always sets [isCollapsed] to false.
InputDecoration copyWith({
Widget icon,
String labelText,
@@ -3320,6 +3318,7 @@
int errorMaxLines,
bool hasFloatingPlaceholder,
FloatingLabelBehavior floatingLabelBehavior,
+ bool isCollapsed,
bool isDense,
EdgeInsetsGeometry contentPadding,
Widget prefixIcon,
@@ -3365,6 +3364,7 @@
// ignore: deprecated_member_use_from_same_package
hasFloatingPlaceholder: hasFloatingPlaceholder ?? this.hasFloatingPlaceholder,
floatingLabelBehavior: floatingLabelBehavior ?? this.floatingLabelBehavior,
+ isCollapsed: isCollapsed ?? this.isCollapsed,
isDense: isDense ?? this.isDense,
contentPadding: contentPadding ?? this.contentPadding,
prefixIcon: prefixIcon ?? this.prefixIcon,
@@ -3412,6 +3412,7 @@
// ignore: deprecated_member_use_from_same_package
hasFloatingPlaceholder: hasFloatingPlaceholder ?? theme.hasFloatingPlaceholder,
floatingLabelBehavior: floatingLabelBehavior ?? theme.floatingLabelBehavior,
+ isCollapsed: isCollapsed ?? theme.isCollapsed,
isDense: isDense ?? theme.isDense,
contentPadding: contentPadding ?? theme.contentPadding,
prefixStyle: prefixStyle ?? theme.prefixStyle,
diff --git a/packages/flutter/test/material/input_decorator_test.dart b/packages/flutter/test/material/input_decorator_test.dart
index 7063f98..6187713 100644
--- a/packages/flutter/test/material/input_decorator_test.dart
+++ b/packages/flutter/test/material/input_decorator_test.dart
@@ -2243,7 +2243,6 @@
),
),
);
-
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension));
expect(tester.getTopLeft(find.text('text')).dy, 15.0);
expect(tester.getBottomLeft(find.text('text')).dy, 31.0);
@@ -2630,6 +2629,79 @@
expect(getBorderWeight(tester), 1.0);
});
+ testWidgets('contentPadding smaller than kMinInteractiveDimension', (WidgetTester tester) async {
+ // Regression test for https://github.com/flutter/flutter/issues/42449
+ const double verticalPadding = 1.0;
+ await tester.pumpWidget(
+ buildInputDecorator(
+ // isEmpty: false (default),
+ // isFocused: false (default)
+ decoration: const InputDecoration(
+ hintText: 'hint',
+ contentPadding: EdgeInsets.symmetric(vertical: verticalPadding),
+ isDense: true,
+ ),
+ ),
+ );
+
+ // The overall height is 18dps. This is shorter than
+ // kMinInteractiveDimension, but because isDense is true, the minimum is
+ // ignored.
+ // 16 - input text (ahem font size 16dps)
+ // 2 - total vertical padding
+
+ expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 18.0));
+ expect(tester.getSize(find.text('text')).height, 16.0);
+ expect(tester.getTopLeft(find.text('text')).dy, 1.0);
+ expect(getOpacity(tester, 'hint'), 0.0);
+ expect(getBorderWeight(tester), 1.0);
+
+ await tester.pumpWidget(
+ buildInputDecorator(
+ // isEmpty: false (default),
+ // isFocused: false (default)
+ decoration: const InputDecoration.collapsed(
+ hintText: 'hint',
+ // InputDecoration.collapsed does not support contentPadding
+ ),
+ ),
+ );
+
+ // The overall height is 16dps. This is shorter than
+ // kMinInteractiveDimension, but because isCollapsed is true, the minimum is
+ // ignored. There is no padding at all, because isCollapsed doesn't support
+ // contentPadding.
+ // 16 - input text (ahem font size 16dps)
+
+ expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 16.0));
+ expect(tester.getSize(find.text('text')).height, 16.0);
+ expect(tester.getTopLeft(find.text('text')).dy, 0.0);
+ expect(getOpacity(tester, 'hint'), 0.0);
+ expect(getBorderWeight(tester), 1.0);
+
+ await tester.pumpWidget(
+ buildInputDecorator(
+ // isEmpty: false (default),
+ // isFocused: false (default)
+ decoration: const InputDecoration(
+ hintText: 'hint',
+ contentPadding: EdgeInsets.symmetric(vertical: verticalPadding),
+ ),
+ ),
+ );
+
+ // The requested overall height is 18dps, however the minimum height is
+ // kMinInteractiveDimension because neither isDense or isCollapsed are true.
+ // 16 - input text (ahem font size 16dps)
+ // 2 - total vertical padding
+
+ expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension));
+ expect(tester.getSize(find.text('text')).height, 16.0);
+ expect(tester.getTopLeft(find.text('text')).dy, 16.0);
+ expect(getOpacity(tester, 'hint'), 0.0);
+ expect(getBorderWeight(tester), 0.0);
+ });
+
testWidgets('InputDecorator.collapsed', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
@@ -2641,12 +2713,13 @@
),
);
- // Overall height for this InputDecorator is 16dps:
+ // Overall height for this InputDecorator is 16dps. There is no minimum
+ // height when InputDecoration.collapsed is used.
// 16 - input text (ahem font size 16dps)
- expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension)); // 16 bumped up to minimum.
+ expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 16.0));
expect(tester.getSize(find.text('text')).height, 16.0);
- expect(tester.getTopLeft(find.text('text')).dy, 16.0);
+ expect(tester.getTopLeft(find.text('text')).dy, 0.0);
expect(getOpacity(tester, 'hint'), 0.0);
expect(getBorderWeight(tester), 0.0);
@@ -2662,11 +2735,11 @@
);
await tester.pumpAndSettle();
- expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension));
+ expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 16.0));
expect(tester.getSize(find.text('text')).height, 16.0);
- expect(tester.getTopLeft(find.text('text')).dy, 16.0);
+ expect(tester.getTopLeft(find.text('text')).dy, 0.0);
expect(tester.getSize(find.text('hint')).height, 16.0);
- expect(tester.getTopLeft(find.text('hint')).dy, 16.0);
+ expect(tester.getTopLeft(find.text('hint')).dy, 0.0);
expect(getBorderWeight(tester), 0.0);
});