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

Модальные окна и уведомления в Mantine UI

Модальные окна и уведомления — два самых частых способа привлечь внимание пользователя к важному событию в интерфейсе. Mantine предлагает для этого готовый компонент Modal и отдельный пакет @mantine/notifications с функцией notifications.show(). В этом уроке разберём, как быстро подключить оба инструмента, настроить их внешний вид и научиться управлять уведомлениями по ходу работы приложения.

Модальные окна и уведомления в Mantine UI

Зачем нужны модальные окна и уведомления

У модального окна и уведомления похожая цель — сообщить пользователю что-то важное, не уводя его со страницы, но разный характер работы.

Modal блокирует остальной интерфейс модальным слоем поверх контента, пока пользователь не примет решение: подтвердит действие, заполнит форму или просто закроет окно. Уведомление, наоборот, появляется ненавязчиво в углу экрана, не мешает продолжать работу и обычно исчезает само через несколько секунд.

Когда применять модальные окна

  1. Подтверждение опасного действия, например удаления записи
  2. Быстрое редактирование данных без перехода на отдельную страницу
  3. Предпросмотр изображения, документа или карточки товара
  4. Сбор дополнительной информации перед продолжением сценария

Уведомления лучше подходят для информирования о результате действий, которые выполняются в фоне: запрос сохранился, файл загрузился, произошла ошибка сети. Пользователь может продолжать работать с интерфейсом, а короткое сообщение просто подтверждает, что операция завершилась успешно или потребовала внимания.

Компонент 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 задаёт ширину окна — от предустановленных значений xsxl до произвольного значения в пикселях, а 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.

Теги: