A lightweight, animated expandable tab component for React Native with zero runtime dependencies. Perfect for floating action buttons, bottom navigation, and contextual menus.
- π― 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
npm install react-native-expandable-tabsor
yarn add react-native-expandable-tabsimport 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;<ExpandableTabs tabs={tabs} direction="horizontal" radius={120} /><ExpandableTabs tabs={tabs} direction="vertical" radius={120} /><ExpandableTabs
tabs={tabs}
direction="radial"
radius={140}
startAngle={0}
endAngle={360}
/><ExpandableTabs
tabs={tabs}
showOverlay={true}
overlayOpacity={0.3}
closeOnOverlayPress={true}
/><ExpandableTabs
tabs={tabs}
primaryColor="#6C63FF"
activeColor="#6C63FF"
backgroundColor="#FFFFFF"
textColor="#333333"
tabSize={50}
centerButtonSize={60}
/>const [expanded, setExpanded] = useState(false);
<ExpandableTabs
tabs={tabs}
expanded={expanded}
onExpandedChange={setExpanded}
/>;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();| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
The component includes built-in accessibility support:
accessibilityRole="button"for the center buttonaccessibilityRole="tab"for tabsaccessibilityStatefor expanded/selected/disabled states- Configurable labels and hints
This project is under the MIT license.
Built with β€οΈ by Nascenture.
- π Website: https://www.nascenture.com
- π± React Native Development Services: https://www.nascenture.com/react-native-app-development/
