React Select 自动调整宽度
React Select auto size width
当使用 react-select
时,它不是根据选项值自动调整大小,而是使用 width:100%
,如图所示:
选项很短:
getOptions() {
return [
{ value: 'AND', label: 'AND' },
{ value: 'OR', label: 'OR' }
]
}
以及生成它的代码:
<Select
options={this.getOptions()}
value={value}
autosize={true}
clearable={false}
simpleValue
/>
有什么方法可以让 react-select
显示这些值并自动调整大小,这样 select 框将与选项长度相同,例如,我可以将此 [= <div>
?
中的 33=] 框
2017 年 11 月 14 日更新
完整示例可以在 jsFiddle
中看到
解决方案 1
您可以通过根据所选选项的长度更新组件的 width
来利用 React 的 inline styles
。
让我进一步解释:假设选择的值为HelloWorld
。该字符串的长度为 10
。我们可以猜测每个字符平均每个占 say 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 sit amet
,则长度现在为 26
。通过应用公式,我们得到更大的宽度:(8px * 26 letters) + 100px = 308px
.
为了在 React 中起作用,这里有一个片段:
<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 }); }}
/>
如你所见,我添加了:
style={{width: `${(8*this.state.selectedOption2.length) + 100}px`}}
到您的组件。每当状态更新时,所有内容都会传播,包括组件的宽度。
请参阅此 fiddle 中的工作示例。
最终,您想根据自己的需要微调规则和平均值。我还建议您根据所选值中大小写字母的数量应用字母大小。
解决方案 2(编辑)
如果您愿意,我想出了一个纯粹的 CSS 解决方案。它应该针对您的设计进行更好的测试,但这应该有效:
/* .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;
}
查看工作 fiddle(我更改了一些示例以更好地说明)
告诉我你的想法。 :)
内联样式对我不起作用。
我只是将 Select 组件包裹在 div 中,并为 div 提供了我想要的宽度。
<div style={{width: '300px'}}>
<Select
menuPlacement="auto"
menuPosition="fixed"
etc, etc..
/>
</div>
如果你使用的是 react-select v3,你可以使用 customStyles 对象:
const customStyles = {
container: provided => ({
...provided,
width: 150
})
};
<Select
styles={customStyles}
{...otherProps}
/>
更新:对于使用 React-Select 作为 "tags autocomplete" 功能但在设置样式宽度时遇到问题的人,该宽度基于之前的设置太窄您搜索的标签,这对我有用:
设置样式为:
.myCustomPrefix__value-container > div {
width: auto !important;
}
在组件(docs)中设置classNamePrefix="myCustomPrefix"
。
旧答案:
查看官方文档 https://react-select.com/styles#style-object
我最初认为 option
的 width
设置为 "auto" 对我有用:
const customStyles = {
option: (styles, { data, isDisabled, isFocused, isSelected }) => {
return {
...styles,
fontSize: '12px',
textAlign: 'left',
width: 'auto',
}
},
}
...
return (
//https://react-select.com/props
<AsyncSelect
components={animatedComponents}
isMulti
// isDisabled={isLoading}
// isLoading={isLoading}
onChange={handleChange}
onInputChange={handleInputChange}
cacheOptions
defaultOptions
defaultMenuIsOpen={false}
closeMenuOnSelect={closeMenuOnSelect}
placeholder={placeholder}
loadOptions={promiseOptions}
value={selectedOptions}
styles={customStyles}
formatOptionLabel={formatOptionLabel}
/>
)
9/2020
大家好 :) 解决方案比解决方法简单!
问题在这些类__placeholder
,__single-value
只需将此 css 添加到它们中,您将获得自动调整大小 react-select
.CUSTOM_PREFIX__single-value,
.CUSTOM_PREFIX__placeholder {
position: static;
transform: none;
max-width: none;
}
在上面的例子中,prop classNamePrefix
将等于 CUSTOM_PREFIX
classNamePrefix="CUSTOM_PREFIX"
我从 aidan-keay on the repo thread 那里借来了这个,但是将它添加到自定义样式道具对我有用:
menu: (base) => ({
...base,
width: "max-content",
minWidth: "100%"
}),
09/2021(反应-select v4)
添加 position: static
和 transform: none
将相应地缩放 select-容器。
placeholder: (provided) => ({
...provided,
position: 'static',
transform: 'none',
}),
singleValue: (provided) => ({
...provided,
position: 'static',
transform: 'none',
}),
当使用 react-select
时,它不是根据选项值自动调整大小,而是使用 width:100%
,如图所示:
选项很短:
getOptions() {
return [
{ value: 'AND', label: 'AND' },
{ value: 'OR', label: 'OR' }
]
}
以及生成它的代码:
<Select
options={this.getOptions()}
value={value}
autosize={true}
clearable={false}
simpleValue
/>
有什么方法可以让 react-select
显示这些值并自动调整大小,这样 select 框将与选项长度相同,例如,我可以将此 [= <div>
?
2017 年 11 月 14 日更新 完整示例可以在 jsFiddle
中看到解决方案 1
您可以通过根据所选选项的长度更新组件的 width
来利用 React 的 inline styles
。
让我进一步解释:假设选择的值为HelloWorld
。该字符串的长度为 10
。我们可以猜测每个字符平均每个占 say 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 sit amet
,则长度现在为 26
。通过应用公式,我们得到更大的宽度:(8px * 26 letters) + 100px = 308px
.
为了在 React 中起作用,这里有一个片段:
<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 }); }}
/>
如你所见,我添加了:
style={{width: `${(8*this.state.selectedOption2.length) + 100}px`}}
到您的组件。每当状态更新时,所有内容都会传播,包括组件的宽度。
请参阅此 fiddle 中的工作示例。
最终,您想根据自己的需要微调规则和平均值。我还建议您根据所选值中大小写字母的数量应用字母大小。
解决方案 2(编辑)
如果您愿意,我想出了一个纯粹的 CSS 解决方案。它应该针对您的设计进行更好的测试,但这应该有效:
/* .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;
}
查看工作 fiddle(我更改了一些示例以更好地说明)
告诉我你的想法。 :)
内联样式对我不起作用。 我只是将 Select 组件包裹在 div 中,并为 div 提供了我想要的宽度。
<div style={{width: '300px'}}>
<Select
menuPlacement="auto"
menuPosition="fixed"
etc, etc..
/>
</div>
如果你使用的是 react-select v3,你可以使用 customStyles 对象:
const customStyles = {
container: provided => ({
...provided,
width: 150
})
};
<Select
styles={customStyles}
{...otherProps}
/>
更新:对于使用 React-Select 作为 "tags autocomplete" 功能但在设置样式宽度时遇到问题的人,该宽度基于之前的设置太窄您搜索的标签,这对我有用:
设置样式为:
.myCustomPrefix__value-container > div {
width: auto !important;
}
在组件(docs)中设置classNamePrefix="myCustomPrefix"
。
旧答案:
查看官方文档 https://react-select.com/styles#style-object
我最初认为 option
的 width
设置为 "auto" 对我有用:
const customStyles = {
option: (styles, { data, isDisabled, isFocused, isSelected }) => {
return {
...styles,
fontSize: '12px',
textAlign: 'left',
width: 'auto',
}
},
}
...
return (
//https://react-select.com/props
<AsyncSelect
components={animatedComponents}
isMulti
// isDisabled={isLoading}
// isLoading={isLoading}
onChange={handleChange}
onInputChange={handleInputChange}
cacheOptions
defaultOptions
defaultMenuIsOpen={false}
closeMenuOnSelect={closeMenuOnSelect}
placeholder={placeholder}
loadOptions={promiseOptions}
value={selectedOptions}
styles={customStyles}
formatOptionLabel={formatOptionLabel}
/>
)
9/2020
大家好 :) 解决方案比解决方法简单!
问题在这些类__placeholder
,__single-value
只需将此 css 添加到它们中,您将获得自动调整大小 react-select
.CUSTOM_PREFIX__single-value,
.CUSTOM_PREFIX__placeholder {
position: static;
transform: none;
max-width: none;
}
在上面的例子中,prop classNamePrefix
将等于 CUSTOM_PREFIX
classNamePrefix="CUSTOM_PREFIX"
我从 aidan-keay on the repo thread 那里借来了这个,但是将它添加到自定义样式道具对我有用:
menu: (base) => ({
...base,
width: "max-content",
minWidth: "100%"
}),
09/2021(反应-select v4)
添加 position: static
和 transform: none
将相应地缩放 select-容器。
placeholder: (provided) => ({
...provided,
position: 'static',
transform: 'none',
}),
singleValue: (provided) => ({
...provided,
position: 'static',
transform: 'none',
}),