ModalCard
Компонент реализующий модальную карточку. Позволяет показать небольшой дополнительный контент, удерживая пользователя в текущем контексте страницы/приложения.
Область применения
- показ уведомления (например, о новом функционале);
- отображение формы ввода (например, ввод СМС-кода).
Анатомия
Вёрстку и параметры ModalCard
наследует от ModalCardBase. Также используется компоновка из следующих внутренних
компонентов:
ModalOutlet
– обёртка с фиксированной позицией для перекрытия других элементов в DOM;ModalOverlay
– интерактивный задний фон;ModalCardInternal
– инкапсулирует в себе всю логику поведения.
Поведение
Параметр open
задает состояние показа/скрытия ModalCard
. По умолчанию компонент скрыт.
При состоянии open={false}
компонент размонтируется из DOM. Чтобы отключить это поведение, необходимо задать параметр
keepMounted
.
Смена состояния сопровождается анимацией содержимого ModalCard
, а также ModalOverlay
. За сменой состояния можно следить
через события:
onOpen
onOpened
onClose
– передаёт в аргумент причину закрытия (см. описание в таблице с API)onClosed
Отличие onOpened
/onClosed
от onOpen
/onClose
в том, что они вызываются после завершения анимации.
Далее поведение зависит от разрешения экрана.
Настольный режим
При разрешении >= 768px
компонент ModalCard
имеет вид диалогового окна.
При open={true}
:
- навигация через
Tab
иShift
+Tab
будет зациклена на содержимомModalCard
.
По умолчанию, пользователь может закрыть диалоговое окно с помощью:
- нажатия на кнопку закрытия, что вызовет событие
onClose
с аргументомclick-close-button
; - нажатия на
ModalOverlay
, что вызовет событиеonClose
с аргументомclick-overlay
; - нажатия на
Esc
, что вызовет событиеonClose
с аргументомescape-key
.
Мобильный режим
При разрешении <= 767px
компонент ModalCard
имеет вид панели, выдвигающейся снизу вверх (далее bottom card).
При open={true}
навигация через Tab
и Shift
+ Tab
будет зациклена на содержимом ModalCard
(допустимо, т.к. к устройству
может быть подключена клавиатура).
По умолчанию, пользователь может закрыть bottom card с помощью:
- нажатия на
ModalOverlay
, что вызовет событиеonClose
с аргументомclick-overlay
; - нажатия на
Esc
, что вызовет событиеonClose
с аргументомescape-key
(допустимо, т.к. к устройству может быть подключена клавиатура); - определенное взаимодействие через тач или указатель мыши, что вызовет событие
onClose
с аргументомswipe-down
(см. Взаимодействие через тач или указатель мыши)
Взаимодействие через тач или указатель мыши
Перетаскивание bottom card изменяет прозрачность ModalOverlay
– при перетаскивание вниз фон становится светлее.
Пользователь через перетаскивание может вызвать закрытие bottom card по следующим условиям:
onClose('swipe-down')
вызовется сразу же если bottom card достиг высоты0
, независимо закончил ли пользователь взаимодействие с ним или нет;onClose('swipe-down')
вызовется если после окончания взаимодействия с bottom card его высота будет меньше половины контента;onClose('swipe-down')
вызовется при сильном смахивании вниз;
При следующих условиях возможность перетаскивания замораживается, чтобы не блокировать пользователя:
- есть взаимодействие с горизонтальной полосой прокрутки;
- есть взаимодействие с текстовым полем;
- есть взаимодействие с выделенным текстом;
- есть взаимодействие с элементом вызвавшим
event.stopPropagation()
наonTouchStart
илиonMouseDown
; - есть взаимодействие с элементом с data-атрибутом
data-vkui-block-sheet-behavior
;
Доступность (a11y)
ModalCard
является модальным окном (role="dialog"
), а значит у него обязательно должно быть имя — его краткое название. Благодаря этому пользователи вспомогательных технологий знают, что это за элемент и какое у него содержимое.
Задать имя можно с помощью следующих способов:
- используя свойство
title
. Компонент в котором отрендеритсяtitle
будет связан с модальным окном через аттрибутaria-labelledby
; - используя свойство
aria-label
; - используя свойство
aria-labelledby
; - используя внутри компонент ModalPageHeader. Этот компонент сам свяжется с
ModalCard
через контекст c помощьюaria-labelledby
.
FAQ
Как правильно применять параметр autoFocus
?
К сожалению, из-за особенностей React, autoFocus
ломает CSS анимацию.
Чтобы исправить проблему, следует отказаться от autoFocus
и выставлять фокус вручную при событии onOpened
.
Свойства и методы
Свойство | Описание |
---|---|
actions | ReactNode Кнопки-действия. Принимает
Для набора кнопок используйте
По умолчанию: - |
description | ReactNode Описание. По умолчанию: - |
descriptionComponent | ElementType<any, keyof IntrinsicElements> Позволяет поменять тег используемый для описания. По умолчанию: - |
disableFocusTrap | boolean Позволяет отключить захват фокуса. Нужно использовать, когда поверх одной модалки открывается другая, чтобы два По умолчанию: - |
dismissButtonMode | "none" | "inside" | "outside" Расположение кнопки закрытия (внутри и вне Доступно только в На ⚠️ ВНИМАНИЕ: использование По умолчанию: - |
dismissLabel | string Текст кнопки закрытия. Делает ее доступной для ассистивных технологий. По умолчанию: - |
getRootRef | Ref<HTMLDivElement> По умолчанию: - |
icon | ReactNode Иконка. Может быть компонентом иконки, например, По умолчанию: - |
id | string По умолчанию: - |
keepMounted | boolean Сохранять ли компонент в DOM при По умолчанию: false |
modalDismissButtonTestId | string Передает атрибут По умолчанию: - |
modalOverlayTestId | string
По умолчанию: - |
nav | string Уникальный идентификатор навигационного элемента (вместо id) По умолчанию: - |
noFocusToDialog | boolean Отключает фокус на интерактивный элемент после открытия модалки. По умолчанию: - |
onClose | ((reason: ModalCardCloseReason, event?: UIEvent<HTMLElement, UIEvent>) => void) | undefined Будет вызвано при начале закрытия модалки. По умолчанию: - |
onClosed | VoidFunction Будет вызвано при окончательном закрытии модалки. По умолчанию: - |
onOpen | VoidFunction Будет вызвано при начале открытия модалки. По умолчанию: - |
onOpened | VoidFunction Будет вызвано при окончательном открытии модалки. По умолчанию: - |
open | boolean Состояние видимости. По умолчанию: false |
outsideButtons | ReactNode Управляющие элементы под кнопкой закрытия. Доступно только в По умолчанию: - |
preventClose | boolean Позволяет отключить возможность закрытия модальной страницы (смахивание, клавиша ⚠️ ВНИМАНИЕ: использование этой опции негативно сказывается на пользовательском опыте. По умолчанию: - |
restoreFocus | boolean | (() => boolean | HTMLElement) По умолчанию: true |
size | number Задаёт контенту максимальную ширину для десктопной версии. По умолчанию: - |
title | ReactNode Заголовок карточки. По умолчанию: - |
titleComponent | ElementType<any, keyof IntrinsicElements> Позволяет поменять тег используемый для заголовка. По умолчанию: - |
titleId | string Позволяет задать id для заголовка. Используется, чтобы связать модальное окно и title через aria-labelledby, тем самым задав модальному окну имя через title. По умолчанию: - |