API корня
Dialog — корневой контейнер состояния для модального поведения.
| Проп | Тип | По умолчанию |
|---|---|---|
open | boolean | — |
| Открыто ли модальное окно сейчас. Если задан, модальное окно становится контролируемым компонентом. | ||
defaultOpen | boolean | false |
| Открыто ли модальное окно по умолчанию. | ||
onChangeOpen | (state: boolean) => void | — |
| Колбэк, вызываемый при изменении состояния открытия модального окна. Получает следующее состояние в виде boolean. | ||
children | ReactNode | ReactNode[] | — |
| Содержимое, рендерящееся внутри диалога. Может включать заголовки, текст, действия и вложенные компоненты. | ||
fluid | boolean | — |
| Делает диалог резиновым, позволяя ему адаптивно растягиваться в контейнере. Полезно для адаптации к разным размерам экрана и раскладкам. | ||
API дочерних частей
DialogTrigger
Действие, открывающее диалог.
| Проп | Тип | По умолчанию |
|---|---|---|
asChild | boolean | — |
Если true, рендерит триггер как дочерний элемент через Slot. Позволяет собственным элементам-обёрткам (например, <a>, <div>) работать как триггеры модального окна. | ||
ref | Ref<HTMLButtonElement> | — |
Ref, передаваемый на нижележащий элемент триггера (обычно <button>). Полезен для управления фокусом или императивного доступа. | ||
Также принимает все атрибуты <button>.
- Типичное использование:
asChildсButton - Должен оставаться внутри
Dialog - Выставляет
aria-haspopup='dialog'иaria-expanded
DialogContent
Нативный модальный <dialog>.
| Проп | Тип | По умолчанию |
|---|---|---|
shadowed | boolean | true |
| Добавляет панели диалога тень. Создаёт глубину и отделяет её от фона. | ||
blurred | boolean | true |
| Размывает страницу за диалогом. | ||
overlay | boolean | true |
| Затемняет страницу за диалогом. При false страница остаётся видимой, а диалог — модальным. | ||
closedBy | ModalDialogClosedBy | 'closerequest' |
Какие действия пользователя закрывают диалог, как нативный атрибут closedby: any — клик по подложке или Escape, closerequest — только Escape, none — ни то, ни другое. | ||
ref | Ref<HTMLDialogElement> | — |
Ref, передаваемый на нативный элемент <dialog>. Полезен для управления фокусом, анимациями или измерений. | ||
children | ReactNode | — |
| Дочерние узлы для рендера внутри диалога. | ||
Также принимает все атрибуты <dialog>.
- Сам не задаёт ни
id, ниaria-labelledby: назовите его черезaria-labelledby, указывающий наidвашего заголовка, или черезaria-label.onCancelиonCloseвыполняются после внутренних обработчиков. blurred(по умолчаниюtrue) размывает страницу за диалогом;overlay(по умолчаниюtrue) затемняет её, а сoverlay={false}диалог остаётся модальным над прозрачной подложкой;shadowed(по умолчаниюtrue) добавляет поверхности тень.closedByзадаёт, какие действия пользователя закрывают диалог, как нативный атрибутclosedby:'any'(клик по подложке илиEscape),'closerequest'(толькоEscape, по умолчанию) или'none'. Клик по подложке не закрывает диалог, если не заданclosedBy='any'.- Закрывается при отправке
<form method="dialog">внутри него, в том числе сclosedBy='none'. Закрытие проходит черезonChangeOpen(false), поэтому проигрывается переход закрытия, а контролирующий родитель может оставить диалог открытым;valueкнопки отправки становитсяreturnValueдиалога. - Остаётся смонтированным, только пока открыт и пока проигрывается переход закрытия.
DialogClose
Закрывает диалог по клику. У него нет стилей, иконки и aria-label по умолчанию: отрендерите внутри свою кнопку через asChild и задайте ей метку.
| Проп | Тип | По умолчанию |
|---|---|---|
asChild | boolean | — |
Если true, рендерит действие закрытия как дочерний элемент через Slot, поэтому любая ваша кнопка закрывает диалог. | ||
ref | Ref<HTMLButtonElement> | — |
| Ref, передаваемый на нижележащую кнопку. | ||
Также принимает все атрибуты <button>.
- Закрытие проходит через
onChangeOpen(false), поэтому проигрывается переход закрытия, а контролирующий родитель может оставить диалог открытым. - Используйте его для отдельной кнопки закрытия, например крестика в шапке. Для кнопок, которые отвечают на диалог («Отмена», «Подтвердить»,
returnValue), используйте<form method="dialog">. БезasChildон рендеритtype="button", поэтому работает и внутри вашей собственной формы, не отправляя её; сasChildзадайте своей кнопкеtype="button". - Ваш
onClickсрабатывает после запроса на закрытие, поэтому в нём можно запомнить, какой кнопкой закрыли диалог.
close-with-handler.tsx · 55 строк
import { useId, useState, type CSSProperties } from 'react';
import {
Button,
Dialog,
DialogClose,
DialogContent,
DialogTrigger,
Heading,
Icon,
IconButton,
Text,
} from '@vega-ui/react';Хуки
useDialogContext
Продвинутый хук для кастомных обёрток и действий закрытия. Возвращает { open, changeOpen, fluid }.
Используйте его, только если экспортируемых частей недостаточно для нужной композиции.
Типы
| Тип | Определение | Примечания |
|---|---|---|
DialogProps | Тип пропсов корня | Здесь находится API состояния открытия. |
DialogTriggerProps | Тип пропсов триггера | Контракт композиции триггера. |
DialogContentProps | Тип пропсов содержимого | Пропсы контейнера содержимого. |
DialogCloseProps | Тип пропсов части закрытия | Атрибуты <button> плюс asChild. |
Модель состояния
- Состояние открытия может быть контролируемым через
openили неконтролируемым черезdefaultOpen. DialogTrigger— обычный способ открытия в неконтролируемом режиме.- Каждый запрос на закрытие, разрешённый
closedBy(клик по подложке,Escape), каждый клик поDialogCloseи каждая отправка<form method="dialog">проходят черезonChangeOpen(false); контролируемый диалог остаётся открытым, покаopenне станетfalse. - Если браузер сам закрывает диалог, а
openвсё ещёtrue, диалог открывается снова.
Замечания по интеграции
- Называйте каждый диалог через
aria-labelledbyилиaria-labelнаDialogContent. - Чтобы закрыть диалог изнутри, используйте
DialogCloseдля отдельной кнопки закрытия, кнопки в<form method="dialog">для действий, отвечающих на диалог, или контролируемыйopenи кнопку, вызывающуюsetOpen(false). - Перепроверяйте вложенные оверлеи в реальной композиции, а не только изолированно.
- Делайте длинное содержимое прокручиваемым, чтобы закрытие и действия оставались доступными.