Ответ вслух Middle Компоненты на практике обновлено

Доступная модалка

Вопрос

Как бы ты сделал модальное окно в React, чтобы им было удобно пользоваться и с клавиатуры, и со скринридером?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Самый простой надёжный вариант сегодня это нативный <dialog и метод showModal(): браузер сам ставит окно в верхний слой, делает остальную страницу инертной, закрывает по Escape. В React я держу ref на элемент и вызываю showModal и close в эффекте в зависимости от пропса open.

Что должно прозвучать в ответе

  • Портал в `document.body` или нативный `<dialog>` с `showModal()`

  • `role="dialog"`, `aria-modal="true"`, заголовок через `aria-labelledby`

  • Фокус в окно при открытии, ловушка фокуса внутри, возврат фокуса на кнопку при закрытии

  • Закрытие по Escape и по клику на подложку, но не по клику внутри окна

  • Блокировка прокрутки страницы под окном

  • Очистка обработчиков клавиатуры при закрытии

Что могут спросить следом

  • Зачем нужен портал, если есть z-index?
  • Что даёт нативный dialog по сравнению с div?
  • Как реализовать ловушку фокуса?

Разбор

Самый простой надёжный вариант сегодня это нативный <dialog> и метод showModal(): браузер сам ставит окно в верхний слой, делает остальную страницу инертной, закрывает по Escape. В React я держу ref на элемент и вызываю showModal и close в эффекте в зависимости от пропса open.

Если делаю на div, рендерю окно через createPortal в document.body, чтобы его не обрезали overflow и z-index родителей. Добавляю role="dialog", aria-modal="true" и связываю заголовок через aria-labelledby.

С фокусом три правила: при открытии фокус переходит в окно, Tab не выходит за его пределы, при закрытии фокус возвращается на кнопку, которая окно открыла. Закрываю по Escape и по клику на подложку, проверяя, что клик был именно по ней. Блокирую прокрутку страницы, пока окно открыто, и снимаю все обработчики при закрытии.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.