反应选择自动大小宽度 [英] React Select auto size width
问题描述
当使用 react-select
时,它不是按选项值自动调整大小,而是使用 width:100%
,如图所示:
选项很短:
getOptions() {返回 [{ 值:'AND',标签:'AND' },{ 值:'或',标签:'或'}]}
以及产生它的代码:
<选择选项={this.getOptions()}价值={价值}自动大小={真}可清除={假}简单值/>
有什么方法可以让 react-select
使用自动调整大小来显示这些值,因此选择框将与选项长度相同,例如,我可以将此选择框居中
2017 年 11 月 14 日更新完整示例可以在此 jsFiddle
中看到解决方案 1
您可以根据所选选项的长度更新组件的width
,从而利用 React 的内联样式
.
让我进一步解释:假设选定的值是 HelloWorld
.该字符串的长度为 10
.我们可以猜测每个字符平均占 8px
每个(总猜测我根本不知道).所以这个字的宽度在8*10=80px
左右吧?另外,单词后面有一些控件(carret 和 cross),我们需要一些最小的填充:它们一起可能是 100px
宽度.然后你就知道了:你的 div 的宽度应该是 ( 8px * 10 letters ) + 100px = 180px
.
更准确地说,正确的公式类似于:
(average_letter_size * selected_value.length) + other_elements_sizes
当 selected_value
改变时,它的 length
也会改变,因此 div 的宽度会用新的总数更新.
示例:如果选择的值现在是 Lorem Ipsum dolor sat amet
,则长度现在是 26
.通过应用公式,我们得到了更大的宽度:(8px * 26 字母) + 100px = 308px
.
为了让它在反应中工作,这里是一个片段:
<选择style={{width: `${(8*this.state.selectedOption2.length) + 100}px`}}className="选择自定义类"名称=表单字段名称"值={this.state.selectedOption2}选项={选项2}onChange={(value) =>{ this.setState({ selectedOption2: value.value });}}/>
如你所见,我添加了:
style={{width: `${(8*this.state.selectedOption2.length) + 100}px`}}
到您的组件.每当状态更新时,所有内容都会传播,包括组件的宽度.
查看此 fiddle 中的工作示例.
最终,您希望根据需要微调规则和平均值.我还建议您根据所选值中的大小写字母数量应用字母大小.
解决方案 2(编辑)
如果您愿意,我想出了一个纯 CSS 解决方案.它应该针对您的设计进行更好的测试,但这应该可行:
//.Select-value 带有一个绝对位置,将其堆叠在 .Select-input 下方//我们需要修改它,以便我们能够让 div 根据其内容大小而增长.Select-placeholder, .Select--single >.Select-control .Select-value {位置:相对;填充左:0;}//所有这 3 个类都带有丑陋的表格"显示....Select-control, .Select-clear-zone, .Select-arrow-zone {显示:继承;}//这里是技巧:我们将包装器显示为 flex 以使其适合高度//我们使用 row-reverse 翻转 .Select-value 和 .Select-input 的位置,以便在左侧有一个好的输入,而没有在右侧.select-custom-class .Select-multi-value-wrapper {显示:弹性;flex-direction: 行反向;}//我们将控件放回更好的中心位置.select-clear-zone {位置:绝对;顶部:8px;右:20px;}.选择箭头区域{位置:绝对;顶部:8px;右:0px;}
查看有效的 fiddle(为了更好的说明,我更改了一些示例)
告诉我你的想法.:)
When using react-select
it is not auto sizing by option value, but using width:100%
as you can see in picture:
Options are short:
getOptions() {
return [
{ value: 'AND', label: 'AND' },
{ value: 'OR', label: 'OR' }
]
}
And code which produces it:
<Select
options={this.getOptions()}
value={value}
autosize={true}
clearable={false}
simpleValue
/>
Is there any way to make react-select
to show these values with auto sizing, so select box would be the same as option length, and I could, for example, center this select box in <div>
?
Updated 14.11.2017 Full example can be seen in this jsFiddle
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. :)
这篇关于反应选择自动大小宽度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!