BetaOverlays

Dialog

A question the page has to be answered before it goes on.

Overview

A question the page has to be answered before it goes on.

First example

<Dialog>
<Dialog.Trigger asChild>
<Button variant="danger">Supprimer</Button>
</Dialog.Trigger>
<Dialog.Overlay />
<Dialog.Content>
<Dialog.Title>Supprimer ce document ?</Dialog.Title>
<Dialog.Description>Définitif, sans corbeille.</Dialog.Description>
<Dialog.Close asChild>
<Button variant="danger">Supprimer</Button>
</Dialog.Close>
</Dialog.Content>
</Dialog>

Anatomy

<Dialog>
  <Dialog.Trigger>…</Dialog.Trigger>
  <Dialog.Overlay />
  <Dialog.Content>
    <Dialog.Close />
    <Dialog.Title>…</Dialog.Title>
    <Dialog.Description>…</Dialog.Description>
    <Dialog.Close>…</Dialog.Close>
  </Dialog.Content>
</Dialog>
  • Dialog — state and resolved style. It renders no node.
  • Dialog.Trigger — what asks the question.
  • Dialog.Overlay — the backdrop. It dims, and closes on a press.
  • Dialog.Content — the panel, centred and inset from the screen's edges.
  • Dialog.Title / Dialog.Description — the question and what it costs.
  • Dialog.Close — the way out. A cross when it is empty, whatever you put in it otherwise.

Usage

Basic

<Dialog>
  <Dialog.Trigger asChild>
    <Button variant="danger">Supprimer</Button>
  </Dialog.Trigger>
  <Dialog.Overlay />
  <Dialog.Content>
    <Dialog.Title>Supprimer ce document ?</Dialog.Title>
    <Dialog.Description>Définitif, sans corbeille.</Dialog.Description>
    <Dialog.Close asChild>
      <Button variant="danger">Supprimer</Button>
    </Dialog.Close>
  </Dialog.Content>
</Dialog>

One that must be answered

<Dialog.Overlay isDismissable={false} />

A press outside does nothing, so the only way out is through a Dialog.Close.

Style as props

<Dialog.Content padding={24} borderRadius={16} />
<Dialog.Title fontSize={22} />

Full RN names, full RN values (R14). Every node takes them.

Root props

DialogProps

The node's inherited React Native props apply too, and so do its style props padding, margin, width and the rest.

PropTypeRequiredDescription
childrenReactNodeNo
radiusRadiusKey | undefinedNo
isOpenboolean | undefinedNo
defaultOpenboolean | undefinedNo
onOpenChange((isOpen: boolean) => void) | undefinedNo
isDisabledboolean | undefinedNo

Slots

DialogCloseProps

The node's inherited React Native props apply too, and so do its style props padding, margin, width and the rest.

This slot adds nothing to the props of its React Native node.

DialogContentProps

The node's inherited React Native props apply too, and so do its style props padding, margin, width and the rest.

PropTypeRequiredDescription
childrenReactNodeNo

DialogDescriptionProps

The node's inherited React Native props apply too, and so do its style props padding, margin, width and the rest.

PropTypeRequiredDescription
childrenReactNodeNo

DialogOverlayProps

The node's inherited React Native props apply too, and so do its style props padding, margin, width and the rest.

PropTypeRequiredDescription
childrenReactNodeNo
isDismissableboolean | undefinedNoPressing the backdrop closes the dialog. Off for one that must be answered.

DialogTitleProps

The node's inherited React Native props apply too, and so do its style props padding, margin, width and the rest.

PropTypeRequiredDescription
childrenReactNodeNo

DialogTriggerProps

The node's inherited React Native props apply too, and so do its style props padding, margin, width and the rest.

PropTypeRequiredDescription
childrenReactNodeNo
asChildboolean | undefinedNo

Variants, sizes and colour

This component adds no visual axis of its own. The values it does take are in the generated types above and in the live demo.

Accessibility

The panel is accessibilityViewIsModal, so a screen reader stops at the dialog rather than reading the page behind it — the spoken half of what the backdrop says visually. The title is a header. The overlay announces nothing.

Migration from legacy

This component declares no rule of its own. The migration guide covers variants, colours and slots.

Implementation notes

How it differs from the `Popover`

Same portal, same context re-provision, same overlay keyframes. What it drops is everything that needs an anchor: the measuring pass, the host origin, the collision flip. A centred box has nothing to be measured against.

What it adds is two things:

The backdrop dims. A popover is an aside you read the page around; a dialog is a question, and the page behind it is not available until it is answered.

It grows from its own centre, 200 ms from scale: 0.94, rather than out of a trigger. A popover's entrance is offset towards the thing that opened it so the motion points back at it; a dialog belongs to the screen rather than to a control, so the absence of a direction is the message.

Two layers on the content

A centred box cannot also be the thing that centres it. An outer layer fills the portal and does the centring; the panel is the box. The outer one takes no touches, so a press that misses the panel reaches the overlay under it and closes the dialog.