Диалоговое окно с focus trap, Portal в document.body и анимацией входа/выхода. Блокирует скролл страницы. Закрывается по Escape, клику на бэкдроп или кнопке ×.
Базовый пример
MD · 640px
Размеры
SM · MD · LG · Fullscreen
Варианты поведения
closeOnBackdrop · closeOnEscape
Токены
--ds-modal-*
Токен
Значение
--ds-modal-sm-w
480px
--ds-modal-md-w
640px — Figma Modal 1215:36573
--ds-modal-lg-w
800px
--ds-modal-padding
24px
--ds-modal-r
var(--ds-radius-xxl) = 24px
--ds-modal-shadow
var(--ds-shadow-xl)
--ds-modal-z
900
--ds-modal-backdrop-bg
rgba(0, 0, 0, 0.40)
--ds-modal-bg
var(--ds-surface-nb-hc) — mirror-aware, не surface-0
--ds-modal-title-fs / fw / lh
20px / 600 / 1.4 → 28px — Figma Title
--ds-modal-subtitle-fs / lh / fw
16px / 20px / 500 — Figma Subtitle
--ds-modal-gap
24px — Figma root itemSpacing
--ds-modal-header-gap
8px — Figma Header itemSpacing
--ds-modal-close-inset
16px — close ABSOLUTE, constraints MAX/MIN
--ds-modal-close-size
40px — close 40×40; из него и инсета выведены резервы 48 и 32
--ds-modal-dur
200ms
Правила использования
Доступность · Клавиатура · UX
Focus trap
Tab остаётся внутри
При открытом Modal фокус циклически обходит только интерактивные элементы внутри. Shift+Tab работает в обратном направлении. При открытии фокус ставится на первый фокусируемый элемент.
Keyboard
Escape и клики
Escape закрывает Modal (если closeOnEscape=true). Backdrop-click закрывает если closeOnBackdrop=true. Кнопка × видима по умолчанию.
Portal
ReactDOM.createPortal
Modal рендерится в document.body через Portal вне иерархии DOM. Исключает z-index конфликты. Backdrop всегда поверх интерфейса (z-index: 900).
B2B правило
Irreversible actions
Modal обязателен для необратимых действий (удаление записи, перевод средств). Reversible actions (фильтры, сортировка) не требуют Modal. Включать error code в сообщения об ошибках.
Scroll lock
Блокировка прокрутки
При открытии устанавливается overflow: hidden на body. Восстанавливается при закрытии. Предотвращает прокрутку страницы позади Modal.
Dark mode
Автоматическая адаптация
Backdrop: фиксированный rgba(0,0,0,0.4) — одинаков в обеих темах. Surface: --ds-modal-bg адаптируется. Close-кнопка: nba-40 override в dark.