npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-curved-tab-bar

v0.4.5

Published

A customizable curved tab bar component for React Native with smooth animations

Downloads

99

Readme

React Native Curved Tab Bar

A beautiful, customizable curved tab bar component for React Native with smooth animations and floating active tab button.

Features

  • 🎨 Customizable gradient backgrounds (pure SVG, no external dependencies)
  • 🎯 Smooth spring animations
  • 📱 Responsive design that adapts to different screen sizes
  • 🔧 Highly configurable with TypeScript support
  • 📋 Badge support for notifications
  • ⌨️ Optional keyboard hiding
  • 🎭 Custom icons and styling
  • 📱 iOS and Android compatible
  • 🚀 Lightweight with minimal dependencies (only react-native-svg required)

📱 Demo

Installation

npm install react-native-curved-tab-bar
# or
yarn add react-native-curved-tab-bar

Peer Dependencies

Make sure you have this peer dependency installed:

npm install react-native-svg
# or
yarn add react-native-svg

Additional Setup

For react-native-svg:

  • Follow the installation guide: https://github.com/react-native-svg/react-native-svg

Basic Usage

import React, { useState } from 'react';
import { View } from 'react-native';
import { CurvedTabBar, TabItem } from 'react-native-curved-tab-bar';

const tabs: TabItem[] = [
  {
    key: 'home',
    label: 'Home',
    icon: require('./assets/home-icon.png'),
  },
  {
    key: 'search',
    label: 'Search',
    icon: require('./assets/search-icon.png'),
  },
  {
    key: 'profile',
    label: 'Profile',
    icon: require('./assets/profile-icon.png'),
    badgeCount: 3,
  },
];

const App = () => {
  const [activeTab, setActiveTab] = useState(0);

  const handleTabPress = (index: number, tab: TabItem) => {
    setActiveTab(index);
    // Handle navigation or other logic here
    console.log('Tab pressed:', tab.key);
  };

  return (
    <View style={{ flex: 1 }}>
      {/* Your app content */}

      <CurvedTabBar
        tabs={tabs}
        activeIndex={activeTab}
        onTabPress={handleTabPress}
        gradientColors={['#6366f1', '#8b5cf6']}
      />
    </View>
  );
};

export default App;

Advanced Usage

import React, { useState } from 'react';
import { CurvedTabBar, TabItem } from 'react-native-curved-tab-bar';

const tabs: TabItem[] = [
  {
    key: 'dashboard',
    label: 'Dashboard',
    icon: require('./assets/dashboard.png'),
  },
  {
    key: 'analytics',
    label: 'Analytics',
    icon: require('./assets/analytics.png'),
    badgeCount: 12,
  },
  {
    key: 'settings',
    label: 'Settings',
    icon: require('./assets/settings.png'),
  },
];

const AdvancedExample = () => {
  const [activeTab, setActiveTab] = useState(0);

  return (
    <CurvedTabBar
      tabs={tabs}
      activeIndex={activeTab}
      onTabPress={(index, tab) => {
        setActiveTab(index);
        // Custom logic for each tab
        if (tab.key === 'analytics') {
          // Navigate to analytics screen
        }
      }}
      gradientColors={['#ff6b6b', '#feca57']}
      heightPercentage={10}
      floatingButtonSize={7}
      activeIconColor="#ffffff"
      inactiveIconColor="#999999"
      activeTextColor="#333333"
      inactiveTextColor="#999999"
      fontSize={14}
      fontFamily="Arial"
      hideOnKeyboard={true}
      springConfig={{
        damping: 15,
        stiffness: 150,
      }}
      shadowConfig={{
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 5 },
        shadowOpacity: 0.3,
        shadowRadius: 25,
        elevation: 10,
      }}
    />
  );
};

Props

| Prop | Type | Default | Description | | -------------------- | --------------------------------------- | ------------------------------- | --------------------------------------------------- | | tabs | TabItem[] | Required | Array of tab items | | activeIndex | number | Required | Currently active tab index | | onTabPress | (index: number, tab: TabItem) => void | Required | Callback when tab is pressed | | gradientColors | string[] | ['#6366f1', '#8b5cf6'] | Background gradient colors | | heightPercentage | number | 9 | Tab bar height as percentage of screen height | | floatingButtonSize | number | 6 | Floating button size as percentage of screen height | | activeIconColor | string | '#ffffff' | Active tab icon tint color | | inactiveIconColor | string | '#cccccc' | Inactive tab icon tint color | | activeTextColor | string | activeIconColor | Active tab text color | | inactiveTextColor | string | '#cccccc' | Inactive tab text color | | fontSize | number | 12 | Tab label font size | | fontFamily | string | undefined | Custom font family for labels | | hideOnKeyboard | boolean | false | Hide tab bar when keyboard is visible | | springConfig | object | {damping: 12, stiffness: 120} | Animation spring configuration | | shadowConfig | object | See below | Shadow configuration for floating button |

TabItem Interface

interface TabItem {
  key: string; // Unique identifier
  label: string; // Display label
  icon: any; // Icon source (require() or URI)
  badgeCount?: number; // Optional badge count
}

Shadow Configuration

shadowConfig?: {
  shadowColor?: string;
  shadowOffset?: { width: number; height: number };
  shadowOpacity?: number;
  shadowRadius?: number;
  elevation?: number; // Android only
}

Default shadow configuration:

{
  shadowColor: '#000',
  shadowOffset: { width: 0, height: 3 },
  shadowOpacity: 0.2,
  shadowRadius: 20,
  elevation: 8,
}

Customization Examples

Single Color Gradient

<CurvedTabBar
  // ... other props
  gradientColors={['#ff6b6b']} // Will use same color for both ends
/>

Custom Colors

<CurvedTabBar
  // ... other props
  gradientColors={['#667eea', '#764ba2']}
  activeIconColor="#ffffff"
  inactiveIconColor="#a0a0a0"
  activeTextColor="#333333"
  inactiveTextColor="#888888"
/>

Different Heights and Sizes

<CurvedTabBar
  // ... other props
  heightPercentage={12} // Taller tab bar
  floatingButtonSize={8} // Larger floating button
  fontSize={16} // Larger text
/>

Integration with Navigation Libraries

React Navigation v6

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { CurvedTabBar } from 'react-native-curved-tab-bar';

const Tab = createBottomTabNavigator();

function MyTabs() {
  return (
    <Tab.Navigator tabBar={(props) => <CustomTabBar {...props} />}>
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Search" component={SearchScreen} />
      <Tab.Screen name="Profile" component={ProfileScreen} />
    </Tab.Navigator>
  );
}

function CustomTabBar({ state, navigation }) {
  const tabs = state.routes.map((route) => ({
    key: route.key,
    label: route.name,
    icon: getIconForRoute(route.name), // Your icon mapping function
  }));

  return (
    <CurvedTabBar
      tabs={tabs}
      activeIndex={state.index}
      onTabPress={(index) => {
        const route = state.routes[index];
        navigation.navigate(route.name);
      }}
      gradientColors={['#6366f1', '#8b5cf6']}
    />
  );
}

Troubleshooting

Icons not showing

Make sure your icon images are properly imported and accessible:

// Correct
icon: require('./assets/home.png');

// Also correct for remote images
icon: {
  uri: 'https://example.com/icon.png';
}

Animations not smooth

Try adjusting the spring configuration:

springConfig={{
  damping: 15,    // Higher = less bouncy
  stiffness: 100, // Higher = faster animation
}}

Tab bar covering content

The tab bar uses absolute positioning. Make sure your content has appropriate bottom padding:

<View style={{ flex: 1, paddingBottom: 80 }}>{/* Your content */}</View>

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.