> ## Documentation Index
> Fetch the complete documentation index at: https://docs.twenty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AlertDialog

> Запрашивает подтверждение перед действием, требующим явного решения.

## Обзор

Используйте `AlertDialog` для решения, которое прерывает текущий рабочий процесс, например для подтверждения удаления. Он предоставляет семантику `alertdialog`, управление фокусом и явное подтверждение или отмену.

Этот примитив предназначен для автономных интерфейсов Twenty UI и интерфейсов, принадлежащих хосту. Компоненты Front должны запрашивать подтверждение через [API диалогового окна хоста SDK](https://docs.twenty.com/ru/developers/extend/apps/layout/front-components.md#host-communication-api). Прямое использование `Dialog`, `AlertDialog` и нативных диалоговых окон браузера запрещено внутри рендерера фронтового компонента.

**Light**

[Пример AlertDialog (light)](https://storybook.twenty.com/iframe.html?id=ui-surfaces-alertdialog--display\&viewMode=story\&globals=colorScheme:light)

**Dark**

[Пример AlertDialog (dark)](https://storybook.twenty.com/iframe.html?id=ui-surfaces-alertdialog--display\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-surfaces-alertdialog--display)

## Использование

### Неконтролируемое состояние

Используйте `defaultOpen`, чтобы задать начальную видимость. Диалог управляет последующими изменениями, вызванными его триггером, элементами управления закрытием и взаимодействиями закрытия.

```tsx theme={null}
import { Button } from 'twenty-ui/primitives/input';
import { AlertDialog } from 'twenty-ui/primitives/surfaces';

type DeleteConfirmationProps = { onDelete: () => void };

export const DeleteConfirmation = ({ onDelete }: DeleteConfirmationProps) => (
  <AlertDialog.Root defaultOpen={false}>
    <AlertDialog.Trigger
      render={<Button variant="solid">Delete record</Button>}
    />
    <AlertDialog.Portal>
      <AlertDialog.Backdrop />
      <AlertDialog.Viewport>
        <AlertDialog.Popup>
          <AlertDialog.Header>
            <AlertDialog.Title>Delete this record?</AlertDialog.Title>
            <AlertDialog.Description>
              This record will be permanently deleted. This action cannot be
              undone.
            </AlertDialog.Description>
          </AlertDialog.Header>
          <AlertDialog.Footer>
            <AlertDialog.Close render={<Button>Cancel</Button>} />
            <AlertDialog.Close
              onClick={onDelete}
              render={<Button color="danger">Delete</Button>}
            />
          </AlertDialog.Footer>
        </AlertDialog.Popup>
      </AlertDialog.Viewport>
    </AlertDialog.Portal>
  </AlertDialog.Root>
);
```

По умолчанию для `defaultOpen` установлено значение `false`, поэтому его можно опустить. В этом примере используется синхронный обратный вызов подтверждения, и диалог закрывается после выполнения действия.

## Анатомия компонента.

Держите связанные части внутри `AlertDialog.Root` или подключайте отдельные триггеры через дескриптор. Комбинируйте портал, фон, область просмотра и всплывающее окно по отдельности.

```text theme={null}
AlertDialog.Root
├── AlertDialog.Trigger
└── AlertDialog.Portal
    ├── AlertDialog.Backdrop
    └── AlertDialog.Viewport
        └── AlertDialog.Popup
            ├── AlertDialog.Header
            │   ├── AlertDialog.Title
            │   └── AlertDialog.Description
            ├── AlertDialog.Body
            └── AlertDialog.Footer
                ├── AlertDialog.Close
                └── Confirmation action
```

| Часть | Требование | Назначение |
| - | - | - |
| `Root` | Обязательно | Управляет состоянием открытия и поведением модального окна. |
| `Триггер` | Необязательно для диалога, открываемого программно | Открывает диалог и предоставляет цель для возврата фокуса. |
| `Portal` | Рекомендуется | Перемещает наложение в контейнер и управляет монтированием. |
| `Backdrop` | Необязательно | Визуально отделяет предупреждение от окружающей страницы. |
| `Viewport` | Рекомендуется | Размещает всплывающее окно и предоставляет окружающую его прокручиваемую область. |
| `Popup` | Обязательно | Отрисовывает содержимое предупреждения с управлением фокусом. |
| `Заголовок` | Рекомендуется | Предоставляет видимое имя предупреждения. Доступное имя всегда обязательно. |
| `Description` | Рекомендуется для подтверждения | Объясняет решение и его последствия. |
| `Header`, `Body`, `Footer` | Необязательные части структуры | Упорядочивают заголовки, дополнительное содержимое и действия. |
| `Закрыть` | Рекомендуется для отмены | Предоставляет явное действие закрытия. |

Задайте `container` и `keepMounted` для `Portal`, атрибуты фона для `Backdrop`, атрибуты макета для `Viewport`, а также `size` и свойства фокуса для `Popup`. Каждая часть элемента принимает собственные нативные атрибуты, обработчики, ref и композицию `render`. `Popup.ref` указывает на элемент содержимого предупреждения. `Title` и `Description` устанавливают связи для доступности; при отсутствии заголовка укажите `aria-label` для `Popup`.

Действие подтверждения является содержимым приложения, а не экспортируемой частью. Используйте `Close` с синхронным обработчиком или `Button` с управляемым состоянием открытия для асинхронного подтверждения.

## Контролируемое состояние

Передайте `open` и обновляйте его с помощью `onOpenChange`, чтобы управлять видимостью этого же диалога в состоянии React. Функция обратного вызова получает запрошенное логическое значение и сведения о вышестоящем событии, включая `reason`, `event` и `cancel()`. Вызовите `eventDetails.cancel()`, чтобы отклонить запрошенное изменение. `onOpenChangeComplete` выполняется после завершения переходов открытия или закрытия.

```tsx theme={null}
import { useState } from 'react';
import { Button } from 'twenty-ui/primitives/input';
import { AlertDialog } from 'twenty-ui/primitives/surfaces';

type DeleteConfirmationProps = { onDelete: () => void };

export const DeleteConfirmation = ({ onDelete }: DeleteConfirmationProps) => {
  const [open, setOpen] = useState(false);

  return (
    <AlertDialog.Root open={open} onOpenChange={setOpen}>
      <AlertDialog.Trigger
        render={<Button variant="solid">Delete record</Button>}
      />
      <AlertDialog.Portal>
        <AlertDialog.Backdrop />
        <AlertDialog.Viewport>
          <AlertDialog.Popup>
            <AlertDialog.Header>
              <AlertDialog.Title>Delete this record?</AlertDialog.Title>
              <AlertDialog.Description>
                This record will be permanently deleted. This action cannot be
                undone.
              </AlertDialog.Description>
            </AlertDialog.Header>
            <AlertDialog.Footer>
              <AlertDialog.Close render={<Button>Cancel</Button>} />
              <AlertDialog.Close
                onClick={onDelete}
                render={<Button color="danger">Delete</Button>}
              />
            </AlertDialog.Footer>
          </AlertDialog.Popup>
        </AlertDialog.Viewport>
      </AlertDialog.Portal>
    </AlertDialog.Root>
  );
};
```

Для асинхронного подтверждения используйте `Button` с обработчиком вашего действия вместо `AlertDialog.Close`. Сохраняйте значение `open` равным true, пока действие выполняется, вызовите `setOpen(false)` после его успешного завершения и покажите ошибку внутри диалога в случае сбоя.

## Композиция с кнопками

Используйте `render`, чтобы придать триггеру и элементам управления закрытием стиль кнопок Twenty UI. Части диалога предоставляют обработчики взаимодействия и ссылки для кнопок.

```tsx theme={null}
import { Button } from 'twenty-ui/primitives/input';
import { AlertDialog } from 'twenty-ui/primitives/surfaces';

type DeleteConfirmationProps = { onDelete: () => void };

export const DeleteConfirmation = ({ onDelete }: DeleteConfirmationProps) => (
  <AlertDialog.Root>
    <AlertDialog.Trigger
      render={<Button variant="solid">Delete record</Button>}
    />
    <AlertDialog.Portal>
      <AlertDialog.Backdrop />
      <AlertDialog.Viewport>
        <AlertDialog.Popup>
          <AlertDialog.Header>
            <AlertDialog.Title>Delete this record?</AlertDialog.Title>
            <AlertDialog.Description>
              This record will be permanently deleted. This action cannot be
              undone.
            </AlertDialog.Description>
          </AlertDialog.Header>
          <AlertDialog.Footer>
            <AlertDialog.Close render={<Button>Cancel</Button>} />
            <AlertDialog.Close
              onClick={onDelete}
              render={<Button color="danger">Delete</Button>}
            />
          </AlertDialog.Footer>
        </AlertDialog.Popup>
      </AlertDialog.Viewport>
    </AlertDialog.Portal>
  </AlertDialog.Root>
);
```

Сохраняйте каждое действие как один интерактивный элемент управления. Если вы оборачиваете `Button` в собственный компонент, [передавайте предоставленные свойства и ссылку](https://docs.twenty.com/ru/ui/primitives/overview#custom-components).

## Отдельные триггеры и императивные действия

Создайте дескриптор один раз с помощью `AlertDialog.createHandle\<Payload>()` и передайте его в `handle` у `Root` и каждого отдельного `Trigger`. Типизированный `payload` триггера доступен функции рендеринга дочернего элемента корневого компонента. Дескриптор также поддерживает `open(triggerId)`, `openWithPayload(payload)`, `close()` и геттер `isOpen`, пока его корневой компонент смонтирован. Передайте соответствующий идентификатор триггера в `open` или `null`, чтобы открыть без триггера. Вызывайте императивные методы из обработчиков событий или эффектов.

`Root.actionsRef` предоставляет `close()` и `unmount()`. Для внешне управляемой анимации закрытия вызовите `eventDetails.preventUnmountOnClose()` в `onOpenChange`, затем вызовите `actionsRef.current?.unmount()` после завершения анимации. Обычные стилизованные части управляют собственными переходами без этих императивных действий.

## Размеры и порталы

`Popup.size` принимает `sm`, `md`, `lg`, `xl` и `fullscreen`; по умолчанию используется `md`. Размер и внешний вид относятся к поверхности AlertDialog и не обязаны соответствовать предустановкам Dialog.

По умолчанию `Portal.container` использует контейнер портала ближайшей темы. Без него Base UI использует назначение портала по умолчанию, обычно `document.body`. Явно указанный элемент, теневой корень или ref переопределяет это назначение. Явно указанное значение `null` откладывает монтирование, пока контейнер не станет доступен. Base UI разрешает ref, у которого `current` имеет значение `null`, используя назначение по умолчанию; используйте `container={null}`, когда монтирование должно ожидать.

Содержимое, отрисованное через портал, сохраняет контекст темы. `Portal` и `Viewport` наследуют заданное направление текста, если вы явно не установите `dir`. Установите `Portal.keepMounted`, чтобы сохранять смонтированное содержимое и состояние формы в закрытом состоянии.

## Фокус и закрытие

Пока предупреждение открыто, оно удерживает фокус, блокирует внешнее взаимодействие и блокирует прокрутку страницы. Escape запрашивает закрытие; щелчок снаружи этого не делает. Чтобы предотвратить закрытие по Escape, отмените изменение `escape-key` в `onOpenChange`. Всегда предоставляйте видимое действие «Отмена» или «Закрыть».

По умолчанию фокус перемещается на первый элемент управления, доступный по Tab, или на всплывающее окно при открытии касанием. Поместите первым наименее разрушительное действие или используйте `Popup.initialFocus`, чтобы выбрать его. При закрытии предупреждения фокус возвращается к триггеру или ранее сфокусированному элементу. Используйте `Popup.finalFocus`, когда успешное действие удаляет этот целевой элемент. Оба свойства фокуса принимают логическое значение, ref элемента или функцию обратного вызова типа взаимодействия в соответствии с вышестоящим контрактом.

## Свойства

Справочник генерируется из публичных типов компонентов. Нативные атрибуты, включая доступные имена и обработчики событий, также поддерживаются для частей, отображающих элементы.

### AlertDialog.Root

**Root.actionsRef** `RefObject\<DialogRootActions | null\>`

A ref to imperative actions.

* `unmount`: Ends the closing phase of the alert dialog after an externally controlled closing animation finishes.
  Call `preventUnmountOnClose()` in `onOpenChange` first, otherwise the alert dialog completes closing on its own.
  Whether it leaves the DOM is decided by `keepMounted` on the portal.
* `close`: Closes the alert dialog imperatively when called.

**Root.children** `ReactNode | PayloadChildRenderFunction\<Payload\>`

The content of the dialog.
This can be a regular React node or a render function that receives the `payload` of the active trigger.

**Root.defaultOpen** `boolean` (default: false)

Whether the dialog is initially open.

To render a controlled dialog, use the `open` prop instead.

**Root.defaultTriggerId** `string | null`

ID of the trigger that the dialog is associated with.
This is useful in conjunction with the `defaultOpen` prop to create an initially open dialog.

**Root.handle** `AlertDialogHandle\<Payload\>`

A handle to associate the alert dialog with a trigger.
If specified, allows external triggers to control the alert dialog's open state.
Can be created with the AlertDialog.createHandle() method.

**Root.onOpenChange** `((open: boolean, eventDetails: AlertDialogRootChangeEventDetails) =\> void)`

Event handler called when the alert dialog is opened or closed.

**Root.onOpenChangeComplete** `((open: boolean) =\> void)`

Event handler called after any animations complete when the dialog is opened or closed.

**Root.open** `boolean`

Whether the dialog is currently open.

**Root.triggerId** `string | null`

ID of the trigger that the dialog is associated with.
This is useful in conjunction with the `open` prop to create a controlled dialog.
There's no need to specify this prop when the dialog is uncontrolled (that is, when the `open` prop is not set).

### AlertDialog.Trigger

**Trigger.className** `string | ((state: DialogTriggerState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Trigger.handle** `AlertDialogHandle\<Payload\>`

A handle to associate the trigger with an alert dialog.
Can be created with the AlertDialog.createHandle() method.

**Trigger.id** `string`

ID of the trigger. In addition to being forwarded to the rendered element,
it is also used to specify the active trigger for the dialog in controlled mode (with the DialogRoot `triggerId` prop).

**Trigger.nativeButton** `boolean` (default: true)

Whether the component renders a native `<button>` element when replacing it
via the `render` prop.
Set to `false` if the rendered element is not a button (for example, `<div>`).

**Trigger.payload** `Payload`

A payload to pass to the dialog when it is opened.

**Trigger.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, DialogTriggerState\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.

**Trigger.style** `CSSProperties | ((state: DialogTriggerState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

### AlertDialog.Portal

**Portal.className** `string | ((state: DialogPortalState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Portal.container** `HTMLElement | ShadowRoot | RefObject\<HTMLElement | ShadowRoot | null\> | null`

Portal destination. Omission uses the theme container or Base UI default; explicit `null` defers mounting. A ref with a null current value uses the Base UI default destination.

**Portal.keepMounted** `boolean` (default: false)

Keeps content mounted while the alert is closed.

**Portal.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, DialogPortalState\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.

**Portal.style** `CSSProperties | ((state: DialogPortalState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

### AlertDialog.Backdrop

**Backdrop.className** `string | ((state: DialogBackdropState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Backdrop.forceRender** `boolean` (default: false)

Whether the backdrop is forced to render even when nested.

**Backdrop.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, DialogBackdropState\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.

**Backdrop.style** `CSSProperties | ((state: DialogBackdropState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

### AlertDialog.Viewport

**Viewport.className** `string | ((state: DialogViewportState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Viewport.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, DialogViewportState\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.

**Viewport.style** `CSSProperties | ((state: DialogViewportState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

### AlertDialog.Popup

**Popup.className** `string | ((state: DialogPopupState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Popup.finalFocus** `boolean | RefObject\<HTMLElement | null\> | ((closeType: InteractionType) =\> boolean | void | HTMLElement | null)`

Determines the element to focus when the dialog is closed.

* `false`: Do not move focus.
* `true`: Move focus based on the default behavior (trigger or previously focused element).
* `RefObject`: Move focus to the ref element.
* `function`: Called with the interaction type (`mouse`, `touch`, `pen`, or `keyboard`).
  Return an element to focus, `true` to use the default behavior, `null` to fall back to the default behavior, or `false`/`undefined` to do nothing.

**Popup.initialFocus** `boolean | RefObject\<HTMLElement | null\> | ((openType: InteractionType) =\> boolean | void | HTMLElement | null)`

Determines the element to focus when the dialog is opened.
By default, focus moves to the first tabbable element inside the popup, except when the dialog
is opened by touch — then the popup itself is focused to avoid opening the virtual keyboard.

* `false`: Do not move focus.
* `true`: Move focus based on the default behavior (first tabbable element or popup).
* `RefObject`: Move focus to the ref element.
* `function`: Called with the interaction type (`mouse`, `touch`, `pen`, or `keyboard`).
  Return an element to focus, `true` to use the default behavior, `null` to fall back to the default behavior, or `false`/`undefined` to do nothing.

**Popup.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, DialogPopupState\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.

**Popup.size** `"fullscreen" | "lg" | "md" | "sm" | "xl"` (default: md)

Width of the alert, or `fullscreen` to fill the viewport.

**Popup.style** `CSSProperties | ((state: DialogPopupState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

### AlertDialog.Title

**Title.className** `string | ((state: DialogTitleState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Title.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, DialogTitleState\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.

**Title.style** `CSSProperties | ((state: DialogTitleState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

### AlertDialog.Description

**Description.className** `string | ((state: DialogDescriptionState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Description.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, DialogDescriptionState\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.

**Description.style** `CSSProperties | ((state: DialogDescriptionState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

### AlertDialog.Close

**Close.className** `string | ((state: DialogCloseState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Close.nativeButton** `boolean` (default: true)

Whether the component renders a native `<button>` element when replacing it
via the `render` prop.
Set to `false` if the rendered element is not a button (for example, `<div>`).

**Close.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, DialogCloseState\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.

**Close.style** `CSSProperties | ((state: DialogCloseState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

### AlertDialog.Header

**Header.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, \{\}\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.

### AlertDialog.Body

**Body.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, \{\}\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.

### AlertDialog.Footer

**Footer.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, \{\}\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.