@emekauja/react-native-toast-message
v0.1.1
Published
Reusable React Native toast library with Reanimated-powered stacking and custom layouts.
Maintainers
Readme
React Native Toast Message Reanimated
A reusable toast library for React Native built around react-native-reanimated, react-native-gesture-handler, and react-native-safe-area-context.
Features
- Reanimated toast stack with swipe-to-dismiss
- Queueing with configurable
maxVisible - Imperative API and hook API
- Named hosts with optional extra
ToastViewportinstances - Default layout plus full custom renderers
- Slot-based style overrides for the default layout
- Typography that inherits the app's default font unless you override it
Preview
| Info | Success |
| --- | --- |
|
|
|
Installation
Install the peer dependencies in your app:
npm install react-native-gesture-handler react-native-reanimated react-native-safe-area-contextThen add this library to your project and make sure your app already follows the standard setup for Reanimated and Gesture Handler.
Quick Start
import React from 'react';
import { Button, View } from 'react-native';
import { Toast, ToastProvider, useToast } from '@emekauja/react-native-toast-message';
const DemoButton = () => {
const toast = useToast();
return (
<Button
title='Show toast'
onPress={() =>
toast.show({
title: 'Saved successfully',
subtitle: 'Your changes are already synced.',
type: 'success'
})
}
/>
);
};
export default function App() {
return (
<ToastProvider>
<View>
<DemoButton />
<Button
title='Show global toast'
onPress={() =>
Toast.show({
title: 'Sent',
type: 'info'
})
}
/>
</View>
</ToastProvider>
);
}Public API
ToastProvider
Mounts the default toast host and provides the hook/imperative API bridge.
Props:
layouts: register named custom layoutsdefaultLayout: choose the fallback layout keydefaultOptions: default toast options merged before each toasticonByTone: override the default layout icons for any tone and the closexshowToneIcons: hide or show the default layout tone icons globallymaxVisible: number of simultaneously visible toasts per hostoffsets: top/bottom edge offsetstheme: toast theme overrides, including typography slotsrenderDefaultViewport: disable the automatic default host if you want to mount all viewports manuallyviewportProps: props forwarded to the automatic default viewport
useToast()
Returns:
show(options)hide(id)hideAll(host?)
Toast
Imperative singleton with the same methods as useToast():
Toast.show(options);
Toast.hide(id);
Toast.hideAll();
Toast.hideAll('modal');ToastViewport
Manually renders a named host. This is primarily useful inside modals or if you disable the default viewport.
Props:
hostmaxVisibleoffsetsdefaultOptionsstyle
Toast Options
type ToastOptions = {
id?: string;
title: React.ReactNode;
subtitle?: React.ReactNode;
type?: 'default' | 'success' | 'error' | 'warning' | 'info';
placement?: 'top' | 'bottom';
duration?: number;
autoHide?: boolean;
host?: string;
leading?: React.ReactNode;
trailing?: React.ReactNode;
action?: {
label: string;
onPress: () => void;
closeOnPress?: boolean;
};
layout?: string;
render?: (props: ToastLayoutRenderProps) => React.ReactNode;
styles?: ToastStyleOverrides;
};Toast.show() returns the toast id.
Typography and Font Behavior
The default layout does not bundle or load fonts. It uses normal React Native text styles and therefore inherits the consuming app's default font behavior.
If your app uses a custom family globally, the toast will follow that. If you want toast-specific typography, pass theme overrides:
<ToastProvider
theme={{
typography: {
title: { fontFamily: 'YourApp-Semibold' },
subtitle: { fontFamily: 'YourApp-Regular' },
action: { fontFamily: 'YourApp-Semibold' }
}
}}
/>If no fontFamily is supplied, React Native falls back to the native/system font on that platform.
Custom Layouts and Styles
Register named layouts:
<ToastProvider
layouts={{
banner: ({ toast, dismiss, tone }) => (
<Pressable onPress={dismiss} style={{ backgroundColor: tone.background, padding: 16 }}>
<Text>{toast.title}</Text>
</Pressable>
)
}}
/>Use the layout:
Toast.show({
title: 'Server updated',
layout: 'banner'
});Or override one toast inline:
Toast.show({
title: 'Inline custom toast',
render: ({ toast, dismiss }) => (
<Pressable onPress={dismiss}>
<Text>{toast.title}</Text>
</Pressable>
)
});Slot-based styling is available for the default layout:
Toast.show({
title: 'Styled toast',
styles: {
container: { backgroundColor: '#111827' },
title: { color: '#ffffff' },
subtitle: { color: '#d1d5db' }
}
});You can also replace or suppress the default layout icons from the provider:
import { CheckCircle, TriangleAlert, X } from 'lucide-react-native';
<ToastProvider
iconByTone={{
success: CheckCircle,
error: CheckCircle,
warning: TriangleAlert,
info: CheckCircle,
x: X
}}
/>To hide the leading tone icons entirely while keeping the close button:
<ToastProvider showToneIcons={false} />See API docs, custom layouts, and modal usage.
