web-dev-qa-db-fra.com

Définir hauteur TextField matériau-ui

index.js

import React from 'react'
import TextField from '@material-ui/core/TextField'
import style from './style'
import withStyles from 'hoc/withStyles'
import { connect } from 'react-redux'

class SearchField extends React.Component {
  constructor (props) {
    super(props)
    this.onChange = this.onChange.bind(this)
  }

  onChange (event) {
    const { dispatcher } = this.props
    this.props.dispatch(dispatcher(event.target.value))
    event.preventDefault()
  }

  render () {
    const { classes, placeholder } = this.props
    return (
      <TextField 
        label={placeholder} 
        placeholder={placeholder}
        InputProps={{ classes: { input: classes.resize } }}
        className={classes.textField}
        margin="normal"
        autoFocus={true} 
        variant="outlined" 
        onChange={this.onChange}
      />
    )
  }
}

export default withStyles(style)(connect()(SearchField))

style.js

export default function () {
  return {
    container: {
      display: 'flex',
      flexWrap: 'wrap'
    },
    textField: {
      width: 'auto'
    },
    resize: {
      fontSize: 11
    }
  }
}

https://material-ui.com/api/text-field/

Comment puis-je changer TextField height? Je ne le trouve pas dans la documentation. Lorsque j'essaie de le changer directement en CSS, cela ne fonctionne pas correctement (il a l'air comme ceci - hauteur sélectionnée sur l'écran 26px).

Que devrais-je faire?

8
Andrey Radkevich

L'autre réponse est utile mais n'a pas fonctionné pour moi car si un label est utilisé dans un composant outlined (comme dans la question), il laisse le label uncentered . Si tel est votre cas d'utilisation, lisez la suite.

La façon dont le <label> Le composant est stylé est quelque peu idiosyncratique, en utilisant position: absolute et transform. Je crois que c'est fait de cette façon pour que l'animation fonctionne lorsque vous vous concentrez sur le terrain.

Ce qui suit a fonctionné pour moi, avec le dernier matériel-ui v4 (cela devrait fonctionner correctement avec v aussi).

// height of the TextField
const height = 44

// magic number which must be set appropriately for height
const labelOffset = -6

// get this from your form library, for instance in
// react-final-form it's fieldProps.meta.active
// or provide it yourself - see notes below
const focused = ???

---

<TextField
  label="Example"
  variant="outlined"

  /* styles the wrapper */
  style={{ height }}

  /* styles the label component */
  InputLabelProps={{
    style: {
      height,
      ...(!focused && { top: `${labelOffset}px` }),
    },
  }}

  /* styles the input component */
  inputProps={{
      style: {
        height,
        padding: '0 14px',
      },
  }}
/>

Notes

  • Je viens d'utiliser des styles en ligne plutôt que le withStyles HOC, car cette approche me semble plus simple
  • La variable focused est requise pour cette solution - vous l'obtenez avec final-form, formik et probablement d’autres bibliothèques de formulaires. Si vous utilisez simplement un TextField brut, ou une autre bibliothèque de formulaires qui ne le supporte pas, vous devrez le connecter vous-même.
  • La solution s'appuie sur un nombre magique labelOffset pour centrer le label qui est couplé au statique height que vous choisissez. Si vous souhaitez éditer height, vous devrez également éditer labelOffset de manière appropriée.
  • Cette solution ne fonctionne pas prend en charge la modification de la taille de la police de l'étiquette. Vous pouvez modifier la taille de la police de saisie, uniquement si cela ne vous gêne pas, il y a un décalage entre cela et l'étiquette. Le problème est que la taille de l'encoche qui héberge l'étiquette dans la bordure est calculée en javascript selon un rapport de nombre magique qui ne fonctionne que lorsque la taille de police de l'étiquette est la valeur par défaut. Si vous réduisez la taille de la police de l'étiquette, l'encoche sera également trop petite lorsque l'étiquette apparaît dans la bordure. Il n'y a pas de moyen facile de remplacer cela, à moins de répéter vous-même l'intégralité du calcul et de définir la largeur de l'encoche (le composant est fieldset> legend) vous-même via CSS. Pour moi, cela n’en valait pas la peine, car j’utilise bien les tailles de police par défaut d’une hauteur de 44 pixels.
5
davnicwil

Vous n'avez pas montré comment vous avez essayé de spécifier la hauteur, mais l'approche que vous avez utilisée pour la taille de police est la bonne. Voici un exemple montrant deux champs de texte avec des hauteurs différentes:

import React from "react";
import ReactDOM from "react-dom";
import TextField from "@material-ui/core/TextField";
import { withStyles } from "@material-ui/core/styles";
const styles = {
  input1: {
    height: 50
  },
  input2: {
    height: 200,
    fontSize: "3em"
  }
};
function App(props) {
  return (
    <div className="App">
      <TextField
        variant="outlined"
        InputProps={{ classes: { input: props.classes.input1 } }}
      />
      <TextField
        variant="outlined"
        InputProps={{ classes: { input: props.classes.input2 } }}
      />
    </div>
  );
}
const StyledApp = withStyles(styles)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(<StyledApp />, rootElement);

Et voici un code sandbox avec le même code pour que vous puissiez le voir en cours d'exécution.

4
Ryan Cogswell

Le composant prend un multiline prop qui est un booléen. Définissez ceci sur true, puis définissez rows prop du composant sur un nombre.

   <TextField
      multiline={true}
      rows={3}
      name="Description"
      label="Description"
      placeholder="Description"
      autoComplete="off"
      variant="outlined"
      value={description}
      onChange={e => setDescription(e.target.value)}
    />
0
Bruno Crosier