反应选择自动调整大小宽度

问题描述 投票:0回答:8

使用

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
通过自动调整大小来显示这些值,这样选择框将与选项长度相同,例如,我可以将此选择框置于
<div>
的中心?

更新于2017年11月14日 完整的例子可以在这个jsFiddle

中看到
reactjs react-select
8个回答
42
投票

内联样式对我不起作用。 我只是将 Select 组件包装在一个 div 中,并给了 div 我想要的宽度。

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

22
投票

我从repo线程上的aidan-keay借来了这个,但是将其添加到自定义样式道具对我有用:

menu: (base) => ({
      ...base,
      width: "max-content",
      minWidth: "100%"
 }),

18
投票

解决方案1

您可以根据所选选项的长度更新组件的

inline styles
,从而利用 React 的
width

让我进一步解释一下:假设所选值为

HelloWorld
。该字符串的长度为
10
。我们可以猜测每个角色平均都占
8px
(总的猜测我根本不知道)。因此,这个单词的宽度约为
8*10=80px
,对吧?另外,单词后面有一些控件(红心和十字),我们需要一些最小填充:它们一起的宽度可能是
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;
}

查看工作小提琴(我更改了一些示例以便更好地说明)

告诉我你的想法。 :)


12
投票

如果您使用的是react-select v3,您可以使用customStyles对象:

const customStyles = {
  container: provided => ({
    ...provided,
    width: 150
  })
};

<Select
    styles={customStyles}
    {...otherProps}
/>

8
投票

9/2020

嘿伙计们:)解决方案比解决方法如此简单!

这些课程中的问题

__placeholder
__single-value

只需将此 css 添加到它们两个中,您将获得自动调整大小的反应选择

.CUSTOM_PREFIX__single-value,
.CUSTOM_PREFIX__placeholder {
    position: static;
    transform: none;
    max-width: none;
  }

在上面的例子中,prop

classNamePrefix
将等于
CUSTOM_PREFIX

classNamePrefix="CUSTOM_PREFIX"


5
投票

09/2021(反应选择 v4)

添加

position: static
transform: none
将相应地缩放选择容器。

  placeholder: (provided) => ({
    ...provided,
    position: 'static',
    transform: 'none',
  }),
  singleValue: (provided) => ({
    ...provided,
    position: 'static',
    transform: 'none',
  }),

1
投票

更新:对于使用 React-Select 实现“标签自动完成”功能但遇到麻烦的人,它根据您搜索的上一个标签设置的样式宽度太窄,这对我有用:

设置样式:

.myCustomPrefix__value-container > div {
  width: auto !important;
}

在组件中设置

classNamePrefix="myCustomPrefix"
(docs)。


旧答案:

请参阅官方文档https://react-select.com/styles#style-object

我最初认为将

width
设置为“自动”对于
option
对我有用:

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}
    />
  )

0
投票

   <Select styles={{ container: (base) => ({ ...base, width: '100%', }), }} />

© www.soinside.com 2019 - 2024. All rights reserved.