@xsolla/xui-tab-bar
v0.106.0
Published
A cross-platform React tab bar component implementing mobile-style bottom navigation, typically used with React Navigation. Follows WAI-ARIA Tabs pattern with proper keyboard navigation.
Readme
Tab Bar
A cross-platform React tab bar component implementing mobile-style bottom navigation, typically used with React Navigation. Follows WAI-ARIA Tabs pattern with proper keyboard navigation.
Installation
npm install @xsolla/xui-tab-bar
# or
yarn add @xsolla/xui-tab-barDemo
Basic Tab Bar
import * as React from 'react';
import { TabBar } from '@xsolla/xui-tab-bar';
import { Home, Search, User, Settings } from '@xsolla/xui-icons-base';
export default function BasicTabBar() {
// Simulated React Navigation state
const state = {
index: 0,
routes: [
{ key: 'home', name: 'Home' },
{ key: 'search', name: 'Search' },
{ key: 'profile', name: 'Profile' },
{ key: 'settings', name: 'Settings' },
],
};
const descriptors = {
home: { options: { tabBarIcon: ({ size }) => <Home size={size} />, title: 'Home' } },
search: { options: { tabBarIcon: ({ size }) => <Search size={size} />, title: 'Search' } },
profile: { options: { tabBarIcon: ({ size }) => <User size={size} />, title: 'Profile' } },
settings: { options: { tabBarIcon: ({ size }) => <Settings size={size} />, title: 'Settings' } },
};
return (
<TabBar
state={state}
descriptors={descriptors}
navigation={{ emit: () => ({}), navigate: () => {} }}
/>
);
}Anatomy
import { TabBar } from '@xsolla/xui-tab-bar';
<TabBar
state={navigationState} // React Navigation state
descriptors={descriptors} // Route descriptors
navigation={navigation} // Navigation object
labelPosition="below-icon" // below-icon or beside-icon
backgroundColor={color} // Custom background
activateOnFocus={true} // Activate tab on focus
aria-label="Main navigation" // Accessible label
id="main-tabs" // Element ID
/>Examples
With React Navigation
import * as React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { TabBar } from '@xsolla/xui-tab-bar';
import { Home, User, Settings } from '@xsolla/xui-icons-base';
const Tab = createBottomTabNavigator();
export default function AppNavigator() {
return (
<Tab.Navigator
tabBar={(props) => <TabBar {...props} />}
>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({ size, color }) => <Home size={size} color={color} />,
}}
/>
<Tab.Screen
name="Profile"
component={ProfileScreen}
options={{
tabBarIcon: ({ size, color }) => <User size={size} color={color} />,
}}
/>
<Tab.Screen
name="Settings"
component={SettingsScreen}
options={{
tabBarIcon: ({ size, color }) => <Settings size={size} color={color} />,
}}
/>
</Tab.Navigator>
);
}With Badges
import * as React from 'react';
import { TabBar } from '@xsolla/xui-tab-bar';
import { Home, Bell, ShoppingCart, User } from '@xsolla/xui-icons-base';
export default function TabBarWithBadges() {
const state = {
index: 0,
routes: [
{ key: 'home', name: 'Home' },
{ key: 'notifications', name: 'Notifications' },
{ key: 'cart', name: 'Cart' },
{ key: 'profile', name: 'Profile' },
],
};
const descriptors = {
home: { options: { tabBarIcon: ({ size }) => <Home size={size} />, title: 'Home' } },
notifications: {
options: {
tabBarIcon: ({ size }) => <Bell size={size} />,
title: 'Notifications',
tabBarBadge: 3, // Shows badge with count
},
},
cart: {
options: {
tabBarIcon: ({ size }) => <ShoppingCart size={size} />,
title: 'Cart',
tabBarBadge: '!', // Shows badge with text
},
},
profile: { options: { tabBarIcon: ({ size }) => <User size={size} />, title: 'Profile' } },
};
return (
<TabBar
state={state}
descriptors={descriptors}
navigation={{ emit: () => ({}), navigate: () => {} }}
/>
);
}Custom Styling
import * as React from 'react';
import { TabBar } from '@xsolla/xui-tab-bar';
import { Home, Search, User } from '@xsolla/xui-icons-base';
export default function CustomStyledTabBar() {
const state = {
index: 0,
routes: [
{ key: 'home', name: 'Home' },
{ key: 'search', name: 'Search' },
{ key: 'profile', name: 'Profile' },
],
};
const descriptors = {
home: { options: { tabBarIcon: ({ size }) => <Home size={size} />, title: 'Home' } },
search: { options: { tabBarIcon: ({ size }) => <Search size={size} />, title: 'Search' } },
profile: { options: { tabBarIcon: ({ size }) => <User size={size} />, title: 'Profile' } },
};
return (
<TabBar
state={state}
descriptors={descriptors}
navigation={{ emit: () => ({}), navigate: () => {} }}
backgroundColor="#1a1a1a"
labelPosition="below-icon"
/>
);
}API Reference
TabBar
TabBarProps:
| Prop | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| state | NavigationState | - | React Navigation state object. |
| descriptors | Descriptors | - | Route descriptor objects. |
| navigation | Navigation | - | Navigation object with emit/navigate. |
| labelPosition | "below-icon" \| "beside-icon" | "below-icon" | Label position relative to icon. |
| backgroundColor | string | theme background | Custom background color. |
| activateOnFocus | boolean | true | Navigate on focus (keyboard). |
| aria-label | string | "Tab navigation" | Accessible label. |
| aria-labelledby | string | - | ID of labelling element. |
| id | string | - | Element ID for accessibility. |
| testID | string | - | Test identifier. |
Route Options
Each route in descriptors can have these options:
| Option | Type | Description |
| :----- | :--- | :---------- |
| tabBarIcon | (props) => ReactNode | Icon render function. |
| tabBarLabel | string \| (props) => ReactNode | Tab label. |
| title | string | Fallback label if tabBarLabel not set. |
| tabBarBadge | string \| number | Badge content. |
| tabBarShowLabel | boolean | Show/hide label. |
| tabBarAccessibilityLabel | string | Custom accessible label. |
| tabBarTestID | string | Test ID for individual tab. |
Keyboard Navigation
| Key | Action |
| :-- | :----- |
| ArrowRight / ArrowDown | Move to next tab |
| ArrowLeft / ArrowUp | Move to previous tab |
| Home | Jump to first tab |
| End | Jump to last tab |
| Enter / Space | Activate focused tab |
Specifications
| Property | Value | | :------- | :---- | | Height | 60px | | Width | 100% | | Border | 1px top border |
Accessibility
- Uses
role="tablist"witharia-orientation="horizontal" - Individual tabs have
role="tab"with properaria-selected - Keyboard navigation follows WAI-ARIA Tabs pattern
- Focus management between tabs
- Badge content is announced to screen readers
- Custom accessibility labels supported per tab
