Маски ввода и форматирование

Библиотека MUI (Material-UI) предоставляет гибкие инструменты для работы с формами, полями ввода и компонентами, требующими форматирования данных. Маски ввода позволяют пользователю вводить данные в строго определённом формате, снижая вероятность ошибок и улучшая пользовательский опыт.


Компонент TextField и интеграция с масками

Основной строительный блок ввода в MUI — компонент TextField. Для реализации масок ввода его можно комбинировать с внешними библиотеками, например react-input-mask. Маска задаётся через проп inputComponent.

Пример использования:

import React from 'react';
import TextField from '@mui/material/TextField';
import InputMask from 'react-input-mask';

function MaskedInput(props) {
  return (
    <InputMask {...props} mask="9999-9999-9999-9999">
      {(inputProps) => <TextField {...inputProps} label="Номер карты" variant="outlined" />}
    </InputMask>
  );
}

Здесь маска "9999-9999-9999-9999" гарантирует, что пользователь может вводить только цифры в формате банковской карты. Проп inputComponent позволяет интегрировать любое кастомное поле ввода с маской.


Маски для телефонов и дат

Для телефонов и дат особенно полезны шаблоны с динамическим вводом. Например, для телефонного номера формата +7 (999) 999-99-99:

<InputMask mask="+7 (999) 999-99-99" value={phone} onCha nge={handleChange}>
  {(inputProps) => <TextField {...inputProps} label="Телефон" />}
</InputMask>

Для даты можно использовать маску "99/99/9999", что позволит автоматически вставлять символы / при вводе дня, месяца и года.


Форматирование с помощью InputAdornment

MUI предоставляет компонент InputAdornment для визуального форматирования данных внутри поля ввода. Это полезно для валют, процентов и единиц измерения.

Пример с валютой:

<TextField
  label="Сумма"
  InputProps={{
    startAdornment: <InputAdornment position="start">₽</InputAdornment>,
  }}
/>

Пример с процентами:

<TextField
  label="Ставка"
  InputProps={{
    endAdornment: <InputAdornment position="end">%</InputAdornment>,
  }}
/>

InputAdornment не изменяет сам ввод пользователя, а только визуально добавляет элементы, которые помогают ориентироваться при заполнении формы.


Валидация и форматирование числовых данных

Для числовых данных часто требуется не только маска, но и контроль диапазона. MUI предоставляет проп type="number" и inputProps для ограничения:

<TextField
  label="Возраст"
  type="number"
  inputProps={{ min: 0, max: 120 }}
/>

Если требуется более сложное форматирование, можно комбинировать маски с библиотеками вроде react-number-format:

import NumberFormat from 'react-number-format';

function NumberFormatCustom(props) {
  const { inputRef, onChange, ...other } = props;
  return (
    <NumberFormat
      {...other}
      getInputRef={inputRef}
      onValueCha nge={(values) => onChange({ target: { value: values.value } })}
      thousandSeparator=" "
      isNumericString
      prefix="₽"
    />
  );
}

<TextField
  label="Сумма"
  InputProps={{
    inputComponent: NumberFormatCustom,
  }}
/>

Такой подход позволяет автоматически добавлять разделители тысяч, префиксы и управлять форматированием на лету.


Автоформатирование даты с AdapterDateFns

MUI предоставляет компонент DatePicker для выбора даты с встроенным форматированием через адаптеры, например AdapterDateFns:

import { LocalizationProvider, DatePicker } from '@mui/x-date-pickers';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';

<LocalizationProvider dateAdapter={AdapterDateFns}>
  <DatePicker
    label="Дата рождения"
    value={selectedDate}
    onCha nge={(newValue) => setSelectedDate(newValue)}
    inputFormat="dd/MM/yyyy"
    renderInput={(params) => <TextField {...params} />}
  />
</LocalizationProvider>

inputFormat задаёт шаблон отображения даты, а DatePicker автоматически предотвращает ввод недопустимых значений.


Комбинация масок и валидации

Для сложных форм удобно комбинировать маски и кастомную валидацию. Например, проверка номера карты:

function validateCardNumber(value) {
  return /^\d{4}-\d{4}-\d{4}-\d{4}$/.test(value);
}

<TextField
  label="Номер карты"
  value={cardNumber}
  onCha nge={(e) => setCardNumber(e.target.value)}
  error={!validateCardNumber(cardNumber)}
  helperText={!validateCardNumber(cardNumber) ? "Неверный формат карты" : ""}
/>

Такой подход позволяет обеспечить строгие требования к вводу и визуально информировать пользователя о корректности данных.


Динамические маски

Иногда необходимо менять маску в зависимости от контекста. Например, номер телефона может меняться в зависимости от страны:

const masks = {
  RU: "+7 (999) 999-99-99",
  US: "+1 (999) 999-9999"
};

<InputMask mask={masks[country]} value={phone} onCha nge={handleChange}>
  {(inputProps) => <TextField {...inputProps} label="Телефон" />}
</InputMask>

Маска автоматически обновляется при смене страны, сохраняя удобство ввода.


Итоговые рекомендации

  • Использовать TextField с внешними масками для строгого контроля ввода.
  • Для визуального форматирования применять InputAdornment.
  • Для числовых данных и валют — react-number-format или аналогичные библиотеки.
  • Для дат и времени — встроенные DatePicker и TimePicker с адаптерами.
  • Комбинировать маски и валидацию для обеспечения корректности данных на клиентской стороне.
  • Динамические маски позволяют адаптировать ввод под контекст пользователя.

Такой подход обеспечивает удобство, предотвращает ошибки ввода и соответствует принципам Material Design, заложенным в MUI.