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

Add virtual prop to Combobox component #2740

Merged
merged 7 commits into from
Sep 15, 2023
Merged

Add virtual prop to Combobox component #2740

merged 7 commits into from
Sep 15, 2023

Conversation

RobinMalfait
Copy link
Member

@RobinMalfait RobinMalfait commented Sep 11, 2023

This PR adds a new virtual prop to the Combobox component to improve performance issues by only
rendering what's visible on the screen.

Behind the scenes the @tanstack/react-virtual and @tanstack/vue-virtual libraries are used to do the heavy lifting.

Once the virtual prop is in use, it also requires the Combobox.Option to have an order prop. This prop is used to improve internal sorting based on this number instead of sorting by DOM node position.

This prop can also be used in a non-virtual Combobox version to improve some of the performance.

The diff looks like this:

React

- <Combobox>
+ <Combobox virtual>
    <Combobox.Input />
    <Combobox.Options>
      {countries.map((country, idx) => (
-       <Combobox.Option key={country} value={country}>
+       <Combobox.Option key={country} value={country} order={idx}>
          {country}
        </Combobox.Option>
      ))}
    </Combobox.Options>
  </Combobox>

Vue

- <Combobox>
+ <Combobox virtual>
    <ComboboxInput />
    <ComboboxOptions>
      <ComboboxOption 
-       v-for="country in countries"
+       v-for="(country, idx) in countries"
+       :order="idx"
        :key="country" 
        :value="country"
      >
        {country}
      </ComboboxOption>
    </ComboboxOptions>
  </Combobox>

You can play with the virtual examples here:

If you are on a beefy machine, open this up in a browser (like Chrome) where you can slowdown the CPU by 4x or 6x.
image

Caveats:

  • When using the virtual prop, then you won't be able to use the static or unmount={false} props on the options / option because the goal is to not render items in the DOM.
  • When using the virtual prop, then the order prop on the Combobox.Option is required.

Fixes: #2441

@vercel
Copy link

vercel bot commented Sep 11, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
headlessui-react ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 15, 2023 10:34am
headlessui-vue ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 15, 2023 10:34am

- Also wrap `click` helpers in `act` for React (use `rawClick` without
  `act` in tests related to `Transition`)
@mralexfed007
Copy link

mralexfed007 commented Sep 20, 2023

Hi, Is this virtual feature already implement in last version ? npm install @headlessui/react@latest or should I install from npm install @headlessui/react@insiders

@gomorizsolt
Copy link

gomorizsolt commented Sep 25, 2023

@mralexfed007 given that the most recent release was in august, you will have to rely on the insiders build for now.

edit: at the time of writing, it is mentioned as an unreleased addition in the CHANGELOG file.

@RobinMalfait
Copy link
Member Author

For anyone stumbling upon this PR, there is a follow up PR with more information and a different approach here: #2779

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 this pull request may close these issues.

Combobox option list scrolling problem starting from v1.7.5
4 participants