Mantine: компоненты ввода — от текста до файлов
В предыдущих уроках мы научились работать с формами и валидацией. Теперь пришло время познакомиться со всем арсеналом компонентов ввода, которые предлагает Mantine. В этом уроке мы разберем все основные типы полей: от простых TextInput и NumberInput до сложных Select, FileInput и MaskInput.
Базовые компоненты для текста
TextInput – самое частое поле
TextInput — базовое поле для ввода текста. Оно поддерживает все стандартные пропсы: label, description, error, placeholder, withAsterisk и другие.
import { TextInput } from '@mantine/core';
function BasicTextInput() {
return (
<>
<TextInput
label="Имя пользователя"
placeholder="Введите имя"
description="Ваше имя будет видно другим пользователям"
withAsterisk
/>
<TextInput
label="Скрытый пароль"
type="password"
placeholder="Придумайте пароль"
mt="md"
/>
<TextInput
label="Ошибка"
placeholder="Ошибочное поле"
error="Поле обязательно для заполнения"
mt="md"
/>
<TextInput
label="Успех"
placeholder="Валидное поле"
rightSection="✅"
mt="md"
/>
</>
);
}
Textarea – многострочный ввод
Textarea — это TextInput с возможностью ввода нескольких строк текста. Управляется через проп autosize и minRows/maxRows.
import { Textarea } from '@mantine/core';
function CommentArea() {
return (
<>
<Textarea
label="Комментарий"
placeholder="Напишите ваш отзыв..."
minRows={3}
maxRows={6}
autosize
/>
<Textarea
label="Фиксированная высота"
placeholder="Это поле не растягивается"
rows={4}
mt="md"
/>
</>
);
}
PasswordInput – поле с маскировкой
PasswordInput наследует TextInput, но добавляет кнопку для переключения видимости пароля.
import { PasswordInput } from '@mantine/core';
function PasswordField() {
return (
<PasswordInput
label="Пароль"
placeholder="Введите пароль"
withAsterisk
visibilityToggleButtonLabel="Показать/скрыть пароль"
/>
);
}
Числовые поля и диапазоны
NumberInput – работа с числами
NumberInput автоматически преобразует ввод в число и поддерживает минимальные/максимальные значения.
import { NumberInput } from '@mantine/core';
function NumberFields() {
return (
<>
<NumberInput
label="Возраст"
placeholder="Ваш возраст"
min={0}
max={120}
withAsterisk
/>
<NumberInput
label="Цена"
placeholder="Укажите цену"
prefix="$"
decimalScale={2}
thousandSeparator=" "
mt="md"
/>
<NumberInput
label="Проценты"
placeholder="Введите проценты"
suffix="%"
step={0.5}
min={0}
max={100}
mt="md"
/>
</>
);
}
Slider – ползунок для диапазонов
Slider отлично подходит для выбора значений из диапазона, например, для рейтинга или громкости.
import { Slider, RangeSlider } from '@mantine/core';
function SliderFields() {
return (
<>
<Slider
label="Громкость"
min={0}
max={100}
step={5}
defaultValue={50}
marks={[
{ value: 0, label: '0%' },
{ value: 50, label: '50%' },
{ value: 100, label: '100%' },
]}
/>
<RangeSlider
label="Диапазон цен"
min={0}
max={1000}
step={50}
defaultValue={[200, 800]}
mt="xl"
/>
</>
);
}
Выбор из списка
Select – одиночный выбор
Select позволяет выбрать один вариант из выпадающего списка. Данные передаются через проп data в формате { value: string; label: string }.
import { Select } from '@mantine/core';
function SelectExample() {
const frameworks = [
{ value: 'react', label: 'React' },
{ value: 'vue', label: 'Vue.js' },
{ value: 'angular', label: 'Angular' },
{ value: 'svelte', label: 'Svelte' },
];
return (
<Select
label="Любимый фреймворк"
placeholder="Выберите фреймворк"
data={frameworks}
withAsterisk
searchable
nothingFoundMessage="Ничего не найдено"
/>
);
}
MultiSelect – множественный выбор
MultiSelect позволяет выбирать несколько вариантов. Отлично подходит для тегов, категорий или любых множественных выборов.
import { MultiSelect } from '@mantine/core';
function MultiSelectExample() {
const technologies = [
{ value: 'react', label: 'React' },
{ value: 'vue', label: 'Vue.js' },
{ value: 'angular', label: 'Angular' },
{ value: 'svelte', label: 'Svelte' },
{ value: 'nextjs', label: 'Next.js' },
{ value: 'nuxt', label: 'Nuxt.js' },
];
return (
<MultiSelect
label="Технологии, которые вы знаете"
placeholder="Выберите технологии"
data={technologies}
searchable
clearable
withAsterisk
nothingFoundMessage="Ничего не найдено"
/>
);
}
NativeSelect – нативный select
Если вам нужен стандартный <select> без стилизации Mantine, используйте NativeSelect.
import { NativeSelect } from '@mantine/core';
function NativeSelectExample() {
return (
<NativeSelect
label="Выберите страну"
data={['Россия', 'США', 'Великобритания', 'Германия', 'Франция']}
/>
);
}
Переключатели и чекбоксы
Checkbox – флажок
Checkbox используется для согласия, подтверждения или включения опций.
import { Checkbox, CheckboxGroup } from '@mantine/core';
function CheckboxExample() {
return (
<>
<Checkbox
label="Я согласен с условиями использования"
withAsterisk
/>
<Checkbox
label="Запомнить меня"
description="Вы не будете входить заново при каждом посещении"
mt="md"
/>
<CheckboxGroup
label="Выберите языки программирования"
description="Какие языки вы знаете?"
withAsterisk
defaultValue={['javascript']}
mt="xl"
>
<Checkbox value="javascript" label="JavaScript" />
<Checkbox value="python" label="Python" />
<Checkbox value="typescript" label="TypeScript" />
<Checkbox value="java" label="Java" />
<Checkbox value="csharp" label="C#" />
</CheckboxGroup>
</>
);
}
Radio – переключатели с исключением
Radio используется, когда нужно выбрать ровно один вариант из группы.
import { Radio, RadioGroup } from '@mantine/core';
function RadioExample() {
return (
<RadioGroup
label="Выберите уровень сложности"
description="Выберите один вариант"
withAsterisk
defaultValue="middle"
>
<Radio value="beginner" label="Начинающий" />
<Radio value="middle" label="Средний" />
<Radio value="advanced" label="Продвинутый" />
<Radio value="expert" label="Эксперт" />
</RadioGroup>
);
}
Switch – тумблер (переключатель)
Switch — это современная альтернатива чекбоксу для включения/отключения опций.
import { Switch, SwitchGroup } from '@mantine/core';
function SwitchExample() {
return (
<>
<Switch
label="Включить уведомления"
description="Получать уведомления на email"
/>
<Switch
label="Темная тема"
mt="md"
color="blue"
/>
<SwitchGroup
label="Настройки уведомлений"
description="Выберите типы уведомлений"
defaultValue={['email']}
mt="xl"
>
<Switch value="email" label="Email" />
<Switch value="push" label="Push-уведомления" />
<Switch value="sms" label="SMS" />
</SwitchGroup>
</>
);
}
Собери свой код. Запусти сайт!
От наброска на салфетке до первого работающего лендинга. Наш онлайн-курс «Веб-верстка с нуля и до профессионала» — это интенсивный трек, где ты не будешь зубрить теорию, а с первого дня начнешь превращать идеи в чистый HTML и CSS.
Собери свой первый проект под руководством практикующих разработчиков.
Специализированные компоненты
FileInput – загрузка файлов
FileInput позволяет пользователю выбирать файлы с диска. Поддерживает ограничения по размеру и типам файлов.
import { FileInput } from '@mantine/core';
function FileInputExample() {
return (
<FileInput
label="Загрузите резюме"
placeholder="Выберите файл"
accept=".pdf,.doc,.docx"
withAsterisk
clearable
description="Поддерживаются форматы PDF, DOC, DOCX"
// Для ограничения размера используйте валидацию
/>
);
}
MaskInput – форматированный ввод
MaskInput — это компонент для ввода данных по маске. Отлично подходит для телефонов, кредитных карт, дат и других форматированных данных .
Встроенные токены маски
| Токен | Описание |
|---|---|
9 |
Любая цифра [0-9] |
a |
Любая буква [A-Za-z] |
A |
Заглавная буква [A-Z] |
* |
Любой алфавитно-цифровой символ |
# |
Цифра или знак [-+0-9] |
import { MaskInput } from '@mantine/core';
function MaskInputExample() {
return (
<>
<MaskInput
label="Номер телефона"
placeholder="+7 (999) 999-99-99"
mask="+7 (999) 999-99-99"
withAsterisk
/>
<MaskInput
label="Серия паспорта"
placeholder="99 99 999999"
mask="99 99 999999"
mt="md"
/>
<MaskInput
label="Дата рождения"
placeholder="ДД.ММ.ГГГГ"
mask="99.99.9999"
mt="md"
/>
<MaskInput
label="Имя (заглавные буквы)"
placeholder="Введите имя заглавными"
mask="AAA AAA"
mt="md"
/>
</>
);
}
Rating – рейтинг
Rating позволяет пользователю оценить что-либо по шкале от 1 до 5 (или до любого другого числа).
import { Rating, Box, Text } from '@mantine/core';
import { useState } from 'react';
function RatingExample() {
const [value, setValue] = useState(0);
return (
<>
<Box>
<Text fw={500} mb={5}>Оцените наш сервис</Text>
<Rating
value={value}
onChange={setValue}
fractions={2}
count={5}
/>
{value > 0 && <Text size="sm" c="dimmed" mt={5}>Ваша оценка: {value}</Text>}
</Box>
<Box mt="xl">
<Text fw={500} mb={5}>Рейтинг (только чтение)</Text>
<Rating
value={4.5}
readOnly
fractions={2}
/>
</Box>
</>
);
}
Продвинутые компоненты
ColorInput – выбор цвета
ColorInput предоставляет удобный интерфейс для выбора цвета — как из палитры, так и с помощью hex-кода.
import { ColorInput } from '@mantine/core';
function ColorInputExample() {
return (
<ColorInput
label="Выберите цвет"
placeholder="Введите hex или выберите из палитры"
format="hex"
/>
);
}
PinInput – ввод PIN-кода
PinInput — это компонент для ввода коротких кодов, например, для подтверждения по SMS или двухфакторной аутентификации.
import { PinInput } from '@mantine/core';
function PinInputExample() {
return (
<>
<PinInput
length={6}
placeholder=""
label="Введите код подтверждения"
description="Код отправлен на ваш телефон"
withAsterisk
oneTimeCode
type="number"
/>
<PinInput
length={4}
placeholder="•"
type="number"
mt="xl"
/>
</>
);
}
Использование с useForm
Все компоненты ввода отлично интегрируются с useForm через getInputProps. Вот полный пример:
import { useForm } from '@mantine/form';
import {
TextInput,
NumberInput,
Select,
Checkbox,
FileInput,
MaskInput,
Button,
Box,
Group,
} from '@mantine/core';
interface FormValues {
name: string;
age: number;
country: string;
agree: boolean;
resume: File | null;
phone: string;
}
function CompleteForm() {
const form = useForm<FormValues>({
mode: 'uncontrolled',
initialValues: {
name: '',
age: 0,
country: '',
agree: false,
resume: null,
phone: '',
},
validate: {
name: (value) => (value.length < 2 ? 'Имя должно быть минимум 2 символа' : null),
age: (value) => (value < 18 ? 'Вам должно быть минимум 18 лет' : null),
country: (value) => (!value ? 'Выберите страну' : null),
agree: (value) => (!value ? 'Необходимо согласие' : null),
resume: (value) => (!value ? 'Загрузите резюме' : null),
phone: (value) => (value.length < 10 ? 'Введите полный номер телефона' : null),
},
});
return (
<Box component="form" onSubmit={form.onSubmit((values) => console.log(values))}>
<TextInput
label="Имя"
placeholder="Введите имя"
withAsterisk
key={form.key('name')}
{...form.getInputProps('name')}
/>
<NumberInput
label="Возраст"
placeholder="Ваш возраст"
min={0}
max={120}
withAsterisk
mt="md"
key={form.key('age')}
{...form.getInputProps('age')}
/>
<Select
label="Страна"
placeholder="Выберите страну"
data={[
{ value: 'ru', label: 'Россия' },
{ value: 'us', label: 'США' },
{ value: 'uk', label: 'Великобритания' },
]}
withAsterisk
mt="md"
key={form.key('country')}
{...form.getInputProps('country')}
/>
<MaskInput
label="Телефон"
placeholder="+7 (999) 999-99-99"
mask="+7 (999) 999-99-99"
withAsterisk
mt="md"
key={form.key('phone')}
{...form.getInputProps('phone')}
/>
<FileInput
label="Резюме"
placeholder="Выберите файл"
accept=".pdf,.doc,.docx"
withAsterisk
mt="md"
key={form.key('resume')}
{...form.getInputProps('resume')}
/>
<Checkbox
label="Я согласен с условиями использования"
withAsterisk
mt="md"
key={form.key('agree')}
{...form.getInputProps('agree', { type: 'checkbox' })}
/>
<Group justify="flex-end" mt="xl">
<Button type="submit">Отправить</Button>
</Group>
</Box>
);
}
Итоги
Сегодня вы познакомились со всеми основными компонентами ввода Mantine:
- Текстовые поля:
TextInput,Textarea,PasswordInput - Числовые поля:
NumberInput,Slider,RangeSlider - Выбор:
Select,MultiSelect,NativeSelect - Переключатели:
Checkbox,Radio,Switch - Специализированные:
FileInput,MaskInput,Rating,ColorInput,PinInput
Что должно быть в вашем проекте после этого урока:
- Создана форма, содержащая как минимум 5 различных типов полей ввода
- Использован
MaskInputдля телефона или другой маски - Реализован выбор из списка через
SelectилиMultiSelect - Добавлены переключатели (
CheckboxилиSwitch) с валидацией - Настроена загрузка файлов через
FileInput - Все поля интегрированы с
useFormи проходят валидацию
В следующем уроке мы перейдем к кнопкам и элементам обратной связи — разберем Button, ActionIcon, Loader и системы уведомлений.