Skip to content

CdsModal

Модальное окно открывается поверх страницы и держит фокус на одной задаче: подтвердить действие, заполнить короткую форму, показать детали — не уводя пользователя с текущего экрана. Пока окно открыто, страница под ним затемнена, не прокручивается и не принимает клики.

Storybook GitLab
Покрытие тестами: 100% — хорошее покрытие
API в спеках
58 / 58 пропсы, события, слоты и exposed, у которых есть тест
Тест-кейсы
45 юнит · 4 браузерных
Известные баги
2 зафиксированы тестом it.fails
Покрытие кода
100% строк · 95.5% ветвей замер v4.0.0-alpha.13
A11y (axe)
9 рекомендаций в 11 историях замер v4.0.0-alpha.11

Для списка действий у элемента возьмите CdsMenu, для короткой подсказки — CdsTooltip, для уведомления о результате — CdsToast. Сложное содержимое окна — шапку, прокручиваемый текст и ряд кнопок — собирают из CdsCard.

Внутри окна работает CdsOverlay: он выводит контент поверх страницы, затемняет её, блокирует прокрутку и удерживает фокус внутри окна — по Tab не выбраться наружу, а после закрытия фокус возвращается на активатор. Поэтому пропсы открытия и позиционирования у модального окна общие с оверлеем.

Вариации ​

Активаторы ​

Окно открывает элемент-активатор — задать его можно тремя способами:

  1. Через слот activator — пропсы из слота (v-bind="props") вешают на элемент обработчики и aria-атрибуты. Способ по умолчанию.
  2. Через родителя — activator="parent" берёт элемент, внутри которого лежит CdsModal.
  3. Через селектор — activator="#id" связывает окно с любым элементом страницы, даже далёким по разметке.
Sandbox Storybook

Использование v-model ​

Состоянием окна можно управлять напрямую через v-model — без активатора. Так открывают окно из кода: по ответу сервера, из обработчика в таблице, из стора.

Sandbox Storybook

Размеры ​

Проп size задаёт ширину окна: xs (250), sm (350), md (500, по умолчанию), lg (700), xl — почти на всю ширину экрана. Число вместо алиаса — точная ширина в пикселях. Высота всегда подстраивается под контент, а width и max-width переопределяют размер, когда нужна нестандартная сетка.

Sandbox Storybook

Постоянные окна ​

Проп persistent отключает закрытие кликом мимо окна и клавишей Esc — закрыть окно можно только кнопками внутри. Клик мимо встряхивает окно, подсказывая, что ответить всё-таки придётся; анимацию убирает no-click-animation. Берите persistent, когда закрытие потеряет данные или пользователь обязан сделать выбор.

Sandbox Storybook

Скролл внутри окна ​

По умолчанию длинный контент прокручивается вместе с окном целиком. Проп scrollable фиксирует шапку и кнопки, а прокручивает только середину — для этого содержимое собирают из CdsCard: карточка становится поверхностью окна, зона прокрутки — её CdsCardText.

Sandbox Storybook

На весь экран ​

Проп fullscreen разворачивает окно на весь экран: пропсы размеров игнорируются, отступы и скругления убираются. Подходит для просмотра документов и сложных форм на небольших экранах.

Sandbox Storybook

Анимации ​

По умолчанию окно вырастает из активатора и сжимается обратно — так видно, откуда оно появилось. Проп transition меняет анимацию: готовые modal-transition-top и modal-transition-bottom выдвигают окно от края экрана, подойдёт и любая своя CSS-анимация.

Sandbox Storybook

Слоты ​

СлотОписание
activatorЭлемент, открывающий окно. Пропсы слота (props) вешают на него обработчики
defaultСодержимое окна. Из слота доступен isActive — им окно закрывают без внешней переменной

Рекомендации ​

Сценарии использования ​

Подтверждение удаления ​

Необратимое действие подтверждают компактным окном size="sm": заголовок называет действие, текст уточняет, что именно будет удалено, главная кнопка повторяет глагол из заголовка. Одно окно обслуживает весь список — перед открытием в него кладут выбранную запись.

Sandbox Storybook

Форма в модальном окне ​

Короткую форму открывают поверх списка, чтобы не уводить пользователя на отдельную страницу. persistent защищает введённое от случайного клика мимо, кнопка отправки показывает loading, а «Отмена» блокируется на время запроса. Поля сбрасываются в событии after-leave — после анимации закрытия, чтобы значения не мигали в ещё видимом окне.

Sandbox Storybook

Соглашение с прокруткой ​

Документ, требующий явного ответа, показывают в окне с persistent и scrollable: текст прокручивается, а кнопки «Принять» и «Отклонить» всегда на виду. Закрыть окно, не ответив, не получится — решение фиксируется только кнопками.

Sandbox Storybook

API ​

Пропсы

ИмяТипПо умолчаниюОписание
absoluteboolean | undefined—Указывает, что элемент должен быть позиционирован абсолютно, а не фиксированно. Это может быть полезно для оверлеев, которые должны быть ограничены определенной областью, например, внутри контейнера с position: relative.
activator(string & {}) | Element | "parent" | ComponentPublicInstance | undefined—Элемент, который будет активировать компонент
activatorPropsRecord<string, any> | undefined{}Свойства для элемента активатора
attachstring | boolean | Element | undefined—Указывает, в какой элемент DOM следует переместить содержимое overlay. Может быть прямой ссылкой на элемент, строкой querySelector или значением true для отключения перемещения. По умолчанию используется элемент body. Как правило, не рекомендуется изменять это свойство, за исключением крайних случаев: алгоритм позиционирования по умолчанию должен справляться с большинством сценариев лучше, чем это возможно без перемещения, и может возникнуть непредвиденное поведение, если меню окажется дочерним элементом своего активатора.
captureFocusboolean | undefinedtrueВозвращает фокус внутрь контента, если он ушёл за его пределы — например, по Tab с конца страницы. Клик мышью фокус не перехватывает.
closeDelaystring | number | undefined—Время ожидания в миллисекундах перед закрытием компонента. Работает только с параметром open-on-hover.
closeOnBackboolean | undefinedtrueЗакрывает содержимое оверлея при нажатии кнопки «Назад» в браузере или вызове $router.back(), отменяя исходную навигацию. persistent оверлеи отменяют навигацию и анимируются так, как будто по ним щелкнули за пределами оверлея, вместо того чтобы закрываться.
closeOnContentClickboolean | undefined—Скрыть компонент по клику на контент
containedboolean | undefined—Ограничивает размер компонента и сетки в соответствии с его смещенным родительским элементом. Подразумевает использование свойств absolute и attach. (Примечание: родительский элемент должен иметь свойство position: relative.)
contentClassany—Применяет пользовательский класс к отдельному элементу. Это удобно, поскольку содержимое перемещается в начало компонента cds-app (если не указан параметр attach) и не может быть выделено с помощью классов, переданных непосредственно в компонент.
contentPropsany—Применяет кастомные свойства (props) к перемещаемому контенту
disabledboolean | null | undefinednullЗаблокированное состояние
eagerboolean | undefined—Принудительно рендерит содержимое компонента при его использовании. Это полезно, если у вас есть контент, который не отображается в DOM, но который необходимо проиндексировать для SEO.
fullscreenboolean | undefined—Разворачивает модальное окно на весь экран.
heightstring | number | undefined—Высота компонента
locationAnchor | undefined'center center'Указывает точку привязки для позиционирования компонента с использованием ориентиров для выравнивания по горизонтали, по вертикали или по обоим направлениям
locationStrategy"static" | "connected" | LocationStrategyFunction | undefined'static'Определяет способ позиционирования содержимого оверлея. По умолчанию используется значение static, при котором содержимое центрируется в контейнере. Используйте connected для привязки к элементу-активатору.
maxHeightstring | number | undefined—Максимальная высота компонента
maxWidthstring | number | undefined—Максимальная ширина компонента
minHeightstring | number | undefined—Минимальная высота компонента
minWidthstring | number | undefined—Минимальная ширина компонента
modelValueboolean | undefined—Значение компонента v-model. Если компонент поддерживает свойство multiple, по умолчанию используется пустой массив.
noClickAnimationboolean | undefined—Отключает эффект bounce при нажатии за пределами элемента контента при использовании атрибута persistent.
offsetstring | number | number[] | undefined—Увеличивает расстояние до цели. Если передать два числа, второе значение смещает анкер вбок и в сторону от цели.
opacitystring | number | undefined—Прозрачность элемента «scrim». Применяется только в том случае, если св-во scrim=true.
openDelaystring | number | undefined—Время ожидания в миллисекундах перед открытием компонента. Работает только с параметром open-on-hover.
openOnClickboolean | undefined—Показать компонент по клику на активатор
openOnFocusboolean | undefined—Показать компонент по фокусу на активатор
openOnHoverboolean | undefined—Показать компонент по наведению на активатор
originAnchor | "auto" | "overlap" | undefined'center center'Устанавливает точку привязки для содержимого наложения, которая выравнивается по точке привязки «location» на объекте-цели. При значении «auto» используется противоположная сторона точки «location». При значении «overlap» используется та же точка привязки, в результате чего наложение перекрывает объект-цель. Также задает значение CSS-свойства transform-origin для transitions enter/leave.
persistentboolean | undefined—Клик за пределами элемента или нажатие клавиши Esc не приведет к его закрытию.
retainFocusboolean | undefinedtrueЗамыкает Tab-навигацию внутри контента: с последнего фокусируемого элемента фокус переходит на первый и наоборот.
scrimstring | boolean | undefinedtrueФон при активации overlay. Принимает значения true/false для включения фона и строку для определения цвета.
scrollableboolean | undefined—Включает прокрутку контента внутри модального окна.
scrollStrategy"none" | "close" | "block" | "reposition" | ScrollStrategyFunction | undefined'block'Стратегия, применяемая при активации компонента и прокрутке страницы пользователем.
sizenumber | "xs" | "sm" | "md" | "lg" | "xl" | undefined'md'Размер компонента
stickToTargetboolean | undefined—Позволяет контенту наложения выходить за пределы экрана при прокрутке.
target(string & {}) | Element | "parent" | ComponentPublicInstance | "cursor" | [x: number, y: number] | undefined—Если для параметра locationStrategy задано значение «connected», необходимо указать элемент или массив координат x, y, относительно которых должен располагаться оверлей. По умолчанию в качестве такого элемента используется элемент-активатор.
themestring | undefined—Тема компонента
transitionstring | boolean | (TransitionProps & { component?: Component | undefined; }) | { component: Component; } | null | undefined{ component: CdsModalTransition }Анимация перехода
viewportMarginstring | number | undefined12Устанавливает пользовательские viewport margin для содержимого наложения
widthstring | number | undefined—Ширина компонента
zIndexstring | number | undefined2400Значение z-index для компонента.

События

ИмяТипОписание
afterEnter[]Событие завершения анимации открытия модального окна.
afterLeave[]Событие завершения анимации закрытия модального окна.
update:modelValue[value: boolean]Событие изменения состояния модального окна.

Слоты

ИмяТипОписание
activator{ isActive: boolean; props: Record<string, any>; targetRef: TemplateRef; }Слот для элемента, который будет выступать в роли активатора для оверлея.
default{ isActive: Ref<boolean, boolean>; }Слот для контента оверлея.

Exposed

ИмяТипОписание
activatorElHTMLElement | undefinedDOM-элемент активатора.
activatorRefTemplateRefTemplate ref для назначения активатора вручную.
animateClick() => voidЗапускает bounce-анимацию контента — как при клике мимо persistent-оверлея.
contentElHTMLElement | undefinedDOM-элемент контента оверлея.
globalTopbooleanЯвляется ли оверлей верхним в глобальном стеке открытых оверлеев.
rootElHTMLElement | undefinedКорневой DOM-элемент оверлея.
scrimElHTMLElement | undefinedDOM-элемент подложки (scrim), затемняющей страницу.
targetElHTMLElement | undefinedDOM-элемент цели позиционирования.
targetRefTemplateRefTemplate ref для назначения цели позиционирования вручную.
updateLocation((e: Event) => void) | undefinedПересчитывает позицию контента относительно цели.