-
Notifications
You must be signed in to change notification settings - Fork 28.5k
(Raw)Autocomplete: Add optional [optionsViewOpenDirection] param #129802
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
(Raw)Autocomplete: Add optional [optionsViewOpenDirection] param #129802
Conversation
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.
Thanks! Generally this looks great — I like the more specific name for the enum and the parameter. Comments below.
This responds to gnprice's review at flutter#129802 (review)
Thanks for the review! Added 003f88a with corresponding changes. I've also added ba7d49d on top of that; it's something I forgot about in my first draft. Oh! Also: this only touches |
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.
Thanks! This now all LGTM.
Oh! Also: this only touches
RawAutocomplete
, but #129748 coversAutocomplete
too. Should I mark this as a draft until I update it to add the param onAutocomplete
too (which I can aim to do soon)?
Ah, good thought. I'll mark as draft (it looks like I have a button to do that too), and please go ahead and re-mark as ready once you add that bit.
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. For more guidance, visit Writing a golden file test for Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
Like similar types in widgets/autocomplete.dart, such as: AutocompleteOptionsBuilder AutocompleteOnSelected AutocompleteOptionsViewBuilder and so on. It makes for a pretty long name, though; hmm.
OK! Pushed a commit that makes this new param available on |
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.
Thanks! Small comments.
home: Scaffold( | ||
body: Center( | ||
child: RawAutocomplete<String>( | ||
optionsViewOpenDirection: AutocompleteOptionsViewOpenDirection.up, |
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.
Hmm yeah, with the "Autocomplete" prefix on the name of the enum, this gets kind of long.
I think it's OK to leave that prefix off, and make it just OptionsViewOpenDirection
. My reasoning is:
-
Those other types around it that have that prefix are typedefs, not enums. So there's basically no cost in the niceness of the API from making their names long, because calling code won't typically mention them.
-
On the other side, the risk from having a less specific name is that it effectively lives in a single shared namespace with the other public names in the framework, and so it might collide in the future with some name we want elsewhere, or sound confusingly like something that'd appear elsewhere in the framework.
But I think "options view open direction" is already specific enough that that's not a big worry: if there's something else that might be thought of as an "options view" and it has an "open direction", then I think it'd have to have enough in common with
RawAutocomplete
that basically the same set of values for the "open direction" will make sense for that other thing as forRawAutocomplete
. Namely the "options view" can go above, or go below, or better yet in the future would be able to automatically go where it fits but the app should decide whether to prefer above or below.So if there ever is such a collision, I think we can cheerfully use the same enum for both. We'd just revise its docs to be worded more generally, and to mention both uses under "See also:".
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.
That reasoning makes sense; will do.
This responds to gnprice's review at flutter#129802 (review)
Thanks for the review! Added 3f9a61e. |
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! Thanks for adding this.
I'll see about trying to find a second reviewer.
It would be much more useful to get an option for the widget to calculate which direction it should show the list in by itself, like external packages like flutter_typeahead already do. |
That would be useful too, but is more complex. There are plenty of use cases where the app knows it always wants the options to go above (or always below), so this option is already useful in itself. See discussion in the issue #129748, and the related issues linked from there. For the feature you mentioned, I think the issue to track is #101620. Even in a future where the widget can dynamically decide whether to go above or below, we'll still want an option like this, because there's still the question of which direction it should prefer (which direction it should go in when there's room in both directions). The API in this PR is designed so that it can smoothly be extended for that future, using an enum. |
Waiting for: flutter/flutter#129802 The UI for now is kept simple; the optionsViewBuilder closely follows the one in the Material library's `Autocomplete`, which thinly wraps `RawAutocomplete`: https://api.flutter.dev/flutter/material/Autocomplete-class.html
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.
Some formatting to clean up, but otherwise this looks good. Also see my comment about the format of optionsViewOpenDirection. I think it's probably fine as-is but wanted to put my thoughts down.
followerAnchor: switch (widget.optionsViewOpenDirection) { | ||
OptionsViewOpenDirection.up => Alignment.bottomLeft, | ||
OptionsViewOpenDirection.down => Alignment.topLeft, | ||
}, |
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.
Just thinking out loud, instead of OptionsViewOpenDirection we could expose targetAnchor and followerAnchor directly... But 1. that's harder for users to understand and 2. I can't think of a reason for anyone to want that kind of control outside of these two cases.
They could hypothetically use that kind of control to position the options on top of the field when it doesn't fit above/below, but that case probably requires more changes to Autocomplete to really be doable (as mentioned in #129748 by @gnprice). We'd probably need a custom RenderObjectWidget or something to do the positioning, similar to how the text selection context menus are positioned. Without that, it would be pretty crazy trying to position the options using the anchors.
So I think I'm on board with OptionsViewOpenDirection as-is. It can grow to support new features like options that move to stay on the screen, and it's also simple to use now.
group('optionsViewOpenDirection', () { | ||
testWidgets('default (down)', (WidgetTester tester) async { | ||
await tester.pumpWidget( | ||
MaterialApp( | ||
home: Scaffold( | ||
body: Autocomplete<String>( | ||
optionsBuilder: (_) => <String>['a'])))); |
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.
The _
parameter should instead give the full type and name according to the styleguide: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#avoid-anonymous-parameter-names
body: Autocomplete<String>( | ||
optionsBuilder: (_) => <String>['a'])))); |
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.
Also see the position of your closing parentheses related to this: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#if-you-have-a-newline-after-some-opening-punctuation-match-it-on-the-closing-punctuation
The |
Thanks for the review! Fixes pushed; PTAL. 🙂 |
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 👍
expect(tester.getBottomLeft(find.byType(TextField)), | ||
offsetMoreOrLessEquals(tester.getTopLeft(find.text('a')))); |
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.
Nit: Another place where the formatting is off from the styleguide standard. Here and in the other tests in this file.
expect(tester.getBottomLeft(find.byType(TextField)), | |
offsetMoreOrLessEquals(tester.getTopLeft(find.text('a')))); | |
expect( | |
tester.getBottomLeft(find.byType(TextField)), | |
offsetMoreOrLessEquals(tester.getTopLeft(find.text('a'))), | |
); |
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 happy to change it if you prefer, but I think in this case, this more compact form is actually consistent with the style guide. Do you have the same section in mind as last time (this one)? It says:
If you have a newline after some opening punctuation, match it on the closing punctuation.
Note "newline after [the] opening punctuation". In this case, my expect(
isn't followed by a newline. There's a newline between the two arguments, but that doesn't force adding newlines near the (
and )
, does it? Under the "GOOD" heading, there's a case like the code in this revision:
// BAD:
foo(
bar, baz);
foo(
bar,
baz);
foo(bar,
baz
);
// GOOD:
foo(bar, baz);
foo(
bar,
baz,
);
foo(bar,
baz);
in particular
foo(bar,
baz);
. In the code here, in place of foo
, bar
, and baz
, we have expect
, tester.getBottomLeft(find.byType(TextField))
, and offsetMoreOrLessEquals(tester.getTopLeft(find.text('a')))
, respectively.
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.
Ah sorry you're right, that's explicitly allowed!
flutter/flutter@d55a7d8...65ff3cb 2023-07-08 [email protected] Roll Flutter Engine from 69eb8275ce47 to 189f823e7b41 (1 revision) (flutter/flutter#130201) 2023-07-08 [email protected] Roll Flutter Engine from d5a35b4650b1 to 69eb8275ce47 (1 revision) (flutter/flutter#130199) 2023-07-08 [email protected] Roll Flutter Engine from 9006633571bb to d5a35b4650b1 (1 revision) (flutter/flutter#130197) 2023-07-08 [email protected] Roll Flutter Engine from 4ca619166c4a to 9006633571bb (2 revisions) (flutter/flutter#130195) 2023-07-08 [email protected] Roll Flutter Engine from 13d9d84e8aba to 4ca619166c4a (2 revisions) (flutter/flutter#130191) 2023-07-08 [email protected] Roll Flutter Engine from 40a8732a5de0 to 13d9d84e8aba (2 revisions) (flutter/flutter#130189) 2023-07-08 [email protected] fix: duplicated Intellij IDE message when running flutter doctor (flutter/flutter#129030) 2023-07-08 [email protected] Remove unneeded configuration file (flutter/flutter#130183) 2023-07-08 [email protected] Roll Flutter Engine from 893ab3bf7bb9 to 40a8732a5de0 (1 revision) (flutter/flutter#130186) 2023-07-07 [email protected] Roll Flutter Engine from b39e6fe4b3bf to 893ab3bf7bb9 (1 revision) (flutter/flutter#130180) 2023-07-07 [email protected] Roll Flutter Engine from 7c83ea3e8542 to b39e6fe4b3bf (1 revision) (flutter/flutter#130176) 2023-07-07 [email protected] Add a threshold when comparing screen order for selectables. (flutter/flutter#130043) 2023-07-07 [email protected] Upgrade framework pub dependencies, roll engine with rolled dart sdk (flutter/flutter#130163) 2023-07-07 [email protected] Revert "[a11y] CupertinoSwitch On/Off labels" (flutter/flutter#130166) 2023-07-07 [email protected] Test that inspector does not hold objects. (flutter/flutter#130102) 2023-07-07 [email protected] Fix XCode download link (flutter/flutter#129795) 2023-07-07 [email protected] Roll Packages from 9bcf4bf to b61eea1 (1 revision) (flutter/flutter#130154) 2023-07-07 [email protected] (Raw)Autocomplete: Add optional [optionsViewOpenDirection] param (flutter/flutter#129802) 2023-07-07 [email protected] Tiny one space formatting fix (flutter/flutter#130053) 2023-07-07 [email protected] Roll Flutter Engine from 8aa2e6516af1 to 5ae09b8b4fa3 (7 revisions) (flutter/flutter#130150) 2023-07-07 [email protected] Add debugging for iOS startup test flakes (flutter/flutter#130099) 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],[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://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Fixes #129748.
This follow's @gnprice's proposal in that issue's description:
except in this revision I emphasize "direction" over "alignment", to try to avoid appearing as though we can control how the options are aligned with a text field built outside
[RawAutocomplete.fieldViewBuilder]
. (In the case where callers don't passfieldViewBuilder
, they can use this new param for the direction, but they'll need to control the top/bottom alignment themselves, e.g., by putting theRawAutocomplete
above or below their text field and parenting it so that itsSizedBox.shrink()
can have zero height.)I've also added a mention in
fieldViewBuilder
's dartdoc about what happens when it's null.I've also updated the dartdoc on
focusNode
andtextEditingController
(via a template shared between those two) to reflect that you can omitfieldViewBuilder
, which is a nicer API than passing a function that returns aSizedBox.shrink()
.Pre-launch Checklist
///
).