@xsolla/xui-tab-bar
v0.162.0
Published
A pill-shaped, segmented-style tab bar that adapts the React Navigation bottom-tab API. Implements the WAI-ARIA Tabs pattern with roving tab index and arrow-key navigation.
Downloads
7,634
Readme
TabBar
A pill-shaped, segmented-style tab bar that adapts the React Navigation bottom-tab API. Implements the WAI-ARIA Tabs pattern with roving tab index and arrow-key navigation.
Installation
npm install @xsolla/xui-tab-barImports
import { TabBar, TabBarItem } from '@xsolla/xui-tab-bar';Quick start
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 Example() {
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: () => {} }}
aria-label="Main navigation"
/>
);
}API Reference
<TabBar>
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| state | { index: number; routes: { key: string; name: string; params?: object }[] } | - | React Navigation state. Required. |
| descriptors | Record<string, { options: TabBarRouteOptions }> | - | Per-route options keyed by route.key. Required. |
| navigation | { navigate: (name, params?) => void; emit: (opts) => any } | - | React Navigation navigation object. Required. |
| labelPosition | 'below-icon' \| 'beside-icon' | 'below-icon' | Label position relative to icon. |
| backgroundColor | string | segmented-control bg token | Container background colour. |
| activateOnFocus | boolean | true | Activate a tab as soon as it receives keyboard focus. When false, arrow keys only move focus and Enter/Space activates. |
| aria-label | string | 'Tab navigation' | Accessible label for the tablist. |
| aria-labelledby | string | - | ID of an external labelling element. |
| id | string | - | Container ID; used to derive per-tab IDs. |
| testID | string | 'tab-bar-container' | Test identifier. |
Inherits ThemeOverrideProps (themeMode, themeProductContext).
Route options (per descriptor)
| Option | Type | Description |
| --- | --- | --- |
| tabBarIcon | (props: { focused, color, size }) => ReactNode | Icon render function. Called with size={24}. |
| tabBarLabel | string \| ((props: { focused, color, position }) => ReactNode) | Label override. |
| title | string | Fallback label when tabBarLabel is unset. |
| tabBarBadge | string \| number | Badge content rendered top-right of the icon. |
| tabBarShowLabel | boolean | Set false to hide the label. |
| tabBarAccessibilityLabel | string | Override per-tab accessible label. |
| tabBarTestID | string | Per-tab test identifier. |
<TabBarItem>
Lower-level item; usually rendered for you by <TabBar>. Exported for custom layouts. Accepts label, icon, badge, focused, onPress, onLongPress, labelPosition, accessibilityLabel, index, tabCount, plus refs and testID. Inherits ThemeOverrideProps.
Examples
React Navigation integration
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} aria-label="Main" />}>
<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 Example() {
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,
},
},
cart: {
options: {
tabBarIcon: ({ size }) => <ShoppingCart size={size} />,
title: 'Cart',
tabBarBadge: '!',
},
},
profile: { options: { tabBarIcon: ({ size }) => <User size={size} />, title: 'Profile' } },
};
return (
<TabBar
state={state}
descriptors={descriptors}
navigation={{ emit: () => ({}), navigate: () => {} }}
/>
);
}Manual focus activation
Set activateOnFocus={false} to require Enter or Space to commit a selection — useful when activation has side effects.
import * as React from 'react';
import { TabBar } from '@xsolla/xui-tab-bar';
export default function Example({ state, descriptors, navigation }) {
return (
<TabBar
state={state}
descriptors={descriptors}
navigation={navigation}
activateOnFocus={false}
aria-label="Settings sections"
/>
);
}Accessibility
- Container is
<nav role="tablist" aria-orientation="horizontal">; each tab isrole="tab"witharia-selected. - Roving tab index: only the active tab is in the tab order.
- Keyboard:
ArrowRight/ArrowDownnext,ArrowLeft/ArrowUpprevious (both wrap),Home/Endjump to ends,Enter/Spaceactivates. - The animated selection indicator is
aria-hidden(web only). - Provide
aria-labeloraria-labelledbyso screen readers can name the tablist.
