Setting accessibility labels with React.Navigator - reactjs

I am working on accessibility labels for the voice assistant, I've done most of the tags but I can not set the bottom tab navigator options, how can I use accessibility labels with the below BottomTab.Navigator components?
In the below, I could set the labels with the Icons but it is encapslating limited area.
When I try with Bottom.Navigator, throwing errors something like that:
Error: A navigator can only contain 'Screen' components as its direct children (found 'undefined'). To render this component in the navigator, pass it in the 'component' prop to 'Screen'.
export default function BottomTabNavigator(): any {
const colorScheme = useColorScheme();
return (
<BottomTab.Navigator
initialRouteName={Routes.TAB_ONE}
tabBarOptions={{
showLabel: false,
inactiveBackgroundColor: Colors[colorScheme].secondaryColor,
activeBackgroundColor: Colors[colorScheme].secondaryColor,
style: {
borderTopWidth: 0,
borderTopColor: 'transparent',
height: 50,
},
}}
>
<BottomTab.Screen
name={Routes.TAB_ONE}
component={TabOneNavigator}
options={{
tabBarIcon: () => (
<View accessible={true} accessibilityLabel="home page">
<CustomIcon name="home" color={Colors[colorScheme].buttonText} />
</View>
),
}}
/>
<BottomTab.Screen
name={Routes.TAB_TWO}
component={TabTwoNavigator}
options={{
tabBarIcon: () => (
<View accessible={true} accessibilityLabel="downloads">
<CustomIcon
name="library"
color={Colors[colorScheme].buttonText}
/>
</View>
),
}}
/>
<BottomTab.Screen
name={Routes.TAB_THREE}
component={TabThreeNavigator}
options={{
tabBarIcon: () => (
<View accessible={true} accessibilityLabel="menu">
<CustomIcon name="menu" color={Colors[colorScheme].buttonText} />
</View>
),
}}
/>
</BottomTab.Navigator>
);
}
Thanks in advance

Related

goBack not working in nested navigators react native. TabNavigator and StackNavigator

I have this problem several days ago and I can't find a solution.
This is my navigation structure
Index.tsx -->
<NavigationContainer>
<Stack.Navigator initialRouteName='tabsBottomHome'
screenOptions={{
headerTitle: () => <Header />,
headerBackground: () => <HeaderBackground />,
headerLeft: ({ onPress, canGoBack }) =>
canGoBack ? (
<Pressable onPress={onPress} style={{ width: 30, height: 15 }}>
<ArrowLeft height={15} width={15} style={{ marginLeft: 15 }} />
</Pressable>
) : (
<Pressable style={{ width: 65, height: 35 }}></Pressable>
),
headerRight: () => <HeaderRight />,
}}
>
{state.isSignIn ? (
<>
<Stack.Screen
name='tabsBottomHome'
component={TabsBottomHome}
options={{headerShown: false }}
/>
</>
) : (
<>
<Stack.Screen
name="Login"
component={LoginScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="LoginError"
component={LoginError}
/>
</>
)}
</Stack.Navigator>
</NavigationContainer>
This would be the first navigation of my application. So far everything is going well.
TabsBottomNavigation -->
<Tab.Navigator
initialRouteName='Home'
screenOptions={{
headerShown:true,
tabBarShowLabel:false,
tabBarStyle:style.tabsBottomContainer,
unmountOnBlur: true,
headerTitle: () => <Header />,
headerBackground: () => <HeaderBackground />,
headerLeft: () =>
routeName != "Home" ? (
<Pressable onPress={navigateBack} style={{ width: 65, height: 15 }}>
<ArrowLeft height={15} width={15} style={{ marginLeft: 15 }} />
</Pressable>
)
: (
<Pressable style={{ width: 65, height: 35 }}></Pressable>
)
,
headerRight: () => <HeaderRight />,
}}
sceneContainerStyle={style.backgroundContent}
screenListeners={({route})=>({
state: ()=> {
setRouteName(route.name);
}
})}
backBehavior={'history'}
>
<Tab.Screen
name='Assets'
component={AssetScreen}
options={{tabBarIcon:({focused,color})=>(
<View>
<Image
source={iconAsset}
style={{
tintColor: focused ? '#00B2DF' : '',
marginTop: 8
}}
/>
</View>
)}} />
<Tab.Screen
name='GatewayStack'
component={ConnectGatewayStack}
options={{tabBarIcon:({focused,color})=>(
<View>
<Image
source={iconBluetooth}
style={{
tintColor: focused ? '#00B2DF' : ''
}}
/>
</View>
)}} />
<Tab.Screen
name='Home'
component={HomeScreen}
options={{tabBarIcon:({focused,color})=>(
<View>
<Image
source={iconHome}
style={{
tintColor: focused ? '#00B2DF' : ''
}}
/>
</View>
)
}} />
</Tab.Navigator>
everything is fine here too, the conflict is in the ConnectGatewayStack stack
ConnectGatewayStack -->
export type StackConnectList = {
Connect: undefined;
QRScan: undefined;
GatewayList: undefined;
GatewayInfo: undefined;
NotFoundGateway: undefined;
GatewayDetected: undefined;
ErrorConnecting: undefined;
}
const GatewayStack = createStackNavigator<StackConnectList>();
const ConnectGatewayStack = () =>{
return (
<GatewayStack.Navigator initialRouteName='Connect'
screenOptions={{headerShown:false}}
>
<GatewayStack.Screen name='Connect' component={ConnectScreen} />
<GatewayStack.Screen name='GatewayList' component={GatewayList} />
<GatewayStack.Screen name='GatewayInfo' component={GatewayInfo} />
<GatewayStack.Screen name='QRScan' component={QRScanScreen} />
<GatewayStack.Screen name='NotFoundGateway' component={NotFoundGateway} />
<GatewayStack.Screen name='GatewayDetected' component={GatewayDetected} />
<GatewayStack.Screen name='ErrorConnecting' component={ErrorConnecting} />
</GatewayStack.Navigator>
)
}
export {ConnectGatewayStack};
When I navigate to the ConnectGatewayStack tab, which contains the other components that I just showed, if I go to a child component and press the back button in header, it returns directly to the TabsBottomHome (that is, to the Tabs navigation) and not to the component that was previously visited.
For the navigation back, i use
import { useNavigation } from '#react-navigation/core';
whit
const navigation = useNavigation();
navigation.goback();
I tried whit diferents methods, but none solved my problem.
example test whit
backBehavior={'history'}
backBehavior={'order'}
and many functions of the core react-native and react-native-navigation
any ideas?
sorry for my bad english and thank you very much

React Navigation change backgroundColor below tabBar

I am using React Navigations tabBar with my React Native project, and I don't know how to change the background color of my bottom tab bar properly. I used Expo to make my app and I have also edited app.json to have the correct backgroundColor, yet nothing changes. Here is my code:
function MyTabs() {
return (
<Tab.Navigator
initialRouteName="Feed"
screenOptions={{
tabBarActiveTintColor: "#E40066",
tabBarInactiveTintColor: "#fff",
tabBarActiveBackgroundColor: "#171717",
tabBarInactiveBackgroundColor: "#171717",
headerShown: false,
tabBarStyle: {
borderWidth: 1,
},
style: {
backgroundColor: "#171717",
},
}}
>
<Tab.Screen
name="Home"
component={Home}
options={{
tabBarLabel: "Home",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons
name="glass-cocktail"
color={color}
size={size}
/>
),
}}
/>
<Tab.Screen
name="Search"
component={Search}
options={{
tabBarLabel: "Search",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="magnify" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Saved"
component={Saved}
options={{
tabBarLabel: "Saved",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="heart" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
);
}
export default function App() {
const navTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: "#171717",
},
};
return (
<NavigationContainer theme={navTheme}>
<MyTabs style={{ backgroundColor: "#171717" }}></MyTabs>
</NavigationContainer>
);
}
Yet my tabBar looks like this, I want it to be #171717, not white... Thank you in advance
The solution was to make a theme to change the background color:
export default function App() {
const navTheme = {
colors: {
background: "#171717"
}
};
return (
<NavigationContainer theme={navTheme}>
<MyTabs style={{ backgroundColor: "#171717" }}></MyTabs>
</NavigationContainer>
);
}
You can use this
<Tab.Navigator
tabBarOptions={{
style: {
backgroundColor:'#171717 '
}
}}>
{Screens}
</Tab.Navigator>

Extend an Screen options in react-native

i have several screens in stack navigator like below
<Stack.Navigator screenOptions={TransitionScreenOptions}>
<Stack.Screen
options={stackoptions}
name="videoScreen"
component={videoScreen}
/>
<Stack.Screen
options={stackoptions}
name="registerScreen"
component={SignUpScreen}
/>
</Stack.Navigator>
for all the screens i set options like below
const stackoptions = ({ navigation }) => ({
headerBackTitleVisible: false,
headerStyle: {
backgroundColor: "#000",
},
headerTintColor: "#fff",
headerRight: () => {
return (
<Pressable
style={{ paddingRight: 8 }}
onPress={() => navigation.toggleDrawer()}
>
<AntDesign name="menu-fold" size={30} color="white" />
</Pressable>
);
},
});
Now , how can i override or add certain options to one of my screen , for example something like below , I want to modify only headerTintColor , whereas remaining stackoptions should be used except headerTintColor.
<Stack.Screen
options={...stackoptions, headerTitle: "" }
name="registerScreen"
component={SignUpScreen}
/>
for all the screens i set options like below
This is unnecessary. You can specify common options in screenOptions and they'll be applied to all screens, it's not needed to repeat them for every screen. You can use spread operator to merge your TransitionScreenOptions with the others:
<Stack.Navigator screenOptions={({ navigation }) => ({
...TransitionScreenOptions,
headerBackTitleVisible: false,
headerStyle: {
backgroundColor: "#000",
},
headerTintColor: "#fff",
headerRight: () => {
return (
<Pressable
style={{ paddingRight: 8 }}
onPress={() => navigation.toggleDrawer()}
>
<AntDesign name="menu-fold" size={30} color="white" />
</Pressable>
);
},
})}>
You can just do this:
options={{ headerTitle: "" }}
This will override the same option if it was specified in screenOptions
If you need to use the current structure, call the stakOptions function and pass the arguments before spreading it:
options={args => ({
...stackoptions(args),
headerTitle: ""
})}

Remove element from react-native navigation

Just wondering how I can remove the (Back) text in navigation and just use the arrow for navigating I am using react native expo.
<Stack.Screen
name="ChatRoom"
component={ChatRoomScreen}
options={({route}) => ({
title: route.params.name,
headerRight: () => (
<View
style={{
flexDirection: "row",
width: 100,
justifyContent: "space-between",
marginRight: 10,
}}
>
<MaterialIcons name="call" size={22} color={'white'} />
<FontAwesome5 name="video" size={22} color={'white'} />
<MaterialCommunityIcons name="dots-vertical" size={22} color={'white'}/>
</View>
)
})}
/>
I found that react navigation behaves weirdly sometimes. But first, you can try this:
headerBackTitle: ' ',
if that makes the back arrow missing, you can add it manually like so:
headerBackImage: ()=> (<Icon name='chevron-left' color='#FFFFF' onPress={()=>{ navigation.goBack();}} />),
you also need to make sure your options has navigation like so:
options={({route, navigation}) => ({
Note: the Icon i used it from react-native-elements.
You need to
headerBackTitleVisible: false,
add this to options like
options={{
...
headerBackTitleVisible: false,
}}
Proof: https://reactnavigation.org/docs/stack-navigator/#headerbacktitlevisible

How to access the navigation prop in the Stack Navigator's screenOptions attribute?

I want to navigate to a particular screen using a common header button in the stack navigator.
<NavigationContainer>
<RootStack.Navigator
mode="modal"
screenOptions={{
headerTitleAlign: 'center',
headerTitle: () => <SpreeLogo />,
headerRight: (props) => <MaterialIcons style={{
marginHorizontal: 10,
}}
onPress={() => console.log(props)}
name="clear" size={28} color="black" />
}}
>
In the header right icon I would like to have access to the navigation prop. I've tried console logging the prop but there is no prop as navigation. How to get access to it?
As per documentation you can provide a function to screenOptions like below which will give you access to the navigation and from there you should be able to jump to any screen
<NavigationContainer>
<RootStack.Navigator
mode="modal"
screenOptions={({ route, navigation }) => ({
headerTitleAlign: 'center',
headerTitle: () => <SpreeLogo />,
headerRight: (props) => <MaterialIcons style={{
marginHorizontal: 10,
}}
onPress={() => console.log(route, navigation)}
name="clear" size={28} color="black" />
})}
>...
Read the docs here https://reactnavigation.org/docs/stack-navigator and search for screenOptions.
Good Luck
In React Navigation V6 you can provide a function to options
<Stack.Screen
name="Screen"
component={Screen}
options={({ route, navigation }) => ({
headerTitleAlign: "center",
headerLeft: () => (
<Icon
name="arrow-back"
onPress={() => navigation.goBack()}
color="#fff"
size={25}
/>
),
})}
/>

Resources