Для списка действий у элемента возьмите CdsMenu, для короткой подсказки — CdsTooltip, для уведомления о результате — CdsToast. Сложное содержимое окна — шапку, прокручиваемый текст и ряд кнопок — собирают из CdsCard.
Внутри окна работает CdsOverlay: он выводит контент поверх страницы, затемняет её, блокирует прокрутку и удерживает фокус внутри окна — по Tab не выбраться наружу, а после закрытия фокус возвращается на активатор. Поэтому пропсы открытия и позиционирования у модального окна общие с оверлеем.
Вариации
Активаторы
Окно открывает элемент-активатор — задать его можно тремя способами:
- Через слот
activator— пропсы из слота (v-bind="props") вешают на элемент обработчики и aria-атрибуты. Способ по умолчанию. - Через родителя —
activator="parent"берёт элемент, внутри которого лежитCdsModal. - Через селектор —
activator="#id"связывает окно с любым элементом страницы, даже далёким по разметке.
Использование v-model
Состоянием окна можно управлять напрямую через v-model — без активатора. Так открывают окно из кода: по ответу сервера, из обработчика в таблице, из стора.
Размеры
Проп size задаёт ширину окна: xs (250), sm (350), md (500, по умолчанию), lg (700), xl — почти на всю ширину экрана. Число вместо алиаса — точная ширина в пикселях. Высота всегда подстраивается под контент, а width и max-width переопределяют размер, когда нужна нестандартная сетка.
Постоянные окна
Проп persistent отключает закрытие кликом мимо окна и клавишей Esc — закрыть окно можно только кнопками внутри. Клик мимо встряхивает окно, подсказывая, что ответить всё-таки придётся; анимацию убирает no-click-animation. Берите persistent, когда закрытие потеряет данные или пользователь обязан сделать выбор.
Скролл внутри окна
По умолчанию длинный контент прокручивается вместе с окном целиком. Проп scrollable фиксирует шапку и кнопки, а прокручивает только середину — для этого содержимое собирают из CdsCard: карточка становится поверхностью окна, зона прокрутки — её CdsCardText.
На весь экран
Проп fullscreen разворачивает окно на весь экран: пропсы размеров игнорируются, отступы и скругления убираются. Подходит для просмотра документов и сложных форм на небольших экранах.
Анимации
По умолчанию окно вырастает из активатора и сжимается обратно — так видно, откуда оно появилось. Проп transition меняет анимацию: готовые modal-transition-top и modal-transition-bottom выдвигают окно от края экрана, подойдёт и любая своя CSS-анимация.
Слоты
| Слот | Описание |
|---|---|
activator | Элемент, открывающий окно. Пропсы слота (props) вешают на него обработчики |
default | Содержимое окна. Из слота доступен isActive — им окно закрывают без внешней переменной |
Рекомендации
Сценарии использования
Подтверждение удаления
Необратимое действие подтверждают компактным окном size="sm": заголовок называет действие, текст уточняет, что именно будет удалено, главная кнопка повторяет глагол из заголовка. Одно окно обслуживает весь список — перед открытием в него кладут выбранную запись.
Форма в модальном окне
Короткую форму открывают поверх списка, чтобы не уводить пользователя на отдельную страницу. persistent защищает введённое от случайного клика мимо, кнопка отправки показывает loading, а «Отмена» блокируется на время запроса. Поля сбрасываются в событии after-leave — после анимации закрытия, чтобы значения не мигали в ещё видимом окне.
Соглашение с прокруткой
Документ, требующий явного ответа, показывают в окне с persistent и scrollable: текст прокручивается, а кнопки «Принять» и «Отклонить» всегда на виду. Закрыть окно, не ответив, не получится — решение фиксируется только кнопками.
API
Пропсы
| Имя | Тип | По умолчанию | Описание |
|---|---|---|---|
absolute | boolean | undefined | — | Указывает, что элемент должен быть позиционирован абсолютно, а не фиксированно. Это может быть полезно для оверлеев, которые должны быть ограничены определенной областью, например, внутри контейнера с position: relative. |
activator | (string & {}) | Element | "parent" | ComponentPublicInstance | undefined | — | Элемент, который будет активировать компонент |
activatorProps | Record<string, any> | undefined | {} | Свойства для элемента активатора |
attach | string | boolean | Element | undefined | — | Указывает, в какой элемент DOM следует переместить содержимое overlay. Может быть прямой ссылкой на элемент, строкой querySelector или значением true для отключения перемещения. По умолчанию используется элемент body. Как правило, не рекомендуется изменять это свойство, за исключением крайних случаев: алгоритм позиционирования по умолчанию должен справляться с большинством сценариев лучше, чем это возможно без перемещения, и может возникнуть непредвиденное поведение, если меню окажется дочерним элементом своего активатора. |
captureFocus | boolean | undefined | true | Возвращает фокус внутрь контента, если он ушёл за его пределы — например, по Tab с конца страницы. Клик мышью фокус не перехватывает. |
closeDelay | string | number | undefined | — | Время ожидания в миллисекундах перед закрытием компонента. Работает только с параметром open-on-hover. |
closeOnBack | boolean | undefined | true | Закрывает содержимое оверлея при нажатии кнопки «Назад» в браузере или вызове $router.back(), отменяя исходную навигацию.
persistent оверлеи отменяют навигацию и анимируются так, как будто по ним щелкнули за пределами оверлея, вместо того чтобы закрываться. |
closeOnContentClick | boolean | undefined | — | Скрыть компонент по клику на контент |
contained | boolean | undefined | — | Ограничивает размер компонента и сетки в соответствии с его смещенным родительским элементом.
Подразумевает использование свойств absolute и attach. (Примечание: родительский элемент должен иметь свойство position: relative.) |
contentClass | any | — | Применяет пользовательский класс к отдельному элементу.
Это удобно, поскольку содержимое перемещается в начало компонента cds-app (если не указан параметр attach) и не может быть выделено с помощью классов, переданных непосредственно в компонент. |
contentProps | any | — | Применяет кастомные свойства (props) к перемещаемому контенту |
disabled | boolean | null | undefined | null | Заблокированное состояние |
eager | boolean | undefined | — | Принудительно рендерит содержимое компонента при его использовании. Это полезно, если у вас есть контент, который не отображается в DOM, но который необходимо проиндексировать для SEO. |
fullscreen | boolean | undefined | — | Разворачивает модальное окно на весь экран. |
height | string | number | undefined | — | Высота компонента |
location | Anchor | undefined | 'center center' | Указывает точку привязки для позиционирования компонента с использованием ориентиров для выравнивания по горизонтали, по вертикали или по обоим направлениям |
locationStrategy | "static" | "connected" | LocationStrategyFunction | undefined | 'static' | Определяет способ позиционирования содержимого оверлея. По умолчанию используется значение static, при котором содержимое центрируется в контейнере. Используйте connected для привязки к элементу-активатору. |
maxHeight | string | number | undefined | — | Максимальная высота компонента |
maxWidth | string | number | undefined | — | Максимальная ширина компонента |
minHeight | string | number | undefined | — | Минимальная высота компонента |
minWidth | string | number | undefined | — | Минимальная ширина компонента |
modelValue | boolean | undefined | — | Значение компонента v-model. Если компонент поддерживает свойство multiple, по умолчанию используется пустой массив. |
noClickAnimation | boolean | undefined | — | Отключает эффект bounce при нажатии за пределами элемента контента при использовании атрибута persistent. |
offset | string | number | number[] | undefined | — | Увеличивает расстояние до цели. Если передать два числа, второе значение смещает анкер вбок и в сторону от цели. |
opacity | string | number | undefined | — | Прозрачность элемента «scrim». Применяется только в том случае, если св-во scrim=true. |
openDelay | string | number | undefined | — | Время ожидания в миллисекундах перед открытием компонента. Работает только с параметром open-on-hover. |
openOnClick | boolean | undefined | — | Показать компонент по клику на активатор |
openOnFocus | boolean | undefined | — | Показать компонент по фокусу на активатор |
openOnHover | boolean | undefined | — | Показать компонент по наведению на активатор |
origin | Anchor | "auto" | "overlap" | undefined | 'center center' | Устанавливает точку привязки для содержимого наложения, которая выравнивается по точке привязки «location» на объекте-цели.
При значении «auto» используется противоположная сторона точки «location».
При значении «overlap» используется та же точка привязки, в результате чего наложение перекрывает объект-цель.
Также задает значение CSS-свойства transform-origin для transitions enter/leave. |
persistent | boolean | undefined | — | Клик за пределами элемента или нажатие клавиши Esc не приведет к его закрытию. |
retainFocus | boolean | undefined | true | Замыкает Tab-навигацию внутри контента: с последнего фокусируемого элемента фокус переходит на первый и наоборот. |
scrim | string | boolean | undefined | true | Фон при активации overlay. Принимает значения true/false для включения фона и строку для определения цвета. |
scrollable | boolean | undefined | — | Включает прокрутку контента внутри модального окна. |
scrollStrategy | "none" | "close" | "block" | "reposition" | ScrollStrategyFunction | undefined | 'block' | Стратегия, применяемая при активации компонента и прокрутке страницы пользователем. |
size | number | "xs" | "sm" | "md" | "lg" | "xl" | undefined | 'md' | Размер компонента |
stickToTarget | boolean | undefined | — | Позволяет контенту наложения выходить за пределы экрана при прокрутке. |
target | (string & {}) | Element | "parent" | ComponentPublicInstance | "cursor" | [x: number, y: number] | undefined | — | Если для параметра locationStrategy задано значение «connected», необходимо указать элемент или массив координат x, y, относительно которых должен располагаться оверлей. По умолчанию в качестве такого элемента используется элемент-активатор. |
theme | string | undefined | — | Тема компонента |
transition | string | boolean | (TransitionProps & { component?: Component | undefined; }) | { component: Component; } | null | undefined | { component: CdsModalTransition } | Анимация перехода |
viewportMargin | string | number | undefined | 12 | Устанавливает пользовательские viewport margin для содержимого наложения |
width | string | number | undefined | — | Ширина компонента |
zIndex | string | number | undefined | 2400 | Значение z-index для компонента. |
События
| Имя | Тип | Описание |
|---|---|---|
afterEnter | [] | Событие завершения анимации открытия модального окна. |
afterLeave | [] | Событие завершения анимации закрытия модального окна. |
update:modelValue | [value: boolean] | Событие изменения состояния модального окна. |
Слоты
| Имя | Тип | Описание |
|---|---|---|
activator | { isActive: boolean; props: Record<string, any>; targetRef: TemplateRef; } | Слот для элемента, который будет выступать в роли активатора для оверлея. |
default | { isActive: Ref<boolean, boolean>; } | Слот для контента оверлея. |
Exposed
| Имя | Тип | Описание |
|---|---|---|
activatorEl | HTMLElement | undefined | DOM-элемент активатора. |
activatorRef | TemplateRef | Template ref для назначения активатора вручную. |
animateClick | () => void | Запускает bounce-анимацию контента — как при клике мимо persistent-оверлея. |
contentEl | HTMLElement | undefined | DOM-элемент контента оверлея. |
globalTop | boolean | Является ли оверлей верхним в глобальном стеке открытых оверлеев. |
rootEl | HTMLElement | undefined | Корневой DOM-элемент оверлея. |
scrimEl | HTMLElement | undefined | DOM-элемент подложки (scrim), затемняющей страницу. |
targetEl | HTMLElement | undefined | DOM-элемент цели позиционирования. |
targetRef | TemplateRef | Template ref для назначения цели позиционирования вручную. |
updateLocation | ((e: Event) => void) | undefined | Пересчитывает позицию контента относительно цели. |