Introduction
Components
- Accordion
- Action Sheet
- Alert
- Audio Player
- Audio Recorder
- Audio Waveform
- Avatar
- Badge
- BottomSheet
- Button
- Camera
- Camera Preview
- Card
- Carousel
- Checkbox
- Collapsible
- Color Picker
- Combobox
- Date Picker
- File Picker
- Gallery
- Hello Wave
- Icon
- Image
- Input
- Input OTP
- Link
- MediaPicker
- Mode Toggle
- Onboarding
- ParallaxScrollView
- Picker
- Popover
- Progress
- Radio
- ScrollView
- SearchBar
- Separator
- Share
- Sheet
- Skeleton
- Spinner
- Switch
- Table
- Tabs
- Text
- Toast
- Toggle
- Video
- View
Charts
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/toast';
import React from 'react';
export function ToastDemo() {
const { toast } = useToast();
const showToast = () => {
toast({
title: 'Toast Notification',
description:
'This is a basic toast notification with title and description.',
variant: 'default',
});
};
return <Button onPress={showToast}>Show Toast</Button>;
}
Installation
pnpm dlx bna-ui add toast
Usage
import { useToast } from '@/components/ui/toast';
function MyComponent() {
const { toast } = useToast();
const showToast = () => {
toast({
title: 'Success!',
description: 'Your changes have been saved.',
variant: 'success',
});
};
return <Button onPress={showToast}>Show Toast</Button>;
}
Examples
Default
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/toast';
import React from 'react';
export function ToastDemo() {
const { toast } = useToast();
const showToast = () => {
toast({
title: 'Toast Notification',
description:
'This is a basic toast notification with title and description.',
variant: 'default',
});
};
return <Button onPress={showToast}>Show Toast</Button>;
}
Variants
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/toast';
import { View } from '@/components/ui/view';
import React from 'react';
export function ToastVariants() {
const { success, error, warning, info } = useToast();
return (
<View style={{ gap: 12 }}>
<Button
onPress={() =>
success('Success!', 'Your action was completed successfully.')
}
variant='success'
>
Success
</Button>
<Button
onPress={() =>
error('Error!', 'Something went wrong. Please try again.')
}
variant='destructive'
>
Error
</Button>
<Button
onPress={() =>
warning('Warning!', 'Please review your input before continuing.')
}
variant='secondary'
>
Warning
</Button>
<Button
onPress={() => info('Info', "Here's some helpful information for you.")}
>
Info
</Button>
</View>
);
}
With Actions
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/toast';
import { View } from '@/components/ui/view';
import React from 'react';
export function ToastActions() {
const { toast } = useToast();
const showToastWithAction = () => {
toast({
title: 'New message received',
description: 'You have a new message from John Doe.',
variant: 'info',
action: {
label: 'View',
onPress: () => {
console.log('View action pressed');
// Navigate to message or perform action
},
},
});
};
const showUndoToast = () => {
toast({
title: 'Item deleted',
description: 'The item has been removed from your list.',
variant: 'warning',
duration: 8000, // Longer duration for undo action
action: {
label: 'Undo',
onPress: () => {
console.log('Undo action pressed');
// Restore the deleted item
},
},
});
};
return (
<View style={{ gap: 12 }}>
<Button onPress={showToastWithAction} variant='outline'>
Show with Action
</Button>
<Button onPress={showUndoToast} variant='outline'>
Show Undo Toast
</Button>
</View>
);
}
Custom Duration
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/toast';
import { View } from '@/components/ui/view';
import React from 'react';
export function ToastDuration() {
const { toast } = useToast();
return (
<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 12 }}>
<Button
onPress={() =>
toast({
title: 'Quick toast',
description: 'This disappears in 2 seconds',
duration: 2000,
variant: 'info',
})
}
variant='outline'
>
2 seconds
</Button>
<Button
onPress={() =>
toast({
title: 'Standard toast',
description: 'This disappears in 4 seconds',
duration: 4000,
variant: 'default',
})
}
variant='outline'
>
4 seconds (default)
</Button>
<Button
onPress={() =>
toast({
title: 'Long toast',
description: 'This disappears in 8 seconds',
duration: 8000,
variant: 'warning',
})
}
variant='outline'
>
8 seconds
</Button>
<Button
onPress={() =>
toast({
title: 'Persistent toast',
description: "This won't disappear automatically",
duration: 0, // No auto-dismiss
variant: 'error',
})
}
variant='outline'
>
Persistent
</Button>
</View>
);
}
Multiple Toasts
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/toast';
import { View } from '@/components/ui/view';
import React from 'react';
export function ToastMultiple() {
const { toast, dismissAll } = useToast();
const showMultipleToasts = () => {
const variants = ['success', 'warning', 'error', 'info'] as const;
const messages = [
{ title: 'Success!', description: 'Operation completed successfully' },
{ title: 'Warning', description: 'Please check your input' },
{ title: 'Error', description: 'Something went wrong' },
{ title: 'Info', description: "Here's some information" },
];
variants.forEach((variant, index) => {
setTimeout(() => {
toast({
...messages[index],
variant,
duration: 6000,
});
}, index * 500); // Stagger the toasts
});
};
const showBatchToasts = () => {
// Show multiple toasts at once
toast({
title: 'First toast',
description: 'This is the first toast',
variant: 'success',
});
toast({
title: 'Second toast',
description: 'This is the second toast',
variant: 'info',
});
toast({
title: 'Third toast',
description: 'This is the third toast',
variant: 'warning',
});
};
return (
<View style={{ gap: 12 }}>
<Button onPress={showMultipleToasts} variant='outline'>
Show Staggered Toasts
</Button>
<Button onPress={showBatchToasts} variant='outline'>
Show Batch Toasts
</Button>
<Button onPress={dismissAll} variant='destructive'>
Dismiss All Toasts
</Button>
</View>
);
}
Compact Mode
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/toast';
import { View } from '@/components/ui/view';
import React from 'react';
export function ToastCompact() {
const { toast } = useToast();
return (
<View style={{ gap: 12 }}>
<Button
onPress={() =>
toast({
variant: 'success',
})
}
variant='success'
>
Success Icon Only
</Button>
<Button
onPress={() =>
toast({
variant: 'error',
})
}
variant='destructive'
>
Error Icon Only
</Button>
<Button
onPress={() =>
toast({
variant: 'warning',
})
}
variant='secondary'
>
Warning Icon Only
</Button>
<Button
onPress={() =>
toast({
variant: 'info',
})
}
variant='outline'
>
Info Icon Only
</Button>
<Button
onPress={() =>
toast({
title: 'Title only',
})
}
>
Title Only
</Button>
</View>
);
}
API Reference
ToastProvider
The provider component that manages toast state and renders toasts.
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | - | The app content to wrap with toast provider. |
maxToasts | number | 3 | Maximum number of toasts to display at once. |
useToast
Hook that provides methods to show and manage toasts.
const { toast, success, error, warning, info, dismiss, dismissAll } =
useToast();
Methods
Method | Type | Description |
---|---|---|
toast | (data: ToastData) => void | Show a toast with custom data. |
success | (title: string, description?: string) => void | Show a success toast. |
error | (title: string, description?: string) => void | Show an error toast. |
warning | (title: string, description?: string) => void | Show a warning toast. |
info | (title: string, description?: string) => void | Show an info toast. |
dismiss | (id: string) => void | Dismiss a specific toast by ID. |
dismissAll | () => void | Dismiss all active toasts. |
ToastData
Configuration object for toast notifications.
Prop | Type | Default | Description |
---|---|---|---|
title | string | - | The title of the toast. |
description | string | - | The description text of the toast. |
variant | 'default' | 'success' | 'error' | 'warning' | 'info' | 'default' | The visual variant of the toast. |
duration | number | 4000 | Duration in milliseconds before auto-dismiss. Set to 0 to disable auto-dismiss. |
action | { label: string; onPress: () => void } | - | Optional action button configuration. |
Animation
The toast component features iOS Dynamic Island-inspired animations:
- Entrance: Smooth slide-in from top with scale and opacity transitions
- Expansion: Automatic expansion when content is present
- Gestures: Swipe-to-dismiss with spring animations
- Stacking: Multiple toasts stack vertically with proper spacing
- Exit: Fade out with scale transition
Accessibility
The Toast component is built with accessibility in mind:
- Proper color contrast for all variants
- Clear visual hierarchy with title and description
- Icon indicators for different toast types
- Dismissible with both gesture and button interactions
- Supports dynamic text sizing
- Screen reader friendly content structure
Customization
Custom Colors
You can customize the colors by modifying the getVariantColor()
function in the component:
const getVariantColor = () => {
switch (variant) {
case 'success':
return '#34D399'; // Custom green
case 'error':
return '#F87171'; // Custom red
// ... other variants
}
};
Custom Positioning
Modify the getTopPosition()
function to change toast positioning:
const getTopPosition = () => {
const statusBarHeight = Platform.OS === 'ios' ? 59 : 20;
const customOffset = 20; // Add custom offset
return (
statusBarHeight + customOffset + index * (EXPANDED_HEIGHT + TOAST_MARGIN)
);
};
Custom Animations
The component uses React Native Animated API. You can customize animation timing and easing:
Animated.spring(translateY, {
toValue: 0,
tension: 100, // Custom tension
friction: 10, // Custom friction
useNativeDriver: true,
});