AnimatedButton
A sophisticated animated button component for React Native that provides smooth state transitions with loading, success, and error states.
Features
- π¨ Smooth Animations: Fade and slide transitions between states
- π Async Support: Works seamlessly with real API calls
- π‘οΈ Error Handling: Automatic error state management
- βοΈ Highly Configurable: Customizable animations and states
- π± Responsive: Maintains consistent height during state changes
- π― Type Safe: Full TypeScript support
Basic Usage
tsx
import React from 'react';
import { AnimatedButton } from '../components/animated-button';
export default function MyComponent() {
const handleSave = async () => {
// Your API call here
await fetch('/api/save', { method: 'POST' });
};
return (
<AnimatedButton
title="Save Changes"
onPress={handleSave}
variant="primary"
size="medium"
fullWidth
/>
);
}Props
Core Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | - | Button text to display |
onPress | () => Promise<void> | void | - | Async function to execute |
variant | 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'primary' | Button style variant |
size | 'small' | 'medium' | 'large' | 'medium' | Button size |
disabled | boolean | false | Disable button interaction |
fullWidth | boolean | false | Make button full width |
style | ViewStyle | - | Custom button styles |
textStyle | TextStyle | - | Custom text styles |
leftIcon | React.ReactNode | - | Icon to display on the left |
rightIcon | React.ReactNode | - | Icon to display on the right |
Animation Configuration
| Prop | Type | Default | Description |
|---|---|---|---|
animationConfig.duration | number | 150 | Animation duration in ms |
animationConfig.delay | number | 150 | Delay before new content appears |
animationConfig.translateDistance | number | 25 | Distance for translate animation |
State Configuration
| Prop | Type | Default | Description |
|---|---|---|---|
stateConfig.successDuration | number | 3500 | How long to show success state |
stateConfig.loadingText | React.ReactNode | null | Custom loading content (or spinner) |
stateConfig.successText | string | 'Login link sent!' | Success message |
stateConfig.errorText | string | 'Something went wrong' | Error message |
Button States
The button automatically manages these states:
- Idle β Loading β Success β Idle
- Idle β Loading β Error β Idle
State Flow
tsx
// 1. User presses button
// 2. Button shows loading state with spinner
// 3. API call executes
// 4. On success: Shows success message for 3.5s, then returns to idle
// 5. On error: Shows error message for 3.5s, then returns to idleVariants
Primary (Default)
tsx
<AnimatedButton
title="Save"
onPress={handleSave}
variant="primary"
/>Secondary
tsx
<AnimatedButton
title="Cancel"
onPress={handleCancel}
variant="secondary"
/>Outline
tsx
<AnimatedButton
title="Edit"
onPress={handleEdit}
variant="outline"
/>Ghost
tsx
<AnimatedButton
title="Delete"
onPress={handleDelete}
variant="ghost"
/>Danger
tsx
<AnimatedButton
title="Delete Account"
onPress={handleDeleteAccount}
variant="danger"
/>Sizes
Small
tsx
<AnimatedButton
title="Save"
onPress={handleSave}
size="small"
/>Medium (Default)
tsx
<AnimatedButton
title="Save"
onPress={handleSave}
size="medium"
/>Large
tsx
<AnimatedButton
title="Save"
onPress={handleSave}
size="large"
/>Advanced Examples
Custom Animation Speed
tsx
<AnimatedButton
title="Quick Save"
onPress={handleQuickSave}
animationConfig={{
duration: 100,
delay: 100,
translateDistance: 30,
}}
/>Custom State Messages
tsx
<AnimatedButton
title="Delete User"
onPress={handleDeleteUser}
variant="danger"
stateConfig={{
loadingText: 'Deleting...',
successText: 'User deleted!',
errorText: 'Failed to delete user',
}}
/>Custom Loading Content
tsx
<AnimatedButton
title="Process Data"
onPress={handleProcessData}
stateConfig={{
loadingText: (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<ActivityIndicator size="small" color="#fff" />
<Text style={{ color: '#fff', marginLeft: 8 }}>Processing...</Text>
</View>
),
}}
/>Form Validation
tsx
const handleSave = async () => {
if (!email || !password) {
throw new Error('Please fill in all fields');
}
await saveUser({ email, password });
};
<AnimatedButton
title="Save"
onPress={handleSave}
stateConfig={{
errorText: 'Please fill in all fields',
}}
/>Real API Integration
tsx
const handleLogin = async () => {
const response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
if (!response.ok) {
throw new Error('Login failed');
}
return response.json();
};
<AnimatedButton
title="Sign In"
onPress={handleLogin}
stateConfig={{
successText: 'Welcome back!',
errorText: 'Invalid credentials',
}}
/>Best Practices
1. Always Handle Errors
tsx
const handleSave = async () => {
try {
await saveData();
} catch (error) {
// The button will automatically show error state
throw error;
}
};2. Use Appropriate Variants
- Primary: Main actions (Save, Submit, Confirm)
- Secondary: Secondary actions (Cancel, Back)
- Outline: Alternative actions (Edit, View)
- Ghost: Subtle actions (More, Details)
- Danger: Destructive actions (Delete, Remove)
3. Customize Messages for Context
tsx
// Login form
stateConfig={{
successText: 'Welcome back!',
errorText: 'Invalid credentials',
}}
// Save form
stateConfig={{
successText: 'Changes saved!',
errorText: 'Failed to save changes',
}}
// Delete action
stateConfig={{
loadingText: 'Deleting...',
successText: 'Item deleted!',
errorText: 'Failed to delete item',
}}4. Optimize Animation Performance
tsx
// For fast operations
animationConfig={{
duration: 100,
delay: 100,
}}
// For slower operations
animationConfig={{
duration: 200,
delay: 200,
}}Dependencies
react-native-reanimated: For smooth animationsreact-native: Core React Native components@expo/vector-icons: For default icons (optional)
License
Feel free to use in your projects after purchasing the pro!