Material UI in React [Day 10] Inputs (Text Field) 文本输入框

Text Field

TextField 包装组件是一个完整的表单控件,包括标签、输入和帮助文本,它支持标准、轮廓和填充样式。简单来说它是一个整合了 FormControl, InputLabel, Input, FormHelperText 的综合组件,从原生的 html 标签来看,它确实是使用了 fieldset 来整合整个 input 输入框的样式,这也是它会命名为text field的原因吧。
以下两种写法是相同的

<TextField id="textfield" label="Standard" />
<FormControl>
<InputLabel htmlFor="form-control">Form Control</InputLabel>
<Input id="form-control" />
</FormControl>

variant

在基础引入状态下的 variant 有以下三种,预设值为 standard:

<form noValidate autoComplete="off">
  <TextField id="standard-basic" label="Standard" />
  <TextField id="filled-basic" label="Filled" variant="filled" />
  <TextField id="outlined-basic" label="Outlined" variant="outlined" />
</form>

表单属性

也支援一些基本的表单属性,例如:required, disabled, type...等等,也包含了helperText,通常用来描述如何使用这个输入框。

<TextField
  required
  id="standard-required"
  label="Required"
  defaultValue="Hello World"
/>
<TextField
  disabled
  id="standard-disabled"
  label="Disabled"
  defaultValue="Hello World"
/>
<TextField
  id="standard-password-input"
  label="Password"
  type="password"
  autoComplete="current-password"
/>
<TextField
  id="standard-read-only-input"
  label="Read Only"
  defaultValue="Hello World"
  InputProps={{
    readOnly: true,
  }}
/>
<TextField
  id="standard-number"
  label="Number"
  type="number"
  InputLabelProps={{
    shrink: true,
  }}
/>
<TextField id="standard-search" label="Search field" type="search" />
<TextField
  id="standard-helperText"
  label="Helper text"
  defaultValue="Default Value"
  helperText="Some important text"
/>

error

可以使用 error 来切换错误的状态,同时也可使用 helperText 来给用户提供错误提示讯息。

<TextField
  variant="filled"
  error
  label="Error"
  defaultValue="Hello World"
  helperText="Incorrect entry."
/>

错误的部分可以按个人喜好选择搭配 formik 或是 react-hook-form 来做检核,之後会做详细的讲解如何与 react-hook-form 做搭配。

multiline

使用 multiline,能将原本的输入框转换成多行,类似 textarea 的特性,简单来说就是 textarea 更换皮肤。

<TextField
  label="Multiline"
  multiline
  maxRows={4}
  value={value}
  onChange={handleChange}
/>
<TextField
  label="Multiline Placeholder"
  variant="filled"
  placeholder="Placeholder"
  multiline
/>
<TextField
  label="Multiline"
  variant="outlined"
  multiline
  rows={4}
  defaultValue="Default Value"
/>

select

使用 select 可以在输入框内插入一个 Select 组件,不过通常会直接使用 Select 组件来处理:

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';
import MenuItem from '@material-ui/core/MenuItem';

const currencies = [
  {
    value: 'USD',
    label: '$',
  },
  {
    value: 'EUR',
    label: '€',
  },
  {
    value: 'BTC',
    label: '฿',
  },
  {
    value: 'JPY',
    label: '¥',
  },
];

const useStyles = makeStyles((theme) => ({
  root: {
    '& .MuiTextField-root': {
      margin: theme.spacing(1),
      width: '25ch',
    },
  },
}));

export default function MultilineTextFields() {
  const classes = useStyles();
  const [currency, setCurrency] = React.useState('EUR');

  const handleChange = (event) => {
    setCurrency(event.target.value);
  };

  return (
    <form className={classes.root} noValidate autoComplete="off">
      <div>
        <TextField
          id="standard-select-currency"
          select
          label="Select"
          value={currency}
          onChange={handleChange}
          helperText="Please select your currency"
        >
          {currencies.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
        </TextField>
        <TextField
          id="standard-select-currency-native"
          select
          label="Native select"
          value={currency}
          onChange={handleChange}
          SelectProps={{
            native: true,
          }}
          helperText="Please select your currency"
        >
          {currencies.map((option) => (
            <option key={option.value} value={option.value}>
              {option.label}
            </option>
          ))}
        </TextField>
      </div>
      <div>
        <TextField
          id="filled-select-currency"
          select
          label="Select"
          value={currency}
          onChange={handleChange}
          helperText="Please select your currency"
          variant="filled"
        >
          {currencies.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
        </TextField>
        <TextField
          id="filled-select-currency-native"
          select
          label="Native select"
          value={currency}
          onChange={handleChange}
          SelectProps={{
            native: true,
          }}
          helperText="Please select your currency"
          variant="filled"
        >
          {currencies.map((option) => (
            <option key={option.value} value={option.value}>
              {option.label}
            </option>
          ))}
        </TextField>
      </div>
      <div>
        <TextField
          id="outlined-select-currency"
          select
          label="Select"
          value={currency}
          onChange={handleChange}
          helperText="Please select your currency"
          variant="outlined"
        >
          {currencies.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
        </TextField>
        <TextField
          id="outlined-select-currency-native"
          select
          label="Native select"
          value={currency}
          onChange={handleChange}
          SelectProps={{
            native: true,
          }}
          helperText="Please select your currency"
          variant="outlined"
        >
          {currencies.map((option) => (
            <option key={option.value} value={option.value}>
              {option.label}
            </option>
          ))}
        </TextField>
      </div>
    </form>
  );
}

InputAdornment

可用於向输入框添加前缀、後缀或动作。 例如,可以用一个icon或按钮来隐藏或者显示输入框内的密码范例

<TextField
  label="加入前缀"
  id="standard-start-adornment"
  InputProps={{
    startAdornment: <InputAdornment position="start">Kg</InputAdornment>,
  }}
/>
<TextField
  label="加入後缀"
  id="standard-end-adornment"
  InputProps={{
    startAdornment: <InputAdornment position="end">Kg</InputAdornment>,
  }}
/>

Layout

使用 margin 属性,你可以改变数入框的垂直间距。 若您使用 none (预设值),将不会在 FormControl 上添加间距,相对的,使用 dense 和 normal 会添加间距。
fullWidth 属性,使用它时,输入框会占满整个容器的宽度。

<TextField
  id="outlined-full-width"
  label="Label"
  style={{ margin: 8 }}
  placeholder="Placeholder"
  helperText="Full width!"
  fullWidth
  margin="normal"
  InputLabelProps={{
    shrink: true,
  }}
  variant="outlined"
/>
<TextField
  label="None"
  id="outlined-margin-none"
  defaultValue="Default Value"
  className={classes.textField}
  helperText="Some important text"
  variant="outlined"
/>
<TextField
  label="Dense"
  id="outlined-margin-dense"
  defaultValue="Default Value"
  className={classes.textField}
  helperText="Some important text"
  margin="dense"
  variant="outlined"
/>
<TextField
  label="Normal"
  id="outlined-margin-normal"
  defaultValue="Default Value"
  className={classes.textField}
  helperText="Some important text"
  margin="normal"
  variant="outlined"
/>

shrink

输入框标签的 "shrink" 状态不正确,标签应在输入框显示内容的时候立即收缩。 在某些情况下,我们无法确定输入框的 "shrink" 状态(如数字、日期时间)如此便有可能出现重叠。
若要解决此问题,可以在输入框的标签上强制给予 "shrink" 状态。

<TextField InputLabelProps={{ shrink: true }} />

<InputLabel shrink>hello</InputLabel>

至此今天大致讲解完基本的应用了,明天会接续讲解 date/time picker 日期输入的部分。


<<:  Day 10:「伸缩自如的,橡胶...」- 断点 / RWD

>>:  基础建设: 原始码版本控制

Day19 X Application Shell Architecture

昨天介绍 Service Workers 後我们知道它是 PWA 的要素之一,且也是让 Web A...

[用 Python 解 LeetCode] (001) 27. Remove Element

题干懒人包 输入一个数组及一个数,最後输出一个数值代表非重复数值的数量,然後以下几点要注意: 只能修...

【Day15】宽松相等、严格相等以及隐含转型

宽松相等( == ) 会进行型别转换後,再对值进行比较 严格相等( === ) 会比较型别和值是否相...

第十五天:初探 Gradle properties

为了让 Gradle 在运行的时候可以更弹性,Gradle 支援一系列载入建置环境(Build En...

Day 12 : 如何正确使用 Zettelkasten 笔记法?了解 4 种笔记形式的功能,以利後续笔记连结

前言 还记得我在 Day03 介绍的《Zettelkasten卡片盒笔记法,建立知识连结网路来活用笔...