# Alert Dialog

A modal confirmation that requires an explicit user response before a destructive action.

## Installation

```tsx
import {
  AlertDialog,
  AlertDialogTrigger,
  AlertDialogContent,
  AlertDialogBody,
  AlertDialogHeader,
  AlertDialogIcon,
  AlertDialogIntro,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogActions,
  AlertDialogActionGroup,
  AlertDialogCloseGroup,
  AlertDialogClose,
} from "@makeplane/propel/components/alert-dialog";
```
## Usage

Compose a 600px card: `AlertDialogBody` stacks the intent badge (`AlertDialogIcon`) above the
title/description (`AlertDialogIntro`), optional fields go in the body under the header, and
`AlertDialogActions` is the flush footer. Pin a corner dismiss with `AlertDialogCloseGroup` +
`IconButton` rendering `AlertDialogClose`.

Escape cancels the topmost alert and restores focus to its trigger. Clicking outside leaves it open.
Cancel and the corner dismiss should produce the same non-destructive outcome. Consumers can veto
a close with `onOpenChange` and `details.cancel()` while an operation is pending.

Below 640px, the card bottom-aligns with 16px viewport gutters, the badge grows to 48px, the intro
centers, and actions stack in reverse order at full width. Larger screens retain the centered
600px Figma card. This retains the legacy mobile behavior approved in AD-F10.

Use `Button variant="secondary" size="md"` for Cancel or the safe alternative, `danger` for an
irreversible action, and `primary` for other confirmations. Reserve `ghost` for an optional third
action. Keep the footer to three actions at most. Within this footer, secondary and ghost buttons
at the recommended size use the Figma 14px label; primary and danger retain 13px. Buttons outside
Alert Dialog retain their normal typography. The alert scrim is black at 25% opacity.

Use `AlertDialogActions layout="split"` with a leading alternative and an `AlertDialogActionGroup`
containing Cancel and Confirm. The default `layout="inline"` retains the end-aligned row. Both
layouts reverse into full-width actions below 640px. When a leading alternative comes before
Cancel in DOM order, pass the Cancel button ref as `AlertDialogContent initialFocus`.

```tsx
<AlertDialogActions layout="split">
  <Button variant="ghost" size="md" stretch="auto" label="Discard changes" />
  <AlertDialogActionGroup>
    <Button
      variant="secondary"
      size="md"
      stretch="auto"
      label="Cancel"
      render={<AlertDialogClose />}
    />
    <Button variant="primary" size="md" stretch="auto" label="Save changes" />
  </AlertDialogActionGroup>
</AlertDialogActions>
```

The design review's AD-F10 decision takes precedence over the reference guidance's “always center”
wording on mobile; this component intentionally preserves the approved responsive behavior.

On open, focus lands on the first action button. If the body can scroll, give `AlertDialogBody`
`tabIndex={0}` so keyboard users can reach the scroll region, and pass `initialFocus` to
`AlertDialogContent` to keep the opening focus on Cancel.

```tsx
import {
  AlertDialog,
  AlertDialogActions,
  AlertDialogBody,
  AlertDialogClose,
  AlertDialogCloseGroup,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogHeader,
  AlertDialogIcon,
  AlertDialogIntro,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@makeplane/propel/components/alert-dialog";
import { Button } from "@makeplane/propel/components/button";
import { Icon } from "@makeplane/propel/components/icon";
import { IconButton } from "@makeplane/propel/components/icon-button";
import { CloseOutline } from "@makeplane/propel/icons";

export default function BasicDemo() {
  return (
    <AlertDialog>
      <Button
        stretch="auto"
        variant="danger"
        size="md"
        render={<AlertDialogTrigger />}
        label="Delete project"
      />
      <AlertDialogContent>
        <AlertDialogBody>
          <AlertDialogHeader>
            <AlertDialogIcon variant="danger" />
            <AlertDialogIntro>
              <AlertDialogTitle>Delete project?</AlertDialogTitle>
              <AlertDialogDescription>
                This permanently removes the project and all of its work items. This action
                can&apos;t be undone.
              </AlertDialogDescription>
            </AlertDialogIntro>
          </AlertDialogHeader>
        </AlertDialogBody>
        <AlertDialogActions>
          <Button
            stretch="auto"
            variant="secondary"
            size="md"
            render={<AlertDialogClose />}
            label="Cancel"
          />
          <Button
            stretch="auto"
            variant="danger"
            size="md"
            render={<AlertDialogClose />}
            label="Delete"
          />
        </AlertDialogActions>
        <AlertDialogCloseGroup>
          <IconButton
            variant="ghost"
            size="xs"
            aria-label="Close"
            render={<AlertDialogClose />}
            icon={<Icon icon={CloseOutline} />}
          />
        </AlertDialogCloseGroup>
      </AlertDialogContent>
    </AlertDialog>
  );
}
```
## Examples

### Variants

The leading `AlertDialogIcon` badge sets the confirmation's intent through its required `variant`
— `danger`, `warning`, `info`, or `success`. It uses the matching Plane outline status glyph. Use a `danger` primary action for destructive confirmations; other intents typically
use `primary`. Use a toast or inline message for passive success information.

```tsx
import {
  AlertDialog,
  AlertDialogActions,
  AlertDialogBody,
  AlertDialogClose,
  AlertDialogCloseGroup,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogHeader,
  AlertDialogIcon,
  AlertDialogIntro,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@makeplane/propel/components/alert-dialog";
import { Button } from "@makeplane/propel/components/button";
import { Icon } from "@makeplane/propel/components/icon";
import { IconButton } from "@makeplane/propel/components/icon-button";
import { CloseOutline } from "@makeplane/propel/icons";

export default function VariantsDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <AlertDialog>
        <Button
          stretch="auto"
          variant="danger"
          size="md"
          render={<AlertDialogTrigger />}
          label="Delete project"
        />
        <AlertDialogContent>
          <AlertDialogBody>
            <AlertDialogHeader>
              <AlertDialogIcon variant="danger" />
              <AlertDialogIntro>
                <AlertDialogTitle>Delete project?</AlertDialogTitle>
                <AlertDialogDescription>
                  This permanently removes the project and all of its work items. This action
                  can&apos;t be undone.
                </AlertDialogDescription>
              </AlertDialogIntro>
            </AlertDialogHeader>
          </AlertDialogBody>
          <AlertDialogActions>
            <Button
              stretch="auto"
              variant="secondary"
              size="md"
              render={<AlertDialogClose />}
              label="Cancel"
            />
            <Button
              stretch="auto"
              variant="danger"
              size="md"
              render={<AlertDialogClose />}
              label="Delete"
            />
          </AlertDialogActions>
          <AlertDialogCloseGroup>
            <IconButton
              variant="ghost"
              size="xs"
              aria-label="Close"
              render={<AlertDialogClose />}
              icon={<Icon icon={CloseOutline} />}
            />
          </AlertDialogCloseGroup>
        </AlertDialogContent>
      </AlertDialog>

      <AlertDialog>
        <Button
          stretch="auto"
          variant="secondary"
          size="md"
          render={<AlertDialogTrigger />}
          label="Archive project"
        />
        <AlertDialogContent>
          <AlertDialogBody>
            <AlertDialogHeader>
              <AlertDialogIcon variant="warning" />
              <AlertDialogIntro>
                <AlertDialogTitle>Archive project?</AlertDialogTitle>
                <AlertDialogDescription>
                  Archiving hides the project from your sidebar. You can restore it later from
                  workspace settings.
                </AlertDialogDescription>
              </AlertDialogIntro>
            </AlertDialogHeader>
          </AlertDialogBody>
          <AlertDialogActions>
            <Button
              stretch="auto"
              variant="secondary"
              size="md"
              render={<AlertDialogClose />}
              label="Cancel"
            />
            <Button
              stretch="auto"
              variant="primary"
              size="md"
              render={<AlertDialogClose />}
              label="Archive"
            />
          </AlertDialogActions>
          <AlertDialogCloseGroup>
            <IconButton
              variant="ghost"
              size="xs"
              aria-label="Close"
              render={<AlertDialogClose />}
              icon={<Icon icon={CloseOutline} />}
            />
          </AlertDialogCloseGroup>
        </AlertDialogContent>
      </AlertDialog>

      <AlertDialog>
        <Button
          stretch="auto"
          variant="secondary"
          size="md"
          render={<AlertDialogTrigger />}
          label="Transfer ownership"
        />
        <AlertDialogContent>
          <AlertDialogBody>
            <AlertDialogHeader>
              <AlertDialogIcon variant="info" />
              <AlertDialogIntro>
                <AlertDialogTitle>Transfer ownership?</AlertDialogTitle>
                <AlertDialogDescription>
                  Ownership of this project moves to another member. You&apos;ll keep your member
                  access.
                </AlertDialogDescription>
              </AlertDialogIntro>
            </AlertDialogHeader>
          </AlertDialogBody>
          <AlertDialogActions>
            <Button
              stretch="auto"
              variant="secondary"
              size="md"
              render={<AlertDialogClose />}
              label="Cancel"
            />
            <Button
              stretch="auto"
              variant="primary"
              size="md"
              render={<AlertDialogClose />}
              label="Transfer"
            />
          </AlertDialogActions>
          <AlertDialogCloseGroup>
            <IconButton
              variant="ghost"
              size="xs"
              aria-label="Close"
              render={<AlertDialogClose />}
              icon={<Icon icon={CloseOutline} />}
            />
          </AlertDialogCloseGroup>
        </AlertDialogContent>
      </AlertDialog>

      <AlertDialog>
        <Button
          stretch="auto"
          variant="secondary"
          size="md"
          render={<AlertDialogTrigger />}
          label="Restore project"
        />
        <AlertDialogContent>
          <AlertDialogBody>
            <AlertDialogHeader>
              <AlertDialogIcon variant="success" />
              <AlertDialogIntro>
                <AlertDialogTitle>Restore project?</AlertDialogTitle>
                <AlertDialogDescription>
                  This brings the project back to your sidebar with all of its work items intact.
                </AlertDialogDescription>
              </AlertDialogIntro>
            </AlertDialogHeader>
          </AlertDialogBody>
          <AlertDialogActions>
            <Button
              stretch="auto"
              variant="secondary"
              size="md"
              render={<AlertDialogClose />}
              label="Cancel"
            />
            <Button
              stretch="auto"
              variant="primary"
              size="md"
              render={<AlertDialogClose />}
              label="Restore"
            />
          </AlertDialogActions>
          <AlertDialogCloseGroup>
            <IconButton
              variant="ghost"
              size="xs"
              aria-label="Close"
              render={<AlertDialogClose />}
              icon={<Icon icon={CloseOutline} />}
            />
          </AlertDialogCloseGroup>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
```

### Rich descriptions

`AlertDialogDescription` defaults to a paragraph. Use `render={<div />}` when its content includes
paragraphs or a list; styling and the popup's accessible description remain connected. Put controls
and larger interactive content in `AlertDialogBody`, outside the description.

### Long content

The body caps at 680px and scrolls while the actions stay pinned. A scrollable region has to be
keyboard-reachable, so pass `tabIndex={0}` on `AlertDialogBody`. That puts the body first in tab
order, so also pass `initialFocus` to `AlertDialogContent` pointing at Cancel; otherwise the dialog
opens focused on the scroll region.

```tsx
import {
  AlertDialog,
  AlertDialogActions,
  AlertDialogBody,
  AlertDialogClose,
  AlertDialogCloseGroup,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogHeader,
  AlertDialogIcon,
  AlertDialogIntro,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@makeplane/propel/components/alert-dialog";
import { Button } from "@makeplane/propel/components/button";
import { Icon } from "@makeplane/propel/components/icon";
import { IconButton } from "@makeplane/propel/components/icon-button";
import { CloseOutline } from "@makeplane/propel/icons";
import * as React from "react";

const AFFECTED = Array.from({ length: 14 }, (_, index) => ({
  identifier: `WEB-${8210 + index}`,
  title: "Cycle burndown drifts after a work item moves between cycles",
}));

export default function LongContentDemo() {
  const cancelRef = React.useRef<HTMLButtonElement>(null);
  return (
    <AlertDialog>
      <Button
        stretch="auto"
        variant="danger"
        size="md"
        render={<AlertDialogTrigger />}
        label="Archive matching work items"
      />
      {/* The body is focusable so keyboard users can scroll it; `initialFocus` keeps the
          opening focus on Cancel instead of the scroll region that now comes first. */}
      <AlertDialogContent initialFocus={cancelRef}>
        <AlertDialogBody tabIndex={0}>
          <AlertDialogHeader>
            <AlertDialogIcon variant="warning" />
            <AlertDialogIntro>
              <AlertDialogTitle>Archive all matching work items?</AlertDialogTitle>
              <AlertDialogDescription>
                This archives every work item that matches the current filter and hides them from
                all default views. An admin can restore any of them from the archive.
              </AlertDialogDescription>
            </AlertDialogIntro>
          </AlertDialogHeader>
          <ul className="flex flex-col gap-2">
            {AFFECTED.map((item) => (
              <li key={item.identifier} className="flex gap-2 text-body-sm-regular">
                <span className="shrink-0 text-tertiary">{item.identifier}</span>
                <span className="text-primary">{item.title}</span>
              </li>
            ))}
          </ul>
        </AlertDialogBody>
        <AlertDialogActions>
          <Button
            stretch="auto"
            variant="secondary"
            size="md"
            ref={cancelRef}
            render={<AlertDialogClose />}
            label="Cancel"
          />
          <Button
            stretch="auto"
            variant="danger"
            size="md"
            render={<AlertDialogClose />}
            label="Archive"
          />
        </AlertDialogActions>
        <AlertDialogCloseGroup>
          <IconButton
            variant="ghost"
            size="xs"
            aria-label="Close"
            render={<AlertDialogClose />}
            icon={<Icon icon={CloseOutline} />}
          />
        </AlertDialogCloseGroup>
      </AlertDialogContent>
    </AlertDialog>
  );
}
```

### Open from menu

An alert dialog opened by a menu item is controlled through `open` / `onOpenChange` rather than an `AlertDialogTrigger`.

```tsx
import {
  AlertDialog,
  AlertDialogActions,
  AlertDialogBody,
  AlertDialogClose,
  AlertDialogCloseGroup,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogHeader,
  AlertDialogIcon,
  AlertDialogIntro,
  AlertDialogTitle,
} from "@makeplane/propel/components/alert-dialog";
import { Button } from "@makeplane/propel/components/button";
import { Icon } from "@makeplane/propel/components/icon";
import { IconButton } from "@makeplane/propel/components/icon-button";
import { Menu, MenuContent, MenuItem, MenuTrigger } from "@makeplane/propel/components/menu";
import { CloseOutline } from "@makeplane/propel/icons";
import * as React from "react";

export default function OpenFromMenuDemo() {
  const [confirmOpen, setConfirmOpen] = React.useState(false);
  return (
    <>
      <Menu>
        <Button
          stretch="auto"
          variant="secondary"
          size="md"
          render={<MenuTrigger />}
          label="Project options"
        />
        <MenuContent>
          <MenuItem label="Rename" />
          <MenuItem label="Duplicate" />
          <MenuItem onClick={() => setConfirmOpen(true)} label="Delete project…" />
        </MenuContent>
      </Menu>
      <AlertDialog open={confirmOpen} onOpenChange={setConfirmOpen}>
        <AlertDialogContent>
          <AlertDialogBody>
            <AlertDialogHeader>
              <AlertDialogIcon variant="danger" />
              <AlertDialogIntro>
                <AlertDialogTitle>Delete project?</AlertDialogTitle>
                <AlertDialogDescription>
                  This permanently removes the project and all of its work items. This action
                  can&apos;t be undone.
                </AlertDialogDescription>
              </AlertDialogIntro>
            </AlertDialogHeader>
          </AlertDialogBody>
          <AlertDialogActions>
            <Button
              stretch="auto"
              variant="secondary"
              size="md"
              render={<AlertDialogClose />}
              label="Cancel"
            />
            <Button
              stretch="auto"
              variant="danger"
              size="md"
              render={<AlertDialogClose />}
              label="Delete"
            />
          </AlertDialogActions>
          <AlertDialogCloseGroup>
            <IconButton
              variant="ghost"
              size="xs"
              aria-label="Close"
              render={<AlertDialogClose />}
              icon={<Icon icon={CloseOutline} />}
            />
          </AlertDialogCloseGroup>
        </AlertDialogContent>
      </AlertDialog>
    </>
  );
}
```

### Multiple triggers

`createAlertDialogHandle` connects many detached triggers to one shared confirmation, each passing the project it acts on as its `payload`.

```tsx
import {
  AlertDialog,
  AlertDialogActions,
  AlertDialogBody,
  AlertDialogClose,
  AlertDialogCloseGroup,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogHeader,
  AlertDialogIcon,
  AlertDialogIntro,
  AlertDialogTitle,
  AlertDialogTrigger,
  createAlertDialogHandle,
} from "@makeplane/propel/components/alert-dialog";
import { Button } from "@makeplane/propel/components/button";
import { Icon } from "@makeplane/propel/components/icon";
import { IconButton } from "@makeplane/propel/components/icon-button";
import { CloseOutline } from "@makeplane/propel/icons";

// One shared confirmation driven by detached triggers: each trigger passes the project it acts on
// as its `payload`, and the root reads that payload to personalize the copy.
const deleteProjectHandle = createAlertDialogHandle();

export default function MultipleTriggersDemo() {
  return (
    <>
      <div className="flex flex-wrap items-center gap-3">
        {["Mobile app", "Design system"].map((project) => (
          <Button
            key={project}
            stretch="auto"
            variant="secondary"
            size="md"
            render={<AlertDialogTrigger handle={deleteProjectHandle} payload={project} />}
            label={`Delete ${project}`}
          />
        ))}
      </div>
      <AlertDialog handle={deleteProjectHandle}>
        {({ payload }: { payload: unknown }) => (
          <AlertDialogContent>
            <AlertDialogBody>
              <AlertDialogHeader>
                <AlertDialogIcon variant="danger" />
                <AlertDialogIntro>
                  <AlertDialogTitle>
                    Delete {typeof payload === "string" ? payload : "this project"}?
                  </AlertDialogTitle>
                  <AlertDialogDescription>
                    This permanently removes the project and all of its work items. This action
                    can&apos;t be undone.
                  </AlertDialogDescription>
                </AlertDialogIntro>
              </AlertDialogHeader>
            </AlertDialogBody>
            <AlertDialogActions>
              <Button
                stretch="auto"
                variant="secondary"
                size="md"
                render={<AlertDialogClose />}
                label="Cancel"
              />
              <Button
                stretch="auto"
                variant="danger"
                size="md"
                render={<AlertDialogClose />}
                label="Delete"
              />
            </AlertDialogActions>
            <AlertDialogCloseGroup>
              <IconButton
                variant="ghost"
                size="xs"
                aria-label="Close"
                render={<AlertDialogClose />}
                icon={<Icon icon={CloseOutline} />}
              />
            </AlertDialogCloseGroup>
          </AlertDialogContent>
        )}
      </AlertDialog>
    </>
  );
}
```
## API Reference

### AlertDialog

Modal confirmation root. Escape dismisses the topmost alert as a cancellation, matching Plane's
existing behavior. Outside presses do not dismiss it. Consumers can veto a close through
`onOpenChange` and `details.cancel()`, for example while a request is pending.

Base UI owns focus trapping, nested dismissal, and focus restoration. Explicit close controls,
`actionsRef.close()`, and controlled `open` state remain available.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode \| PayloadChildRenderFunction<unknown>` | — | The content of the dialog. This can be a regular React node or a render function that receives the `payload` of the active trigger. |

### AlertDialogTrigger

The behavior that opens the alert dialog. Use as the `render` target of a `Button` so the styled
primitive's look wins via render-composition:

```tsx
<Button variant="danger" size="lg" label="Delete project" render={<AlertDialogTrigger />} />;
```

Base UI manages `aria-haspopup`/`aria-expanded` and focus restoration when the alert dialog
closes. Maps 1:1 to `AlertDialog.Trigger`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `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. |

### AlertDialogContent

Convenience that composes the alert dialog overlay boilerplate — Base UI portal, the 25% black
backdrop, the responsive viewport, and the popup — so a consumer only writes the trigger and the
popup body.

Initial focus follows Base UI: the first tabbable element in the popup, which in the default
anatomy is the first action button (Cancel). Pass `initialFocus` (a ref, or a function of the
interaction type) to steer it — for example onto Cancel when a scrollable `AlertDialogBody` with
`tabIndex={0}` would otherwise come first in DOM order. `finalFocus` overrides where focus
returns on close (default: the trigger).

Nested alerts keep their own 25% scrim: Base UI omits a nested Backdrop unless `forceRender` is
set, which would leave a confirmation sitting on its parent dialog with no extra overlay. Closed
force-rendered backdrops set `pointer-events: none` so they cannot steal clicks from the parent
while unmounting.

No component-specific props — accepts the standard HTML attributes for the element it renders.

### AlertDialogBody

The padded content region of the alert dialog popup (20px top and sides, 12px bottom). Stacks the
header (icon + intro) and any optional body content (form fields, extra copy) with a 16px gap.
Caps height so tall content scrolls while the actions footer stays pinned. Wide descendants are
constrained by an inner `overflow-x-clip` wrapper so focus scrolling cannot pan sideways.

Not focusable by default, so the dialog's initial focus lands on the first action button rather
than on a region nothing can be done with (Dialog pattern). When the body can overflow, pass
`tabIndex={0}` so the scroll region is keyboard-reachable (WCAG 2.1.1); pair it with
`initialFocus` on `AlertDialogContent` if focus should still start on an action.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `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. |

### AlertDialogHeader

Groups the leading `AlertDialogIcon` badge above the `AlertDialogIntro` (title + description).
Lives inside `AlertDialogBody`. Pass icon and intro as children.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `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. |

### AlertDialogIcon

The leading intent badge above the title. Soft tinted surface + outline status glyph selected
from `variant` — callers never pass an icon (matches the Alert Dialog Figma family). Decorative
(`aria-hidden`) — the title carries the accessible name.

`variant` is required (`danger` | `warning` | `info` | `success`).

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `variant` (required) | `"danger" \| "warning" \| "info" \| "success"` | — |  |
| `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. |

### AlertDialogIntro

Groups the title and description with a 6px gap. Pass `AlertDialogTitle` and
`AlertDialogDescription` as children.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `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. |

### AlertDialogTitle

The accessible title for the alert dialog. Base UI links it to the popup via `aria-labelledby`;
the styled `elements` title supplies the h6/semibold look.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `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. |

### AlertDialogDescription

The supporting description for the alert dialog. Base UI links it to the popup via
`aria-describedby`; the styled `elements` description supplies the body-sm / secondary look.
Defaults to a paragraph. Pass `render={<div />}` for block content such as an impact list; both
the description styling and Base UI accessibility wiring are preserved.

| Prop | Type | Default | 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. |

### AlertDialogActions

The footer row of action buttons. Sits flush under the body with no divider, pads 12px on top and
20px on the sides and bottom (Figma), and end-aligns children with a 12px gap. Below 640px,
actions form a reversed full-width column, retaining the legacy mobile order.

Layout groups actions at the end, or separates a leading action from an action group.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `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. |
| `layout` | `"inline" \| "split"` | `"inline"` | End-align actions in one row, or separate a leading action from an action group. |

### AlertDialogActionGroup

Keeps related footer actions together in a split footer.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `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. |

### AlertDialogCloseGroup

Positions the corner dismiss control at the popup's top-end. Pass an `IconButton` (components
tier) or the styled `AlertDialogClose` (elements showcase) as the child.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `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. |

### AlertDialogClose

The behavior that closes the alert dialog when activated. Use as the `render` target of a
`Button` so the styled primitive's look wins via render-composition:

```tsx
<Button variant="secondary" size="lg" label="Cancel" render={<AlertDialogClose />} />;
```

Maps 1:1 to `AlertDialog.Close`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `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. |
