Перейти к содержимому
v2.5.0
English
Русский
Документация

Dialog

Dialog — составной компонент для модальных оверлеев с частями корня, триггера и содержимого.

Паттерны

Подтверждение действия

Когда использовать:

  • необратимое или значимое действие требует подтверждения

Заметки по композиции:

  • делайте содержимое коротким
  • используйте явные основное и второстепенное действия
  • формулируйте заголовок через последствия

Компромиссы:

  • сильное прерывание повышает безопасность
  • злоупотребление добавляет трения
confirm-action.tsx · 88 строк
import { useId, useState, type CSSProperties } from 'react';
import {
  Button,
  Dialog,
  DialogClose,
  DialogContent,
  DialogTrigger,
  Heading,
  Icon,
  IconButton,
  Text,
} from '@vega-ui/react';

Форма в модальном окне

Когда использовать:

  • небольшой сценарий редактирования должен остаться на текущей странице

Заметки по композиции:

  • делайте форму короткой
  • следите, чтобы закрытие и отправка оставались видимыми

Компромиссы:

  • хорошо подходит для точечных правок
  • плохо подходит для длинных многошаговых форм
form-in-modal.tsx · 100 строк
import { useId, useState, type CSSProperties, type FormEvent } from 'react';
import {
  Button,
  Dialog,
  DialogClose,
  DialogContent,
  DialogTrigger,
  Heading,
  HelperText,
  Icon,
  IconButton,
  Label,

Прокручиваемое модальное содержимое

Когда использовать:

  • содержимое может вырасти больше комфортной высоты модального окна

Заметки по композиции:

  • задайте телу max-height, overflow: auto и overscroll-behavior: contain
  • держите заголовок и действия вне прокручиваемой области

Компромиссы:

  • сохраняет модальную рамку
  • требует продуманной раскладки, чтобы содержимое не оказалось недоступным
scrollable-content-dialog.tsx · 76 строк
import { useId, type CSSProperties } from 'react';
import {
  Button,
  Dialog,
  DialogClose,
  DialogContent,
  DialogTrigger,
  Heading,
  Icon,
  IconButton,
  Text,
} from '@vega-ui/react';

Вложенный шаг подтверждения

Когда использовать:

  • родительскому модальному сценарию нужен ещё небольшой шаг подтверждения

Заметки по композиции:

  • рассматривайте вложенные диалоги как пограничный случай
  • перепроверяйте восстановление фокуса и обработку Escape

Компромиссы:

  • позволяет сохранить контекст родительского сценария
  • быстро повышает сложность оверлеев и доступности
nested-confirm-step.tsx · 101 строка
import { useId, useState, type CSSProperties } from 'react';
import {
  Button,
  Dialog,
  DialogClose,
  DialogContent,
  DialogTrigger,
  Heading,
  Icon,
  IconButton,
  Text,
} from '@vega-ui/react';

Сравнение

Быстрое правило выбора

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

Dialog или Drawer

Используйте Dialog, когда:

  • задача модальная
  • содержимое должно ощущаться центрированным и ограниченным
  • подтверждение или прерывание — часть UX

Используйте Drawer, когда:

  • задача воспринимается как боковая панель
  • раскладке подходит содержимое, прикреплённое к краю

Компромисс:

  • Dialog сильнее и сильнее прерывает работу
  • выдвижная панель (Drawer) просторнее для рабочих сценариев и второстепенного редактирования

Dialog или Sheet

Используйте Dialog, когда:

  • раскладка должна ощущаться как центрированная модальная поверхность
  • основная ментальная модель — ограниченный фокус в духе десктопа

Используйте Sheet, когда:

  • подача должна быть ближе к мобильной или выезжающей шторке (Sheet)

Dialog или Popover

Используйте Dialog, когда:

  • содержимое — модальная задача
  • важны ловушка фокуса и явное закрытие

Используйте Popover, когда:

  • содержимое лёгкое и немодальное

Dialog или Tooltip

Используйте Dialog, когда:

  • содержимое интерактивное или ориентировано на задачу

Используйте Tooltip, когда:

  • содержимое носит только информационный характер

Выбирайте этот компонент, когда

  • пользователь должен явно завершить или закрыть сценарий
  • в содержимом есть поля формы или действия подтверждения
  • модальное прерывание — задуманный UX
  • более строгая ловушка фокуса — часть продуктового контракта

Не выбирайте этот компонент, когда

  • содержимое лёгкое и контекстное
  • оверлей должен оставаться немодальным
  • главное — текст подсказки, а не взаимодействие

Решение проблем

Фокус не возвращается на триггер

Симптом

После закрытия диалога фокус оказывается в неожиданном месте или кажется полностью потерянным.

Вероятная причина

Реальный сценарий с триггером заменён кастомной обёрткой или композицией вложенных оверлеев.

Как проверить

  • откройте диалог с клавиатуры
  • закройте его через Escape или кнопку закрытия
  • проверьте, куда попадает фокус

Решение

  • сначала вернитесь к стандартной композиции с DialogTrigger
  • перепроверьте именно тот стек вложенных оверлеев

Вложенные диалоги ведут себя нестабильно

Симптом

Обработка Escape, наложение или перемещение фокуса работают непоследовательно, когда открыто несколько диалогов.

Вероятная причина

Вложенные диалоги рассматривались как изолированные оверлеи, а не как интеграционный случай на уровне стека.

Как проверить

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

Решение

  • сохраняйте стандартную структуру частей Dialog
  • перепроверяйте вложенные оверлеи как единый интеграционный сценарий

Длинное содержимое выталкивает действия за пределы экрана

Симптом

Пользователям трудно добраться до действий, когда тело диалога растёт.

Вероятная причина

Для контейнера содержимого не задана стратегия прокрутки.

Как проверить

  • заполните диалог длинным содержимым
  • проверьте на меньших высотах вьюпорта

Решение

  • сделайте внутреннюю область содержимого прокручиваемой
  • по возможности держите шапку и важные действия вне прокручиваемой области

Диалог открывается, но выглядит безымянным

Симптом

Диалог виден, но пользователям не хватает понятной ориентации.

Вероятная причина

У DialogContent нет aria-labelledby или aria-label, либо заголовок, на который он ссылается, слишком расплывчатый.

Как проверить

  • откройте диалог, не глядя на триггер
  • проверьте, понятно ли назначение модального окна

Решение

  • добавьте конкретный заголовок с id и передайте его в DialogContent как aria-labelledby
  • формулируйте заголовок через задачу