MUI (Material-UI) предоставляет мощные возможности для работы с
компонентами диалогов (Dialog) в React-приложениях, включая
управление фокусом. Управление фокусом — ключевой аспект создания
доступного интерфейса, поскольку обеспечивает корректную навигацию с
клавиатуры и взаимодействие с экранными считывателями.
Компонент Dialog в MUI по умолчанию автоматически
устанавливает фокус на первый фокусируемый элемент внутри диалога при
его открытии. Это поведение задается свойством
disableAutoFocus, которое по умолчанию равно
false.
Пример использования:
import React, { useState } from 'react';
import { Dialog, DialogTitle, DialogContent, TextField, Button } from '@mui/material';
function ExampleDialog() {
const [open, setOpen] = useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
return (
<>
<Button variant="outlined" onCl ick={handleOpen}>
Открыть диалог
</Button>
<Dialog open={open} onCl ose={handleClose}>
<DialogTitle>Введите данные</DialogTitle>
<DialogContent>
<TextField label="Имя" autoFocus fullWidth margin="normal" />
<TextField label="Email" fullWidth margin="normal" />
</DialogContent>
</Dialog>
</>
);
}
Ключевые моменты:
autoFocus на TextField внутри диалога
гарантирует установку фокуса на этот элемент при открытии.autoFocus не задан, MUI фокусирует первый
доступный фокусируемый элемент внутри диалога.Для случаев, когда требуется вручную управлять фокусом, можно
отключить автозахват фокуса через
disableAutoFocus={true}:
<Dialog open={open} onCl ose={handleClose} disableAutoFocus>
...
</Dialog>
После этого фокус не будет автоматически перемещён при открытии, что
позволяет программно устанавливать его в нужный элемент с использованием
ref.
refДля более гибкого управления часто используют
React.useRef и метод focus():
import React, { useState, useRef, useEffect } from 'react';
import { Dialog, DialogTitle, DialogContent, TextField, Button } from '@mui/material';
function CustomFocusDialog() {
const [open, setOpen] = useState(false);
const nameRef = useRef(null);
useEffect(() => {
if (open && nameRef.current) {
nameRef.current.focus();
}
}, [open]);
return (
<>
<Button onCl ick={() => setOpen(true)}>Открыть диалог</Button>
<Dialog open={open} onCl ose={() => setOpen(false)} disableAutoFocus>
<DialogTitle>Регистрация</DialogTitle>
<DialogContent>
<TextField label="Имя" inputRef={nameRef} fullWidth margin="normal" />
<TextField label="Пароль" fullWidth margin="normal" />
</DialogContent>
</Dialog>
</>
);
}
Особенности подхода:
inputRef позволяет напрямую ссылаться на
DOM-элемент.useEffect отслеживает изменение состояния открытия
диалога и устанавливает фокус после монтирования.MUI автоматически возвращает фокус на элемент, вызвавший открытие диалога, если используется стандартное API без отключения автофокуса. Для кастомного управления можно сохранять ссылку на кнопку:
const triggerRef = useRef(null);
<Button ref={triggerRef} onCl ick={() => setOpen(true)}>Открыть</Button>
<Dialog
open={open}
onCl ose={() => {
setOpen(false);
triggerRef.current.focus();
}}
>
...
</Dialog>
Важные моменты:
disableAutoFocus).MUI обеспечивает траппинг фокуса внутри диалога: при
открытом диалоге пользователи клавиатуры не могут перейти к элементам
вне него. Для этого используется FocusTrap внутри
Modal. Параметры управления:
disableEnforceFocus: отключает принудительное удержание
фокуса.disableRestoreFocus: отключает автоматический возврат
фокуса после закрытия.Пример:
<Dialog
open={open}
disableEnforceFocus
disableRestoreFocus
>
...
</Dialog>
Для комплексных форм внутри диалога рекомендуется:
autoFocus только на самом важном
поле.ref и focus() после рендеринга.autoFocus и ручного
ref.focus(). Либо одно, либо другое.Управление фокусом в диалогах MUI — это комбинация автоматических
механизмов, встроенных в Dialog и Modal, и
возможностей ручного контроля через ref,
autoFocus и состояния компонентов. Правильное использование
этих инструментов обеспечивает удобство, доступность и предсказуемое
поведение интерфейса.