Dialogs are modal windows that overlay the primary content, interrupting the user’s workflow to communicate important information or require user action.
Import
import { Dialog, DialogHeader, DialogBody, DialogFooter } from '@naturacosmeticos/natds-react'
Basic Usage
Dialogs require state management to control their open/closed state:
import { useState } from 'react'
import { Dialog, DialogHeader, DialogBody, DialogFooter, Button } from '@naturacosmeticos/natds-react'
function Example() {
const [open, setOpen] = useState(false)
return (
<>
<Button onClick={() => setOpen(true)}>Open Dialog</Button>
<Dialog
open={open}
role="dialog"
ariaLabelledBy="dialog-title"
ariaDescribedBy="dialog-description"
onEscapeKeyDown={() => setOpen(false)}
>
<DialogHeader title="Dialog Title" id="dialog-title" />
<DialogBody>
<p id="dialog-description">
This is the dialog content.
</p>
</DialogBody>
<DialogFooter
primaryButton={<Button onClick={() => setOpen(false)}>Confirm</Button>}
secondaryButton={<Button variant="text" onClick={() => setOpen(false)}>Cancel</Button>}
/>
</Dialog>
</>
)
}
Opening and Closing
Control the dialog visibility using the open prop:
const [showDialog, setShowDialog] = useState(false)
// Open the dialog
setShowDialog(true)
// Close the dialog
setShowDialog(false)
// Handle ESC key
<Dialog
open={showDialog}
onEscapeKeyDown={() => setShowDialog(false)}
role="dialog"
>
{/* Dialog content */}
</Dialog>
Dialog Sizes
Dialogs come in three sizes:
// Small dialog
<Dialog open={open} size="small" role="dialog">
{/* Content */}
</Dialog>
// Medium dialog (default)
<Dialog open={open} size="medium" role="dialog">
{/* Content */}
</Dialog>
// Large dialog
<Dialog open={open} size="large" role="dialog">
{/* Content */}
</Dialog>
Dialog Types
Use the appropriate role based on the dialog’s purpose:
// Standard dialog for general interactions
<Dialog open={open} role="dialog">
{/* Content */}
</Dialog>
// Alert dialog for critical messages requiring immediate attention
<Dialog open={open} role="alertdialog">
{/* Content */}
</Dialog>
Add icon buttons to the dialog header:
<Dialog open={open} role="dialog">
<DialogHeader title="Settings" id="dialog-title">
<div style={{ display: 'flex', gap: 16 }}>
<IconButton
onClick={() => handleShare()}
ariaLabel="Share"
IconComponent={<Icon name="outlined-action-share" color="highEmphasis" />}
/>
<IconButton
onClick={() => handleEdit()}
ariaLabel="Edit"
IconComponent={<Icon name="outlined-action-edit" color="highEmphasis" />}
/>
<IconButton
onClick={() => setOpen(false)}
ariaLabel="Close"
IconComponent={<Icon name="outlined-navigation-close" color="highEmphasis" />}
/>
</div>
</DialogHeader>
<DialogBody showDivider>
{/* Content */}
</DialogBody>
</Dialog>
With Dividers
Add visual separation between sections:
<DialogBody showDivider>
This body content has a divider above it.
</DialogBody>
Custom Container
Render the dialog in a custom container:
<Dialog
open={open}
role="dialog"
container={() => document.getElementById('custom-container')}
>
{/* Content */}
</Dialog>
Props
Dialog
Controls whether the dialog is visible.
role
'dialog' | 'alertdialog'
required
Defines the ARIA role. Use dialog for standard dialogs and alertdialog for critical messages.
size
'small' | 'medium' | 'large'
default:"medium"
Determines the width of the dialog. If larger than screen width, 90vw will be applied.
onEscapeKeyDown
(event: KeyboardEvent) => void
Callback fired when the Escape key is pressed.
The ID of the element that labels the dialog (typically the header’s ID).
The ID of the element that describes the dialog (typically the body content’s ID).
container
HTMLElement | (() => HTMLElement)
Container element for rendering the dialog. Defaults to document.body.
Optional className to be added to the Dialog.
Additional accessibility properties for fine-grained control.
Dialog children, typically DialogHeader, DialogBody, and DialogFooter components.
The title text displayed in the header.
ID for the header element, used for ARIA labelling.
Optional action buttons or other elements to display in the header.
DialogBody
Whether to show a divider above the body content.
The main content of the dialog.
The primary action button (typically a confirmation button).
The secondary action button (typically a cancel button).
Accessibility
- Always provide
ariaLabelledBy and ariaDescribedBy to connect the dialog title and description
- Use
role="alertdialog" for dialogs that interrupt workflow with critical information
- Support closing with the Escape key using
onEscapeKeyDown
- Focus is automatically trapped within the dialog when open
- The dialog overlay prevents interaction with background content
Best Practices
Use dialogs sparingly for important interruptions only
Always provide a way to close the dialog (ESC key, close button, or cancel action)
Keep dialog content concise and focused on a single task
Use appropriate button labels that clearly describe the action
Don’t nest dialogs within other dialogs
Don’t use dialogs for non-critical information that could be inline