web-dev-qa-db-fra.com

React Sélectionnez la largeur de taille automatique

Lors de l'utilisation de react-select ce n'est pas un dimensionnement automatique par valeur d'option, mais en utilisant width:100% comme vous pouvez le voir sur l'image:

Select with short values

Les options sont courtes:

getOptions() {
    return [
        { value: 'AND', label: 'AND' },
        { value: 'OR', label: 'OR' }
    ]
}

Et le code qui le produit:

<Select
    options={this.getOptions()}
    value={value}
    autosize={true}
    clearable={false}
    simpleValue
/>

Existe-t-il un moyen de faire react-select pour afficher ces valeurs avec le dimensionnement automatique, donc la case de sélection serait la même que la longueur de l'option, et je pourrais, par exemple, centrer cette case de sélection dans <div>?

Mis à jour le 14.11.2017 Un exemple complet peut être vu dans ce jsFiddle

6
Orbitum

SOLUTION 1

Vous pouvez tirer parti de inline styles en mettant à jour les composants _ width en fonction de la longueur de l'option sélectionnée.

Permettez-moi d'expliquer davantage: Supposons que la valeur sélectionnée soit HelloWorld. Cette chaîne est de longueur 10. On pourrait deviner que chaque personnage représente disons 8px chacun en moyenne (je suppose que je n'ai aucune idée du tout). Ainsi, la largeur de ce mot est d'environ 8*10=80px, droite ? De plus, il y a quelques contrôles après le Word (le carret et la croix) et nous avons besoin d'un minimum de remplissage: ensemble, ils peuvent être de 100px largeur. Alors voilà: la largeur de votre div doit être ( 8px * 10 letters ) + 100px = 180px.

Plus précisément, la bonne formule est quelque chose comme:

(average_letter_size * selected_value.length) + other_elements_sizes

Quand selected_value change, ainsi que son length, et donc la largeur du div est mise à jour avec le nouveau total.

Exemple: si la valeur sélectionnée est maintenant Lorem Ipsum dolor sit amet, la longueur est maintenant 26. En appliquant la formule, nous obtenons une plus grande largeur de: (8px * 26 letters) + 100px = 308px.

Pour que cela fonctionne en réaction, voici un extrait:

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

Comme vous pouvez le voir, j'ai ajouté:

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

à votre composant. Chaque fois que l'état est mis à jour, tout est propagé, y compris la largeur du composant.

Voir un exemple de travail dans ce violon .

Finalement, vous souhaitez affiner les règles et les moyennes à vos besoins. Je vous suggère également d'appliquer une taille de lettre en fonction du nombre de lettres majuscules et minuscules dans la valeur sélectionnée.

SOLUTION 2 (modifier)

J'ai trouvé une solution CSS pure si vous voulez. Il devrait être mieux testé par rapport à votre conception, mais cela devrait fonctionner:

// .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;
}

Voir un fonctionnement violon (J'ai changé certains des exemples pour une meilleure illustration)

Dis-moi ce que tu penses. :)

6
Jona Rodrigues

Les styles en ligne ne fonctionnaient pas pour moi. J'ai juste enveloppé le composant Select dans un div et lui ai donné la largeur que je voulais.

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