web-dev-qa-db-ja.com

React自動サイズ幅を選択

react-selectを使用する場合、オプション値による自動サイジングではなく、図に示すようにwidth:100%を使用します。

Select with short values

オプションは短いです:

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

6
Orbitum

ソリューション1

選択したオプションの長さに基づいてコンポーネントのwidthを更新することにより、Reactのinline stylesを活用できます。

さらに説明します。選択した値がHelloWorldであるとします。この文字列の長さは10です。それぞれのキャラクターが平均して8pxをそれぞれ占めていると推測できます(全体的な推測はまったくわかりません)。したがって、このWordの幅は8*10=80px前後です。また、Wordの後にいくつかのコントロール(キャレットとクロス)があり、最小限のパディングが必要です。それらは一緒に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の幅が大きくなります。

これが反応するようにするには、ここにスニペットがあります:

<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 を参照してください(わかりやすくするためにいくつかの例を変更しました)

あなたの考えを教えてください。 :)

6
Jona Rodrigues

インラインスタイルは機能しませんでした。 Selectコンポーネントをdivでラップし、divに必要な幅を指定しました。

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