@eavfw/react-native-curved-tab-bar
Version:
A beautiful animated curved tab bar for React Native apps with customizable floating action button
218 lines (180 loc) • 6.39 kB
Markdown
[](https://www.npmjs.com/package/react-native-curved-tab-bar)
[](https://opensource.org/licenses/MIT)
A beautiful, customizable curved tab bar for React Native and Expo applications with an optional animated Floating Action Button (FAB).
<p align="center">
<img src="https://github.com/yourusername/react-native-curved-tab-bar/raw/main/demo.gif" alt="React Native Curved Tab Bar Demo" width="300"/>
</p>
- ✨ Beautiful curved tab bar design
- 🎯 Fully customizable (colors, dimensions, animations)
- 💫 Smooth animations powered by Reanimated 2+
- 📱 Compatible with React Navigation's bottom tabs
- 🔥 Optional animated floating action button
- 💪 Written in TypeScript with full type definitions
- 📦 Expo and React Native Web compatible
- 🔧 Simple and intuitive API
## Installation
```sh
npm install react-native-curved-tab-bar
# or
yarn add react-native-curved-tab-bar
```
### Dependencies
This library depends on the following packages:
```sh
# Required peer dependencies
npm install react-native-reanimated react-native-svg react-native-safe-area-context
# Optional (for haptic feedback on native platforms)
npm install expo-haptics
```
## Basic Usage
```tsx
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Home, User, Bell, Settings, ArrowLeftRight } from 'lucide-react-native';
import CurvedTabBar from 'react-native-curved-tab-bar';
// Your screens
import HomeScreen from './screens/HomeScreen';
import ProfileScreen from './screens/ProfileScreen';
import NotificationsScreen from './screens/NotificationsScreen';
import SettingsScreen from './screens/SettingsScreen';
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
tabBar={(props) => (
<CurvedTabBar
{...props}
fabIcon={<ArrowLeftRight color="#fff" size={20} />}
onFabPress={() => console.log('FAB pressed!')}
/>
)}
>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({ color }) => <Home size={24} color={color} />,
}}
/>
<Tab.Screen
name="Profile"
component={ProfileScreen}
options={{
tabBarIcon: ({ color }) => <User size={24} color={color} />,
}}
/>
<Tab.Screen
name="Notifications"
component={NotificationsScreen}
options={{
tabBarIcon: ({ color }) => <Bell size={24} color={color} />,
}}
/>
<Tab.Screen
name="Settings"
component={SettingsScreen}
options={{
tabBarIcon: ({ color }) => <Settings size={24} color={color} />,
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
```
```tsx
<CurvedTabBar
{...props}
backgroundColor="#F8F9FA"
strokeColor="#E9ECEF"
strokeWidth={1}
tabBarHeight={70}
fabSize={56}
fabColor="#FF6B6B"
fabIcon={<Plus color="#fff" size={24} />}
onFabPress={() => console.log('FAB pressed!')}
curveHeight={16}
fabTabIndex={2}
animateOnMount={true}
showFAB={true}
/>
```
```tsx
<CurvedTabBar
{...props}
showFAB={false}
backgroundColor="#F8F9FA"
curveHeight={10} // Lower curve height for a subtle effect
/>
```
```tsx
<CurvedTabBar
{...props}
style={{
borderTopWidth: 1,
borderTopColor: '#E0E0E0',
shadowColor: '#000',
shadowOffset: { width: 0, height: -2 },
shadowOpacity: 0.1,
shadowRadius: 3,
elevation: 10,
}}
fabStyle={{
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 5,
elevation: 12,
}}
/>
```
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| backgroundColor | string | '#FFFFFF' | Custom color for the tab bar background |
| strokeColor | string | 'rgba(0,0,0,0.05)' | Custom color for the stroke outline of the tab bar |
| strokeWidth | number | 0.5 | Custom stroke width for the tab bar outline |
| tabBarHeight | number | 80 | Height of the tab bar in pixels |
| showFAB | boolean | true | Whether to show a floating action button (FAB) in the center |
| fabSize | number | 60 | Size of the floating action button |
| fabColor | string | '#00C09A' | Custom color for the floating action button |
| fabIcon | ReactNode | undefined | Icon to display in the floating action button |
| onFabPress | function | undefined | Function to call when the floating action button is pressed |
| curveHeight | number | 14 | Height of the curve in the tab bar (0 = flat) |
| debug | boolean | false | Enable debug mode to see shape control points |
| fabTabIndex | number | 2 | Index of the tab that should contain the floating action button |
| style | ViewStyle | undefined | Custom styling for the tab bar container |
| fabStyle | ViewStyle | undefined | Custom styling for the floating action button |
| animateOnMount | boolean | true | Whether to animate the tab bar on mount |
## Troubleshooting
### Tab labels are cut off
Increase the `tabBarHeight` prop or add padding to the tab items:
```tsx
<CurvedTabBar
{...props}
tabBarHeight={90} // Increase from default 80
/>
```
Make sure you have properly configured react-native-reanimated in your project. See the [Reanimated installation guide](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation) for more details.
Adjust the `fabTabIndex` prop to match your tab structure. Default is 2 (the middle position for a 5-tab layout).
```tsx
<CurvedTabBar
{...props}
fabTabIndex={1} // For a 3-tab layout, middle position would be 1
/>
```
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
MIT