Animated Tabs
A button which changes it’s appearance if tapped
import { StyleSheet, Text, View } from 'react-native'import React from 'react'import AnimatedTabs from '../components/animatedTabs'
//or if you're using npm package//import {AnimatedTabs} from '@cascadeui/animated-tabs'
const tabs = ["home","profile","settings"]
const HomeContent = () => <Text style={styles.contentText}>Welcome to the Home Tab</Text>; //replace with real screens or contentconst ProfileContent = () => <Text style={styles.contentText}>This is the Profile Tab</Text>;const SettingsContent = () => <Text style={styles.contentText}>Settings Page</Text>;
const App = () => { return ( <View> <TabBar tabs={['Home', 'Profile', 'Settings']} contents={[<HomeContent />, <ProfileContent />, <SettingsContent />]} /> </View> )}
export default AppInstallation
- Install component
Terminal window npm install @cascadeui/animated-tabs - 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/animatedTabs.tsximport React, { useState } from 'react';import { View, Text, TouchableOpacity, StyleSheet, Appearance } from 'react-native';import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';const theme = {dark: {text: 'white',background: '#191e24',primary: '#007AFF',},light: {text: 'black',background: '#f2f2f2',primary: '#007AFF',}};const TAB_WIDTH = 100;const isDarkMode = Appearance.getColorScheme() === 'dark';const colors = theme[isDarkMode ? 'dark' : 'light'];type TabProps = {tabs: string[],contents: React.ReactNode[],};const AnimatedTabs: React.FC<TabProps> = ({ tabs, contents }) => {const [activeTab, setActiveTab] = useState(0);const activeIndex = useSharedValue(0);const onTabPress = (index: number) => {setActiveTab(index);activeIndex.value = withTiming(index, { duration: 300 });};const animatedStyle = useAnimatedStyle(() => {return {transform: [{ translateX: activeIndex.value * TAB_WIDTH }],};});return (<View style={styles.wrapper}><View style={styles.container}><Animated.View style={[styles.highlight, animatedStyle]} /><View style={[styles.tabsContainer, { width: TAB_WIDTH * tabs.length }]}>{tabs.map((tab, index) => (<TouchableOpacity key={index} onPress={() => onTabPress(index)} style={styles.tab}><Text style={activeTab === index ? styles.activeTabText : styles.tabText}>{tab}</Text></TouchableOpacity>))}</View></View><View style={styles.content}>{contents[activeTab]}</View></View>);};const styles = StyleSheet.create({wrapper: {flex: 1,alignItems: 'center',justifyContent: 'center',},container: {position: 'relative',height: 50,flexDirection: 'row',backgroundColor: colors.background,alignItems: 'center',borderRadius: 10,},tabsContainer: {flexDirection: 'row',},tab: {width: TAB_WIDTH,alignItems: 'center',justifyContent: 'center',},tabText: {color: colors.text,fontSize: 16,},activeTabText: {color: '#fff',fontWeight: 'bold',fontSize: 16,},highlight: {position: 'absolute',width: 90,height: '80%',backgroundColor: colors.primary,borderRadius: 10,right: 5,left: 5,},content: {marginTop: 20,},contentText: {fontSize: 18,color: colors.text,},});export default AnimatedTabs;
Props
| Prop | Type | Description |
|---|---|---|
tabs | string[] | Array of string containing name of the tabs. |
Note:To add the content in the tabs you have to do it manually in core component code