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

Combobox - Typing does not replace existing value #2528

Closed
djflorio opened this issue Jun 8, 2023 · 5 comments · Fixed by #2568
Closed

Combobox - Typing does not replace existing value #2528

djflorio opened this issue Jun 8, 2023 · 5 comments · Fixed by #2568
Assignees

Comments

@djflorio
Copy link

djflorio commented Jun 8, 2023

What package within Headless UI are you using?
@headlessui/react

What version of that package are you using?
v1.7.14

What browser are you using?
Chrome

Reproduction URL
As of when this issue was created, it could be reproduced in the demo within the Combobox docs:
https://headlessui.com/react/combobox

combobox

Describe your issue
Currently, when you open the Combobox when a value is populated, the cursor appears after the current value's text. If you start typing, it appends the text to the current value.

If you select a new option, and then open the Combobox again, the cursor does jump to the beginning of the current value text (as expected). However, as you type, it appends the text to the beginning of the current value text, rather than replacing it.

Both of these scenarios are unintuitive, and require the user to manually clear the current value text before performing a new search.

What I believe should be the behavior:

  • When the Combobox is opened, the cursor jumps to the beginning of the text input.
  • The current value's text input is still visible, however if you start typing, it is replaced with the characters you type.
  • Alternatively, when the Combobox is opened, the current value's text is highlighted, indicating that if you type, the text will be replaced with the new characters.
@meruyert93
Copy link

we are also experiencing this issue and will be looking forward to the solution.

@RobinMalfait RobinMalfait self-assigned this Jun 29, 2023
@RobinMalfait
Copy link
Collaborator

RobinMalfait commented Jun 29, 2023

Hey, thank you for this bug report! 🙏

I think the current solution behaves more as a native input field (where nothing is selected and typing adds characters to the current cursor position) but I can see why you want it to behave differently such that your users don't have to do an additional "select all"-type actions before typing.

While the proposed solutions are good, there are also very tricky exceptions that you have to keep in mind and they are typically different depending on the use case you are trying to solve. For example if you are working with countries and I want to change Belize to Belgium and press backspace at the end then I would expect to just remove the last characters instead of removing everything. Similarly with United States to United Kingdom I would use Shift+Cmd+LeftArrow to select the last word and then start typing to replace states to kingdom.

I also think that trying to encode various "strategies" for this behaviour might be a bit too much right now. But I'm open to thinking about this more in the future. But let's try to find a solution for your current problem first, before we try to add new APIs.

Now, the last option you mentioned is a very interesting one:

Alternatively, when the Combobox is opened, the current value's text is highlighted, indicating that if you type, the text will be replaced with the new characters.

I think this is a clean solution because then you can immediately start typing (and text will be replaced because it is selected), and if you don't want this you can click or use arrow keys and can start typing text without "magically" replacing all text.

That said, I also think that while this functionality is very interesting, this shouldn't be the default behaviour that we expose. Main reasoning behind this is that a native input also doesn't select all the text when you focus it or similar.

The good news is that Headless UI forwards all props to the underlying components and you should be able to implement this behaviour yourself. This implementation can look like this:

- <Combobox.Input />
+ <Combobox.Input onFocus={e => e.target.select()} />

In this implementation we will select the text whenever the input is focused. This will happen when you tab to the input, but also when the Combobox is opened or closed.

Will this solution work for you? Going to close this issue for now, but feel free to discuss further and I will re-open the issue if this doesn't solve your issue!

@djflorio
Copy link
Author

djflorio commented Jun 29, 2023

@RobinMalfait thanks for the response and the suggestion. I respect the decision to minimize non-native input features.

Your onFocus tip works well for my needs. Thanks!

The only thing that may be worth considering is the fact that after you make a selection, the next time you open the combobox, the cursor jumps to the beginning of the input. This part is what seems most like a bug to me. Assuming that's not intentional, I'm happy to help explore the code at some point to see why that might be happening.

@RobinMalfait
Copy link
Collaborator

Yep you are right, that part where the cursor jumps to the front is the strange part. Will investigate!

@RobinMalfait
Copy link
Collaborator

@djflorio I've made a PR that makes the position of the caret consistent (at the end) when you select a new option. We will also skip that behaviour if you made a custom selection. For example when you used <Combobox.Input onFocus={e => e.target.select()} />

This should be fixed by #2568, and will be available in the next release.

You can already try it using:

  • npm install @headlessui/react@insiders.
  • npm install @headlessui/vue@insiders.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants