Skip to content

Conversation

@LongCatIsLooong
Copy link
Contributor

@LongCatIsLooong LongCatIsLooong commented Aug 13, 2020

Description

Warns if a single line text field's parent is not able to provide sufficient height to accommodate the text field. So developers don't get surprised when they see weird clipping. Set clipBehavior to Clip.none to opt-out (TextField currently doesn't seem to have a clipBehavior parameter).

Related Issues

Alleviates #51257. Not sure that issue really needs a fix. It happens because we clip the RenderParagraph when the text gets too long along the scroll axis (horizontal for single line and vertical for multiline), but as a side effect the other axis gets clipped as well.
Fixes #35706

Tests

I added the following tests:

  • RenderEditable can stretch vertically

Checklist

Before you create this PR, confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Did any tests fail when you ran them? Please read Handling breaking changes.

@flutter-dashboard flutter-dashboard bot added framework flutter/packages/flutter repository. See also f: labels. work in progress; do not review labels Aug 13, 2020
@skia-gold
Copy link

Gold has detected about 15 untriaged digest(s) on patchset 5.
View them at https://flutter-gold.skia.org/cl/github/63639

@LongCatIsLooong LongCatIsLooong force-pushed the report-text-field-insufficient-height branch from 0c237bb to c12010f Compare August 13, 2020 07:59
@skia-gold
Copy link

Gold has detected about 15 untriaged digest(s) on patchset 5.
View them at https://flutter-gold.skia.org/cl/github/63639

@LongCatIsLooong LongCatIsLooong force-pushed the report-text-field-insufficient-height branch from c12010f to 4762175 Compare August 13, 2020 08:31
@skia-gold
Copy link

Gold has detected about 15 untriaged digest(s) on patchset 6.
View them at https://flutter-gold.skia.org/cl/github/63639

2 similar comments
@skia-gold
Copy link

Gold has detected about 15 untriaged digest(s) on patchset 6.
View them at https://flutter-gold.skia.org/cl/github/63639

@skia-gold
Copy link

Gold has detected about 15 untriaged digest(s) on patchset 6.
View them at https://flutter-gold.skia.org/cl/github/63639

@skia-gold
Copy link

Gold has detected about 15 untriaged digest(s) on patchset 7.
View them at https://flutter-gold.skia.org/cl/github/63639

@LongCatIsLooong
Copy link
Contributor Author

@justinmc @HansMuller I'd like to get a high-level review of this idea. Could there be cases where a single-line text field is intentionally constrained to a small height so the text gets cut off?

@flutter-dashboard flutter-dashboard bot added the a: tests "flutter test", flutter_test, or one of our tests label Aug 13, 2020
@justinmc
Copy link
Contributor

I'm on board with this at a high level. I like the way you implemented it, maybe it'll be useful elsewhere in the future. I can't think of a reason off the top of my head that you would want to purposely have a text field overflow, but interested to hear what Hans says.

@LongCatIsLooong
Copy link
Contributor Author

I put this on frob: cl/326752193.

@flutter-dashboard
Copy link

This pull request has been changed to a draft. The currently pending flutter-gold status will not be able to resolve until a new commit is pushed or the change is marked ready for review again.

@skia-gold
Copy link

Gold has detected about 30 untriaged digest(s) on patchset 10.
View them at https://flutter-gold.skia.org/cl/github/63639

@LongCatIsLooong
Copy link
Contributor Author

Internal tests seem to be passing.

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some small code changes and some questions, but overall this looks good. I think the approach of using composition and RenderConstraintsTransformBox is really solid and reusable. We'll have to watch for this breaking anything else.

How did the tests look when you used frob by the way? (I can't figure out how to see the test results)

_constraintsTransform = _convertAxis;
}

/// The axis to retain constraints on, if any.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a use for retaining constraints on neither axis?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think there's one in the framework or material or cupertino. But this PR does not change RenderUnconstrainedBox's API or functionality.

Comment on lines +795 to +806
if (constrainedAxis == null) {
return const BoxConstraints();
}
switch (constrainedAxis) {
case Axis.horizontal:
return constraints.copyWith(maxHeight: double.infinity, minHeight: 0);
case Axis.vertical:
return constraints.copyWith(maxWidth: double.infinity, minWidth: 0);
}
assert(false);
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use default to handle constrainedAxis == null and then just do everything in the switch statement?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah got it, that makes sense.

TextSpan(text: 'outer', style: TextStyle(fontSize: 20)),
WidgetSpan(
child: SizedBox(width: 70, height: 25, child: TextField()),
child: SizedBox(width: 70, height: 55, child: TextField()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were these being clipped before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, 55 is the minimum height iirc

@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM as long as Frob says it's not going to break any tests 👍

Comment on lines +740 to +741
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alone on an Infinite Canvas with No Constraints will be the name of my breakout studio album.

@LongCatIsLooong LongCatIsLooong force-pushed the report-text-field-insufficient-height branch from f63a552 to 5047a7a Compare August 24, 2020 18:44
@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice piece of work! Just some small-time feedback, mostly wordsmithing.

/// its child using the resulting [BoxConstraints], treating any overflow
/// as error.
///
/// This container sizes its child using a normalized [BoxConstraints] created
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't clear that "normalized" in this context means "satisfies BoxConstraints.isNormalized". Maybe leave the qualifier out here and document that we're going to assert isNormalized elsewhere?

/// printed on the console, and black and yellow striped areas will appear where
/// the overflow occurs.
///
/// This widget can be used to allow the child to enforce some of its intrinsic
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"some of its intrinsic sizing ..."? This widget doesn't necessarily know what the child's intrinsic sizing rules are?

Maybe just say: here's an example.

Ideally, you'd provide a rule of thumb about when to use this widget.

/// enough space:
///
/// {@tool snippet}
/// This snippet allows the [Card] to be at least its intrinsic height high, but
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is a little clearer?
This snippet guarantees that the child [Card]'s height will be at least as tall as its intrinsic height. Unlike an [UnconstrainedBox], the child will be taller if the parent's max height is constrained. If the parent's max height is constrained to be less than the Card's intrinsic height then a warning will be given in debug mode.

///
/// See also:
///
/// * [BoxConstraints], the type constraints of constraints this widget can be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably don't need this reference (plus "the type constraints of constraints" is a typo), since the API includes BoxConstraints.

///
/// * [BoxConstraints], the type constraints of constraints this widget can be
/// used to manipulate.
/// * [ConstrainedBox], which renders a box which imposes constraints
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A widget that imposes additional constraints on its child.

Best to lift these one-liners from the existing API doc; don't want to explain "boxes" vs widget here.

/// [AlignmentDirectional].
final TextDirection textDirection;

/// The alignment to use when laying out the child.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this explain that it's for cases where the parent isn't the same size as the child?

/// The alignment to use when laying out the child.
///
/// If this is an [AlignmentDirectional], then [textDirection] must not be
/// null.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we use Directionality.of(context) if the textDirection parameter is null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does. Copied the docs from unconstrainedbox and didn't check.

final AlignmentGeometry alignment;

/// @{template flutter.widgets.constraintsTransform}
/// The function used to transform the [BoxConstraints] imposed on [child].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If would be a little more helpful to explain that the we're transforming the parent's constraints and then using them to constrain the child's size.

/// The function used to transform the [BoxConstraints] imposed on [child].
///
/// Must not be null. The function must not return null. The result will be
/// normalized.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will be or must be?

AFAICT we don't normalize incoming constraints. Is this really necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Removing the normalize() call from performLayout.

}
constraintsTransform ??= _unconstrained;

return ConstraintsTransformBox(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NICE

@LongCatIsLooong
Copy link
Contributor Author

updated

Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@fluttergithubbot fluttergithubbot merged commit 0ab5ecc into flutter:master Aug 25, 2020
LongCatIsLooong added a commit to LongCatIsLooong/flutter that referenced this pull request Aug 25, 2020
LongCatIsLooong added a commit that referenced this pull request Aug 25, 2020
LongCatIsLooong added a commit to LongCatIsLooong/flutter that referenced this pull request Aug 26, 2020
This reverts commit 6536f65.
smadey pushed a commit to smadey/flutter that referenced this pull request Aug 27, 2020
smadey pushed a commit to smadey/flutter that referenced this pull request Aug 27, 2020
mingwandroid pushed a commit to mingwandroid/flutter that referenced this pull request Sep 6, 2020
mingwandroid pushed a commit to mingwandroid/flutter that referenced this pull request Sep 6, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 25, 2021
@LongCatIsLooong LongCatIsLooong deleted the report-text-field-insufficient-height branch September 5, 2022 08:28
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

a: tests "flutter test", flutter_test, or one of our tests framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TextField should warn on vertical overflow

6 participants