-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Implement new virtual
API for the Combobox
component
#2779
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
This was referenced Oct 2, 2023
@RobinMalfait this one doesn't play nicely with allowing custom values https://headlessui.com/vue/combobox#allowing-custom-values |
This was referenced May 28, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR is an improvement on the previous PR where we introduced a new
virtual
prop to theCombobox
component.This new API requires you to pass in a list of options, and provide a template to the
Combobox.Options
such that we can only render the visible options (+ overscan).React:
Vue:
The
disabled
function in thevirtual
object is optional, but this is used to determine whether an option is disabled or not. In a non-virtualCombobox
, we can check thedisabled
prop on theCombobox.Option
, but since we are not rendering all of those, we don't have access to that information anymore.The API we exposed in #2740 is now deprecated and won't be supported in future version.
Further fixes: #2441
Playground:
Some background:
Why things are slow:
Our default
Combobox
component requires you to render (and mount) all the available options so that we know which options are available and what the next and previous options are based on the current active option to ensure that using arrow keys work as expected.Initial approach:
To ensure that we always go to the correct next / previous option, we have to make sure that everything is sorted. React doesn't expose an "index" or other information about where a certain element is within the React tree (at least not as a public API). Instead, we sorted the options by the DOM node position. When you have a lot of items then this is very slow.
A first approach, is that we introduced and
order
prop on theCombobox.Option
to sort based on this instead of the DOM node, which is muchmuch faster.
React:
Vue:
Next approach:
This was still too slow, especially when you have a lot of items. Instead, to keep the API clean, there is another approach we can use, which is only mount the items that are necessary, but still have them in the React/Vue tree.
This was a huge improvement for React, but it was still a bit too slow for Vue. This approach also required us to still register each individial option in memory. This was especially noticeable when you open the
Combobox
component.From an API perspective, this looks very clean, and it's easy to change a non-virtual Combobox to a virtual one.
React:
Vue:
This PR:
Next, the goal is to get rid of all the pre-registering of options. Instead, let's pass in all the available options. Then, we will make sure that only the visible options are being rendered. To do this, you have to provide a "template":
React:
Vue: