Текстовое поле (Text Field)
Текстовые поля позволяют пользователям вводить и редактировать текст.
Текстовые поля позволяют пользователям вводить текст в пользовательский интерфейс. Они обычно появляются в формах и диалогах.
Базовое текстовое поле
Компонент-обертка TextField
представляет собой полноценный элемент формы, включающий подпись (label), поле для ввода (input) и подсказку (help text). Он имеет три варианта: с обводкой (по умолчанию), заполненный и стандартный.
Примечание: Стандартный вариант TextField
больше не документирован в Material Design guidelines (вот почему), но MUI будет продолжать его поддерживать.
Свойства формы
Поддерживаются стандартные атрибуты формы, например, required
, disabled
, type
, и т.д., а также helperText
, который используется для предоставления контекста о вводимом поле, например, о том, как оно будет использоваться.
Валидация
Свойство error
включает или выключает состояние ошибки. Затем можно воспользоваться свойством helperText
, чтобы сообщить пользователю об ошибке.
Многострочное поле
Свойство multiline
преобразует текстовое поле в элемент TextareaAutosize. Если не установлено свойство rows
, высота текстового поля динамически соответствует его содержимому (с помощью TextareaAutosize). Чтобы ограничить высоту, можно использовать свойства minRows
и maxRows
.
Выбор
Свойство select
заставляет текстовое поле использовать компонент Select внутри поля.
Дополнительные элементы
Основной способ добавить дополнительный элемент в поле - с помощью InputAdornment
. Его можно использовать для добавления префикса (до ввода), суффикса (после ввода) или действия. Например, можно добавить кнопку-иконку, которая будет прятать или показывать пароль.
kg
kg
Weight
$
kg
kg
Weight
$
kg
kg
Weight
$
Вариант filled
можно сделать еще меньше, если переместить подпись.
Отступ
Свойство margin
можно использовать для изменения вертикального отступа текстового поля. Использование none
(по умолчанию) не добавляет отступ к FormControl
, тогда как dense
и normal
добавляют.
Полная ширина
Свойство fullWidth
можно использовать для того, чтобы поле занимало всю ширину своего контейнера.
Неуправляемые (uncontrolled) и управляемые (controlled) поля
Компонент может быть управляемым или неуправляемым.
Компоненты
TextField
состоит из меньших компонентов (FormControl
, Input
, FilledInput
, InputLabel
, OutlinedInput
, и FormHelperText
), которые вы можете использовать напрямую, если хотите кастомизировать текстовое поле.
Вы также могли заметить, что в компоненте TextField
отсутствуют некоторые нативные свойства элемента "input" из HTML. Это специально. Компонент сам заботится о наиболее часто используемых свойствах. Затем пользователю остается использовать базовый компонент, показанный в следующем демонстрационном примере. Тем не менее, вы можете использовать inputProps
(и свойства InputProps
, InputLabelProps
), если вы хотите избежать шаблонного кода.
Кастомизация
Вот несколько примеров кастомизации компонента. Подробнее об этом можно узнать на странице документации по переопределениям.
Кастомизация не ограничивается CSS. Вы можете использовать композицию для создания особенных компонентов и придания вашему приложению уникальности. Ниже приведен пример с использованием компонента InputBase
, вдохновленный Google Maps.
🎨 Если вы ищете вдохновение, вы можете посмотреть примеры кастомизации MUI Treasury.
useFormControl
Для расширенной кастомизации используется хук useFormControl()
. Этот хук возвращает значение контекста родительского компонента FormControl
.
API
import { useFormControl } from '@mui/material/FormControl';
Возвращает
value
(object):
value.adornedStart
(bool): Указывает, имеет ли дочерний компонентInput
илиSelect
дополнительный элемент (adornment) в начале.value.setAdornedStart
(func): Функция-сеттер для состоянияadornedStart
.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): Функция будет вызываться, когда поле становится заполненным
Пример
Ограничения
Сжатие подписи (shrink)
Состояние подписи "shrink" не всегда корректно. Предполагается, что подпись сжимается, как только в поле что-то введено. В некоторых обстоятельствах мы не можем определить состояние "сжатия" (ввод числа, ввод даты, ввод Stripe). Вы можете заметить перекрытие.
Чтобы обойти эту проблему, можно принудительно установить состояние "сжатия" для подписи.
<TextField InputLabelProps={{ shrink: true }} />
или
<InputLabel shrink>Количество</InputLabel>
Плавающая подпись
Плавающая подпись позиционирована абсолютно. Она не повлияет на макет (layout) страницы. Для правильного отображения убедитесь, что поле больше, чем подпись.
type="number"
Поля с type="number" имеют потенциальные проблемы с удобством использования:
- Разрешают некоторые нецифровые символы ('e', '+', '-', '.') и без предупреждения выкидывают другие
- Использование прокрутки для увеличения/уменьшения числа может привести к случайным и труднозаметным изменениям
и многое другое - смотрите эту статью команды GOV.UK Design System для более подробного объяснения.
Для валидации чисел одной из возможных альтернатив является использование стандартного типа ввода type="text" с атрибутом pattern, например:
<TextField inputProps={{ inputMode: 'numeric', pattern: '[0-9]*' }} />
В будущем, возможно, мы предоставим компонент для ввода чисел.
Подсказка
Добавление подсказки влияет на высоту текстового поля. Если два текстовых поля расположены рядом, одно с подсказкой, а другое без него, они будут иметь разную высоту. Например:
Please enter your name
Это можно исправить, передав пробел в свойстве helperText
:
Please enter your name
Интеграция со сторонними библиотеками
Для форматирования поля можно использовать сторонние библиотеки. Вы должны предоставить свою реализацию элемента <input>
со свойством inputComponent
.
В следующем демонстрационном примере используются библиотеки 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;
// имплементируем интерфейс `InputElement`
React.useImperativeHandle(ref, () => ({
focus: () => {
// здесь надо фокусировать использованный сторонний компонент
},
// прячем значение, например react-stripe-elements
}));
// `Component` будет вашим `SomeThirdPartyComponent`
return <Component {...other} />;
});
// использование
<TextField
InputProps={{
inputComponent: MyInputComponent,
inputProps: {
component: SomeThirdPartyComponent,
},
}}
/>;
Доступность
Чтобы текстовое поле было доступным (accessible), поле должно быть связано с подписью и подсказкой. Соответствующие узлы DOM должны иметь такую структуру:
<div class="form-control">
<label for="my-input">Электронная почта</label>
<input id="my-input" aria-describedby="my-helper-text" />
<span id="my-helper-text">Мы никому не дадим вашу почту.</span>
</div>
- Если вы используете компонент
TextField
, вам просто нужно предоставить уникальныйid
, если вы не используетеTextField
только на стороне клиента (client-side). Пока UI не будет гидрирован (hydrated),TextField
без явногоid
не будет иметь связанных подписей. - Если вы составляете компонент из базовых компонентов:
<FormControl>
<InputLabel htmlFor="my-input">Электронная почта</InputLabel>
<Input id="my-input" aria-describedby="my-helper-text" />
<FormHelperText id="my-helper-text">Мы никому не дадим вашу почту.</FormHelperText>
</FormControl>
Дополнительно
Для более сложных случаев использования вы можете воспользоваться:
- react-hook-form: React-хук для валидации формы.
- react-hook-form-mui: объединение MUI и react-hook-form.
- formik-material-ui: Использование MUI с formik.
- redux-form-material-ui: Использование MUI с Redux Form.
- mui-rff: Использование MUI с React Final Form.
- @ui-schema/ds-material Использование Material UI с UI Schema. Совместимо с JSON Schema.
- @data-driven-forms/mui-component-mapper: Использование Material UI с Data Driven Forms.
Unstyled
The component also comes with an unstyled version. It's ideal for doing heavy customizations and minimizing bundle size.