文本字段
文本字段允许用户输入和编辑文本。
文本字段允许用户在 UI 中输入文本。它们通常出现在表单和对话框中。
基本文本字段
`TextField` 包装组件是一个完整的表单控件,包括标签、输入和帮助文本。它有三种变体:outlined(默认)、filled 和 standard。
表单属性
支持标准表单属性,例如 required
、disabled
、type
等,以及 helperText
,它用于提供关于字段输入的上下文,例如输入将如何使用。
控制 HTML 输入
使用 slotProps.htmlInput
将属性传递给底层的 <input>
元素。
<TextField slotProps={{ htmlInput: { 'data-testid': '…' } }} />
渲染后的 HTML 输入将如下所示
<input
aria-invalid="false"
class="MuiInputBase-input MuiOutlinedInput-input"
type="text"
data-testid="…"
/>
验证
`error` 属性切换错误状态。然后可以使用 `helperText` 属性向用户提供有关错误的反馈。
多行
`multiline` 属性将文本字段转换为 MUI Base Textarea Autosize 元素。除非设置了 rows
属性,否则文本字段的高度会动态匹配其内容。您可以使用 minRows
和 maxRows
属性来限制它。
选择
`select` 属性使文本字段在内部使用 Select 组件。
图标
有多种方法可以在文本字段中显示图标。
输入装饰
主要方法是使用 InputAdornment
。这可以用于向输入添加前缀、后缀或操作。例如,您可以使用图标按钮来隐藏或显示密码。
千克
千克
重量
$
千克
千克
重量
$
千克
千克
重量
$
自定义装饰
您可以将自定义样式应用于装饰,并根据另一个装饰的属性触发对一个装饰的更改。例如,下面的演示使用标签的 [data-shrink=true]` 属性使后缀在标签处于收缩状态时可见(通过不透明度)。
尺寸
想要更小的输入框?使用 size
属性。
通过在外部渲染标签,可以进一步减小 filled
变体输入的高度。
外边距
`margin` 属性可用于更改文本字段的垂直间距。使用 none
(默认)不会将外边距应用于 FormControl
,而 dense
和 normal
会应用。
全宽
`fullWidth` 可用于使输入框占据其容器的完整宽度。
非受控 vs. 受控
组件可以是受控的或非受控的。
组件
`TextField` 由更小的组件(FormControl
、Input
、FilledInput
、InputLabel
、OutlinedInput
和 FormHelperText
)组成,您可以直接利用这些组件来显著自定义您的表单输入。
您可能还注意到,某些原生 HTML 输入属性在 TextField
组件中缺失。这是故意的。该组件负责处理最常用的属性。然后,由用户使用以下演示中显示的底层组件。不过,如果您想避免一些样板代码,仍然可以使用 slotProps.htmlInput
(以及 slotProps.input
、slotProps.inputLabel
属性)。
颜色
`color` 属性更改文本字段在聚焦时的突出显示颜色。
使用主题样式覆盖 API
使用 styleOverrides
键来更改 Material UI 注入到 DOM 中的任何样式。有关更多详细信息,请参阅主题样式覆盖文档。
自定义不仅仅限于 CSS。您可以使用组合来构建自定义组件,并为您的应用赋予独特的感觉。下面是一个使用 InputBase
组件的示例,灵感来自 Google Maps。
🎨 如果您正在寻找灵感,可以查看 MUI Treasury 的自定义示例。
`useFormControl`
对于高级自定义用例,公开了一个 useFormControl()
Hook。此 Hook 返回父 FormControl
组件的上下文值。
API
import { useFormControl } from '@mui/material/FormControl';
返回值
`value` (对象)
- `value.adornedStart` (bool):指示子
Input
或Select
组件是否具有开始装饰。 - `value.setAdornedStart` (func):`adornedStart` 状态值的 Setter 函数。
- `value.color` (string):正在使用的主题颜色,继承自
FormControl
color
属性。 - `value.disabled` (bool):指示组件是否以禁用状态显示,继承自
FormControl
disabled
属性。 - `value.error` (bool):指示组件是否以错误状态显示,继承自
FormControl
error
属性 - `value.filled` (bool):指示输入是否已填充
- `value.focused` (bool):指示组件及其子组件是否以聚焦状态显示
- `value.fullWidth` (bool):指示组件是否占据其容器的完整宽度,继承自
FormControl
fullWidth
属性 - `value.hiddenLabel` (bool):指示标签是否被隐藏,继承自
FormControl
hiddenLabel
属性 - `value.required` (bool):指示标签是否指示输入是必填输入,继承自
FormControl
required
属性 - `value.size` (string):组件的大小,继承自
FormControl
size
属性 - `value.variant` (string):
FormControl
组件及其子组件正在使用的变体,继承自FormControl
variant
属性 - `value.onBlur` (func):应在输入失焦时调用
- `value.onFocus` (func):应在输入聚焦时调用
- `value.onEmpty` (func):应在输入为空时调用
- `value.onFilled` (func):应在输入已填充时调用
示例
性能
自动填充关键帧的全局样式分别在每次挂载和卸载时注入和移除。如果您一次加载大量文本字段组件,则最好通过在 MuiInputBase
中启用 disableInjectingGlobalStyles
来更改此默认行为。请确保在应用程序顶部注入自动填充关键帧的 GlobalStyles
。
import { GlobalStyles, createTheme, ThemeProvider } from '@mui/material';
const theme = createTheme({
components: {
MuiInputBase: {
defaultProps: {
disableInjectingGlobalStyles: true,
},
},
},
});
export default function App() {
return (
<ThemeProvider theme={theme}>
<GlobalStyles
styles={{
'@keyframes mui-auto-fill': { from: { display: 'block' } },
'@keyframes mui-auto-fill-cancel': { from: { display: 'block' } },
}}
/>
...
</ThemeProvider>
);
}
局限性
Shrink 效果
输入标签的“shrink”状态并不总是正确的。输入标签应该在输入显示内容后立即收缩。在某些情况下,我们无法确定“shrink”状态(数字输入、日期时间输入、Stripe 输入)。您可能会注意到重叠。
为了解决这个问题,您可以强制标签的“shrink”状态。
<TextField slotProps={{ inputLabel: { shrink: true } }} />
或
<InputLabel shrink>Count</InputLabel>
浮动标签
浮动标签是绝对定位的。它不会影响页面的布局。请确保输入框大于标签以正确显示。
type="number"
如果您需要具有数字验证的文本字段,可以使用 MUI Base 的 Number Input 代替。
您可以关注此 GitHub issue 以跟踪将 Number Input 组件引入 Material UI 的进度。
辅助文本
辅助文本属性会影响文本字段的高度。如果两个文本字段并排放置,一个带有辅助文本,另一个没有,它们将具有不同的高度。例如
请输入您的姓名
可以通过将空格字符传递给 helperText
属性来解决此问题
请输入您的姓名
与第三方输入库集成
您可以使用第三方库来格式化输入。您必须使用 inputComponent
属性提供 <input>
元素的自定义实现。
以下演示使用 react-imask 和 react-number-format 库。相同的概念可以应用于例如 react-stripe-element。
提供的输入组件应公开一个 ref,其值实现以下接口
interface InputElement {
focus(): void;
value?: string;
}
const MyInputComponent = React.forwardRef((props, ref) => {
const { component: Component, ...other } = props;
// implement `InputElement` interface
React.useImperativeHandle(ref, () => ({
focus: () => {
// logic to focus the rendered component from 3rd party belongs here
},
// hiding the value e.g. react-stripe-elements
}));
// `Component` will be your `SomeThirdPartyComponent` from below
return <Component {...other} />;
});
// usage
<TextField
slotProps={{
input: {
inputComponent: MyInputComponent,
inputProps: {
component: SomeThirdPartyComponent,
},
},
}}
/>;
可访问性
为了使文本字段可访问,**输入应链接到标签和辅助文本**。底层的 DOM 节点应具有以下结构
<div class="form-control">
<label for="my-input">Email address</label>
<input id="my-input" aria-describedby="my-helper-text" />
<span id="my-helper-text">We'll never share your email.</span>
</div>
- 如果您正在使用
TextField
组件,您只需提供一个唯一的id
,除非您仅在客户端使用TextField
。在 UI 水合之前,没有显式id
的TextField
将不会有相关的标签。 - 如果您正在组合组件
<FormControl>
<InputLabel htmlFor="my-input">Email address</InputLabel>
<Input id="my-input" aria-describedby="my-helper-text" />
<FormHelperText id="my-helper-text">We'll never share your email.</FormHelperText>
</FormControl>
补充项目
对于更高级的用例,您或许可以利用
- react-hook-form-mui:Material UI 和 react-hook-form 的结合。
- formik-material-ui:用于将 Material UI 与 formik 结合使用的绑定。
- mui-rff:用于将 Material UI 与 React Final Form 结合使用的绑定。
- @ui-schema/ds-material 用于将 Material UI 与 UI Schema 结合使用的绑定。JSON Schema 兼容。
无样式
使用 Base UI 文本字段 完全掌控组件的设计,无需覆盖 Material UI 或 Joy UI 样式。此无样式版本的组件是需要重度自定义且捆绑包更小的理想选择。
API
请参阅下面的文档,以获得此处提及的组件的所有可用属性和类的完整参考。