-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Dismiss Autocomplete with ESC #97790
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
Dismiss Autocomplete with ESC #97790
Conversation
|
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!). If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
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.
Thanks for taking this on, I have multiple times been using an Autocomplete and instinctively tried to dismiss the options with escape, only to be disappointed. We should support this feature.
The biggest point that I brought up in my comments is that we might be able to use Shortcuts instead of onKeyDown. Otherwise my comments are pretty minor and I like the approach.
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.
Missing a space after if here, and in a few other places in this PR.
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.
So the point of _lastText is (tell me if I'm wrong):
Say you're typing into the field with the menu visible, and then you hit escape to close it. It will only reopen again if you modify the text. If you just change the selection then the menu will stay hidden.
Do you need to set _lastText when _onKeyEvent hides the menu too?
As a nit, maybe add a comment at the definition of _lastText and/or here to explain this stuff a bit.
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.
You understood correctly but I decided to remove the check for _hidden here to remove any doubts about this being checked against an outdated value.
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 trust your judgement on this. Both seem like reasonable choices to me. We can keep an eye out for any issues in the future in case users disagree (as well as for the other inconsistencies with Angular Material that you pointed out).
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 if we use Shortcuts, as mentioned below, then users could do whichever behavior they want here.
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: I feel like this _hidden piece of state can be implemented in a way that's more clear. My problems with it are:
- It's called
_hidden, but it's not a direct indication of whether the options are currently hidden or not. It's possible that _hidden is false but the options are not shown. - It encompasses both whether the user has recently pressed escape and the current focus, which is already used elsewhere as
_focusNode.hasFocus.
What if we call it something like _userHidOptions and don't change it in _onChangedFocus? Just use _focusNode.hasFocus when you need to know that.
Then we know what it means when it's true (the user hid the options recently and that hasn't yet been reset) and we have a better idea of what implications it has (the options may be hidden, but check _shouldShowOptions to be sure).
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 fact that this piece of state also encompasses if the field has focus is just a byproduct of the fact that it needs to be reset when the field is un-focused and re-focused. It might be more clear if the bit in _onChangedFocus is changed to something like
// Called when the field's FocusNode changes.
void _onChangedFocus() {
// Options should no longer be hidden when the field is re-focused.
if(_userHidOptions && _focusNode.hasFocus) {
_userHidOptions = false;
}
_updateOverlay();
}but I just figured this is more concise. If you think it would help readability I'm not against this change.
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 see you went with my idea, it's not perfect as you pointed out but hopefully it helps improve readability a bit. I'll try to keep an eye out in case anyone is confused by this and we can reconsider.
|
Thanks for the fast review @justinmc. I think the Shortcuts solution also makes a lot more sense because the One slight snag I ran into was that shortcuts need to be disabled and enabled according to the old Either way it looks a bit silly with Also added a test, I just left in a bunch of hiding with the escape key but it could maybe be made more concise somehow? |
|
Just noticed that this could be using the DismissIntent instead of a custom one (not sure which is preferable). |
|
I'd say |
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 👍
Just nits otherwise (DismissIntent and a few other small things).
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.
+1 to @gspencergoog's suggestion to use DismissIntent instead of this new one.
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.
Good call saving this value locally, I guess it could change after the await.
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: "gets changes" => "gets changed" or "changes"? Or maybe I'm reading that wrong...
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: The styleguide says never use "we" (though that's mainly for public docs).
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 test is super thorough and easy to follow 👍
ff79efe to
6eeec63
Compare
|
Fixed the nit, going to merge and check that this plays well with #98511 |
|
Update: they did not play nice together at all, see #98600 |
Allows the
Autocompleteoptions to be hidden by pressing ESC. As for revealing the options again here's how it should work:This is mostly based off of the angular implementation of material autocomplete but there are some discrepancies:
_selection == nullinflutter/packages/flutter/lib/src/widgets/autocomplete.dart
Line 294 in fd8d035
once a selection has been made the autocomplete options will not appear to show the only completed option.
optionsBuilder).Another interesting detail is that in the angular material implementation the highlighted selection index gets reset when the options are hidden. This is different from something like the search bar in YouTube, where the highlighted option remains the same when the options are shown again by pressing the up or down arrow. The latter is how it works in the current version of the PR.
Basic autocomplete sample
Fixes #84416
Pre-launch Checklist
///).