MessageBox
Подтверждение действия
Оповещения с одной кнопкой
Очередь вызовов
Второй вызов не показывается, пока не закрыт первый: диалоги выстраиваются в очередь.
Именованные слоты
Слоты задаются один раз — в хосте <C3MessageBox> в корневом макете (playground/app.vue) и действуют на все вызовы приложения. Отдельный хост на странице ставить нельзя: состояние диалога общее, и два хоста отрисовали бы одно окно поверх другого.
Результаты
Нажмите кнопки выше — здесь появятся результаты вызовов.
Входные параметры
Компонент C3MessageBox не имеет пропов: он рендерит диалог, который открыли программно. Все параметры задаются в вызове confirm(), alert() или open() (см. useC3MessageBox()).
Слоты
| Слот | Параметры | Описание |
|---|---|---|
#icon | { box } | Заменяет иконку типа. Без слота показывается иконка по box.type. |
#default | { box } | Дополнительное содержимое между сообщением и кнопками. |
#footer | { box } | Содержимое под сообщением, но над кнопками: подсказки, ссылки, чекбокс «больше не спрашивать». |
#actions | { box, close, dismiss } | Заменяет кнопки. Строка кнопок остаётся, поэтому отступы и выравнивание сохраняются. close(action) закрывает диалог с результатом ('confirm' | 'cancel' | 'ok', без аргумента — отмена), dismiss() — то же отменой. |
Параметры open / confirm / alert
| Имя | Тип | По умолчанию | Описание |
|---|---|---|---|
message | string | '' | Текст сообщения. Переводы строк сохраняются. |
title | string | '' | Заголовок. Попадает в aria-label. Пустая строка — заголовок не рендерится. |
type | 'info' | 'success' | 'warning' | 'error' | 'question' | 'question' у confirm, 'info' у alert | Тип диалога: иконка, цвет акцента кнопки и роль для скринридера (alertdialog у question и error). |
confirmText | string | 'ОК' | Текст кнопки подтверждения. |
cancelText | string | 'Отмена' | Текст кнопки отмены. |
showCancel | boolean | true у confirm, false у alert | Показывать кнопку отмены. |
closeOnBackdrop | boolean | false | Закрывать по клику по подложке. По умолчанию выключено, чтобы случайный клик не терял выбор. |
Методы useC3MessageBox()
| Имя | Возвращает | Описание |
|---|---|---|
open(options) | Promise<MessageBoxResult> | Диалог с произвольными параметрами. |
confirm(message, options?) | Promise<MessageBoxResult> | Диалог подтверждения, по умолчанию тип question и кнопка отмены. |
alert(message, options?) | Promise<MessageBoxResult> | Оповещение с одной кнопкой ОК. |
close(action) | — | Закрыть текущий диалог результатом 'confirm' | 'cancel' | 'ok'. |
dismiss() | — | Закрыть текущий диалог как отменённый. |
reset() | — | Сбросить очередь: текущий и ожидающие диалоги резолвятся как отменённые. |
current | Ref<MessageBoxState | null> | Показываемый диалог. |
isOpen | ComputedRef<boolean> | Есть ли активные диалоги (показанный или в очереди). |
Результат
Промис резолвится объектом MessageBoxResult: { confirmed: boolean, action: 'confirm' | 'cancel' | 'ok' }. Для alert confirmed всегда true, а action равен 'ok'. Закрытие по Escape и по подложке считается отменой (action: 'cancel'), поэтому результат всегда однозначен.
Описание
Императивные диалоги нужны там, где нельзя описать действие декларативно: обработчик удаления, выход со страницы с несохранёнными изменениями, подтверждение опасной операции. Обычный C3Modal требует состояния в компоненте и слота с разметкой, а здесь достаточно двух строк:
const { confirm } = useC3MessageBox() и await confirm('Точно удалить?').
Состояние общее для приложения, поэтому confirm() можно вызвать из composable, стора или обработчика — без передачи ссылок на компоненты. Вызовы не конфликтуют: если диалог уже открыт, следующий встаёт в очередь и показывается после закрытия текущего.
Хост C3MessageBox нужно разместить один раз в корневом макете (например, в app.vue), а не на каждой странице.
Дополнительная информация
- Доступность: роль
alertdialogдляquestionиerror, иначеdialog;aria-modal="true"; заголовок дублируется вaria-label. - Фокус при открытии переносится на кнопку подтверждения — так Enter даёт безопасный ответ, а Shift+Enter отменяет. При закрытии фокус возвращается на элемент, вызвавший диалог.
- Escape отменяет диалог; Tab удерживает фокус внутри (фокус-тэп через
trapFocus). - Пока открыт диалог, прокрутка страницы блокируется (
lockBodyScroll). - Телепорт рендерится только на клиенте, поэтому SSR-разметка не расходится при нескольких таких компонентах.
- Анимация появления использует переход
c3-modal-*и отключается приprefers-reduced-motion. - Тип
danger, как уButton, намеренно не поддерживается: для опасных действий передавайтеtype: 'error'— так палитра остаётся семантической.