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 use virtualized and renderMenuItem together in the SelectPicker #3187

Closed
hedzerkoolstra opened this issue May 9, 2023 · 8 comments
Closed
Labels
Answered A question that was resolved with an answer. Use along with "Not an issue" label. component: SelectPicker type: Not an issue Issues that are not actually an issue, e.g. questions. Prefer using discussions.

Comments

@hedzerkoolstra
Copy link

hedzerkoolstra commented May 9, 2023

What version of rsuite are you using?

latest

What version of React are you using?

17.0.0

What version of TypeScript are you using (if any)?

No response

What browser are you using?

Chrome

Describe the Bug

Combining virtualized and renderMenuItem in the SelectPicker doesn't work together. When using just renderMenuItem the custom menuItem renders fine, when adding virtualized prop the height and width of the container get changed and this messes up the menuList component.

Expected Behavior

Be able to use virtualized and renderMenuItem together.

To Reproduce

https://codesandbox.io/s/serene-mahavira-8evty0?file=/index.js

@SevenOutman
Copy link
Member

SevenOutman commented May 10, 2023

Hi @hedzerkoolstra, when you want to render items with custom height in a virtualized list, you need to specify listProps.itemSize prop that returns the height of each item

<SelectPicker
  data={data}
  renderMenuItem={menuItem}
  virtualized
  listProps={{
    itemSize: (index) => 66 // 50px item height + 8px padding top and bottom
  }}
/>
image

Ref: react-window docs https://react-window.vercel.app/#/examples/list/variable-size

@SevenOutman SevenOutman added component: SelectPicker status: Needs Triage New issues that has not been looked into labels May 10, 2023
@hedzerkoolstra
Copy link
Author

Thanks for the reply. The height is fixed although my actual project has variable heights so I need a way to determine the height there but I can maybe find a way,

But the width issues is not yet addressed. When using virtualized the menu list get the size of picker again instead of taking the full-width.

@SevenOutman
Copy link
Member

SevenOutman commented May 11, 2023

But the width issues is not yet addressed. When using virtualized the menu list get the size of picker again instead of taking the full-width.

That's because the style={{ width: 224 }} on SelectPicker. When virtualization is on, the menu's width defaults to the picker toggle's. You can use menuStyle prop to specify a width for the menu.

<SelectPicker
  data={data}
  renderMenuItem={menuItem}
  virtualized
  listProps={{
    itemSize: (index) => 66 // 50px item height + 8px padding top and bottom
  }}
  style={{ width: 224 }}
  menuStyle={{
    width: 424 // 400px item width + 12px padding left and right
  }}
/>

https://codesandbox.io/s/frosty-brown-cqk09c

@hedzerkoolstra
Copy link
Author

Thanks for the explanation. So this means virtualized can work, but if you specify the height and width statically. I have dynamic heights and width based on the options I render, is it the not possible to use it?

@SevenOutman
Copy link
Member

I have dynamic heights and width based on the options I render, is it the not possible to use it?

listProps.itemSize is actually a function that receives the index of an item, and returns the height of it, you could calculate the heights there.

As of width, if I understand correctly, you only need to set the menu's width to the maximum width among all items, rather than setting each menuitems' widths individually 🤔️.

@hedzerkoolstra
Copy link
Author

Yes I could do it with index but then I need to do some extra checks in that function indeed.
For the width I just need to know which item is the largest one and then set width of the menu as a whole to that one.

It's all possible but the CSS worked straight out of the box without virtualized while now I need to do some calculations myself and then set menuItem height and menu width manually. It's more code and more bug prone so I was hoping there would be a way without needing to that. I'll consider the trade-off, thanks!

@SevenOutman
Copy link
Member

It's all possible but the CSS worked straight out of the box without virtualized while now I need to do some calculations myself and then set menuItem height and menu width manually.

That's how virtualization is designed and implemented for now. Every item is absolutely positioned and their position is calculated based on other items before them. Thus it has to know the size of each item before they are actually mounted in the document, otherwise you'll get a layout shift.

@hedzerkoolstra
Copy link
Author

Ok, thanks for the clarification!

@SevenOutman SevenOutman added type: Not an issue Issues that are not actually an issue, e.g. questions. Prefer using discussions. Answered A question that was resolved with an answer. Use along with "Not an issue" label. and removed status: Needs Triage New issues that has not been looked into labels May 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Answered A question that was resolved with an answer. Use along with "Not an issue" label. component: SelectPicker type: Not an issue Issues that are not actually an issue, e.g. questions. Prefer using discussions.
Projects
None yet
Development

No branches or pull requests

2 participants