React Select auto size width React Select auto size width reactjs reactjs

React Select auto size width


Inline styles did not work for me.I just wrapped the Select component in a div and gave the div the width I wanted.

<div style={{width: '300px'}}>  <Select     menuPlacement="auto"    menuPosition="fixed"    etc, etc..  /></div>


SOLUTION 1

You can leverage React's inline styles by updating the components' width based on the length of the selected option.

Let me explain further: Say the selected value is HelloWorld. This string is of length 10. We could guess that each character accounts for say 8px each on average (total guess I have no clue at all). Thus, the width of this word is around 8*10=80px, right ? Also, there are some controls after the word (the carret and the cross) and we need some minimum padding: together they may be of 100px width. Then here you have it: your div's width should be ( 8px * 10 letters ) + 100px = 180px.

More precisely, the correct formula is something like:

(average_letter_size * selected_value.length) + other_elements_sizes

When selected_value changes, so does its length, and therefore the width of the div gets updated with the new total.

Example: if the selected value is now Lorem Ipsum dolor sit amet, the length is now 26. By applying the formula we get a larger width of : (8px * 26 letters) + 100px = 308px.

For this to work in react, here is a snippet:

<Select  style={{width: `${(8*this.state.selectedOption2.length) + 100}px`}}              className="select-custom-class"  name="form-field-name"  value={this.state.selectedOption2}  options={options2}  onChange={(value) => { this.setState({ selectedOption2: value.value }); }} />

As you can see I added :

style={{width: `${(8*this.state.selectedOption2.length) + 100}px`}}

to your component. Whenever the state gets updated, everything is propagated including the width of the component.

See a working example in this fiddle.

Eventually, you want to fine-tune the rules and averages to your needs. I also suggest you apply a letter size depending on the number of capital and lowercase letters in the selected value.

SOLUTION 2 (edit)

I came up with a pure CSS solution if you want. It should be better tested against your design, but this should work:

/* .Select-value comes with an absolute position to stack it below .Select-input *//* we need to scratch that in order for us to be able to let the div grow depending on its content size */.Select-placeholder, .Select--single > .Select-control .Select-value {  position: relative;  padding-left: 0;}/* All these 3 classes come with ugly "table" display...*/.Select-control, .Select-clear-zone, .Select-arrow-zone {  display: inherit;}/* here is the trick: we display the wrapper as flex in order to make it fit in height*//* we flip positions of .Select-value and .Select-input using row-reverse in order to have a nice input to the left and no to the right */.select-custom-class .Select-multi-value-wrapper {  display: flex;  flex-direction: row-reverse;}/*we put our controls back to a better center position */ .Select-clear-zone {  position: absolute;  top: 8px;  right: 20px;}.Select-arrow-zone {  position: absolute;  top: 8px;  right: 0px;}

See a working fiddle (I changed some of the examples for better illustration)

Tell me what you think. :)


if you're using react-select v3 you can use customStyles object:

const customStyles = {  container: provided => ({    ...provided,    width: 150  })};<Select    styles={customStyles}    {...otherProps}/>