Alert Dialog
A modal dialog that interrupts the user with important content and expects a response.
The Alert Dialog component is a modal overlay that requires user acknowledgment before proceeding. It supports controlled and uncontrolled state, animated transitions with React Native Reanimated, and a compound component API for full flexibility.
Preview
Installation
npx novaui-cli add alert-dialogDependencies
The Alert Dialog requires the following peer dependencies:
react-native-reanimated>= 3
Import
import {
AlertDialog,
AlertDialogTrigger,
AlertDialogContent,
AlertDialogHeader,
AlertDialogFooter,
AlertDialogTitle,
AlertDialogDescription,
AlertDialogAction,
AlertDialogCancel,
} from 'novaui-components'Basic Usage
The Alert Dialog is a compound component with these parts:
AlertDialog- Root container with open/close stateAlertDialogTrigger- Button that opens the dialogAlertDialogContent- The modal overlay and content containerAlertDialogHeader- Groups the title and descriptionAlertDialogFooter- Groups the action buttonsAlertDialogTitle- The dialog headingAlertDialogDescription- The dialog body textAlertDialogAction- Confirm button (closes on press)AlertDialogCancel- Cancel button (closes on press)
import {
AlertDialog,
AlertDialogTrigger,
AlertDialogContent,
AlertDialogHeader,
AlertDialogFooter,
AlertDialogTitle,
AlertDialogDescription,
AlertDialogAction,
AlertDialogCancel,
} from 'novaui-components'
export function BasicAlertDialog() {
return (
<AlertDialog>
<AlertDialogTrigger variant="outline" label="Show Dialog" />
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This will permanently delete your
account and remove your data from our servers.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel label="Cancel" />
<AlertDialogAction label="Continue" />
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)
}Destructive Action
Use a destructive action button for dangerous operations:
<AlertDialog>
<AlertDialogTrigger variant="destructive" label="Delete Account" />
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Delete Account</AlertDialogTitle>
<AlertDialogDescription>
Are you sure you want to delete your account? All of your data will
be permanently removed. This action cannot be undone.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel label="Cancel" />
<AlertDialogAction variant="destructive" label="Yes, delete account" />
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>Controlled State
Control the dialog open/close state programmatically:
import { useState } from 'react'
export function ControlledAlertDialog() {
const [open, setOpen] = useState(false)
return (
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogTrigger variant="outline" label="Controlled Dialog" />
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Controlled Alert</AlertDialogTitle>
<AlertDialogDescription>
This dialog's state is managed externally via the open and
onOpenChange props.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel label="Dismiss" />
<AlertDialogAction label="Got it" />
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)
}With Async Action
Handle async operations (e.g. API calls) in the action button:
import { useState } from 'react'
export function AsyncAlertDialog() {
const [open, setOpen] = useState(false)
const handleDelete = async () => {
await fetch('/api/delete-account', { method: 'DELETE' })
setOpen(false)
}
return (
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogTrigger variant="destructive" label="Delete" />
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Confirm Deletion</AlertDialogTitle>
<AlertDialogDescription>
This will permanently delete the selected items.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel label="Cancel" />
<AlertDialogAction
variant="destructive"
label="Delete"
onPress={handleDelete}
/>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
)
}Props API
AlertDialog Props
Extends React.ComponentPropsWithoutRef<typeof View> and includes:
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | - | Controlled open state |
onOpenChange | (open: boolean) => void | - | Callback when open state changes |
defaultOpen | boolean | false | Initial open state (uncontrolled) |
AlertDialogTrigger Props
Extends ButtonProps and includes:
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Render as the child element instead of a Button |
AlertDialogContent Props
Extends React.ComponentPropsWithoutRef<typeof View>:
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes for the dialog content |
AlertDialogHeader Props
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
AlertDialogFooter Props
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
AlertDialogTitle Props
Extends React.ComponentPropsWithoutRef<typeof Text>:
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
AlertDialogDescription Props
Extends React.ComponentPropsWithoutRef<typeof Text>:
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes |
AlertDialogAction Props
Extends ButtonProps:
| Prop | Type | Default | Description |
|---|---|---|---|
onPress | (e: GestureResponderEvent) => void | - | Called before the dialog closes |
AlertDialogCancel Props
Extends ButtonProps:
| Prop | Type | Default | Description |
|---|---|---|---|
variant | ButtonVariant | 'outline' | Defaults to outline style |
onPress | (e: GestureResponderEvent) => void | - | Called before the dialog closes |
Animation
The Alert Dialog uses react-native-reanimated for entrance/exit animations:
- Overlay: Fades in with
FadeIn/FadeOut - Content: Spring-based zoom with
FadeIn.springify().damping(20) - Dismissal: Fades out when closed
Accessibility
- Uses React Native
Modalfor proper overlay behavior onRequestClosehandles the Android back buttonstatusBarTranslucentensures the overlay covers the full screen- Backdrop press dismisses the dialog
Best Practices
-
Use for destructive actions: Alert dialogs are best for confirming irreversible actions (delete, discard, etc.)
-
Keep it focused: Only one action + one cancel — don't add multiple choices
-
Clear copy: The title should state the action, the description should explain the consequences
-
Appropriate button labels: Use specific labels like "Delete" instead of generic "OK"
-
Don't overuse: Reserve alert dialogs for truly important decisions — overuse causes dismissal fatigue
Related Components
- Use
Alertfor non-blocking informational messages - Use
Dialogfor general-purpose modal content that doesn't require confirmation