Animated Button
A button which changes it’s appearance if tapped
import { StyleSheet, Text, View } from 'react-native'import React from 'react'import { AnimatedSubscribeButton } from '../components/animatedButton'
//or if you're using npm package// import { AnimatedSubscribeButton } from '@cascadeui/animatedbutton'
const App = () => { return ( <View>
<AnimatedSubscribeButton buttonColor="#000000" buttonTextColor="#ffffff" subscribeStatus={false} initialText="Subscribe" changeText="Subscribed" />
</View> )}
export default AppInstallation
- Install component
Terminal window npm install @cascadeui/animatedbutton - Add react-native-reanimated plugin into
babel.configmodule.exports = {presets: [... // don't add it here :)],plugins: [...'react-native-reanimated/plugin',],};
-
Install React Native Reanimated
Terminal window npm install react-native-reanimatedTerminal window yarn add react-native-reanimatedTerminal window npx expo install react-native-reanimated -
Add Reanimated plugin into babel.config file
module.exports = {presets: [... // don't add it here :)],plugins: [...'react-native-reanimated/plugin',],}; -
Copy core component
src/components/AnimatedButton.tsximport React, { useState } from 'react';import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';import Animated, { useSharedValue, useAnimatedStyle, withTiming } from 'react-native-reanimated';interface AnimatedSubscribeButtonProps {buttonColor: string;buttonTextColor?: string;subscribeStatus: boolean;initialText: React.ReactElement | string;changeText: React.ReactElement | string;buttonWidth?:number}export const AnimatedSubscribeButton: React.FC<AnimatedSubscribeButtonProps> = ({buttonColor,subscribeStatus = false,buttonTextColor = '#fff',initialText,changeText,buttonWidth}) => {const [isSubscribed, setIsSubscribed] = useState<boolean>(subscribeStatus);// Shared value for the opacity animationconst opacity = useSharedValue(1);const translateY = useSharedValue(0);// Animate styles based on the subscription statusconst animatedButtonStyle = useAnimatedStyle(() => {return {opacity: withTiming(opacity.value, { duration: 300 }),};});const animatedTextStyle = useAnimatedStyle(() => {return {transform: [{ translateY: withTiming(translateY.value, { duration: 300 }) }],};});const handlePress = () => {// Trigger animation and toggle subscription stateopacity.value = 0; // Fade outtranslateY.value = -50; // Move text upsetTimeout(() => {setIsSubscribed(!isSubscribed);opacity.value = 1; // Fade intranslateY.value = 0; // Move text back to original position}, 300);};return (<Animated.View style={[styles.buttonContainer,{width:buttonWidth||200}]}><TouchableOpacityonPress={handlePress}style={[styles.button,{ backgroundColor: isSubscribed ? '#fff' : buttonColor, borderColor: buttonColor },]}activeOpacity={1}><Animated.View style={[animatedButtonStyle, animatedTextStyle]}>{isSubscribed ? (<View style={styles.textContainer}><Text style={[styles.buttonText, { color: buttonColor }]}>{changeText}</Text></View>) : (<View style={styles.textContainer}><Text style={[styles.buttonText, { color: buttonTextColor }]}>{initialText}</Text></View>)}</Animated.View></TouchableOpacity></Animated.View>);};// Styles for the componentconst styles = StyleSheet.create({buttonContainer: {borderRadius: 8,justifyContent: 'center',alignItems: 'center',overflow: 'hidden',},button: {width: '100%',height: 50,justifyContent: 'center',alignItems: 'center',borderWidth: 1,borderRadius: 8,},textContainer: {flexDirection: 'row',alignItems: 'center',},buttonText: {fontWeight: '600',fontSize: 16,},});
Props
| Prop | Type | Description |
|---|---|---|
buttonColor | string | Color of the button. |
buttonTextColor | string | Color of button Text. |
subscribeStatus | boolean | state of the button(subscribed/unsubscribed). |
initialText | string | First text of button . |
changeText | string | Text that will appear after state change . |