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.
install | yarn add @react-spectrum/dialog |
---|---|
version | 3.3.8 |
usage | import {Dialog, DialogTrigger} from '@react-spectrum/dialog' |
Example#
import {ActionButton, Button} from '@react-spectrum/button';
import {ButtonGroup} from '@react-spectrum/buttongroup';
import {Content, Header} from '@react-spectrum/view';
import {Dialog, DialogTrigger} from '@react-spectrum/dialog';
import {Divider} from '@react-spectrum/divider';
import {Heading, Text} from '@react-spectrum/text';
<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="cta" onPress={close}>Confirm</Button>
</ButtonGroup>
</Dialog>
)}
</DialogTrigger>
import {ActionButton, Button} from '@react-spectrum/button';
import {ButtonGroup} from '@react-spectrum/buttongroup';
import {Content, Header} from '@react-spectrum/view';
import {
Dialog,
DialogTrigger
} from '@react-spectrum/dialog';
import {Divider} from '@react-spectrum/divider';
import {Heading, Text} from '@react-spectrum/text';
<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="cta" onPress={close}>
Confirm
</Button>
</ButtonGroup>
</Dialog>
)}
</DialogTrigger>
import {
ActionButton,
Button
} from '@react-spectrum/button';
import {ButtonGroup} from '@react-spectrum/buttongroup';
import {
Content,
Header
} from '@react-spectrum/view';
import {
Dialog,
DialogTrigger
} from '@react-spectrum/dialog';
import {Divider} from '@react-spectrum/divider';
import {
Heading,
Text
} from '@react-spectrum/text';
<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="cta"
onPress={close}
>
Confirm
</Button>
</ButtonGroup>
</Dialog>
)}
</DialogTrigger>
Content#
A standard Dialog has the following anatomy:
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="cta" 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="cta" 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="cta"
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" placeholder="John" autoFocus />
<TextField label="Last Name" placeholder="Smith" />
<TextField label="Street Address" placeholder="123 Any Street" />
<TextField label="City" placeholder="San Francisco" />
</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="cta" 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"
placeholder="John"
autoFocus
/>
<TextField
label="Last Name"
placeholder="Smith"
/>
<TextField
label="Street Address"
placeholder="123 Any Street"
/>
<TextField
label="City"
placeholder="San Francisco"
/>
</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="cta" 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"
placeholder="John"
autoFocus
/>
<TextField
label="Last Name"
placeholder="Smith"
/>
<TextField
label="Street Address"
placeholder="123 Any Street"
/>
<TextField
label="City"
placeholder="San Francisco"
/>
</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="cta"
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="cta" 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="cta" 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="cta"
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.
When a Dialog is open, then it should be the only thing that can be interacted with. If your application's Provider
is at the root of the page, this is handled automatically. However, if your application has content outside the Provider
, then you should use the @react-aria/aria-modal-polyfill
package to hide this content from assistive technology while a modal is open. See the watchModals docs for more details.
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="cta" 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="cta"
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="cta"
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#
Name | Type | Default | Description |
children | ReactNode | — | The contents of the Dialog. |
size | 'S'
| 'M'
| 'L' | — | The size of the Dialog. Only applies to "modal" type Dialogs. |
isDismissable | boolean | — | Whether the Dialog is dismissable. See the examples for more details. |
Events
Name | Type | Default | Description |
onDismiss | () => void | — | Handler that is called when the 'x' button of a dismissable Dialog is clicked. |
Layout
Name | Type | Default | Description |
flex | Responsive<string
| number
| boolean> | — | When used in a flex layout, specifies how the element will grow or shrink to fit the space available. See MDN. |
flexGrow | Responsive<number> | — | When used in a flex layout, specifies how the element will grow to fit the space available. See MDN. |
flexShrink | Responsive<number> | — | When used in a flex layout, specifies how the element will shrink to fit the space available. See MDN. |
flexBasis | Responsive<number | string> | — | When used in a flex layout, specifies the initial main size of the element. See MDN. |
alignSelf | Responsive<'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. |
justifySelf | Responsive<'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. |
order | Responsive<number> | — | The layout order for the element within a flex or grid container. See MDN. |
gridArea | Responsive<string> | — | When used in a grid layout, specifies the named grid area that the element should be placed in within the grid. See MDN. |
gridColumn | Responsive<string> | — | When used in a grid layout, specifies the column the element should be placed in within the grid. See MDN. |
gridRow | Responsive<string> | — | When used in a grid layout, specifies the row the element should be placed in within the grid. See MDN. |
gridColumnStart | Responsive<string> | — | When used in a grid layout, specifies the starting column to span within the grid. See MDN. |
gridColumnEnd | Responsive<string> | — | When used in a grid layout, specifies the ending column to span within the grid. See MDN. |
gridRowStart | Responsive<string> | — | When used in a grid layout, specifies the starting row to span within the grid. See MDN. |
gridRowEnd | Responsive<string> | — | When used in a grid layout, specifies the ending row to span within the grid. See MDN. |
Spacing
Name | Type | Default | Description |
margin | Responsive<DimensionValue> | — | The margin for all four sides of the element. See MDN. |
marginTop | Responsive<DimensionValue> | — | The margin for the top side of the element. See MDN. |
marginBottom | Responsive<DimensionValue> | — | The margin for the bottom side of the element. See MDN. |
marginStart | Responsive<DimensionValue> | — | The margin for the logical start side of the element, depending on layout direction. See MDN. |
marginEnd | Responsive<DimensionValue> | — | The margin for the logical end side of an element, depending on layout direction. See MDN. |
marginX | Responsive<DimensionValue> | — | The margin for both the left and right sides of the element. See MDN. |
marginY | Responsive<DimensionValue> | — | The margin for both the top and bottom sides of the element. See MDN. |
Sizing
Name | Type | Default | Description |
width | Responsive<DimensionValue> | — | The width of the element. See MDN. |
minWidth | Responsive<DimensionValue> | — | The minimum width of the element. See MDN. |
maxWidth | Responsive<DimensionValue> | — | The maximum width of the element. See MDN. |
height | Responsive<DimensionValue> | — | The height of the element. See MDN. |
minHeight | Responsive<DimensionValue> | — | The minimum height of the element. See MDN. |
maxHeight | Responsive<DimensionValue> | — | The maximum height of the element. See MDN. |
Positioning
Name | Type | Default | Description |
position | Responsive<'static'
| 'relative'
| 'absolute'
| 'fixed'
| 'sticky'> | — | Specifies how the element is positioned. See MDN. |
top | Responsive<DimensionValue> | — | The top position for the element. See MDN. |
bottom | Responsive<DimensionValue> | — | The bottom position for the element. See MDN. |
left | Responsive<DimensionValue> | — | The left position for the element. See MDN. Consider using start instead for RTL support. |
right | Responsive<DimensionValue> | — | The right position for the element. See MDN. Consider using start instead for RTL support. |
start | Responsive<DimensionValue> | — | The logical start position for the element, depending on layout direction. See MDN. |
end | Responsive<DimensionValue> | — | The logical end position for the element, depending on layout direction. See MDN. |
zIndex | Responsive<number> | — | The stacking order for the element. See MDN. |
isHidden | Responsive<boolean> | — | Hides the element. |
Accessibility
Name | Type | Default | Description |
role | 'dialog' | 'alertdialog' | 'dialog' | The accessibility role for the dialog. |
id | string | — | The element's unique identifier. See MDN. |
aria-label | string | — | Defines a string value that labels the current element. |
aria-labelledby | string | — | Identifies the element (or elements) that labels the current element. |
aria-describedby | string | — | Identifies the element (or elements) that describes the object. |
aria-details | string | — | Identifies the element (or elements) that provide a detailed, extended description for the object. |
Advanced
Name | Type | Default | Description |
UNSAFE_className | string | — | Sets the CSS className for the element. Only use as a last resort. Use style props instead. |
UNSAFE_style | CSSProperties | — | Sets 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="cta" 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="cta" 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="cta"
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="cta" 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="cta" 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="cta"
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="cta" 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="cta" 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="cta"
onPress={close}
>
Save
</Button>
</ButtonGroup>
<Content>
<Form>
<TextField label="Name" />
<Checkbox>
Make
private
</Checkbox>
</Form>
</Content>
</Dialog>
)}
</DialogTrigger>