Skip to content
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

[Feature] Keyboard focus remains in text field while changing selection #579

Open
wmadden opened this issue Apr 16, 2024 · 12 comments
Open
Assignees
Labels
enhancement New feature or request

Comments

@wmadden
Copy link

wmadden commented Apr 16, 2024

Use case

Please tell us the problem you are running into that led to you wanting a new feature.

Is your feature request related to a problem? Please give a clear and concise description of what the problem is.

My primary use case is on Mac where traversing a form using the keyboard is important, and the focus traversal strategy implemented currently does not follow established convention and makes it hard to move keyboard focus to the next input in a form.

Specifically, it's very unusual in common autocomplete implementations for keyboard focus to traverse the list of selections when the user presses up or down. This prevents the user from continuing to type unless they return focus to the input themselves. Even worse, when the suggestions menu is open, pressing tab will currently move focus to the first element in the list instead of to the next input in the form.

Describe the alternative solutions you've considered.
Can this feature be added from the outside, without needing to change the package itself?

This behavior is baked into the _SuggestionsBoxTraversalConnectorState which calls node.focusInDirection(TraversalDirection.up) (and down). It's impossible to work around this from outside.

Proposal

Briefly but precisely describe what you would like the flutter_typeahead package to be able to do.

I'd like flutter_typeahead to maintain selection state, modify it using keyboard shortcuts/actions and use pass the selection state to the widget responsible for rendering the list items (which is the approach taken by Flutter's built-in Autocomplete widget, incidentally). And retain keyboard focus in the text input at all times.

@wmadden wmadden added the enhancement New feature or request label Apr 16, 2024
@clragon
Copy link
Collaborator

clragon commented Apr 16, 2024

Hi,

Thank you for your issue. The current approach is unfortunately rather janky, as we need to two-way sync state and focus and it becomes very tedious to enforce this without ending up in endless loops.

Looking at Autocomplete, it doesnt seem like it keeps track of a selected entry in any way, rather, it calls onSelected exactly when the user interacts with one of the the items. This is equivalent to TypeAheadField.onSelected.

"Selection" is therefore not related to the item which is currently focused. Focus is only meant to allow users to navigate selecting items via keyboard. I believe it is better if the package stays agnostic to how the onSelected callback is used and the user keeps track of what item was last selected themselves, if necessary. There are many use-cases where this would not be required.

The Autocomplete widget also allows users to navigate the list of suggestions via up and down keyboard keys.
It does however not intercept Tab, allowing users to move to the next field.

I could imagine adding an option to disable _SuggestionsBoxTraversalConnectorState's behaviour, therefore making selection via up and down keys no longer possible.
I could also imagine looking closer into how autocomplete achieves their way of up and down arrow key selection while not intercepting tab and trying to recreate this here.

What would be your preferred outcome?

@wmadden
Copy link
Author

wmadden commented Apr 17, 2024

Hi @clragon,

Sorry, I think I've used the wrong terminology - I'm not actually talking about selection, rather highlighting the option which will become selected when the user presses enter.

The list of options displayed in the popover has a currently-highlighted option which is implemented using keyboard focus. flutter_typeahead moves the highlight up or down the list when the user presses the arrow keys by calling node.focusInDirection().

My feature request, and my preferred outcome, is: retain keyboard focus in the textarea at all times and maintain the currently-highlighted item using internal state, e.g. an index.

@wmadden
Copy link
Author

wmadden commented Apr 17, 2024

I could also imagine looking closer into how autocomplete achieves their way of up and down arrow key selection while not intercepting tab and trying to recreate this here.

It's implemented using Shortcuts. See the relevant code here: https://github.com/flutter/flutter/blob/3.19.5/packages/flutter/lib/src/widgets/autocomplete.dart#L577-L580

@clragon
Copy link
Collaborator

clragon commented May 26, 2024

Thank you for this information. I was not aware that Autocomplete manually implements this, very interesting.
I can imagine that we could follow suit on this and remove the complex focus code I have written - since it is unsightly.
I will look into this.

@clragon
Copy link
Collaborator

clragon commented May 26, 2024

The current way that focus is implemented in the TypeAhead package as of its latest version does indeed seem to cause a lot of trouble. I think we will swap over to the same technique that Autocomplete is using to rectify all this and in the process simplify a lot of the code. Hopefully I'll find time for that soon.

This change might also come with some more freedom so we can fix some other complaints as well.
We might make it easier to customize even more of the field.

@clragon
Copy link
Collaborator

clragon commented Aug 16, 2024

Thank you for your extensive amount of patience.

I have now implemented this feature on the master branch.
Highlighted suggestions are now entirely driven by the SuggestionsController and now longer related to what is focused.

There is probably still some more work needed there, and more of the focus controlling code that I have previously written can be removed now that this new mechanic is in place.

If you would like to, please try out these changes and let me know if they serve your needs.

@clragon
Copy link
Collaborator

clragon commented Aug 16, 2024

For myself, heres a quick note:

  • Write migration guide to version 6
  • Check if the "enter" shortcut needs to be disabled when no suggestion is selected
  • Check if focus control can be removed from suggestions box entirely

@dorklein
Copy link

@clragon any update when the version 6 is released, or need any help before releasing it?

@clragon
Copy link
Collaborator

clragon commented Dec 13, 2024

Preferrably I would like to implement #577 before releasing version 6, as it might also contain breaking changes.

This will probably take some time.

@shatanikmahanty
Copy link

@clragon could you also look into #555 before you release? Thanks!

@clragon
Copy link
Collaborator

clragon commented Dec 17, 2024

Hi @shatanikmahanty

The reason we are holding back the release to address #579 first, is because it contains potentially breaking changes to the API surface.

While #555 is an unfortunate bug, it is just a bug and fixing it will most likely be a patch version at a later date, as it does not require any changes on behalf of the package users.

Version 6 will therefore not address #555 or any other currently open bugs, if not already explicitly stated.

Thanks!

@shatanikmahanty
Copy link

Hi @shatanikmahanty

The reason we are holding back the release to address #579 first, is because it contains potentially breaking changes to the API surface.

While #555 is an unfortunate bug, it is just a bug and fixing it will most likely be a patch version at a later date, as it does not require any changes on behalf of the package users.

Version 6 will therefore not address #555 or any other currently open bugs, if not already explicitly stated.

Thanks!

Thanks for explaining @clragon, wish you all the best for the updates ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants