Alert Dialog
A modal dialog that interrupts the user with important content and expects a response.
import { useState } from "react";
import { Button } from "@/components/ui/button";
import {
AlertDialog,
AlertDialogContent,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogAction,
AlertDialogCancel,
} from "@/components/ui/alert-dialog";
export function MyScreen() {
const [open, setOpen] = useState(false);
return (
<>
<Button onPress={() => setOpen(true)}>Delete Account</Button>
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This will permanently delete your account.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel onPress={() => setOpen(false)}>Cancel</AlertDialogCancel>
<AlertDialogAction onPress={() => setOpen(false)}>Continue</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</>
);
}Installation
npx @aniui/cli add alert-dialogThis component requires react-native-reanimated to be installed in your project.
Usage
app/index.tsx
import { useState } from "react";
import { Button } from "@/components/ui/button";
import {
AlertDialog,
AlertDialogContent,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogAction,
AlertDialogCancel,
} from "@/components/ui/alert-dialog";
export function MyScreen() {
const [open, setOpen] = useState(false);
return (
<>
<Button onPress={() => setOpen(true)}>Delete Account</Button>
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This will permanently delete your account.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel onPress={() => setOpen(false)}>Cancel</AlertDialogCancel>
<AlertDialogAction onPress={() => setOpen(false)}>Continue</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</>
);
}Components
AlertDialog is a compound component made up of several parts:
ComponentDescription
AlertDialogRoot component that manages open state and renders the modal overlay.
AlertDialogContentThe card container for dialog content.
AlertDialogHeaderWraps the title and description with spacing.
AlertDialogTitleThe heading text of the dialog.
AlertDialogDescriptionDescriptive text explaining the action.
AlertDialogFooterWraps action buttons with proper layout.
AlertDialogActionPrimary action button (confirm).
AlertDialogCancelSecondary cancel button (dismiss).
Props
AlertDialog
PropTypeDefault
openbooleanrequiredonOpenChange(open: boolean) => voidrequiredchildrenReact.ReactNoderequiredSub-components (AlertDialogContent, AlertDialogHeader, etc.) accept className and their respective React Native base props.
Source
components/ui/alert-dialog.tsx
import React from "react";
import { View, Pressable, Text, Modal } from "react-native";
import Animated, { FadeIn, FadeOut, ZoomIn, ZoomOut } from "react-native-reanimated";
import { cn } from "@/lib/utils";
export interface AlertDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
children: React.ReactNode;
}
export function AlertDialog({ open, onOpenChange, children }: AlertDialogProps) {
return (
<Modal visible={open} transparent animationType="none" onRequestClose={() => onOpenChange(false)}>
<Animated.View
entering={FadeIn.duration(150)}
exiting={FadeOut.duration(100)}
className="flex-1 items-center justify-center bg-black/50"
>
<Animated.View entering={ZoomIn.duration(200)} exiting={ZoomOut.duration(150)}>
{children}
</Animated.View>
</Animated.View>
</Modal>
);
}
export interface AlertDialogContentProps extends React.ComponentPropsWithoutRef<typeof View> {
className?: string;
children?: React.ReactNode;
}
export function AlertDialogContent({ className, ...props }: AlertDialogContentProps) {
return (
<View
className={cn("mx-6 w-80 rounded-lg bg-card p-6 shadow-xl", className)}
accessibilityRole="alert"
{...props}
/>
);
}
export interface AlertDialogHeaderProps extends React.ComponentPropsWithoutRef<typeof View> {
className?: string;
children?: React.ReactNode;
}
export function AlertDialogHeader({ className, ...props }: AlertDialogHeaderProps) {
return <View className={cn("pb-4", className)} {...props} />;
}
export interface AlertDialogTitleProps extends React.ComponentPropsWithoutRef<typeof Text> {
className?: string;
}
export function AlertDialogTitle({ className, ...props }: AlertDialogTitleProps) {
return <Text className={cn("text-lg font-semibold text-card-foreground", className)} {...props} />;
}
export interface AlertDialogDescriptionProps extends React.ComponentPropsWithoutRef<typeof Text> {
className?: string;
}
export function AlertDialogDescription({ className, ...props }: AlertDialogDescriptionProps) {
return <Text className={cn("text-sm text-muted-foreground mt-1", className)} {...props} />;
}
export interface AlertDialogFooterProps extends React.ComponentPropsWithoutRef<typeof View> {
className?: string;
children?: React.ReactNode;
}
export function AlertDialogFooter({ className, ...props }: AlertDialogFooterProps) {
return <View className={cn("flex-row justify-end gap-3 pt-4", className)} {...props} />;
}
export interface AlertDialogActionProps extends React.ComponentPropsWithoutRef<typeof Pressable> {
className?: string;
children: React.ReactNode;
}
export function AlertDialogAction({ className, children, ...props }: AlertDialogActionProps) {
return (
<Pressable
className={cn("items-center justify-center rounded-md bg-primary px-4 py-2.5 min-h-12", className)}
accessible={true}
accessibilityRole="button"
{...props}
>
{typeof children === "string" ? (
<Text className="text-sm font-medium text-primary-foreground">{children}</Text>
) : children}
</Pressable>
);
}
export interface AlertDialogCancelProps extends React.ComponentPropsWithoutRef<typeof Pressable> {
className?: string;
children: React.ReactNode;
}
export function AlertDialogCancel({ className, children, ...props }: AlertDialogCancelProps) {
return (
<Pressable
className={cn("items-center justify-center rounded-md border border-input px-4 py-2.5 min-h-12", className)}
accessible={true}
accessibilityRole="button"
{...props}
>
{typeof children === "string" ? (
<Text className="text-sm font-medium text-foreground">{children}</Text>
) : children}
</Pressable>
);
}