Radix UI предоставляет набор низкоуровневых компонентов для создания
интерфейсов с высокой степенью контроля над поведением и стилизацией.
Работа с множественными диалогами требует понимания
внутренней архитектуры компонентов Dialog, управления
состоянием и корректного взаимодействия между несколькими открытыми
окнами одновременно.
В Radix UI компонент диалога состоит из нескольких частей:
Dialog.Root — контейнер, управляющий
состоянием диалога (open / closed).Dialog.Trigger — элемент, который
инициирует открытие диалога.Dialog.Overlay — полупрозрачный слой,
блокирующий взаимодействие с фоновым контентом.Dialog.Content — собственно содержимое
диалога, включая заголовки, формы и кнопки.Dialog.Title и
Dialog.Description — семантические
элементы для улучшения доступности.Dialog.Close — элемент, закрывающий
диалог.Для работы с множественными диалогами критически важно не смешивать состояния разных Root-компонентов, иначе возможны конфликты при закрытии и фокусировании.
Radix UI использует контролируемый и неконтролируемый режимы:
open.Для нескольких диалогов рекомендуется использовать
централизованное состояние, например через React
useState или useReducer:
const [dialogs, setDialogs] = useState({
dialogA: false,
dialogB: false,
});
function openDialog(name) {
setDialogs(prev => ({ ...prev, [name]: true }));
}
function closeDialog(name) {
setDialogs(prev => ({ ...prev, [name]: false }));
}
Это позволяет независимо открывать и закрывать несколько диалогов без пересечения поведения.
Одним из важнейших аспектов при работе с множественными диалогами является правильное управление фокусом:
aria-hidden).Для достижения корректной последовательности фокусировки можно
использовать Dialog.Content с пропом
forceMount, чтобы диалог оставался в DOM даже закрытым, что
предотвращает перерисовку при открытии нескольких окон.
<Dialog.Root open={dialogs.dialogA} onOpenCha nge={(open) => closeDialog('dialogA')}>
<Dialog.Trigger>Открыть A</Dialog.Trigger>
<Dialog.Content>
Диалог A
<Dialog.Root open={dialogs.dialogB} onOpenCha nge={(open) => setDialogs({...dialogs, dialogB: open})}>
<Dialog.Trigger>Открыть B</Dialog.Trigger>
<Dialog.Content>Диалог B</Dialog.Content>
</Dialog.Root>
</Dialog.Content>
</Dialog.Root>
Важно: всегда контролировать фокус и состояние через отдельные Root-компоненты, чтобы избежать «зависания» диалогов.
Использование отдельного состояния для каждого Root-компонента
предотвращает конфликт между их Overlay и
Content. Overlay каждого диалога может иметь различный
стиль, чтобы визуально различать активные окна.
Radix UI не накладывает жестких ограничений на стили, что особенно удобно для множественных диалогов:
@stitches/react, используя классы
data-state="open" и data-state="closed" для
управления анимацией.[data-state="open"] {
opacity: 1;
transform: translateY(0);
transition: opacity 200ms, transform 200ms;
}
[data-state="closed"] {
opacity: 0;
transform: translateY(-10px);
}
aria-hidden для скрытых
диалогов.Использование этих подходов позволяет создавать интерфейсы с множественными диалогами, которые остаются стабильными, доступными и эстетически приятными.