Dialog

Dialogs are windows containing contextual information, tasks, or workflows that appear over the user interface. Depending on the kind of Dialog, further interactions may be blocked until the Dialog is acknowledged.

installyarn add @adobe/react-spectrum
added3.0.0
usageimport {Dialog, DialogTrigger} from '@adobe/react-spectrum'

Example#


import {ActionButton, Button, ButtonGroup, Content, Dialog, DialogTrigger, Divider, Header, Heading, Text} from '@adobe/react-spectrum';

<DialogTrigger>
  <ActionButton>Check connectivity</ActionButton>
  {(close) => (
    <Dialog>
      <Heading>Internet Speed Test</Heading>
      <Header>Connection status: Connected</Header>
      <Divider />
      <Content>
        <Text>
          Start speed test?
        </Text>
      </Content>
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>Cancel</Button>
        <Button variant="accent" onPress={close}>Confirm</Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>
import {
  ActionButton,
  Button,
  ButtonGroup,
  Content,
  Dialog,
  DialogTrigger,
  Divider,
  Header,
  Heading,
  Text
} from '@adobe/react-spectrum';

<DialogTrigger>
  <ActionButton>Check connectivity</ActionButton>
  {(close) => (
    <Dialog>
      <Heading>Internet Speed Test</Heading>
      <Header>Connection status: Connected</Header>
      <Divider />
      <Content>
        <Text>
          Start speed test?
        </Text>
      </Content>
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>
          Cancel
        </Button>
        <Button variant="accent" onPress={close}>
          Confirm
        </Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>
import {
  ActionButton,
  Button,
  ButtonGroup,
  Content,
  Dialog,
  DialogTrigger,
  Divider,
  Header,
  Heading,
  Text
} from '@adobe/react-spectrum';

<DialogTrigger>
  <ActionButton>
    Check connectivity
  </ActionButton>
  {(close) => (
    <Dialog>
      <Heading>
        Internet Speed
        Test
      </Heading>
      <Header>
        Connection
        status:
        Connected
      </Header>
      <Divider />
      <Content>
        <Text>
          Start speed
          test?
        </Text>
      </Content>
      <ButtonGroup>
        <Button
          variant="secondary"
          onPress={close}
        >
          Cancel
        </Button>
        <Button
          variant="accent"
          onPress={close}
        >
          Confirm
        </Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>

Content#


A standard Dialog has the following anatomy:

Body areaTitle areaFooter content area (optional)Header content area (optional)Button group areaHeaderFooterBodyDivider

These sections can be populated by providing the following components to your Dialog as children: Header, Heading (title), Divider, Content (body), ButtonGroup, and Footer. Each of these components are required in a Spectrum compliant Dialog except for Header, Footer, and Divider so be sure to design your Dialog accordingly.

Examples#

A typical Dialog with a title, contents, and action buttons can be created like so:

<DialogTrigger>
  <ActionButton>Publish</ActionButton>
  {(close) => (
    <Dialog>
      <Heading>Publish 3 pages</Heading>
      <Divider />
      <Content>Confirm publish?</Content>
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>Cancel</Button>
        <Button variant="accent" onPress={close} autoFocus>Confirm</Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>Publish</ActionButton>
  {(close) => (
    <Dialog>
      <Heading>Publish 3 pages</Heading>
      <Divider />
      <Content>Confirm publish?</Content>
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>
          Cancel
        </Button>
        <Button
          variant="accent"
          onPress={close}
          autoFocus
        >
          Confirm
        </Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>
    Publish
  </ActionButton>
  {(close) => (
    <Dialog>
      <Heading>
        Publish 3 pages
      </Heading>
      <Divider />
      <Content>
        Confirm
        publish?
      </Content>
      <ButtonGroup>
        <Button
          variant="secondary"
          onPress={close}
        >
          Cancel
        </Button>
        <Button
          variant="accent"
          onPress={close}
          autoFocus
        >
          Confirm
        </Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>

A dismissable Dialog forgoes its ButtonGroup in favor of rendering a close button at the top right of the Dialog.

<DialogTrigger isDismissable>
  <ActionButton>Status</ActionButton>
  <Dialog>
    <Heading>Status</Heading>
    <Divider />
    <Content>Printer Status: Connected</Content>
  </Dialog>
</DialogTrigger>
<DialogTrigger isDismissable>
  <ActionButton>Status</ActionButton>
  <Dialog>
    <Heading>Status</Heading>
    <Divider />
    <Content>Printer Status: Connected</Content>
  </Dialog>
</DialogTrigger>
<DialogTrigger
  isDismissable
>
  <ActionButton>
    Status
  </ActionButton>
  <Dialog>
    <Heading>
      Status
    </Heading>
    <Divider />
    <Content>
      Printer Status:
      Connected
    </Content>
  </Dialog>
</DialogTrigger>

It is important to note that the Heading, Header, Content, and Footer content elements accept any renderable node, not just strings. This allows you to create Dialogs for more complex workflows, such as including a form for the user to fill out or adding confirmation checkboxes.

<DialogTrigger>
  <ActionButton>Register</ActionButton>
  {(close) => (
    <Dialog>
      <Heading>
        <Flex alignItems="center" gap="size-100">
          <Book size="S" />
          <Text>
            Register for newsletter
          </Text>
        </Flex>
      </Heading>
      <Header>
        <Link>
          <a href="//example.com" target="_blank">What is this?</a>
        </Link>
      </Header>
      <Divider />
      <Content>
        <Form>
          <TextField label="First Name" autoFocus />
          <TextField label="Last Name" />
          <TextField label="Street Address" />
          <TextField label="City" />
        </Form>
      </Content>
      <Footer>
        <Checkbox>
          I want to receive updates for exclusive offers in my area.
        </Checkbox>
      </Footer>
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>Cancel</Button>
        <Button variant="accent" onPress={close}>Register</Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>Register</ActionButton>
  {(close) => (
    <Dialog>
      <Heading>
        <Flex alignItems="center" gap="size-100">
          <Book size="S" />
          <Text>
            Register for newsletter
          </Text>
        </Flex>
      </Heading>
      <Header>
        <Link>
          <a href="//example.com" target="_blank">
            What is this?
          </a>
        </Link>
      </Header>
      <Divider />
      <Content>
        <Form>
          <TextField label="First Name" autoFocus />
          <TextField label="Last Name" />
          <TextField label="Street Address" />
          <TextField label="City" />
        </Form>
      </Content>
      <Footer>
        <Checkbox>
          I want to receive updates for exclusive offers
          in my area.
        </Checkbox>
      </Footer>
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>
          Cancel
        </Button>
        <Button variant="accent" onPress={close}>
          Register
        </Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>
    Register
  </ActionButton>
  {(close) => (
    <Dialog>
      <Heading>
        <Flex
          alignItems="center"
          gap="size-100"
        >
          <Book size="S" />
          <Text>
            Register
            for
            newsletter
          </Text>
        </Flex>
      </Heading>
      <Header>
        <Link>
          <a
            href="//example.com"
            target="_blank"
          >
            What is
            this?
          </a>
        </Link>
      </Header>
      <Divider />
      <Content>
        <Form>
          <TextField
            label="First Name"
            autoFocus
          />
          <TextField label="Last Name" />
          <TextField label="Street Address" />
          <TextField label="City" />
        </Form>
      </Content>
      <Footer>
        <Checkbox>
          I want to
          receive
          updates for
          exclusive
          offers in my
          area.
        </Checkbox>
      </Footer>
      <ButtonGroup>
        <Button
          variant="secondary"
          onPress={close}
        >
          Cancel
        </Button>
        <Button
          variant="accent"
          onPress={close}
        >
          Register
        </Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>

The example below illustrates how a Dialog with a hero image could be rendered via the hero slot:

<DialogTrigger>
  <ActionButton>Upload</ActionButton>
  {(close) => (
    <Dialog>
      <Image
        slot="hero"
        alt=""
        src="https://i.imgur.com/Z7AzH2c.png"
        objectFit="cover"
      />
      <Heading>Upload file</Heading>
      <Divider />
      <Content>Are you sure you want to upload this file?</Content>
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>Cancel</Button>
        <Button variant="accent" onPress={close} autoFocus>Confirm</Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>Upload</ActionButton>
  {(close) => (
    <Dialog>
      <Image
        slot="hero"
        alt=""
        src="https://i.imgur.com/Z7AzH2c.png"
        objectFit="cover"
      />
      <Heading>Upload file</Heading>
      <Divider />
      <Content>
        Are you sure you want to upload this file?
      </Content>
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>
          Cancel
        </Button>
        <Button
          variant="accent"
          onPress={close}
          autoFocus
        >
          Confirm
        </Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>
    Upload
  </ActionButton>
  {(close) => (
    <Dialog>
      <Image
        slot="hero"
        alt=""
        src="https://i.imgur.com/Z7AzH2c.png"
        objectFit="cover"
      />
      <Heading>
        Upload file
      </Heading>
      <Divider />
      <Content>
        Are you sure
        you want to
        upload this
        file?
      </Content>
      <ButtonGroup>
        <Button
          variant="secondary"
          onPress={close}
        >
          Cancel
        </Button>
        <Button
          variant="accent"
          onPress={close}
          autoFocus
        >
          Confirm
        </Button>
      </ButtonGroup>
    </Dialog>
  )}
</DialogTrigger>

Accessibility#

Keep in mind when creating your Dialog that the tab order within the Dialog follows the order of the children provided. You are also responsible for determining what component, if any, should be automatically focused when the Dialog opens.

Labeling#


Accessibility#

The title of a Dialog is typically provided via its heading. By default, the Dialog sets its aria-labelledby to match the heading id, but this can be overridden by providing an aria-labelledby prop to the Dialog directly. If a visible label isn't specified, an aria-label must be provided instead.

Events#


For Dialogs, user defined callbacks should be chained with the DialogTrigger's close function in the onPress handler of the Dialog's action buttons. The following example alerts if the Dialog's save or cancel button is clicked.

function Example() {
  let alertSave = (close) => {
    close();
    alert('Profile saved!');
  };

  let alertCancel = (close) => {
    close();
    alert('Profile not saved!');
  };

  return (
    <DialogTrigger>
      <ActionButton>Set Profile</ActionButton>
      {(close) => (
        <Dialog>
          <Heading>Profile</Heading>
          <Divider />
          <ButtonGroup>
            <Button variant="secondary" onPress={() => alertCancel(close)}>
              Cancel
            </Button>
            <Button autoFocus variant="accent" onPress={() => alertSave(close)}>
              Save
            </Button>
          </ButtonGroup>
          <Content>
            <Form>
              <TextField label="Name" />
              <Checkbox>Make private</Checkbox>
            </Form>
          </Content>
        </Dialog>
      )}
    </DialogTrigger>
  );
}
function Example() {
  let alertSave = (close) => {
    close();
    alert('Profile saved!');
  };

  let alertCancel = (close) => {
    close();
    alert('Profile not saved!');
  };

  return (
    <DialogTrigger>
      <ActionButton>Set Profile</ActionButton>
      {(close) => (
        <Dialog>
          <Heading>Profile</Heading>
          <Divider />
          <ButtonGroup>
            <Button
              variant="secondary"
              onPress={() => alertCancel(close)}
            >
              Cancel
            </Button>
            <Button
              autoFocus
              variant="accent"
              onPress={() => alertSave(close)}
            >
              Save
            </Button>
          </ButtonGroup>
          <Content>
            <Form>
              <TextField label="Name" />
              <Checkbox>Make private</Checkbox>
            </Form>
          </Content>
        </Dialog>
      )}
    </DialogTrigger>
  );
}
function Example() {
  let alertSave = (
    close
  ) => {
    close();
    alert(
      'Profile saved!'
    );
  };

  let alertCancel = (
    close
  ) => {
    close();
    alert(
      'Profile not saved!'
    );
  };

  return (
    <DialogTrigger>
      <ActionButton>
        Set Profile
      </ActionButton>
      {(close) => (
        <Dialog>
          <Heading>
            Profile
          </Heading>
          <Divider />
          <ButtonGroup>
            <Button
              variant="secondary"
              onPress={() =>
                alertCancel(
                  close
                )}
            >
              Cancel
            </Button>
            <Button
              autoFocus
              variant="accent"
              onPress={() =>
                alertSave(
                  close
                )}
            >
              Save
            </Button>
          </ButtonGroup>
          <Content>
            <Form>
              <TextField label="Name" />
              <Checkbox>
                Make
                private
              </Checkbox>
            </Form>
          </Content>
        </Dialog>
      )}
    </DialogTrigger>
  );
}

Additionally, DialogTrigger accepts an onOpenChange prop which is triggered whenever the Dialog is opened or closed. For more information, see the DialogTrigger docs.

Dismissable dialogs#

Dismissable Dialogs support an optional onDismiss prop which is triggered whenever the Dialog's close button is clicked. Similar to non-dismissable dialogs, you must chain the DialogTrigger's close function with whatever callback you provide as onDismiss. If this event callback is not needed, the dismissiable dialog will behave as normal without passing this callback through.

function Example() {
  let alertDismiss = (close) => {
    close();
    alert('Dialog dismissed.');
  }
  return (
    <DialogTrigger isDismissable>
      <ActionButton>Info</ActionButton>
      {(close) => (
        <Dialog onDismiss={() => alertDismiss(close)}>
          <Heading>Version Info</Heading>
          <Divider />
          <Content>
            <Text>
              Version 1.0.0, Copyright 2020
            </Text>
          </Content>
        </Dialog>
        )}
    </DialogTrigger>
  );
}
function Example() {
  let alertDismiss = (close) => {
    close();
    alert('Dialog dismissed.');
  }
  return (
    <DialogTrigger isDismissable>
      <ActionButton>Info</ActionButton>
      {(close) => (
        <Dialog onDismiss={() => alertDismiss(close)}>
          <Heading>Version Info</Heading>
          <Divider />
          <Content>
            <Text>
              Version 1.0.0, Copyright 2020
            </Text>
          </Content>
        </Dialog>
        )}
    </DialogTrigger>
  );
}
function Example() {
  let alertDismiss = (
    close
  ) => {
    close();
    alert(
      'Dialog dismissed.'
    );
  };
  return (
    <DialogTrigger
      isDismissable
    >
      <ActionButton>
        Info
      </ActionButton>
      {(close) => (
        <Dialog
          onDismiss={() =>
            alertDismiss(
              close
            )}
        >
          <Heading>
            Version Info
          </Heading>
          <Divider />
          <Content>
            <Text>
              Version
              1.0.0,
              Copyright
              2020
            </Text>
          </Content>
        </Dialog>
      )}
    </DialogTrigger>
  );
}

Note: The onDismiss callback is optional. If you don't need to add a onDismiss handler to your dismissable Dialog, you may omit the wrapping close function surrounding the Dialog. An example of this can be found in the Examples section above.

Props#


NameTypeDefaultDescription
childrenReactNodeThe contents of the Dialog.
size'S''M''L'The size of the Dialog. Only applies to "modal" type Dialogs.
isDismissablebooleanWhether the Dialog is dismissable. See the examples for more details.
Events
NameTypeDefaultDescription
onDismiss() => voidHandler that is called when the 'x' button of a dismissable Dialog is clicked.
Layout
NameTypeDefaultDescription
flexResponsive<stringnumberboolean>When used in a flex layout, specifies how the element will grow or shrink to fit the space available. See MDN.
flexGrowResponsive<number>When used in a flex layout, specifies how the element will grow to fit the space available. See MDN.
flexShrinkResponsive<number>When used in a flex layout, specifies how the element will shrink to fit the space available. See MDN.
flexBasisResponsive<numberstring>When used in a flex layout, specifies the initial main size of the element. See MDN.
alignSelfResponsive<'auto''normal''start''end''center''flex-start''flex-end''self-start''self-end''stretch'>Overrides the alignItems property of a flex or grid container. See MDN.
justifySelfResponsive<'auto''normal''start''end''flex-start''flex-end''self-start''self-end''center''left''right''stretch'>Specifies how the element is justified inside a flex or grid container. See MDN.
orderResponsive<number>The layout order for the element within a flex or grid container. See MDN.
gridAreaResponsive<string>When used in a grid layout, specifies the named grid area that the element should be placed in within the grid. See MDN.
gridColumnResponsive<string>When used in a grid layout, specifies the column the element should be placed in within the grid. See MDN.
gridRowResponsive<string>When used in a grid layout, specifies the row the element should be placed in within the grid. See MDN.
gridColumnStartResponsive<string>When used in a grid layout, specifies the starting column to span within the grid. See MDN.
gridColumnEndResponsive<string>When used in a grid layout, specifies the ending column to span within the grid. See MDN.
gridRowStartResponsive<string>When used in a grid layout, specifies the starting row to span within the grid. See MDN.
gridRowEndResponsive<string>When used in a grid layout, specifies the ending row to span within the grid. See MDN.
Spacing
NameTypeDefaultDescription
marginResponsive<DimensionValue>The margin for all four sides of the element. See MDN.
marginTopResponsive<DimensionValue>The margin for the top side of the element. See MDN.
marginBottomResponsive<DimensionValue>The margin for the bottom side of the element. See MDN.
marginStartResponsive<DimensionValue>The margin for the logical start side of the element, depending on layout direction. See MDN.
marginEndResponsive<DimensionValue>The margin for the logical end side of an element, depending on layout direction. See MDN.
marginXResponsive<DimensionValue>The margin for both the left and right sides of the element. See MDN.
marginYResponsive<DimensionValue>The margin for both the top and bottom sides of the element. See MDN.
Sizing
NameTypeDefaultDescription
widthResponsive<DimensionValue>The width of the element. See MDN.
minWidthResponsive<DimensionValue>The minimum width of the element. See MDN.
maxWidthResponsive<DimensionValue>The maximum width of the element. See MDN.
heightResponsive<DimensionValue>The height of the element. See MDN.
minHeightResponsive<DimensionValue>The minimum height of the element. See MDN.
maxHeightResponsive<DimensionValue>The maximum height of the element. See MDN.
Positioning
NameTypeDefaultDescription
positionResponsive<'static''relative''absolute''fixed''sticky'>Specifies how the element is positioned. See MDN.
topResponsive<DimensionValue>The top position for the element. See MDN.
bottomResponsive<DimensionValue>The bottom position for the element. See MDN.
leftResponsive<DimensionValue>The left position for the element. See MDN. Consider using start instead for RTL support.
rightResponsive<DimensionValue>The right position for the element. See MDN. Consider using start instead for RTL support.
startResponsive<DimensionValue>The logical start position for the element, depending on layout direction. See MDN.
endResponsive<DimensionValue>The logical end position for the element, depending on layout direction. See MDN.
zIndexResponsive<number>The stacking order for the element. See MDN.
isHiddenResponsive<boolean>Hides the element.
Accessibility
NameTypeDefaultDescription
role'dialog''alertdialog''dialog'The accessibility role for the dialog.
idstringThe element's unique identifier. See MDN.
aria-labelstringDefines a string value that labels the current element.
aria-labelledbystringIdentifies the element (or elements) that labels the current element.
aria-describedbystringIdentifies the element (or elements) that describes the object.
aria-detailsstringIdentifies the element (or elements) that provide a detailed, extended description for the object.
Advanced
NameTypeDefaultDescription
UNSAFE_classNamestringSets the CSS className for the element. Only use as a last resort. Use style props instead.
UNSAFE_styleCSSPropertiesSets inline style for the element. Only use as a last resort. Use style props instead.

Visual options#


Dialog types#

Dialogs can be rendered as modals, popovers, or trays. Note that popovers are displayed as modals by default on mobile. See the DialogTrigger docs for more information.

<DialogTrigger isDismissable type="modal">
  <ActionButton>Trigger Modal</ActionButton>
  <Dialog>
    <Heading>Modal</Heading>
    <Divider />
    <Content>
      <Text>
        This is a modal.
      </Text>
    </Content>
  </Dialog>
</DialogTrigger>
<DialogTrigger isDismissable type="modal">
  <ActionButton>Trigger Modal</ActionButton>
  <Dialog>
    <Heading>Modal</Heading>
    <Divider />
    <Content>
      <Text>
        This is a modal.
      </Text>
    </Content>
  </Dialog>
</DialogTrigger>
<DialogTrigger
  isDismissable
  type="modal"
>
  <ActionButton>
    Trigger Modal
  </ActionButton>
  <Dialog>
    <Heading>
      Modal
    </Heading>
    <Divider />
    <Content>
      <Text>
        This is a
        modal.
      </Text>
    </Content>
  </Dialog>
</DialogTrigger>
<DialogTrigger type="popover">
  <ActionButton>Trigger Popover</ActionButton>
  <Dialog>
    <Heading>Popover</Heading>
    <Divider />
    <Content>
      <Text>
        This is a popover.
      </Text>
    </Content>
  </Dialog>
</DialogTrigger>
<DialogTrigger type="popover">
  <ActionButton>Trigger Popover</ActionButton>
  <Dialog>
    <Heading>Popover</Heading>
    <Divider />
    <Content>
      <Text>
        This is a popover.
      </Text>
    </Content>
  </Dialog>
</DialogTrigger>
<DialogTrigger type="popover">
  <ActionButton>
    Trigger Popover
  </ActionButton>
  <Dialog>
    <Heading>
      Popover
    </Heading>
    <Divider />
    <Content>
      <Text>
        This is a
        popover.
      </Text>
    </Content>
  </Dialog>
</DialogTrigger>
<DialogTrigger type="tray">
  <ActionButton>Trigger Tray</ActionButton>
  <Dialog>
    <Heading>Tray</Heading>
    <Divider />
    <Content>
      <Text>
        This is a tray.
      </Text>
    </Content>
  </Dialog>
</DialogTrigger>
<DialogTrigger type="tray">
  <ActionButton>Trigger Tray</ActionButton>
  <Dialog>
    <Heading>Tray</Heading>
    <Divider />
    <Content>
      <Text>
        This is a tray.
      </Text>
    </Content>
  </Dialog>
</DialogTrigger>
<DialogTrigger type="tray">
  <ActionButton>
    Trigger Tray
  </ActionButton>
  <Dialog>
    <Heading>
      Tray
    </Heading>
    <Divider />
    <Content>
      <Text>
        This is a tray.
      </Text>
    </Content>
  </Dialog>
</DialogTrigger>

Size#

Only modal type Dialogs support a user defined size prop. Note that the fullscreen and fullscreenTakeover sizes require the DialogTrigger type prop to be set to fullscreen or fullscreenTakeover respectively for container sizing considerations. Modal sizes on mobile devices are also unaffected by this prop due to screen constraints.

<DialogTrigger>
  <ActionButton>Small</ActionButton>
  {(close) => (
    <Dialog size="S">
      <Heading>Profile</Heading>
      <Divider />
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>Cancel</Button>
        <Button autoFocus variant="accent" onPress={close}>Save</Button>
      </ButtonGroup>
      <Content>
        <Form>
          <TextField label="Name" />
          <Checkbox>Make private</Checkbox>
        </Form>
      </Content>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>Small</ActionButton>
  {(close) => (
    <Dialog size="S">
      <Heading>Profile</Heading>
      <Divider />
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>
          Cancel
        </Button>
        <Button
          autoFocus
          variant="accent"
          onPress={close}
        >
          Save
        </Button>
      </ButtonGroup>
      <Content>
        <Form>
          <TextField label="Name" />
          <Checkbox>Make private</Checkbox>
        </Form>
      </Content>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>
    Small
  </ActionButton>
  {(close) => (
    <Dialog size="S">
      <Heading>
        Profile
      </Heading>
      <Divider />
      <ButtonGroup>
        <Button
          variant="secondary"
          onPress={close}
        >
          Cancel
        </Button>
        <Button
          autoFocus
          variant="accent"
          onPress={close}
        >
          Save
        </Button>
      </ButtonGroup>
      <Content>
        <Form>
          <TextField label="Name" />
          <Checkbox>
            Make
            private
          </Checkbox>
        </Form>
      </Content>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>Medium</ActionButton>
  {(close) => (
    <Dialog size="M">
      <Heading>Profile</Heading>
      <Divider />
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>Cancel</Button>
        <Button autoFocus variant="accent" onPress={close}>Save</Button>
      </ButtonGroup>
      <Content>
        <Form>
          <TextField label="Name" />
          <Checkbox>Make private</Checkbox>
        </Form>
      </Content>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>Medium</ActionButton>
  {(close) => (
    <Dialog size="M">
      <Heading>Profile</Heading>
      <Divider />
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>
          Cancel
        </Button>
        <Button
          autoFocus
          variant="accent"
          onPress={close}
        >
          Save
        </Button>
      </ButtonGroup>
      <Content>
        <Form>
          <TextField label="Name" />
          <Checkbox>Make private</Checkbox>
        </Form>
      </Content>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>
    Medium
  </ActionButton>
  {(close) => (
    <Dialog size="M">
      <Heading>
        Profile
      </Heading>
      <Divider />
      <ButtonGroup>
        <Button
          variant="secondary"
          onPress={close}
        >
          Cancel
        </Button>
        <Button
          autoFocus
          variant="accent"
          onPress={close}
        >
          Save
        </Button>
      </ButtonGroup>
      <Content>
        <Form>
          <TextField label="Name" />
          <Checkbox>
            Make
            private
          </Checkbox>
        </Form>
      </Content>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>Large</ActionButton>
  {(close) => (
    <Dialog size="L">
      <Heading>Profile</Heading>
      <Divider />
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>Cancel</Button>
        <Button autoFocus variant="accent" onPress={close}>Save</Button>
      </ButtonGroup>
      <Content>
        <Form>
          <TextField label="Name" />
          <Checkbox>Make private</Checkbox>
        </Form>
      </Content>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>Large</ActionButton>
  {(close) => (
    <Dialog size="L">
      <Heading>Profile</Heading>
      <Divider />
      <ButtonGroup>
        <Button variant="secondary" onPress={close}>
          Cancel
        </Button>
        <Button
          autoFocus
          variant="accent"
          onPress={close}
        >
          Save
        </Button>
      </ButtonGroup>
      <Content>
        <Form>
          <TextField label="Name" />
          <Checkbox>Make private</Checkbox>
        </Form>
      </Content>
    </Dialog>
  )}
</DialogTrigger>
<DialogTrigger>
  <ActionButton>
    Large
  </ActionButton>
  {(close) => (
    <Dialog size="L">
      <Heading>
        Profile
      </Heading>
      <Divider />
      <ButtonGroup>
        <Button
          variant="secondary"
          onPress={close}
        >
          Cancel
        </Button>
        <Button
          autoFocus
          variant="accent"
          onPress={close}
        >
          Save
        </Button>
      </ButtonGroup>
      <Content>
        <Form>
          <TextField label="Name" />
          <Checkbox>
            Make
            private
          </Checkbox>
        </Form>
      </Content>
    </Dialog>
  )}
</DialogTrigger>