Closed garyee closed 3 years ago
Greetings @garyee
Have you tried removing the width of the menu?
const styles = {
menu: ({ width, ...css }) => ({ ...css })
}
<Select styles={styles} .../>
https://codesandbox.io/s/react-select-fitcontent-width-27ed6?file=/example.js
Thank you for your quick answer! But it did not solve the problem. Additional to the snippet you posted in your answer there is:
control:' (css) => ({
...css,
width: "300px"
}),'
This sets a width to the control, which is what I do not want to do as I expect it to have the width of the longest option automatically.
Apologies. I did not click the example links and assumed you were talking about the Menu being as large as the longest item and not the Select itself.
This presents itself as two questions: 1. How do I make the select inline?
I have a working example for this here. Note that this example goes a bit further to strip away more things to fit a use case someone else had, but the point remains the same. Set the container to inline-block and remove some css properties from SingleValue
styles={{
singleValue: ({ maxWidth, position, top, transform, ...otherStyles }) => ({ ...otherStyles }),
}}
2. How do I make the select width equal to the largest option? Far more complicated...
Control and Menu are siblings so it would be much easier if any of the following were true...
menuIsOpen
One late consideration I came across is that the total width of the select. Select Width = Longest possible Option + SingleValue padding (8) + DropdownIndicator width (36)
That all out of the way, the menu width needs to be calculated. I updated the example with the following logic:
Add state variable for menuWidth
Add styling
Add props for onFocus (to handle getting sizing) and openMenuOnFocus (to "programmatically" trigger menu open)
onMount, focus on Select to trigger menu open
The implementation feels clumsy as it relies on setTimeout, but it works. I blame this mostly on the inability to dynamically open/close/render the menu without needing to add menuIsOpen state management everywhere.
As for adding this as a feature I would argue that adding a prop specifically for this feature seems like an edge case, but would instead address the issues that prevents this from being a more straightforward affair (render menu even when menu is closed, or make it easier to open/close menu without completely controlling state). This would allow someone to set the select container style to grid, flex, or even table without adding any complex state changes or DOM width calculations.
Hopefully, this better answers what you were asking and hope it helps
@ebonow you provide a workaround to reproduce a standard behavior of the html element this component replace.
So I agree with @garyee when saying this behavior should be a standard one in this component as the html provided select
element
@mde-pach I understand your perspective, but it is fair to say that this component is a bit more complex and dynamic than a standard select input.
Please consider the following use-cases:
This is all independent of the code complexity required do the width calculations as props, state, and window size changes of each type of available Select. While I understand that it would be nice to have for some, it would likely result in being more problematic for others as listed above if made to be default behavior which would be matching the behavior of a select as proposed.
What could arguably be done to better enable this behavior is to allow the menu to be rendered but hidden so the Menu ref would be easier to calculate its width, or simply roll your own controlled isMenuOpen which instead hide/shows content. Then you can add the resizeObserver to the element and watch for width changes and apply some calculation to the width of your Control (taking all of the factors mentioned above into account).
There are likely others who may be interested in this functionality and I would encourage you or anyone else to put together a codesandbox and share it in the Show and Tell discussion room This is an open source project and thoroughly encourage the community to contribute and share if you or anyone else feels inclined to build such functionality. This however is something that likely does not fit in the roadmap, and instead as a custom developer built component that can be shared with the community. If you would like to continue to discuss the merits of this as a feature, please feel free to start a discussion, but I will be closing this as an issue in an effort to get through known bugs and critical issues.
@mde-pach @garyee
Stopped by to leave a working codesandbox example. Hope this is helpful. https://codesandbox.io/s/react-select-longest-option-width-geunu?file=/src/App.js
Set menu: { minWidth: '100%', left: 0, right: unset } Hope it works for you.
No need to use refs. Using width: "max-content"
and min-width: "100%"
set the menu width equal to the longest option for me.
menu: (base) => ({
...base,
width: "max-content",
minWidth: "100%"
}),
No need to use refs. Using
width: "max-content"
andmin-width: "100%"
set the menu width equal to the longest option for me.Full solution:
menu: ({ width, ...css }) => ({ ...css, width: "max-content", minWidth: "100%" }),
Same as my solution
Same as my solution
Your solution didn't work for me unfortunately. It was still the same width as the selector. I used unset
as a string from your example, should it be something else?
Same as my solution
Your solution didn't work for me unfortunately. It was still the same width as the selector. I used
unset
as a string from your example, should it be something else?
I think this is only working for the options, but not for the entire container.
Does setting display: 'inline-block'
on the container
have the desired effect for you guys? It seems to work for me.
@mde-pach @garyee
Stopped by to leave a working codesandbox example. Hope this is helpful. https://codesandbox.io/s/react-select-longest-option-width-geunu?file=/src/App.js
This is not working in react-select 3.0.1v higher.
This CSS style works for me. No need to use refs and it's worked for the latest version(of 5.2.1v) as well.
const stylesWidth = { control: css => ({ ...css, width: 150, }), menu: ({ width, ...css }) => ({ ...css, width: '400px', minWidth: '20%', }), option: css => ({ ...css, width: 370 }), };
sample project example: :100: https://codesandbox.io/s/react-select-options-width-resize-forked-h0sfg?file=/example.js
menu: provided => ({
...provided,
width: 'max-content'
})
Would be great to implement this feature. I am using menuPortal and none of suggestions works
I have this issue in "react-select": "^5.7.4",
I have issue in "react-select": "^5.7.3",
@mde-pach @garyee Stopped by to leave a working codesandbox example. Hope this is helpful. https://codesandbox.io/s/react-select-longest-option-width-geunu?file=/src/App.js
This is not working in react-select 3.0.1v higher.
I have got same issue in V5.7.3. Have you got any solution?
There are two Stackoverflow questions 1. 2. and an issue #323 asking addressing the issue. But there is no real solution.
The problem: When using a standard html select element the width of the element get's automatically set to the width of the longest/biggest option. This is not the default behaviour of react-select there is not even a prop to make it behave this way. In my opinion, a component built to replace/augment the html select should still implement the behaviour of the html element everybody is used to, which makes this more of a bug than a feature. At least there should be some kind of documentation about this (and why it is not technically feasible or whatever the reason).
The issue #323 does kind of address this but then it is closed without an explanation.
There is another "problem" which is that when inserting a react-select component without setting any width to it, it will not even get the width of the placeholder. Which is also discussed in #323 but this can be solved by modifying the styles of the placeholder,singelValue,menu see #323 for hints on how to.