react-native-expandable-tabs
v1.0.2
Published
Press the center button and hidden tabs smoothly expand around it - a lightweight, animated expandable tab component for React Native
Maintainers
Readme
react-native-expandable-tabs
A lightweight, animated expandable tab component for React Native with zero runtime dependencies. Perfect for floating action buttons, bottom navigation, and contextual menus.
🎥 Demo
Table of Contents
Features
- 🎯 Press to expand — Center button triggers smooth tab expansion
- 🎨 Multiple directions — Horizontal, vertical, radial, semi-circle, and arc
- ⚡ Smooth animations — Built with React Native's Animated API
- 📱 Cross-platform — Works on iOS, Android, and Expo
- 🎛️ Highly configurable — Colors, sizes, animations, and more
- ♿ Accessible — Built-in accessibility support
- 🪶 Lightweight — Zero runtime dependencies
- 🔄 Controlled/Uncontrolled — Flexible state management
- 📦 Ref API — Programmatic control
Installation
npm install react-native-expandable-tabsor
yarn add react-native-expandable-tabsBasic Usage
import React, { useState } from "react";
import ExpandableTabs from "react-native-expandable-tabs";
const tabs = [
{ key: "home", label: "Home", icon: "🏠" },
{ key: "search", label: "Search", icon: "🔍" },
{ key: "profile", label: "Profile", icon: "👤" },
{ key: "settings", label: "Settings", icon: "⚙️", badge: 5 },
];
const App = () => {
const [activeTab, setActiveTab] = useState("home");
return (
<ExpandableTabs
tabs={tabs}
activeTab={activeTab}
onTabPress={(tab) => setActiveTab(tab.key)}
/>
);
};
export default App;Examples
Horizontal Mode (Default)
<ExpandableTabs tabs={tabs} direction="horizontal" radius={120} />Vertical Mode
<ExpandableTabs tabs={tabs} direction="vertical" radius={120} />Radial Mode
<ExpandableTabs
tabs={tabs}
direction="radial"
radius={140}
startAngle={0}
endAngle={360}
/>With Overlay
<ExpandableTabs
tabs={tabs}
showOverlay={true}
overlayOpacity={0.3}
closeOnOverlayPress={true}
/>Custom Theme
<ExpandableTabs
tabs={tabs}
primaryColor="#6C63FF"
activeColor="#6C63FF"
backgroundColor="#FFFFFF"
textColor="#333333"
tabSize={50}
centerButtonSize={60}
/>Controlled Mode
const [expanded, setExpanded] = useState(false);
<ExpandableTabs
tabs={tabs}
expanded={expanded}
onExpandedChange={setExpanded}
/>;With Ref API
const tabsRef = useRef(null);
<ExpandableTabs ref={tabsRef} tabs={tabs} />;
// Programmatic control
tabsRef.current.open();
tabsRef.current.close();
tabsRef.current.toggle();
const activeTab = tabsRef.current.getActiveTab();API Reference
Props
| Prop | Type | Default | Description |
| ------------------------------- | -------- | ----------------- | --------------------------------------------------------------------------------------------------------------------- |
| tabs | array | Required | Array of tab objects |
| direction | string | 'horizontal' | Expansion direction: 'horizontal', 'vertical', 'radial', 'semi-circle', 'arc' |
| position | string | 'bottom-center' | Position on screen: 'bottom-center', 'bottom-left', 'bottom-right', 'top-center', 'top-left', 'top-right' |
| radius | number | 120 | Distance tabs expand from center |
| startAngle | number | 0 | Starting angle for radial/arc modes |
| endAngle | number | 360 | Ending angle for radial/arc modes |
| expanded | bool | - | Controlled expanded state |
| defaultExpanded | bool | false | Default expanded state |
| activeTab | string | - | Controlled active tab key |
| defaultActiveTab | string | - | Default active tab key |
| animationType | string | 'timing' | 'timing' or 'spring' |
| animationDuration | number | 300 | Animation duration in ms |
| stagger | number | 40 | Stagger delay between tabs in ms |
| showLabels | bool | true | Show tab labels |
| showOverlay | bool | false | Show overlay when expanded |
| overlayOpacity | number | 0.2 | Overlay opacity |
| closeOnTabPress | bool | true | Close menu when tab is pressed |
| closeOnOverlayPress | bool | true | Close menu when overlay is pressed |
| primaryColor | string | '#6200EE' | Primary color for center button |
| activeColor | string | '#6200EE' | Active tab color |
| inactiveColor | string | '#777777' | Inactive tab color |
| backgroundColor | string | '#FFFFFF' | Tab background color |
| textColor | string | '#111111' | Tab text color |
| tabSize | number | 50 | Tab size (width/height) |
| centerButtonSize | number | 60 | Center button size |
| iconSize | number | 24 | Icon size |
| labelFontSize | number | 12 | Label font size |
| badgeSize | number | 20 | Badge size |
| edgePadding | number | 20 | Minimum distance from screen edges |
| centerButtonRotation | number | 45 | Rotation angle for center button |
| centerButtonScale | number | 1.05 | Scale factor for center button |
| centerButtonAnimationDuration | number | 250 | Center button animation duration |
Tab Object
| Property | Type | Description |
| ---------- | ------------------------ | -------------------------------- |
| key | string | Required — Unique identifier |
| label | string | Tab label |
| icon | string \| ReactElement | Tab icon (text or component) |
| badge | string \| number | Badge value |
| disabled | bool | Disable tab |
Events
| Prop | Type | Description |
| ------------------ | ---------------------- | ----------------------------------- |
| onTabPress | (tab, index) => void | Called when tab is pressed |
| onTabChange | (tab, index) => void | Called when active tab changes |
| onExpandedChange | (expanded) => void | Called when expansion state changes |
| onOpen | () => void | Called when menu opens |
| onClose | () => void | Called when menu closes |
| onToggle | (expanded) => void | Called when menu toggles |
| onAnimationStart | (expanded) => void | Called when animation starts |
| onAnimationEnd | (expanded) => void | Called when animation ends |
Ref API
| Method | Description |
| ---------------- | ---------------------------- |
| open() | Expand the menu |
| close() | Collapse the menu |
| toggle() | Toggle menu state |
| getActiveTab() | Get the currently active tab |
| isExpanded() | Check if menu is expanded |
Custom Rendering
| Prop | Type | Description |
| -------------------------- | --------------------------------------------------------- | ------------------------------------- |
| renderCenterIcon | () => ReactNode | Custom center button icon (collapsed) |
| renderExpandedCenterIcon | () => ReactNode | Custom center button icon (expanded) |
| renderTab | (tab, index, isActive) => ReactNode | Custom tab renderer |
| renderTabIcon | ({ icon, size, color }) => ReactNode | Custom tab icon renderer |
| renderTabLabel | ({ label, isActive, textColor, fontSize }) => ReactNode | Custom tab label renderer |
| renderBadge | ({ badge, size }) => ReactNode | Custom badge renderer |
Accessibility
The component includes built-in accessibility support:
accessibilityRole="button"for the center buttonaccessibilityRole="tab"for tabsaccessibilityStatefor expanded/selected/disabled states- Configurable labels and hints
License
This project is under the MIT license.
Author
Built with ❤️ by Nascenture.
- 🌐 Website: https://www.nascenture.com
- 📱 React Native Development Services: https://www.nascenture.com/react-native-app-development/
