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

Can't search non-alphanumeric Options in Listbox #2454

Closed
Briscoooe opened this issue Apr 25, 2023 · 2 comments · Fixed by #2471
Closed

Can't search non-alphanumeric Options in Listbox #2454

Briscoooe opened this issue Apr 25, 2023 · 2 comments · Fixed by #2471
Assignees

Comments

@Briscoooe
Copy link

Briscoooe commented Apr 25, 2023

What package within Headless UI are you using?

@headlessui/react

What version of that package are you using?

^1.7.14

What browser are you using?

Chrome

Reproduction URL

https://github.com/Briscoooe/headless-ui-issue
https://headless-ui-issue.vercel.app/

Describe your issue

I'm using the Listbox component in my project and I've noticed that I can't keyboard search for options that are prefixed with emojis. This is because the textValue property of the Listbox that's used for comparison uses textContent to get the value of the Option. This doesn't work when an emoji is used as a prefix as the searched alphanumeric key never matches the non-alphanumeric first character of the textContent.

In my live example you can see that if you open the red Listbox on the left and hit "U" on your keyboard, it will select United States. If you try with the blue Listbox on the right, it will not select anything. The right one will not match any option unless you search with your phone or laptops emoji keyboard. The two Listboxes are functionally identical, the only difference is the the emoji within the Option on the blue one.

Some potential solutions I had in mind were

  • Some sort of way to optionally override the get textValue() function to do something other than return textContent?.toLowerCase()
  • Allow an optional property to TType that is used for comparing <Option /> values
  • Remove non-language specific unicode characters that prefix textContent.

Thought I'd bring this to you guys before I did any work for it, wanted to hear what you guys thought.

@RobinMalfait
Copy link
Member

RobinMalfait commented May 4, 2023

Hey, thank you for this bug report! 🙏

We improved the logic on retrieving the contents of a DOM element. We will make sure to skip emojis and we won't include hidden elements. This can be a costly operation, but the good part is that it is only done once (unless the contents changes).

I wrote more examples in the PR itself (#2471) but the main idea is that this should be solved automatically. If not, you can get full control over the value by providing an aria-label on the Menu.Item or Listbox.Option. This way you have full control over the textual value of the contents. Note that this also means that screenreaders will read out this value of an option instead of the contents itself so you have to make sure that they are in sync.

If you would set the aria-label, then in your case it means that it looks like this:

<Listbox.Option aria-label="Canada">
  🇨🇦 Canada
</Listbox.Option>

I created a CodeSandbox which is your reproduction as-is with the only difference being the insiders build of Headless UI to show that it works as expected now: https://codesandbox.io/s/relaxed-aryabhata-669z8m?file=/src/App.js


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

You can already try it using:

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

@Briscoooe
Copy link
Author

Great thanks!

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

Successfully merging a pull request may close this issue.

2 participants