Модальные окна и уведомления в Mantine UI
Модальные окна и уведомления — два самых частых способа привлечь внимание пользователя к важному событию в интерфейсе. Mantine предлагает для этого готовый компонент Modal и отдельный пакет @mantine/notifications с функцией notifications.show(). В этом уроке разберём, как быстро подключить оба инструмента, настроить их внешний вид и научиться управлять уведомлениями по ходу работы приложения.
Зачем нужны модальные окна и уведомления
Modal блокирует остальной интерфейс модальным слоем поверх контента, пока пользователь не примет решение: подтвердит действие, заполнит форму или просто закроет окно. Уведомление, наоборот, появляется ненавязчиво в углу экрана, не мешает продолжать работу и обычно исчезает само через несколько секунд.
Когда применять модальные окна
- Подтверждение опасного действия, например удаления записи
- Быстрое редактирование данных без перехода на отдельную страницу
- Предпросмотр изображения, документа или карточки товара
- Сбор дополнительной информации перед продолжением сценария
Уведомления лучше подходят для информирования о результате действий, которые выполняются в фоне: запрос сохранился, файл загрузился, произошла ошибка сети. Пользователь может продолжать работать с интерфейсом, а короткое сообщение просто подтверждает, что операция завершилась успешно или потребовала внимания.
Компонент Modal основы использования
Компонент Modal входит в основной пакет @mantine/core, поэтому устанавливать что-то дополнительно не нужно — он доступен сразу после подключения MantineProvider. Modal — управляемый компонент: он не хранит своё состояние сам, а получает булево значение opened и функцию onClose, которые вы задаёте через useState в родительском компоненте. Ниже — минимальный пример модального окна с подтверждением действия.
import { useState } from 'react';
import { Modal, Button } from '@mantine/core';
function ConfirmModal() {
const [opened, setOpened] = useState(false);
return (
<>
<Modal opened={opened} onClose={() => setOpened(false)} title='Подтверждение'>
<p>Вы уверены, что хотите продолжить?</p>
</Modal>
<Button onClick={() => setOpened(true)}>Открыть модалку</Button>
</>
);
}
Заголовок и содержимое
Пропс title отвечает за заголовок окна, а всё, что вы поместите между открывающим и закрывающим тегом Modal, окажется в теле окна. Кнопка закрытия в правом верхнем углу добавляется автоматически: чтобы убрать её, передайте пропс withCloseButton со значением false.
Формы внутри Modal
Одно из самых частых применений Modal — форма быстрого редактирования: пользователь нажимает кнопку, поверх страницы появляется окно с полями формы, а после успешной отправки вызывается onClose и стейт формы сбрасывается. Такой подход избавляет от необходимости заводить отдельный маршрут только ради одной формы и хорошо сочетается с хуком useForm из предыдущих уроков.
Настройка внешнего вида и поведения Modal
У Modal много пропсов для тонкой настройки внешнего вида и поведения. Пропс size задаёт ширину окна — от предустановленных значений xs–xl до произвольного значения в пикселях, а centered вертикально центрирует окно на экране вместо привязки к верхнему краю.
Через radius меняется скругление углов, а overlayProps отвечает за подложку позади окна: можно настроить прозрачность через backgroundOpacity и добавить размытие фона параметром blur. Если нужно упростить поведение — например, запретить закрытие окна кликом по фону, — пригодятся пропсы closeOnClickOutside и closeOnEscape.
<Modal
opened={opened}
onClose={close}
title='Удаление записи'
size='lg'
centered
radius='md'
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
>
<p>Это действие нельзя отменить.</p>
</Modal>
Не храните состояние нескольких модальных окон в одном булевом флаге. Заведите отдельный useState для каждого окна или используйте хук useDisclosure из @mantine/hooks — он сразу возвращает пару opened и объект с методами open, close и toggle, а код читается понятнее ручного булева флага.
Система уведомлений подключаем @mantine/notifications
Modal, система уведомлений живёт в отдельном пакете — @mantine/notifications — и требует установки.После установки пакет добавляют один раз рядом с MantineProvider, оборачивая приложение компонентом Notifications: он рендерит контейнер, в котором будут появляться все уведомления, и не требует ручного управления списком.
npm install @mantine/notifications
import { MantineProvider } from '@mantine/core';
import { Notifications } from '@mantine/notifications';
import '@mantine/core/styles.css';
import '@mantine/notifications/styles.css';
function App() {
return (
<MantineProvider>
<Notifications position='top-right' />
{/* остальное приложение */}
</MantineProvider>
);
}
После того как Notifications подключён, показать уведомление можно из любого места приложения одним вызовом функции notifications.show() — без прокидывания пропсов через дерево компонентов. Достаточно передать объект с текстом и, при желании, цветовым акцентом.
import { notifications } from '@mantine/notifications';
function saveUser() {
notifications.show({
title: 'Готово',
message: 'Данные пользователя сохранены',
color: 'teal',
});
}
Чаще всего в объект настроек передают такие параметры:
| Параметр | Назначение |
|---|---|
title |
Заголовок уведомления |
message |
Основной текст уведомления |
color |
Цветовой акцент, например teal для успеха или red для ошибки |
autoClose |
Через сколько миллисекунд уведомление закроется само, либо false, чтобы не закрывать автоматически |
icon |
Иконка слева от текста, например индикатор загрузки или галочка |
Собери свой код. Запусти сайт!
От наброска на салфетке до первого работающего лендинга. Наш онлайн-курс «Веб-верстка с нуля и до профессионала» — это интенсивный трек, где ты не будешь зубрить теорию, а с первого дня начнешь превращать идеи в чистый HTML и CSS.
Собери свой первый проект под руководством практикующих разработчиков.
Управление уведомлениями обновление скрытие и типы
Иногда одного статичного уведомления недостаточно — например, нужно сначала показать индикатор загрузки, а затем заменить его результатом операции. Для этого каждому уведомлению можно задать собственный id и позже вызвать notifications.update() с тем же id, чтобы изменить текст, цвет и иконку уже показанного уведомления вместо создания нового. Скрыть уведомление раньше времени поможет notifications.hide(id), а очистить сразу все — notifications.clean().
import { notifications } from '@mantine/notifications';
async function saveUser(data: UserData) {
const id = 'save-user';
notifications.show({
id,
loading: true,
title: 'Сохраняем',
message: 'Отправляем данные на сервер',
autoClose: false,
withCloseButton: false,
});
try {
await api.saveUser(data);
notifications.update({
id,
color: 'teal',
title: 'Готово',
message: 'Данные успешно сохранены',
loading: false,
autoClose: 3000,
});
} catch (error) {
notifications.update({
id,
color: 'red',
title: 'Ошибка',
message: 'Не удалось сохранить данные',
loading: false,
autoClose: 3000,
});
}
}
Если запускаете уведомление внутри useEffect, храните его id в useRef, а не в обычном стейте: значение из useRef не вызывает повторный рендер и не теряется между обновлениями компонента, а значит вы не покажете одно и то же уведомление дважды.
Итоги
В этом уроке мы разобрали два инструмента для взаимодействия с пользователем: модальное окно Modal для сценариев, требующих осознанного решения, и систему уведомлений notifications.show() для ненавязчивых сообщений о результате действий. Теперь вы умеете открывать и настраивать модальные окна, подключать провайдер уведомлений и обновлять уведомления по ходу выполнения асинхронных операций.
В следующем уроке разберём работу со списками данных — компоненты Table, Badge и Avatar.