设置material-ui的TextField高度

68

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/

如何更改TextField的高度?在文档中找不到相关说明。当我试图直接在CSS中更改高度时,它的表现是不正确的(在屏幕上选择的高度为26px参见)。

应该怎么做?

14个回答

54

你可以尝试添加在Textfield API中提到的size="small"

<TextField variant="outlined" size="small" / >

8
是的,但我们无法将其放大。只有两个尺寸选项。 - Alan Pallath
请问您能否提供另外两个尺寸选项? - Malindu Sasanga
1
@Malindu 小型和中型。 - Shane Sepac

32

另一个答案很有用,但对我没起作用,因为如果在问题中使用了 outlined 组件中的 label ,它会让 label 无法居中。如果这是您的用例,请继续阅读。

<label> 组件的样式方式有点特别,使用了 position: absolutetransform。我认为它是这样做的,是为了使当你聚焦在该字段上时动画起作用。

以下方法适用于最新的 material-uiv4,并且应该也适用于v3

// 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',
      },
  }}
/>

注释

  • 我只是使用了内联样式而不是withStyles HOC,因为对我来说这种方法似乎更简单。
  • 这个解决方案需要final-formformik和可能其他表单库提供的focused变量。如果您仅使用原始的TextField或另一个不支持此功能的表单库,您将不得不自己挂接此变量。
  • 该解决方案依赖于一个魔法数字labelOffset来居中label,该数字与您选择的静态height耦合。如果您想编辑height,您还必须适当地编辑labelOffset
  • 此解决方案不支持更改标签字体大小。您可以更改输入字体大小,但只有在输入字体大小与标签不匹配时才可以。问题是,在轮廓边框中容纳标签的“缺口”的大小是根据一个魔法数字比例在javascript中计算的,该比例仅适用于标签字体大小为默认值时。如果您将标签字体大小设置得更小,当标签显示在边框中时,缺口也会变得太小。除非您重复整个计算并通过CSS自己设置缺口的宽度(组件为fieldset>legend),否则没有简单的方法可以覆盖这个问题。对我来说,这不值得,因为我可以使用默认字体大小和44px的高度。

29

组件需要一个名为 multiline 的布尔型属性。将其设置为 true,然后将组件的 rows 属性设置为一个数字。

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

4
这应该标记为答案,因为这是最简单的选项。但只适用于增加高度。 - Samitha Chathuranga
谢谢您,这在文档和示例中并不明显。虽然仍无法通过CSS进行精确高度设置,但这符合我的使用情况。 - lpritchard

13

首先,我想要向在这个讨论串中,那些发现自己在与MUI组件的笨拙设计作斗争的人表达我的同情。其次,如果你正在使用主题和“filled”文本框的变体,那么这个解决方案可能适用于你。使用Chrome Dev Tools,我成功地调整了类“MuiFormControl-root”和“MuiInputBase-root”的div高度。这是我的代码(结果可能会有所不同):

const theme = createMuiTheme({
  overrides: {
    MuiFormControl: {
      root: {
        height: '56px',
      },
    },
    MuiInputBase: {
      root: {
        height: '56px',
      },
    },
  },
})

3
先生,您可能已经拯救了我的一周。惊人、全面、简单的解决方案。我不知道为什么这不是 MUI 开发团队更加开箱即用和直观的功能之一。 - cr4z

11
  <TextField
    id="outlined-multiline-static"
    label="Multiline"
    multiline
    fullWidth
    defaultValue="Default Value"
    inputProps={{
      style: {
        height: "600px",
      },
    }}
  />

1
伟大而简单的解决方案。您还可以使用更新的sx替换style - Stefan Haberl

11

您没有展示如何尝试指定高度,但是您用于字体大小的方法是正确的方法。 以下是一个例子,展示了两个不同高度的文本字段:

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

这里有一个代码沙箱,你可以点击 这里 查看它的运行效果。


所以只有当文本框具有不同的字体大小时,才有可能拥有不同大小的文本框?这对我来说似乎过于限制了。 - pfincent
1
@pfincent 不,两者之间没有联系。事实上,我的示例有两个TextFields,它们的高度都不同于默认值,但只有第二个会改变字体大小。 - Ryan Cogswell
糟糕,我的错。 - pfincent

7
改变高度很简单,可以通过以下方式实现:
InputProps={{style: { fontSize: '1.8rem', height: 70 },

但这还不够,因为标签(在这种情况下是 placeholder)将不会居中。

可以使用以下方法使标签居中:

sx={{'.MuiFormLabel-root[data-shrink=false]': { top: <put desired value here>} }}

7
为使其变窄,请设置高度并在TextField上添加“dense” margin属性,以保持标签正确对齐:
<TextField margin="dense" style={{ height: 38 }} />

6

使用 material-ui v4+,你需要调整输入框的填充和标签的位置以达到你想要的效果。

<TextField label="Label" variant="outlined" />

假设我们希望上述文本框高度为48px(默认大小为56px),只需执行以下操作(56px - 48px)/2 = 4px,并在我们的CSS文件中添加如下代码:
.MuiTextField-root input {
  /* 14.5px = 18.5px - 4px (note: 18.5px is the input's default padding top and bottom) */
  padding-top: 14.5px;
  padding-bottom: 14.5px; 
}

.MuiTextField-root label {
  top: -4px;
}

.MuiTextField-root label[data-shrink='true'] {
  top: 0;
}

对于styled-components的用户而言,以上代码块可以定义为Sass mixin,并可在代码库中重复使用。
import { css } from 'styled-components'

const muiTextFieldHeight = (height: number) => {
  const offset = (56 - height) / 2

  return css`
    input {
      padding-top: calc(18.5px - ${offset}px);
      padding-bottom: calc(18.5px - ${offset}px);
    }

    label {
      top: -${offset}px;
    }

    label[data-shrink='true'] {
      top: 0;
    }
  `
}

然后在您的样式表中的某个地方

  .MuiTextField-root {
      ${muiTextFieldHeight(40)} /* set TextField height to 40px */
  }

3
这适用于 material-ui v3。
<div className="container">
  <TextField
    label="Full name"
    margin="dense"
    variant="outlined"
    autoFocus
  />
</div>

.css

.container input {
  height: 36px;
  padding: 0px 14px;
}

.container label {
  height: 36px;
  top: -6px;
}

.container label[data-shrink="true"] {
  top: 0;
}

https://codesandbox.io/s/elated-kilby-9s3ge


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接