@xsolla/xui-tab-bar 0.150.0 → 0.152.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -117
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
#
|
|
1
|
+
# TabBar
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
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.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @xsolla/xui-tab-bar
|
|
9
|
-
# or
|
|
10
|
-
yarn add @xsolla/xui-tab-bar
|
|
11
9
|
```
|
|
12
10
|
|
|
13
|
-
##
|
|
11
|
+
## Imports
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
```tsx
|
|
14
|
+
import { TabBar, TabBarItem } from '@xsolla/xui-tab-bar';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
16
18
|
|
|
17
19
|
```tsx
|
|
18
20
|
import * as React from 'react';
|
|
19
21
|
import { TabBar } from '@xsolla/xui-tab-bar';
|
|
20
22
|
import { Home, Search, User, Settings } from '@xsolla/xui-icons-base';
|
|
21
23
|
|
|
22
|
-
export default function
|
|
23
|
-
// Simulated React Navigation state
|
|
24
|
+
export default function Example() {
|
|
24
25
|
const state = {
|
|
25
26
|
index: 0,
|
|
26
27
|
routes: [
|
|
@@ -43,31 +44,50 @@ export default function BasicTabBar() {
|
|
|
43
44
|
state={state}
|
|
44
45
|
descriptors={descriptors}
|
|
45
46
|
navigation={{ emit: () => ({}), navigate: () => {} }}
|
|
47
|
+
aria-label="Main navigation"
|
|
46
48
|
/>
|
|
47
49
|
);
|
|
48
50
|
}
|
|
49
51
|
```
|
|
50
52
|
|
|
51
|
-
##
|
|
53
|
+
## API Reference
|
|
52
54
|
|
|
53
|
-
|
|
54
|
-
import { TabBar } from '@xsolla/xui-tab-bar';
|
|
55
|
+
### `<TabBar>`
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
| Prop | Type | Default | Description |
|
|
58
|
+
| --- | --- | --- | --- |
|
|
59
|
+
| `state` | `{ index: number; routes: { key: string; name: string; params?: object }[] }` | - | React Navigation state. Required. |
|
|
60
|
+
| `descriptors` | `Record<string, { options: TabBarRouteOptions }>` | - | Per-route options keyed by `route.key`. Required. |
|
|
61
|
+
| `navigation` | `{ navigate: (name, params?) => void; emit: (opts) => any }` | - | React Navigation navigation object. Required. |
|
|
62
|
+
| `labelPosition` | `'below-icon' \| 'beside-icon'` | `'below-icon'` | Label position relative to icon. |
|
|
63
|
+
| `backgroundColor` | `string` | segmented-control bg token | Container background colour. |
|
|
64
|
+
| `activateOnFocus` | `boolean` | `true` | Activate a tab as soon as it receives keyboard focus. When `false`, arrow keys only move focus and Enter/Space activates. |
|
|
65
|
+
| `aria-label` | `string` | `'Tab navigation'` | Accessible label for the tablist. |
|
|
66
|
+
| `aria-labelledby` | `string` | - | ID of an external labelling element. |
|
|
67
|
+
| `id` | `string` | - | Container ID; used to derive per-tab IDs. |
|
|
68
|
+
| `testID` | `string` | `'tab-bar-container'` | Test identifier. |
|
|
69
|
+
|
|
70
|
+
Inherits `ThemeOverrideProps` (`themeMode`, `themeProductContext`).
|
|
71
|
+
|
|
72
|
+
#### Route options (per descriptor)
|
|
73
|
+
|
|
74
|
+
| Option | Type | Description |
|
|
75
|
+
| --- | --- | --- |
|
|
76
|
+
| `tabBarIcon` | `(props: { focused, color, size }) => ReactNode` | Icon render function. Called with `size={24}`. |
|
|
77
|
+
| `tabBarLabel` | `string \| ((props: { focused, color, position }) => ReactNode)` | Label override. |
|
|
78
|
+
| `title` | `string` | Fallback label when `tabBarLabel` is unset. |
|
|
79
|
+
| `tabBarBadge` | `string \| number` | Badge content rendered top-right of the icon. |
|
|
80
|
+
| `tabBarShowLabel` | `boolean` | Set `false` to hide the label. |
|
|
81
|
+
| `tabBarAccessibilityLabel` | `string` | Override per-tab accessible label. |
|
|
82
|
+
| `tabBarTestID` | `string` | Per-tab test identifier. |
|
|
83
|
+
|
|
84
|
+
### `<TabBarItem>`
|
|
85
|
+
|
|
86
|
+
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`.
|
|
67
87
|
|
|
68
88
|
## Examples
|
|
69
89
|
|
|
70
|
-
###
|
|
90
|
+
### React Navigation integration
|
|
71
91
|
|
|
72
92
|
```tsx
|
|
73
93
|
import * as React from 'react';
|
|
@@ -79,43 +99,35 @@ const Tab = createBottomTabNavigator();
|
|
|
79
99
|
|
|
80
100
|
export default function AppNavigator() {
|
|
81
101
|
return (
|
|
82
|
-
<Tab.Navigator
|
|
83
|
-
tabBar={(props) => <TabBar {...props} />}
|
|
84
|
-
>
|
|
102
|
+
<Tab.Navigator tabBar={(props) => <TabBar {...props} aria-label="Main" />}>
|
|
85
103
|
<Tab.Screen
|
|
86
104
|
name="Home"
|
|
87
105
|
component={HomeScreen}
|
|
88
|
-
options={{
|
|
89
|
-
tabBarIcon: ({ size, color }) => <Home size={size} color={color} />,
|
|
90
|
-
}}
|
|
106
|
+
options={{ tabBarIcon: ({ size, color }) => <Home size={size} color={color} /> }}
|
|
91
107
|
/>
|
|
92
108
|
<Tab.Screen
|
|
93
109
|
name="Profile"
|
|
94
110
|
component={ProfileScreen}
|
|
95
|
-
options={{
|
|
96
|
-
tabBarIcon: ({ size, color }) => <User size={size} color={color} />,
|
|
97
|
-
}}
|
|
111
|
+
options={{ tabBarIcon: ({ size, color }) => <User size={size} color={color} /> }}
|
|
98
112
|
/>
|
|
99
113
|
<Tab.Screen
|
|
100
114
|
name="Settings"
|
|
101
115
|
component={SettingsScreen}
|
|
102
|
-
options={{
|
|
103
|
-
tabBarIcon: ({ size, color }) => <Settings size={size} color={color} />,
|
|
104
|
-
}}
|
|
116
|
+
options={{ tabBarIcon: ({ size, color }) => <Settings size={size} color={color} /> }}
|
|
105
117
|
/>
|
|
106
118
|
</Tab.Navigator>
|
|
107
119
|
);
|
|
108
120
|
}
|
|
109
121
|
```
|
|
110
122
|
|
|
111
|
-
### With
|
|
123
|
+
### With badges
|
|
112
124
|
|
|
113
125
|
```tsx
|
|
114
126
|
import * as React from 'react';
|
|
115
127
|
import { TabBar } from '@xsolla/xui-tab-bar';
|
|
116
128
|
import { Home, Bell, ShoppingCart, User } from '@xsolla/xui-icons-base';
|
|
117
129
|
|
|
118
|
-
export default function
|
|
130
|
+
export default function Example() {
|
|
119
131
|
const state = {
|
|
120
132
|
index: 0,
|
|
121
133
|
routes: [
|
|
@@ -132,14 +144,14 @@ export default function TabBarWithBadges() {
|
|
|
132
144
|
options: {
|
|
133
145
|
tabBarIcon: ({ size }) => <Bell size={size} />,
|
|
134
146
|
title: 'Notifications',
|
|
135
|
-
tabBarBadge: 3,
|
|
147
|
+
tabBarBadge: 3,
|
|
136
148
|
},
|
|
137
149
|
},
|
|
138
150
|
cart: {
|
|
139
151
|
options: {
|
|
140
152
|
tabBarIcon: ({ size }) => <ShoppingCart size={size} />,
|
|
141
153
|
title: 'Cart',
|
|
142
|
-
tabBarBadge: '!',
|
|
154
|
+
tabBarBadge: '!',
|
|
143
155
|
},
|
|
144
156
|
},
|
|
145
157
|
profile: { options: { tabBarIcon: ({ size }) => <User size={size} />, title: 'Profile' } },
|
|
@@ -155,97 +167,31 @@ export default function TabBarWithBadges() {
|
|
|
155
167
|
}
|
|
156
168
|
```
|
|
157
169
|
|
|
158
|
-
###
|
|
170
|
+
### Manual focus activation
|
|
171
|
+
|
|
172
|
+
Set `activateOnFocus={false}` to require Enter or Space to commit a selection — useful when activation has side effects.
|
|
159
173
|
|
|
160
174
|
```tsx
|
|
161
175
|
import * as React from 'react';
|
|
162
176
|
import { TabBar } from '@xsolla/xui-tab-bar';
|
|
163
|
-
import { Home, Search, User } from '@xsolla/xui-icons-base';
|
|
164
|
-
|
|
165
|
-
export default function CustomStyledTabBar() {
|
|
166
|
-
const state = {
|
|
167
|
-
index: 0,
|
|
168
|
-
routes: [
|
|
169
|
-
{ key: 'home', name: 'Home' },
|
|
170
|
-
{ key: 'search', name: 'Search' },
|
|
171
|
-
{ key: 'profile', name: 'Profile' },
|
|
172
|
-
],
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
const descriptors = {
|
|
176
|
-
home: { options: { tabBarIcon: ({ size }) => <Home size={size} />, title: 'Home' } },
|
|
177
|
-
search: { options: { tabBarIcon: ({ size }) => <Search size={size} />, title: 'Search' } },
|
|
178
|
-
profile: { options: { tabBarIcon: ({ size }) => <User size={size} />, title: 'Profile' } },
|
|
179
|
-
};
|
|
180
177
|
|
|
178
|
+
export default function Example({ state, descriptors, navigation }) {
|
|
181
179
|
return (
|
|
182
180
|
<TabBar
|
|
183
181
|
state={state}
|
|
184
182
|
descriptors={descriptors}
|
|
185
|
-
navigation={
|
|
186
|
-
|
|
187
|
-
|
|
183
|
+
navigation={navigation}
|
|
184
|
+
activateOnFocus={false}
|
|
185
|
+
aria-label="Settings sections"
|
|
188
186
|
/>
|
|
189
187
|
);
|
|
190
188
|
}
|
|
191
189
|
```
|
|
192
190
|
|
|
193
|
-
## API Reference
|
|
194
|
-
|
|
195
|
-
### TabBar
|
|
196
|
-
|
|
197
|
-
**TabBarProps:**
|
|
198
|
-
|
|
199
|
-
| Prop | Type | Default | Description |
|
|
200
|
-
| :--- | :--- | :------ | :---------- |
|
|
201
|
-
| state | `NavigationState` | - | React Navigation state object. |
|
|
202
|
-
| descriptors | `Descriptors` | - | Route descriptor objects. |
|
|
203
|
-
| navigation | `Navigation` | - | Navigation object with emit/navigate. |
|
|
204
|
-
| labelPosition | `"below-icon" \| "beside-icon"` | `"below-icon"` | Label position relative to icon. |
|
|
205
|
-
| backgroundColor | `string` | theme background | Custom background color. |
|
|
206
|
-
| activateOnFocus | `boolean` | `true` | Navigate on focus (keyboard). |
|
|
207
|
-
| aria-label | `string` | `"Tab navigation"` | Accessible label. |
|
|
208
|
-
| aria-labelledby | `string` | - | ID of labelling element. |
|
|
209
|
-
| id | `string` | - | Element ID for accessibility. |
|
|
210
|
-
| testID | `string` | - | Test identifier. |
|
|
211
|
-
|
|
212
|
-
### Route Options
|
|
213
|
-
|
|
214
|
-
Each route in descriptors can have these options:
|
|
215
|
-
|
|
216
|
-
| Option | Type | Description |
|
|
217
|
-
| :----- | :--- | :---------- |
|
|
218
|
-
| tabBarIcon | `(props) => ReactNode` | Icon render function. |
|
|
219
|
-
| tabBarLabel | `string \| (props) => ReactNode` | Tab label. |
|
|
220
|
-
| title | `string` | Fallback label if tabBarLabel not set. |
|
|
221
|
-
| tabBarBadge | `string \| number` | Badge content. |
|
|
222
|
-
| tabBarShowLabel | `boolean` | Show/hide label. |
|
|
223
|
-
| tabBarAccessibilityLabel | `string` | Custom accessible label. |
|
|
224
|
-
| tabBarTestID | `string` | Test ID for individual tab. |
|
|
225
|
-
|
|
226
|
-
## Keyboard Navigation
|
|
227
|
-
|
|
228
|
-
| Key | Action |
|
|
229
|
-
| :-- | :----- |
|
|
230
|
-
| `ArrowRight` / `ArrowDown` | Move to next tab |
|
|
231
|
-
| `ArrowLeft` / `ArrowUp` | Move to previous tab |
|
|
232
|
-
| `Home` | Jump to first tab |
|
|
233
|
-
| `End` | Jump to last tab |
|
|
234
|
-
| `Enter` / `Space` | Activate focused tab |
|
|
235
|
-
|
|
236
|
-
## Specifications
|
|
237
|
-
|
|
238
|
-
| Property | Value |
|
|
239
|
-
| :------- | :---- |
|
|
240
|
-
| Height | 60px |
|
|
241
|
-
| Width | 100% |
|
|
242
|
-
| Border | 1px top border |
|
|
243
|
-
|
|
244
191
|
## Accessibility
|
|
245
192
|
|
|
246
|
-
-
|
|
247
|
-
-
|
|
248
|
-
- Keyboard
|
|
249
|
-
-
|
|
250
|
-
-
|
|
251
|
-
- Custom accessibility labels supported per tab
|
|
193
|
+
- Container is `<nav role="tablist" aria-orientation="horizontal">`; each tab is `role="tab"` with `aria-selected`.
|
|
194
|
+
- Roving tab index: only the active tab is in the tab order.
|
|
195
|
+
- Keyboard: `ArrowRight`/`ArrowDown` next, `ArrowLeft`/`ArrowUp` previous (both wrap), `Home`/`End` jump to ends, `Enter`/`Space` activates.
|
|
196
|
+
- The animated selection indicator is `aria-hidden` (web only).
|
|
197
|
+
- Provide `aria-label` or `aria-labelledby` so screen readers can name the tablist.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsolla/xui-tab-bar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.152.0",
|
|
4
4
|
"main": "./web/index.js",
|
|
5
5
|
"module": "./web/index.mjs",
|
|
6
6
|
"types": "./web/index.d.ts",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"test:coverage": "vitest run --coverage"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@xsolla/xui-badge": "0.
|
|
17
|
-
"@xsolla/xui-core": "0.
|
|
18
|
-
"@xsolla/xui-primitives-core": "0.
|
|
16
|
+
"@xsolla/xui-badge": "0.152.0",
|
|
17
|
+
"@xsolla/xui-core": "0.152.0",
|
|
18
|
+
"@xsolla/xui-primitives-core": "0.152.0"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"react": ">=16.8.0"
|