Хотите заказать веб-сайт? Связаться с нами

Mantine: компоненты ввода — от текста до файлов

В предыдущих уроках мы научились работать с формами и валидацией. Теперь пришло время познакомиться со всем арсеналом компонентов ввода, которые предлагает Mantine. В этом уроке мы разберем все основные типы полей: от простых TextInput и NumberInput до сложных Select, FileInput и MaskInput.

Mantine: компоненты ввода — от текста до файлов

Базовые компоненты для текста

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:

  1. Текстовые поля: TextInput, Textarea, PasswordInput
  2. Числовые поля: NumberInput, Slider, RangeSlider
  3. Выбор: Select, MultiSelect, NativeSelect
  4. Переключатели: Checkbox, Radio, Switch
  5. Специализированные: FileInput, MaskInput, Rating, ColorInput, PinInput

Что должно быть в вашем проекте после этого урока:

  1. Создана форма, содержащая как минимум 5 различных типов полей ввода
  2. Использован MaskInput для телефона или другой маски
  3. Реализован выбор из списка через Select или MultiSelect
  4. Добавлены переключатели (Checkbox или Switch) с валидацией
  5. Настроена загрузка файлов через FileInput
  6. Все поля интегрированы с useForm и проходят валидацию

В следующем уроке мы перейдем к кнопкам и элементам обратной связи — разберем Button, ActionIcon, Loader и системы уведомлений.

Теги: