-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Correct editable text and placeholder position in baseline aligned stack #177342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
justinmc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
I guess it's possible this will break visual diff tests, so let's see what the Google tests say.
| child: _BaselineAlignedStack( | ||
| placeholder: placeholder, | ||
| editableText: editableText, | ||
| textAlignVertical: _textAlignVertical, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok so previously the placeholder and the EditableText were aligned by baseline. However, when they have different font sizes, this might look wrong (as seen in the screenshots in the description of #176817). Now with this PR it will default to center, which looks correct when the font sizes differ, and otherwise it's configurable with the textAlignVertical parameter.
Am I understanding correctly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partly.
This PR doesn't change the default. The wrong look happened because the position of the placeholder and editable text was slightly wrong (wrong calculations) and also wasn't configurable (even though the property textAlignVertical existed).
textAlignVertical originally wrapped the text dependent attachments (placeholder, editable text etc.) in an Align. My understanding (but might be wrong) is in writing our own renderbox, we now arbitrarily fixed the position of the placeholder + editable text in the entire space the Align contained, making the Align uneffective.
This PR basically copies over the alignment into the renderbox positioning so it is respected.
| required this.editableTextBaseline, | ||
| required this.placeholderBaseline, | ||
| required this.editableText, | ||
| required this.textAlignVertical, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we make textAlignVertical before the editableText parameter?
It feels a little weird that textAlignVertical is in between editableText and placeholder. It feels like we're "interrupting" the section of children arguments, if that makes sense.
This would also match the order used by the fields below.
loic-sharma
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| Expanded( | ||
| child: Directionality( | ||
| textDirection: widget.textDirection ?? Directionality.of(context), | ||
| child: _BaselineAlignedStack( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a useful widget. Should we add a generic version of this widget to the widgets library? I imagine other design systems would want to use this.
This isn't a blocker for landing this PR. Just an idea for future improvement :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we can just do this by adding a flag to Stack. The problem would be knowing which child's baseline should be the reference baseline.
I do think this is very doable though. Off the top of my head I think the API could have two main properties: a child with a reference baseline and children for all the other widgets that should be aligned to that baseline. Although if we know the baseline distance for the reference child's renderbox, we can use that number to align other children in a Stack by wrapping each child in a Baseline.
But getting the reference child's renderbox outside layout might be problematic (using a post frame callback can mitigate this, but that has its problems as well). So it's a good argument for writing a custom renderobject for this, but (correct me if I'm wrong here) that will mean we will have to manually position the children instead of relying on Baseline to simplify the work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could do something like this:
BaselineStack(
alignment: Alignment.top,
children: [
child1,
BaselineReference(child: child2),
child3,
],
),BaselineReference must be the child of a BaselineStack (similar to how Flexible and Expanded must be the direct child of a Row/Colum/Flex)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've always been confused by the Row/Column/Flex and Flexible/Expanded API because forcing a widget to only have a specific parent/child relationship introduces additional cognitive complexity.
Since all we need here is a reference baseline (so no Positioned widget as in Stack), I'm strongly inclined to an API that separates the child with the reference baseline from the other children. And this API means we can require the reference child but not necessarily the other children.
I do think we need some sort of intermediary configuration class that wraps both the reference child and other children. This is so that the TextBaseline for each child can be provided. Or is there an alternative way to provide the TextBaseline for each child?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since all we need here is a reference baseline (so no Positioned widget as in Stack), I'm strongly inclined to an API that separates the child with the reference baseline from the other children. And this API means we can require the reference child but not necessarily the other children.
That's fair. Another alternative might be:
BaselineStack(
alignment: Alignment.top,
baselineReferenceIndex: 1,
children: [
child1,
child2,
child3,
],
),flutter/flutter@4c91098...7cf0dc1 2025-10-28 [email protected] Roll Skia from 602bbd4af8f9 to e4d3d8f31aef (4 revisions) (flutter/flutter#177647) 2025-10-28 [email protected] Fix AppBar Semantics namesRoute for mismatched platforms (flutter/flutter#176694) 2025-10-28 [email protected] Fix Popup menu Semantics label for mismatched platforms (flutter/flutter#177049) 2025-10-28 [email protected] Roll Skia from 8b2d056701df to 602bbd4af8f9 (1 revision) (flutter/flutter#177628) 2025-10-28 [email protected] Roll Skia from 5723f87f8530 to 8b2d056701df (3 revisions) (flutter/flutter#177626) 2025-10-27 [email protected] Roll Skia from 170c11f1ddc5 to 5723f87f8530 (6 revisions) (flutter/flutter#177618) 2025-10-27 [email protected] Enhance DropdownMenuEntry's labelWidget docs (flutter/flutter#177160) 2025-10-27 [email protected] Regenerated lockfiles for New Template Values (flutter/flutter#177617) 2025-10-27 [email protected] Correct editable text and placeholder position in baseline aligned stack (flutter/flutter#177342) 2025-10-27 49699333+dependabot[bot]@users.noreply.github.com Bump actions/upload-artifact from 4 to 5 in the all-github-actions group (flutter/flutter#177620) 2025-10-27 [email protected] add gn flag to optimize builds for size (flutter/flutter#176835) 2025-10-27 [email protected] disable metal for crosscompile from mac to linux (flutter/flutter#176639) 2025-10-27 [email protected] [DDM] enable host builds in the merge queue (flutter/flutter#177446) 2025-10-27 [email protected] Disable vulkan X11 support when building for minimal linux (flutter/flutter#176697) 2025-10-27 [email protected] Roll Skia from 77348c40d101 to 170c11f1ddc5 (6 revisions) (flutter/flutter#177602) 2025-10-27 [email protected] Set the font weight variation axis based on the text style's FontWeight (flutter/flutter#175771) 2025-10-27 [email protected] Fixed `RuntimeEffect` with `ImageFilter.compose` (flutter/flutter#177510) 2025-10-27 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Clean before building when framework headers change (#177512)" (flutter/flutter#177610) 2025-10-27 [email protected] [skia] Disable legacy png encoding/decoding in skp (flutter/flutter#177462) 2025-10-27 [email protected] Clean before building when framework headers change (flutter/flutter#177512) 2025-10-27 [email protected] Roll dartdoc to 9.0.0 (flutter/flutter#177590) 2025-10-27 [email protected] Fix typo in comment about `manifestFile` in `DeepLinkJsonFromManifestTaskHelper.kt` (flutter/flutter#177538) 2025-10-27 [email protected] Fix RoundedSuperellipse crashes for tiny corners (flutter/flutter#177070) 2025-10-27 [email protected] Roll Packages from 53d6138 to bbf96a0 (7 revisions) (flutter/flutter#177588) 2025-10-27 [email protected] Fix missing list indicators in CHANGELOG.md (flutter/flutter#177484) 2025-10-27 [email protected] [ Tool ] Add `Stream.transformWithCallSite` to provide more useful stack traces (flutter/flutter#177470) 2025-10-27 [email protected] Roll Skia from 06243224ecf0 to 77348c40d101 (1 revision) (flutter/flutter#177585) 2025-10-27 [email protected] Add guided error for precompiled cache error (flutter/flutter#177327) 2025-10-27 [email protected] Roll Fuchsia Linux SDK from tKrvmvTOQITL81oOC... to ir6J2isKAYa1jNLyJ... (flutter/flutter#177578) 2025-10-27 [email protected] Roll Skia from 784ed1787bd6 to 06243224ecf0 (1 revision) (flutter/flutter#177575) 2025-10-27 [email protected] Roll Skia from de52b3a7585a to 784ed1787bd6 (5 revisions) (flutter/flutter#177571) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…ack (#177342) This PR makes CupertinoTextField's placeholder and editable text position respect `CupertinoTextField.textAlignVertical`. <details open> <summary>Image comparison</summary> | | Before | After | | --- | --- | --- | | top | <img width="436" height="327" alt="top b4" src="https://github.com/user-attachments/assets/39606c72-fb1f-4619-bfb2-ccaeaf502324" /> | <img width="436" height="327" alt="top" src="https://github.com/user-attachments/assets/faea26fc-c934-4660-bbee-e62effa44599" /> | | center | <img width="436" height="327" alt="top b4" src="https://github.com/user-attachments/assets/39606c72-fb1f-4619-bfb2-ccaeaf502324" /> | <img width="436" height="327" alt="center" src="https://github.com/user-attachments/assets/2ee7004a-6f70-4af2-b33b-76293c8deac1" /> | | bottom | <img width="436" height="327" alt="top b4" src="https://github.com/user-attachments/assets/39606c72-fb1f-4619-bfb2-ccaeaf502324" /> | <img width="436" height="327" alt="bottom" src="https://github.com/user-attachments/assets/69ba89fb-9f1c-456e-9889-216eb31d66b9" /> | </details> <details> <summary>Sample code</summary> ```dart import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; void main() => runApp(const TextFieldApp()); class TextFieldApp extends StatelessWidget { const TextFieldApp({super.key}); @OverRide Widget build(BuildContext context) { return const MaterialApp(home: HomePage()); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @OverRide State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { TextEditingController commentController = TextEditingController(); @OverRide Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey, body: SafeArea( child: Center( child: Padding( padding: const EdgeInsets.all(8.0), child: CupertinoTextField( style: const TextStyle(fontSize: 40), placeholderStyle: const TextStyle( fontSize: 80, color: CupertinoColors.inactiveGray, ), placeholder: 'Enter text', textAlignVertical: TextAlignVertical.bottom, ), ), ), ), ); } } ``` </details> Fixes [CupertinoTextField text not vertically centered when fontSize differs between style and placeholderStyle.](#176817)
…ack (flutter#177342) This PR makes CupertinoTextField's placeholder and editable text position respect `CupertinoTextField.textAlignVertical`. <details open> <summary>Image comparison</summary> | | Before | After | | --- | --- | --- | | top | <img width="436" height="327" alt="top b4" src="https://github.com/user-attachments/assets/39606c72-fb1f-4619-bfb2-ccaeaf502324" /> | <img width="436" height="327" alt="top" src="https://github.com/user-attachments/assets/faea26fc-c934-4660-bbee-e62effa44599" /> | | center | <img width="436" height="327" alt="top b4" src="https://github.com/user-attachments/assets/39606c72-fb1f-4619-bfb2-ccaeaf502324" /> | <img width="436" height="327" alt="center" src="https://github.com/user-attachments/assets/2ee7004a-6f70-4af2-b33b-76293c8deac1" /> | | bottom | <img width="436" height="327" alt="top b4" src="https://github.com/user-attachments/assets/39606c72-fb1f-4619-bfb2-ccaeaf502324" /> | <img width="436" height="327" alt="bottom" src="https://github.com/user-attachments/assets/69ba89fb-9f1c-456e-9889-216eb31d66b9" /> | </details> <details> <summary>Sample code</summary> ```dart import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; void main() => runApp(const TextFieldApp()); class TextFieldApp extends StatelessWidget { const TextFieldApp({super.key}); @OverRide Widget build(BuildContext context) { return const MaterialApp(home: HomePage()); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @OverRide State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { TextEditingController commentController = TextEditingController(); @OverRide Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey, body: SafeArea( child: Center( child: Padding( padding: const EdgeInsets.all(8.0), child: CupertinoTextField( style: const TextStyle(fontSize: 40), placeholderStyle: const TextStyle( fontSize: 80, color: CupertinoColors.inactiveGray, ), placeholder: 'Enter text', textAlignVertical: TextAlignVertical.bottom, ), ), ), ), ); } } ``` </details> Fixes [CupertinoTextField text not vertically centered when fontSize differs between style and placeholderStyle.](flutter#176817)
This PR makes CupertinoTextField's placeholder and editable text position respect
CupertinoTextField.textAlignVertical.Image comparison
Sample code
Fixes CupertinoTextField text not vertically centered when fontSize differs between style and placeholderStyle.