Unverified Commit 924e48ee authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

Increase TextField's minimum height from 40 to 48 (#42449)

This is being done to match the Material spec. It will likely break many visual diff tests.
parent 3cd8c314
......@@ -10,6 +10,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'constants.dart';
import 'input_border.dart';
import 'theme.dart';
......@@ -496,6 +497,7 @@ class _Decoration {
this.counter,
this.container,
this.alignLabelWithHint,
this.isDense,
}) : assert(contentPadding != null),
assert(isCollapsed != null),
assert(floatingLabelHeight != null),
......@@ -508,6 +510,7 @@ class _Decoration {
final InputBorder border;
final _InputBorderGap borderGap;
final bool alignLabelWithHint;
final bool isDense;
final Widget icon;
final Widget input;
final Widget label;
......@@ -1037,10 +1040,19 @@ class _RenderDecoration extends RenderBox {
+ fixBelowInput
+ contentPadding.bottom,
);
final double minContainerHeight = decoration.isDense || expands
? 0.0
: kMinInteractiveDimension;
final double maxContainerHeight = boxConstraints.maxHeight - bottomHeight;
final double containerHeight = expands
? maxContainerHeight
: math.min(contentHeight, maxContainerHeight);
: math.min(math.max(contentHeight, minContainerHeight), maxContainerHeight);
// Ensure the text is vertically centered in cases where the content is
// shorter than kMinInteractiveDimension.
final double interactiveAdjustment = minContainerHeight > contentHeight
? (minContainerHeight - contentHeight) / 2.0
: 0.0;
// Try to consider the prefix/suffix as part of the text when aligning it.
// If the prefix/suffix overflows however, allow it to extend outside of the
......@@ -1058,7 +1070,8 @@ class _RenderDecoration extends RenderBox {
final double topInputBaseline = contentPadding.top
+ topHeight
+ inputInternalBaseline
+ baselineAdjustment;
+ baselineAdjustment
+ interactiveAdjustment;
final double maxContentHeight = containerHeight
- contentPadding.top
- topHeight
......@@ -2156,7 +2169,10 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
widthFactor: 1.0,
heightFactor: 1.0,
child: ConstrainedBox(
constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0),
constraints: const BoxConstraints(
minWidth: kMinInteractiveDimension,
minHeight: kMinInteractiveDimension,
),
child: IconTheme.merge(
data: IconThemeData(
color: iconColor,
......@@ -2172,7 +2188,10 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
widthFactor: 1.0,
heightFactor: 1.0,
child: ConstrainedBox(
constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0),
constraints: const BoxConstraints(
minWidth: kMinInteractiveDimension,
minHeight: kMinInteractiveDimension,
),
child: IconTheme.merge(
data: IconThemeData(
color: iconColor,
......@@ -2253,6 +2272,7 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
input: widget.child,
label: label,
alignLabelWithHint: decoration.alignLabelWithHint,
isDense: decoration.isDense,
hint: hint,
prefix: prefix,
suffix: suffix,
......
......@@ -509,12 +509,12 @@ void main() {
),
);
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 40.0));
expect(tester.getTopLeft(find.text('text')).dy, 12.0);
expect(tester.getBottomLeft(find.text('text')).dy, 28.0);
expect(tester.getTopLeft(find.text('hint')).dy, 12.0);
expect(tester.getBottomLeft(find.text('hint')).dy, 28.0);
expect(getBorderBottom(tester), 40.0);
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension));
expect(tester.getTopLeft(find.text('text')).dy, 16.0);
expect(tester.getBottomLeft(find.text('text')).dy, 32.0);
expect(tester.getTopLeft(find.text('hint')).dy, 16.0);
expect(tester.getBottomLeft(find.text('hint')).dy, 32.0);
expect(getBorderBottom(tester), 48.0);
expect(getBorderWeight(tester), 1.0);
expect(tester.getSize(find.text('hint')).width, tester.getSize(find.text('text')).width);
......@@ -1144,14 +1144,14 @@ void main() {
// The prefix and suffix wrap the input text and are left and right justified
// respectively. They should have the same height as the input text (16).
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 40.0));
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension));
expect(tester.getSize(find.text('text')).height, 16.0);
expect(tester.getSize(find.text('p')).height, 16.0);
expect(tester.getSize(find.text('s')).height, 16.0);
expect(tester.getTopLeft(find.text('text')).dy, 12.0);
expect(tester.getTopLeft(find.text('p')).dy, 12.0);
expect(tester.getTopLeft(find.text('text')).dy, 16.0);
expect(tester.getTopLeft(find.text('p')).dy, 16.0);
expect(tester.getTopLeft(find.text('p')).dx, 12.0);
expect(tester.getTopLeft(find.text('s')).dy, 12.0);
expect(tester.getTopLeft(find.text('s')).dy, 16.0);
expect(tester.getTopRight(find.text('s')).dx, 788.0);
// layout is a row: [p text s]
......@@ -1179,18 +1179,18 @@ void main() {
// 16 - input text (ahem font size 16dps)
// 12 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 40.0));
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension));
expect(tester.getSize(find.text('text')).height, 16.0);
expect(tester.getSize(find.text('p')).height, 16.0);
expect(tester.getSize(find.text('s')).height, 16.0);
expect(tester.getTopLeft(find.text('text')).dy, 12.0);
expect(tester.getTopLeft(find.text('p')).dy, 12.0);
expect(tester.getTopLeft(find.text('s')).dy, 12.0);
expect(tester.getTopLeft(find.text('text')).dy, 16.0);
expect(tester.getTopLeft(find.text('p')).dy, 16.0);
expect(tester.getTopLeft(find.text('s')).dy, 16.0);
expect(tester.getTopRight(find.text('s')).dx, 788.0);
expect(tester.getSize(find.byType(Icon)).height, 24.0);
// The 24dps high icon is centered on the 16dps high input line
expect(tester.getTopLeft(find.byType(Icon)).dy, 8.0);
expect(tester.getTopLeft(find.byType(Icon)).dy, 12.0);
// layout is a row: [icon, p text s]
expect(tester.getTopLeft(find.byType(Icon)).dx, 0.0);
......@@ -1939,10 +1939,10 @@ void main() {
),
);
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 44.0));
expect(tester.getTopLeft(find.text('text')).dy, 13.0);
expect(tester.getBottomLeft(find.text('text')).dy, 29.0);
expect(getBorderBottom(tester), 44.0);
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
expect(tester.getTopLeft(find.text('text')).dy, 15.0);
expect(tester.getBottomLeft(find.text('text')).dy, 31.0);
expect(getBorderBottom(tester), 48.0);
expect(getBorderWeight(tester), 1.0);
});
......@@ -1960,10 +1960,10 @@ void main() {
),
);
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 44.0));
expect(tester.getTopLeft(find.text('text')).dy, 13.0);
expect(tester.getBottomLeft(find.text('text')).dy, 29.0);
expect(getBorderBottom(tester), 44.0);
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);
expect(getBorderBottom(tester), 48.0);
expect(getBorderWeight(tester), 1.0);
});
......@@ -2098,7 +2098,7 @@ void main() {
// Margin for text decoration is 12 when filled
// (dx) - 12 = (text offset)x.
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 60.0));
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 68.0));
final double dx = tester.getRect(find.byType(InputDecorator)).right;
expect(tester.getRect(find.text('test')).right, dx - 12.0);
});
......@@ -2118,7 +2118,7 @@ void main() {
// Margin for text decoration is 12 when filled and top left offset is (0, 0)
// 0 + 12 = 12.
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 60.0));
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 68.0));
expect(tester.getRect(find.text('test')).left, 12.0);
});
......@@ -2236,13 +2236,13 @@ void main() {
// 16 - input text (ahem font size 16dps)
// 12 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 40.0));
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension)); // 40 bumped up to minimum.
expect(tester.getSize(find.text('text')).height, 16.0);
expect(tester.getSize(find.text('p')).height, 16.0);
expect(tester.getSize(find.text('s')).height, 16.0);
expect(tester.getTopLeft(find.text('text')).dy, 12.0);
expect(tester.getTopLeft(find.text('p')).dy, 12.0);
expect(tester.getTopLeft(find.text('s')).dy, 12.0);
expect(tester.getTopLeft(find.text('text')).dy, 16.0);
expect(tester.getTopLeft(find.text('p')).dy, 16.0);
expect(tester.getTopLeft(find.text('s')).dy, 16.0);
// layout is a row: [s text p]
expect(tester.getTopLeft(find.text('s')).dx, 12.0);
......@@ -2339,10 +2339,10 @@ void main() {
// 16 - input text (ahem font size 16dps)
// 12 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 40.0));
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension)); // 40 bumped up to minimum.
expect(tester.getSize(find.text('text')).height, 16.0);
expect(tester.getTopLeft(find.text('text')).dy, 12.0);
expect(getBorderBottom(tester), 40.0);
expect(tester.getTopLeft(find.text('text')).dy, 16.0);
expect(getBorderBottom(tester), kMinInteractiveDimension); // 40 bumped up to minimum.
expect(getBorderWeight(tester), 1.0);
}, skip: isBrowser);
......@@ -2360,9 +2360,9 @@ void main() {
// Overall height for this InputDecorator is 16dps:
// 16 - input text (ahem font size 16dps)
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 16.0));
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension)); // 16 bumped up to minimum.
expect(tester.getSize(find.text('text')).height, 16.0);
expect(tester.getTopLeft(find.text('text')).dy, 0.0);
expect(tester.getTopLeft(find.text('text')).dy, 16.0);
expect(getOpacity(tester, 'hint'), 0.0);
expect(getBorderWeight(tester), 0.0);
......@@ -2378,11 +2378,11 @@ void main() {
);
await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 16.0));
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, 0.0);
expect(tester.getTopLeft(find.text('text')).dy, 16.0);
expect(tester.getSize(find.text('hint')).height, 16.0);
expect(tester.getTopLeft(find.text('hint')).dy, 0.0);
expect(tester.getTopLeft(find.text('hint')).dy, 16.0);
expect(getBorderWeight(tester), 0.0);
}, skip: isBrowser);
......@@ -2418,13 +2418,13 @@ void main() {
// 10 - label (ahem font size 10dps)
// 17.75 - bottom padding (empty input text still appears here)
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 45.5));
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension)); // 45.5 bumped up to minimum.
expect(tester.getSize(find.text('hint')).height, 10.0);
expect(tester.getSize(find.text('label')).height, 10.0);
expect(tester.getSize(find.text('text')).height, 10.0);
expect(tester.getTopLeft(find.text('hint')).dy, 23.5);
expect(tester.getTopLeft(find.text('label')).dy, 17.75);
expect(tester.getTopLeft(find.text('text')).dy, 23.5);
expect(tester.getTopLeft(find.text('hint')).dy, 24.75);
expect(tester.getTopLeft(find.text('label')).dy, 19.0);
expect(tester.getTopLeft(find.text('text')).dy, 24.75);
}, skip: isBrowser);
testWidgets('InputDecorator with empty style overrides', (WidgetTester tester) async {
......
......@@ -519,10 +519,10 @@ void main() {
// This tap just puts the cursor somewhere different than where the double
// tap will occur to test that the double tap moves the existing cursor first.
await tester.tapAt(textfieldStart + const Offset(50.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump(const Duration(milliseconds: 500));
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
// First tap moved the cursor.
expect(
......@@ -530,7 +530,7 @@ void main() {
const TextSelection.collapsed(
offset: 8, affinity: TextAffinity.downstream),
);
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump();
// Second tap selects the word around the cursor.
......@@ -566,10 +566,10 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump();
// Selected text shows 'COPY', and not 'PASTE', 'CUT', 'SELECT ALL'.
......@@ -2870,7 +2870,7 @@ void main() {
),
);
expect(tester.getTopLeft(find.text('hint')), equals(tester.getTopLeft(find.byType(TextField))));
expect(tester.getTopLeft(find.text('hint')), equals(tester.getTopLeft(find.byType(EditableText))));
});
testWidgets('Can align to center', (WidgetTester tester) async {
......@@ -5523,7 +5523,7 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.tapAt(textfieldStart + const Offset(50.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump();
// We moved the cursor.
......@@ -5557,7 +5557,7 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.tapAt(textfieldStart + const Offset(50.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump();
// We moved the cursor.
......@@ -5592,9 +5592,9 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.tapAt(textfieldStart + const Offset(50.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump(const Duration(milliseconds: 500));
await tester.tapAt(textfieldStart + const Offset(50.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump();
// Plain collapsed selection.
......@@ -5631,17 +5631,17 @@ void main() {
// This tap just puts the cursor somewhere different than where the double
// tap will occur to test that the double tap moves the existing cursor first.
await tester.tapAt(textfieldStart + const Offset(50.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump(const Duration(milliseconds: 500));
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
// First tap moved the cursor.
expect(
controller.selection,
const TextSelection.collapsed(offset: 8, affinity: TextAffinity.downstream),
);
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump();
// Second tap selects the word around the cursor.
......@@ -5677,17 +5677,17 @@ void main() {
// This tap just puts the cursor somewhere different than where the double
// tap will occur to test that the double tap moves the existing cursor first.
await tester.tapAt(textfieldStart + const Offset(50.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump(const Duration(milliseconds: 500));
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
// First tap moved the cursor.
expect(
controller.selection,
const TextSelection.collapsed(offset: 9),
);
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump();
// Second tap selects the word around the cursor.
......@@ -5896,10 +5896,10 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
final TestGesture gesture =
await tester.startGesture(textfieldStart + const Offset(150.0, 5.0));
await tester.startGesture(textfieldStart + const Offset(150.0, 9.0));
// Hold the press.
await tester.pump(const Duration(milliseconds: 500));
......@@ -5945,17 +5945,17 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
// First tap moved the cursor.
expect(
controller.selection,
const TextSelection.collapsed(offset: 8, affinity: TextAffinity.downstream),
);
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 500));
await tester.tapAt(textfieldStart + const Offset(100.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(100.0, 9.0));
await tester.pump();
// Plain collapsed selection at the edge of first word. In iOS 12, the
......@@ -5993,7 +5993,7 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.longPressAt(textfieldStart + const Offset(50.0, 5.0));
await tester.longPressAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump();
// Collapsed cursor for iOS long press.
......@@ -6027,7 +6027,7 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.longPressAt(textfieldStart + const Offset(50.0, 5.0));
await tester.longPressAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump();
expect(
......@@ -6061,10 +6061,10 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.longPressAt(textfieldStart + const Offset(50.0, 5.0));
await tester.longPressAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
await tester.tapAt(textfieldStart + const Offset(50.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump();
// We ended up moving the cursor to the edge of the same word and dismissed
......@@ -6101,7 +6101,7 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
final TestGesture gesture =
await tester.startGesture(textfieldStart + const Offset(50.0, 5.0));
await tester.startGesture(textfieldStart + const Offset(50.0, 9.0));
await tester.pump(const Duration(milliseconds: 500));
// Long press on iOS shows collapsed selection cursor.
......@@ -6258,17 +6258,17 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
// First tap moved the cursor to the beginning of the second word.
expect(
controller.selection,
const TextSelection.collapsed(offset: 8, affinity: TextAffinity.downstream),
);
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 500));
await tester.longPressAt(textfieldStart + const Offset(100.0, 5.0));
await tester.longPressAt(textfieldStart + const Offset(100.0, 9.0));
await tester.pump();
// Plain collapsed selection at the exact tap position.
......@@ -6303,17 +6303,17 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.longPressAt(textfieldStart + const Offset(50.0, 5.0));
await tester.longPressAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
// First tap moved the cursor.
expect(
controller.selection,
const TextSelection.collapsed(offset: 8, affinity: TextAffinity.downstream),
);
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump();
// Double tap selection.
......@@ -6346,13 +6346,13 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
await tester.tapAt(textfieldStart + const Offset(50.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
expect(
controller.selection,
const TextSelection.collapsed(offset: 7, affinity: TextAffinity.upstream),
);
await tester.tapAt(textfieldStart + const Offset(50.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(50.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
expect(
controller.selection,
......@@ -6361,14 +6361,14 @@ void main() {
expect(find.byType(CupertinoButton), findsNWidgets(3));
// Double tap selecting the same word somewhere else is fine.
await tester.tapAt(textfieldStart + const Offset(100.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(100.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
// First tap moved the cursor.
expect(
controller.selection,
const TextSelection.collapsed(offset: 7, affinity: TextAffinity.upstream),
);
await tester.tapAt(textfieldStart + const Offset(100.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(100.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
expect(
controller.selection,
......@@ -6376,14 +6376,14 @@ void main() {
);
expect(find.byType(CupertinoButton), findsNWidgets(3));
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
// First tap moved the cursor.
expect(
controller.selection,
const TextSelection.collapsed(offset: 8, affinity: TextAffinity.downstream),
);
await tester.tapAt(textfieldStart + const Offset(150.0, 5.0));
await tester.tapAt(textfieldStart + const Offset(150.0, 9.0));
await tester.pump(const Duration(milliseconds: 50));
expect(
controller.selection,
......@@ -6407,7 +6407,7 @@ void main() {
),
);
final Offset offset = tester.getTopLeft(find.byType(TextField)) + const Offset(150.0, 5.0);
final Offset offset = tester.getTopLeft(find.byType(TextField)) + const Offset(150.0, 9.0);
const int pointerValue = 1;
final TestGesture gesture = await tester.createGesture();
......@@ -6421,7 +6421,7 @@ void main() {
pressureMin: 0.0,
),
);
await gesture.updateWithCustomEvent(PointerMoveEvent(pointer: pointerValue, position: offset + const Offset(150.0, 5.0), pressure: 0.5, pressureMin: 0, pressureMax: 1));
await gesture.updateWithCustomEvent(PointerMoveEvent(pointer: pointerValue, position: offset + const Offset(150.0, 9.0), pressure: 0.5, pressureMin: 0, pressureMax: 1));
// We don't want this gesture to select any word on Android.
expect(controller.selection, const TextSelection.collapsed(offset: -1));
......@@ -6449,7 +6449,7 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
const int pointerValue = 1;
final Offset offset = textfieldStart + const Offset(150.0, 5.0);
final Offset offset = textfieldStart + const Offset(150.0, 9.0);
final TestGesture gesture = await tester.createGesture();
await gesture.downWithCustomEvent(
offset,
......@@ -6462,7 +6462,7 @@ void main() {
),
);
await gesture.updateWithCustomEvent(PointerMoveEvent(pointer: pointerValue, position: textfieldStart + const Offset(150.0, 5.0), pressure: 0.5, pressureMin: 0, pressureMax: 1));
await gesture.updateWithCustomEvent(PointerMoveEvent(pointer: pointerValue, position: textfieldStart + const Offset(150.0, 9.0), pressure: 0.5, pressureMin: 0, pressureMax: 1));
// We expect the force press to select a word at the given location.
expect(
controller.selection,
......@@ -6492,7 +6492,7 @@ void main() {
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
const int pointerValue = 1;
final Offset offset = textfieldStart + const Offset(150.0, 5.0);
final Offset offset = textfieldStart + const Offset(150.0, 9.0);
final TestGesture gesture = await tester.createGesture();
await gesture.downWithCustomEvent(
offset,
......@@ -6506,7 +6506,7 @@ void main() {
),
);
await gesture.updateWithCustomEvent(PointerMoveEvent(pointer: pointerValue, position: textfieldStart + const Offset(150.0, 5.0), pressure: 0.5, pressureMin: 0, pressureMax: 1));
await gesture.updateWithCustomEvent(PointerMoveEvent(pointer: pointerValue, position: textfieldStart + const Offset(150.0, 9.0), pressure: 0.5, pressureMin: 0, pressureMax: 1));
await gesture.up();
// The event should fallback to a normal tap and move the cursor.
// Single taps selects the edge of the word.
......@@ -6602,9 +6602,11 @@ void main() {
expect(
tester.getSize(find.byType(TextField)),
// This is the height of the decoration (24) plus the metrics from the default
// TextStyle of the theme (16).
const Size(800, 40),
// The TextField will be as tall as the decoration (24) plus the metrics
// from the default TextStyle of the theme (16), or 40 altogether.
// Because this is less than the kMinInteractiveDimension, it will be
// increased to that value (48).
const Size(800, kMinInteractiveDimension),
);
},
);
......@@ -6629,7 +6631,7 @@ void main() {
tester.getSize(find.byType(TextField)),
// Strut should inherit the TextStyle.fontSize by default and produce the
// same height as if it were disabled.
const Size(800, 44),
const Size(800, kMinInteractiveDimension), // Because 44 < 48.
);
await tester.pumpWidget(
......@@ -6649,7 +6651,7 @@ void main() {
expect(
tester.getSize(find.byType(TextField)),
// The height here should match the previous version with strut enabled.
const Size(800, 44),
const Size(800, kMinInteractiveDimension), // Because 44 < 48.
);
},
);
......@@ -7235,7 +7237,6 @@ void main() {
testWidgets('when TextField would be blocked by keyboard, it is shown with enough space for the selection handle', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController();
final TextEditingController controller = TextEditingController();
await tester.pumpWidget(MaterialApp(
theme: ThemeData(),
......@@ -7245,7 +7246,7 @@ void main() {
controller: scrollController,
children: <Widget>[
Container(height: 579), // Push field almost off screen.
TextField(controller: controller),
const TextField(),
Container(height: 1000),
],
),
......@@ -7255,12 +7256,62 @@ void main() {
// Tap the TextField to put the cursor into it and bring it into view.
expect(scrollController.offset, 0.0);
await tester.tap(find.byType(TextField));
await tester.tapAt(tester.getTopLeft(find.byType(TextField)));
await tester.pumpAndSettle();
// The ListView has scrolled to keep the TextField and cursor handle
// visible.
expect(scrollController.offset, 44.0);
expect(scrollController.offset, 48.0);
});
group('height', () {
testWidgets('By default, TextField is at least kMinInteractiveDimension high', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
theme: ThemeData(),
home: const Scaffold(
body: Center(
child: TextField(),
),
),
));
final RenderBox renderBox = tester.renderObject(find.byType(TextField));
expect(renderBox.size.height, greaterThanOrEqualTo(kMinInteractiveDimension));
});
testWidgets('When text is very small, TextField still doesn\'t go below kMinInteractiveDimension height', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
theme: ThemeData(),
home: const Scaffold(
body: Center(
child: TextField(
style: TextStyle(fontSize: 2.0),
),
),
),
));
final RenderBox renderBox = tester.renderObject(find.byType(TextField));
expect(renderBox.size.height, kMinInteractiveDimension);
});
testWidgets('When isDense, TextField can go below kMinInteractiveDimension height', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
theme: ThemeData(),
home: const Scaffold(
body: Center(
child: TextField(
decoration: InputDecoration(
isDense: true,
),
),
),
),
));
final RenderBox renderBox = tester.renderObject(find.byType(TextField));
expect(renderBox.size.height, lessThan(kMinInteractiveDimension));
});
});
testWidgets("Arrow keys don't move input focus", (WidgetTester tester) async {
final TextEditingController controller1 = TextEditingController();
......
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