A fully customizable alert system for React Native with promise-based API and queue support
- ⚡ Easy
async/await
usage (await alert.show()
) - ⏳ Sequential alert queue management
- 🛠️ Realtime UI update: dynamically update alert title, message, buttons, and more
- 🎨 Full UI customization with slots and custom renderers
- 🖼️ SVG icon support
- ⚙️ Global styling and behavior configuration
- ✅ Built-in helpers for success, error, and confirm dialogs
- 🎉 Confetti support
- 🌐 React Native Web support
See how react-native-alert-queue
works in action! 🚀
Basic usage:
Custom titles, messages, icons, buttons, and slots:
Dynamically update the alert while it's displayed:
Alerts automatically adjust position when the keyboard appears:
Celebrate success with built-in confetti effects:
2.x
versions requirereact-native-reanimated 3.x
.- If your project does not use Reanimated, you can use
react-native-alert-queue@1.x
.
Install RN Reanimated
following their official guide.
npm install react-native-alert-queue
# or
yarn add react-native-alert-queue
⚡ Full working examples available! Explore the example app here to see all features in action.
First, add the AlertContainer
to your app:
import { AlertContainer } from 'react-native-alert-queue';
function App() {
return (
<View>
{/* Your app content */}
<AlertContainer />
</View>
);
}
Any where in your app you can show alerts by using the alert
object:
import { alert } from 'react-native-alert-queue';
// Basic alert
alert.show({
title: 'Hello',
message: 'I am an alert',
});
// Success alert
alert.success({
message: 'Operation successful',
});
// Error alert
alert.error(new Error('Something went wrong'));
// Confirm dialog
const result = await alert.confirm({
message: 'Are you sure you want to proceed?',
});
alert.show({
title: 'Custom Alert',
message: 'This is a custom alert',
buttons: [
{
text: 'OK!',
onPress: () => console.log('OK pressed'),
},
],
});
alert.success({
message: 'Operation completed successfully',
});
alert.error(new Error('Operation failed'));
const result = await alert.confirm({
message: 'Are you sure you want to proceed?',
});
alert.show({
message: 'Welcome to the app!',
confetti: true,
});
alert.show({
title: 'Congratulations!',
message: 'You are a winner!',
confetti: {
colors: ['#4CAF50', '#8BC34A', '#CDDC39', '#81C784', '#A5D6A7', '#C8E6C9'],
numberOfPieces: 200,
pieceDimensions: {
height: 10,
width: 30,
},
},
});
Confetti can be used with any alert type. Also, you can customize the confetti appearance globally in the config.
You can create your own helper functions to simplify common alert patterns in your app:
const transactionCompletedAlert = (amount: string) =>
alert.show({
title: 'Transaction Complete',
message: `Successfully transferred ${amount}`,
icon: SuccessIcon,
buttons: [
{
text: 'View Details',
onPress: () => navigateToTransactionDetails(),
},
{
text: 'Done',
},
],
});
// Create a custom error alert for network issues
const networkErrorAlert = (retryCallback: () => void) =>
alert.show({
title: 'Network Error',
message: 'Network connection lost',
icon: NetworkErrorIcon,
buttons: [
{
text: 'Retry',
onPress: retryCallback,
},
{
text: 'Cancel',
},
],
});
// Usage
await transactionCompletedAlert('$100.00');
networkErrorAlert(() => fetchData());
alert.show({
title: 'Custom Alert',
message: 'This alert has custom rendering',
renderTitle: ({ style, text }) => (
<Text style={[style, { color: 'red' }]}>{text}</Text>
),
renderMessage: ({ style, text }) => (
<Text style={[style, { fontSize: 16 }]}>{text}</Text>
),
renderButton: (props) => (
<TouchableOpacity
style={[styles.button, props.disabled && styles.disabled]}
onPress={props.onPress}
disabled={props.disabled}
>
<Text style={styles.buttonText}>{props.text}</Text>
</TouchableOpacity>
),
renderDismissButton: ({ onPress }) => (
<TouchableOpacity onPress={onPress}>
<Text>×</Text>
</TouchableOpacity>
),
});
Slots allow you to inject custom content at specific positions within the alert:
alert.show({
title: 'Alert with Slots',
message: 'This alert uses slots for custom content',
// Content before the title
beforeTitleSlot: () => (
<View style={styles.badge}>
<Text style={styles.badgeText}>New</Text>
</View>
),
// Content before the message
beforeMessageSlot: () => <View style={styles.divider} />,
// Content before the buttons
beforeButtonsSlot: () => (
<View style={styles.terms}>
<Text>By continuing you agree to our terms</Text>
</View>
),
// Content after the buttons
afterButtonsSlot: () => (
<View style={styles.footer}>
<Text style={styles.footerText}>Need help? Contact support</Text>
</View>
),
});
const result = await alert.show<string | null>({
title: 'Async Operation',
buttons: [
{
text: 'Confirm',
onAwaitablePress: async (resolve) => {
// Perform async operation
resolve('Operation completed');
},
},
{
text: 'Cancel',
onAwaitablePress: async (resolve) => {
resolve(null);
},
},
],
});
// These alerts will be shown in sequence
alert.show({ message: 'First alert' });
alert.show({ message: 'Second alert' });
alert.show({ message: 'Third alert' });
You can extend the AlertButtonCustomProps
interface to add custom properties to your buttons using TypeScript declaration merging:
// In your project's type declaration file (e.g., types.d.ts)
import 'react-native-alert-queue';
declare module 'react-native-alert-queue' {
interface AlertButtonCustomProps {
// Add your custom props here
variant?: 'primary' | 'secondary' | 'danger';
size?: 'small' | 'medium' | 'large';
isLoading?: boolean;
// ... any other custom props
}
}
// Usage in your components
alert.show({
title: 'Custom Button Props',
message: 'This alert uses custom button props',
buttons: [
{
text: 'Primary Button',
customProps: {
variant: 'primary',
size: 'large',
isLoading: true,
},
},
{
text: 'Secondary Button',
customProps: {
variant: 'secondary',
size: 'medium',
},
},
],
// you can define it globally in the config or override it here
renderButton: (props) => (
<TouchableOpacity
style={[
styles.button,
styles[props.customProps.variant],
styles[props.customProps.size],
]}
onPress={props.onPress}
disabled={props.disabled || props.customProps.isLoading}
>
{props.customProps.isLoading ? (
<ActivityIndicator color="white" />
) : (
<Text style={styles.buttonText}>{props.text}</Text>
)}
</TouchableOpacity>
),
});
You can customize the default appearance and behavior of alerts using the config
prop:
<AlertContainer
config={{
testID: 'alert_test_id',
backdropBackgroundColor: 'rgba(255, 255, 255, 0.5)',
alertStyle: {
borderRadius: 20,
padding: 20,
backgroundColor: theme.colors.alert.background,
},
success: {
icon: SuccessIcon,
iconColor: 'green',
title: 'Success',
},
error: {
icon: ErrorIcon,
iconColor: 'red',
title: 'Error',
},
buttons: {
gap: 10,
default: {
text: 'OK',
testID: 'default-button',
},
},
}}
/>
show(alert: AlertProps)
- Shows a custom alertsuccess(alert: AlertProps)
- Shows a success alerterror(error: Error, isFixable?: boolean)
- Shows an error alertconfirm(alert?: ConfirmProps)
- Shows a confirmation dialoghide()
- Hides the currently displayed alertclearQueue(hideDisplayedAlert?: boolean)
- Clears the alert queueupdate(id: string, alert: AlertProps)
- Updates an existing alertgetAlertData(id: string)
- Retrieves alert data by ID
id?: string
- Unique identifiertitle?: string
- Alert titlemessage?: string
- Alert messagetestID?: string
- Test identifierisDismissible?: boolean
- Whether alert can be dismissedbuttonsDirection?: 'row' | 'column'
- Button layout directionicon?: FC<IconProps>
- Custom icon componenticonColor?: ColorValue
- Icon coloriconSize?: number
- Icon sizebuttons?: AlertButton[]
- Array of buttonsconfetti?: boolean | ConfettiProps
- Confetti configurationrenderMessage?: ({ style, text }) => ReactElement
- Custom message rendererrenderTitle?: ({ style, text }) => ReactElement
- Custom title rendererrenderButton?: (props) => ReactElement
- Custom button rendererrenderDismissButton?: ({ onPress }) => ReactElement
- Custom dismiss button rendererbeforeTitleSlot?: () => ReactElement
- Content to render before the titlebeforeMessageSlot?: () => ReactElement
- Content to render before the messagebeforeButtonsSlot?: () => ReactElement
- Content to render before the buttonsafterButtonsSlot?: () => ReactElement
- Content to render after the buttons
text: string
- Button textonPress?: () => Promise<R> | R
- Press handlerdisabled?: boolean
- Whether button is disabledtestID?: string
- Test identifierhideAlertOnPress?: boolean
- Whether to hide alert on pressonAwaitablePress?: (resolve) => void
- Async press handlercustomProps?: AlertButtonCustomProps
- Custom button properties
type AlertConfig = {
// Test identifier for the alert
testID?: string;
// Background color of the backdrop
backdropBackgroundColor?: ColorValue;
// Custom alert style
alertStyle?: StyleProp<ViewStyle>;
// Default success alert configuration
success?: {
// Custom icon component for success alerts
icon?: FC<IconProps>;
// Icon color for success alerts
iconColor?: ColorValue;
// Icon size for success alerts
iconSize?: number;
// Default title for success alerts
title?: string;
};
// Default error alert configuration
error?: {
// Custom icon component for error alerts
icon?: FC<IconProps>;
// Icon color for error alerts
iconColor?: ColorValue;
// Icon size for error alerts
iconSize?: number;
// Default title for error alerts
title?: string;
};
// Default confirm dialog configuration
confirm?: {
// Custom icon component for confirm dialogs
icon?: FC<IconProps>;
// Icon color for confirm dialogs
iconColor?: ColorValue;
// Icon size for confirm dialogs
iconSize?: number;
// Default title for confirm dialogs
title?: string;
// Default button texts for confirm dialogs
buttons?: {
text: string;
customProps?: AlertButtonCustomProps;
}[];
};
// Global icon configuration
icon?: {
// Default icon size
size?: number;
// Default icon color
color?: ColorValue;
};
// Confetti configuration
confetti?: ConfettiProps;
// Custom renderers for alert components
renderTitle?: AlertProps['renderTitle'];
renderMessage?: AlertProps['renderMessage'];
renderDismissButton?: AlertProps['renderDismissButton'];
// Custom slots for additional content
afterButtonsSlot?: AlertProps['afterButtonsSlot'];
beforeButtonsSlot?: AlertProps['beforeButtonsSlot'];
beforeMessageSlot?: AlertProps['beforeMessageSlot'];
beforeTitleSlot?: AlertProps['beforeTitleSlot'];
// Button configuration
buttons?: {
// Gap between buttons
gap?: number;
// Custom button renderer
render?: AlertProps['renderButton'];
// Default button configuration
default?: {
// Default button text
text?: string;
// Default button testID
testID?: string;
};
};
};
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
Made with create-react-native-library