Navigation inside TabBar React Native - javascript

I'm pretty new to React Native, I have the following tab bar navigation page:
const TabBar = () => {
return (
<BottomTab.Navigator
screenOptions={{
showIcon: true,
tabBarShowLabel: false,
tabBarStyle: {
position: "absolute",
bottom: 25,
left: 20,
right: 20,
elevation: 0,
backgroundColor: global.GUI.WHITE,
borderRadius: 15,
height: 90,
...styles.shadow,
},
header: ({ navigation, route, options }) => {
return (
<View
style={{
justifyContent: "space-between",
height: 110,
backgroundColor: global.GUI.WHITE,
alignItems: "center",
width: "100%",
flexDirection: "row",
...styles.shadow,
}}
>
<Image
source={ctsLogo}
style={{
resizeMode: "contain",
width: 100,
height: 70,
marginTop: 40,
marginLeft: 10,
}}
/>
<Button title="test" onPress={()=>{
}}>
<FontAwesomeIcon
icon={faCog}
style={{
color: global.GUI.ORANGE,
marginTop: 40,
marginRight: 20,
}}
size={30}
/>
</Button>
</View>
);
},
}}
>
<BottomTab.Screen
name="Home"
component={Main}
options={{
...
}}
/>
<BottomTab.Screen
name="Flyers"
component={Flyers}
options={{
...
}}
/>
<BottomTab.Screen
name="OnlineShop"
component={OnlineShop}
options={{
...
}}
/>
<BottomTab.Screen
name="Cards"
component={Cards}
options={{...}}
/>
<BottomTab.Screen
name="Shops"
component={Shops}
options={{
....
}}
/>
</BottomTab.Navigator>
);
};
I want to add navigate to another page while remaining in the context of the tab bar (let's says I want to go to another component called "Settings") programmatically by triggering the test button:
<Button title="test" onPress={()=>{...}}>
Inside the custom header, is it possible to do that? Thanks
EDIT:
I've changed my App.js code to this:
import { NavigationContainer } from "#react-navigation/native";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import TabBar from "./navigation/TabBar";
import Settings from "./page/Settings";
const Stack = createNativeStackNavigator();
export default function App() {
function Tabs() {
return <TabBar />;
}
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Tabs" component={Tabs}
options={{ headerShown: false }}/>
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
}
And now I'm able to navigate, thanks!

inside your SCREEN call navigation hook
const navigation = useNavigation();
then u can use NAVIGATION functions anywhere you want :) even inside Button
Button
<Button title="test" onPress={()=>{
navigation.navigate('Settings') // param here is "name" prop from your navigator
// navigation.goBack()
}}>

Try using this
props.navigation.navigate('Settings')

Related

How to customize button css in react-admin

I am new to react-admin, and how to customize react admin buttons?
In my scenario I have a list also in create, edit, and export button there and I don't know which is the best way to change button css in react-admin. Can anyone solve this?
By default I have button like above mentioned, so I need to add css for this two buttons.
Here is my sample code
// style list
const useStyles = makeStyles((theme) => ({
userCard: {
padding: "20px",
borderRadius: "12px",
},
btn_edit: {
background: "#5E35B1",
color: "#fff",
fontSize: "10px",
},
mainList: {
boxShadow: "none !important",
borderRadius: "0px",
},
listCreateIcon: {
padding: "0px !important",
},
}));
//main
export const UserList = (props) => {
const classes = useStyles();
return (
<Card className={classes.userCard}>
<List
{...props}
pagination={null}
perPage={9999}
className={classes.mainList}
>
<Datagrid className={classes.listCard}>
<TextField source="username" />
<BooleanField source="enabled" />
<ReferenceArrayField reference="_roles" source="roles">
<SingleFieldList>
<ChipField source="name" />
</SingleFieldList>
</ReferenceArrayField>
<EditButton className={classes.btn_edit} />
</Datagrid>
</List>
</Card>
);
};
export const UserCreate = (props) => {
const classes = useStyles();
return (
<Create {...props} className={classes.listCreateIcon}>
<SimpleForm style={{ padding: "0px !important" }}>
<TextInput source="username" />
<TextInput type="password" source="password" />
<ReferenceArrayInput source="roles" reference="_roles" allowEmpty>
<SelectArrayInput optionText="name" />
</ReferenceArrayInput>
<BooleanInput source="enabled" defaultValue={true} />
</SimpleForm>
</Create>
);
};
export const UserEdit = (props) => (
<Edit {...props}>
<SimpleForm>
<TextField source="username" />
<ReferenceArrayInput source="roles" reference="_roles">
<SelectArrayInput optionText="name" />
</ReferenceArrayInput>
<BooleanInput source="enabled" />
</SimpleForm>
</Edit>
);
This will work for you.
btn_create: {
display: "inline-flex",
alignItems: "center",
gridGap: 4,
backgroundColor: "transparent",
borderColor: "transparent",
fontSize: 16,
color: "blue" // the text color you want
// if you are using the svg icon
svg : {
width: 16,
height: 16,
path: {
fill : "blue" //color code of icon
}
}
},
btn_group: {
display:"flex",
gridGap: "16px",
alignItems: "Center",
}
on Component
<div className={classes.btn_group}>
<EditButton className={classes.btn_create} />
<EditButton className={classes.btn_create} />
</div>
PS. If the icon is font icon, you may not use the svg styling.

Customize React Native drawer navigation

I want to create drawer navigation like that
I able to add icons but don't know how to design right side like in the image
that's my drawer navigator
<Drawer.Navigator
drawerContent={(props) => <CustomDrawer {...props} />}
drawerStyle={{
width: '80%',
}}>
<Drawer.Screen name={strings.NAV_HOME} component={StackComp} />
<Drawer.Screen name={strings.NAV_MY_PROFILE} component={Proifle} />
<Drawer.Screen name={strings.NAV_SETTING} component={Setting} />
<Drawer.Screen
name={strings.NAV_MANAGE_BOOKING}
component={Booking}
/>
</Drawer.Navigator>
and that's my customize code
<DrawerContentScrollView
style={{backgroundColor: colors.themeColor, flex: 1}}
{...props}>
<View style={{flex: 1}}>
<View
style={{
flex: 1,
paddingTop: moderateScaleVertical(24),
}}>
<Image
source={imagePath.logo}
style={{marginLeft: moderateScale(16)}}
/>
<TouchableOpacity
onPress={() => navigation.navigate(strings.NAV_HOME)}
style={styles.drawCont}>
<Image source={imagePath.homeIcon} />
<Text style={styles.text}>{strings.HOME}</Text>
</TouchableOpacity>
</View>
</View>
</DrawerContentScrollView>
Can someone tell me how can I design it like in the image?
To create a drawer component you can check the official documentation here
You will then have to make use of icons such as MaterialCommunityIcons. First on your drawer navigator import MaterialCommunityIcons like this
import { MaterialCommunityIcons } from "#expo/vector-icons";
Then add an options props on screen navigation as shown
<Drawer.Screen name={strings.NAV_HOME} component={StackComp} options={{
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}} />
nice to meet you.
pls check my code....
const Tab = createBottomTabNavigator();
const Main = () => {
return (
<Tab.Navigator
initialRouteName="Home"
tabBarOptions={{
activeTintColor: '#fda039',
activeBackgroundColor: 'transparent',
labelPosition: 'bottom-icon',
tabStyle: styles.tabStyle,
style: styles.tabBarStyle,
}}>
<Tab.Screen name="Home" component={Home}
options={{
tabBarIcon: ({ color }) => <TabBarIcon name="home" color={color}/>,
tabBarLabel: ({ focused, color}) => focused?<Text style={{color: color, marginTop: 5, fontSize: 14}}>Hogar</Text>: null,
}}
/>
<Tab.Screen name="QRscan" component={ProfileScreen}
options={{
tabBarIcon: ({ color }) => <TabBarIcon name="qr-code-scanner" color={color}/>,
tabBarLabel: ({ focused, color}) => focused?<Text style={{color: color, marginTop: 5, fontSize: 14}}>QR Scan</Text>: null,
}}
/>
<Tab.Screen name="Help" component={Help}
options={{
tabBarIcon: ({ color }) => <TabBarIcon name="help" color={color}/>,
tabBarLabel: ({ focused, color}) => focused?<Text style={{color: color, marginTop: 5, fontSize: 16}}>Ayuda</Text>: null,
}}
/>
</Tab.Navigator>
);
It's my project code running now using React Native navigator.
It's using react bottom navigation.
You can rewrite the code like mine.
Thank you.

Custom Drawer in react navigation

In my react native project I have custom drawer with screens like screen1 and screen2. Screen1 is used for stack navigator and in Screen 2 it contains tab navigator. How to enable this kind of nesting navigation.
I am using react navigation 5 in order to build custom drawer.
Here is my code:
import { DrawerContentScrollView, DrawerItem } from "#react-navigation/drawer";
.............
render = () => {
<DrawerContentScrollView {...props}>
<View style={styles.menuContainer}>
<View style={[styles.menuItemsCard, { backgroundColor: "#fff2df" }]}>
<View style={[styles.circleContainer, { backgroundColor: "#FFC56F" }]}>
<Icon travel name="suitcase" type="font-awesome" color="#fbae41" />
</View>
<DrawerItem
label="Screen1"
labelStyle={{ color: "#fbae41", fontSize: 10 }}
onPress={() => {
props.navigation.navigate("PatientInfo");
}}
/>
</View>
<View style={[styles.itemCard, { backgroundColor: "#EFFFD5" }]}>
<View style={[styles.circleContainer, { backgroundColor: "#b5ff39" }]}>
<Icon Medical name="briefcase" type="font-awesome" color="#609806"></Icon>
</View>
<DrawerItem
label="Screen2"
labelStyle={{ color: "#609806" }}
onPress={() => {
props.navigation.navigate("Diagnose");
}}
/>
</View>
</View>
</DrawerContentScrollView>
}
mainNaviagtor:
const MainNavigator = () => {
return (
<Drawer.Navigator drawerContent={props => <Menu {...props} />} drawerStyle={{ width:
"100%" }}>
<Stack.Screen name="Screen1" component={PatientInfoScreen} screenOptions={headerOptions} />
<Stack.Screen name="Screen2" component={DiagnoseScreen} /> //Here i need tab navigator
</Drawer.Navigator>
);
};
My older code: (react navigation 4.x)
createDrawerNavigator(
{
Screen1: {
screen: createStackNavigator(
{
PatientInfo: { screen: PatientInfoScreen }
},
headerOptions
)
},
Screen2: {
screen: createBottomTabNavigator({
Diagnose: {
screen: diagnoseNavigation
},
Causes: { screen: causeNavigation },
})
},
})
Output:
How should I solve this issue? I also referred to the https://reactnavigation.org/docs/nesting-navigators/.
Any one please help me to solve this issue.
Working Example: Expo Snack
Final Output:
Full source Code:
import * as React from 'react';
import {
View,
Text,
StyleSheet,
useWindowDimensions,
Button,
} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { Feather } from '#expo/vector-icons';
import { createStackNavigator } from '#react-navigation/stack';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItemList,
DrawerItem,
} from '#react-navigation/drawer';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const Drawer = createDrawerNavigator();
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
function TabNav() {
return (
<Tab.Navigator>
<Tab.Screen
name="TabOne"
component={() => (
<View style={styles.container}>
<Text>TabOne</Text>
</View>
)}
/>
<Tab.Screen
name="TabTwo"
component={() => (
<View style={styles.container}>
<Text>TabTwo</Text>
</View>
)}
/>
</Tab.Navigator>
);
}
const StackNav = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Feed" component={Feed} />
<Stack.Screen name="Article" component={Article} />
</Stack.Navigator>
);
};
function CustomDrawerContent(props) {
const width = useWindowDimensions().width * 0.3;
return (
<DrawerContentScrollView {...props}>
<View style={styles.menuContainer}>
<View
style={[
styles.menuItemsCard,
{ backgroundColor: '#fff2df', width: width, height: width },
]}>
<>
<View
style={[styles.circleContainer, { backgroundColor: '#FFC56F' }]}>
<Feather travel name="briefcase" size={25} color="#fbae41" />
<DrawerItem
label="Screen1"
labelStyle={{ color: '#fbae41', fontSize: 10 }}
onPress={() => {
props.navigation.navigate('Screen1');
}}
/>
</View>
</>
<DrawerItem
style={{
position: 'absolute',
left: 0,
width: width,
height: width,
}}
label="Screen2"
labelStyle={{ color: '#609806' }}
onPress={() => {
props.navigation.navigate('Screen1');
}}
/>
</View>
<View
style={[
styles.menuItemsCard,
{ backgroundColor: '#EFFFD5', width: width, height: width },
]}>
<View
style={[styles.circleContainer, { backgroundColor: '#b5ff39' }]}>
<Feather Medical name="briefcase" size={25} color="#609806" />
</View>
<DrawerItem
style={{
position: 'absolute',
left: 0,
width: width,
height: width,
}}
label="Screen2"
labelStyle={{ color: '#609806' }}
onPress={() => {
props.navigation.navigate('StackNav');
}}
/>
</View>
</View>
</DrawerContentScrollView>
);
}
function MyDrawer() {
return (
<Drawer.Navigator
drawerContent={(props) => <CustomDrawerContent {...props} />}>
<Drawer.Screen name="Screen1" component={StackNav} />
<Drawer.Screen name="StackNav" component={TabNav} />
</Drawer.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyDrawer />
</NavigationContainer>
);
}
function Feed({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Feed Screen</Text>
<Button
title={'Article'}
onPress={() => navigation.navigate('Article')}
/>
</View>
);
}
function Article({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Article Screen</Text>
<Button title={'Feed'} onPress={() => navigation.navigate('Feed')} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
menuContainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-evenly',
},
menuItemsCard: {
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
},
circleContainer: {
width: 50,
height: 50,
borderRadius: 25,
padding: 10,
},
});

React native expo: Tab navigator set initial screen

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { MaterialCommunityIcons } from '#expo/vector-icons';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { NavigationContainer } from '#react-navigation/native';
function LoginScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Login</Text>
</View>
);
}
function VideoScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Video</Text>
</View>
);
}
function PodcastScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Podcast</Text>
</View>
);
}
function TravelScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Travel</Text>
</View>
);
}
function InfoScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Info</Text>
</View>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Video" component={VideoScreen} />
<Tab.Screen name="Podcast" component={PodcastScreen} />
<Tab.Screen name="Travel" component={TravelScreen} />
<Tab.Screen name="Info" component={InfoScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
The code is from App.js. I will add the icons later
I want to have the login screen as the first screen to show up when the user opens the app. And when the user presses the login button then it should open like it is now. Also the loginScreen should not show up on the tab navigator.
Thank you for your help
This might help
const MainTabNavigator = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Video" component={VideoScreen} />
<Tab.Screen name="Podcast" component={PodcastScreen} />
<Tab.Screen name="Travel" component={TravelScreen} />
<Tab.Screen name="Info" component={InfoScreen} />
</Tab.Navigator>
);
}
<NavigationContainer>
<Stack.Navigator>
{Store.userToken == null ? (
<Stack.Screen name="Login" component={LoginStackScreen} options={{ headerShown: false }} />
) : (
<Stack.Screen name="MainTabNavigator" component={MainTabNavigator} options={{ headerShown: false }} />)}
</Stack.Navigator>
</NavigationContainer>

How do I pass a Prop to a Navigation Screen Component - React Native

I'm fairly new to React native . I have created a Drawer Navigator in my App.js file.
One of my navigation Components is a component named LoginScreen.
I am trying to to pass a prop to LoginScreen to display when the user navigates to it.
App.js (Navigator)
const Tab = createMaterialBottomTabNavigator()
const Stack = createStackNavigator()
const Drawer = createDrawerNavigator()
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
isAdmin: 'false',
checked: false,
}
}
async componentDidMount() {
try {
const adm = await AsyncStorage.getItem('is_admin')
if (adm == null) {
adm = await AsyncStorage.setItem('is_admin', 'false')
}
this.setState({ isAdmin: adm, checked: true })
} catch (error) {
console.log(error)
}
}
render() {
const { isAdmin } = this.state
console.log(isAdmin)
//is admin
return isAdmin == 'true' ? (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={MyStack} />
<Drawer.Screen
name="Admin Panel"
component={props => {
return <LoginScreen props={props} propName = {'Hello'} />
}}
/>
</Drawer.Navigator>
</NavigationContainer>
) : (
//ISNOT ADMIN
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={MyStack} />
<Drawer.Screen name="Login" component={LoginScreen} />
</Drawer.Navigator>
</NavigationContainer>
)
}
}
LginScreen.js
const LoginScreen = ({ navigation, propName }) => {
// const [bridge, setB] = useState(false)
return (
<SafeAreaView style={{ flex: 1, backgroundColor: '#376772' }}>
<TopHeader
onRefresh={() => fetch_crossings}
onMenuToggle={() => navigation.toggleDrawer()}
/>
<View style={{ flex: 1 }}>
<View
style={{
backgroundColor: '#fff',
margin: 10,
borderRadius: 5,
alignItems: 'center',
padding: 10,
paddingBottom: scale(20),
}}
>
<Avatar
rounded
size={'xlarge'}
overlayContainerStyle={{
backgroundColor: '#185a9d',
}}
icon={{
color: 'orange',
type: 'ionicon',
name: 'ios-log-in',
}}
/>
<Input
placeholder=" Email"
placeholderTextColor={'#292b2c'}
style={{ margin: 5 }}
errorStyle={{ color: '#d9534f' }}
leftIcon={<Icon name="mail" color="#292b2c" />}
errorMessage="Enter a valid Email"
/>
<Divider
style={{
backgroundColor: 'orange',
height: 3,
margin: scale(20),
borderRadius: 3,
}}
/>
<Input
placeholder=" Password"
placeholderTextColor={'#292b2c'}
secureTextEntry={true}
style={{ margin: 5 }}
errorStyle={{ color: '#d9534f' }}
leftIcon={<Icon name={'lock'} color="#292b2c" />}
errorMessage="Enter a valid Email"
/>
</View>
<View
style={{
backgroundColor: '#fff',
margin: 10,
marginTop: 0,
borderRadius: 5,
padding: 10,
}}
>
<Button
buttonStyle={{
margin: 10,
backgroundColor: '#5cb85c',
borderRadius: 4,
alignSelf: 'stretch',
}}
onPress={async () => {
try {
await AsyncStorage.setItem('is_admin', 'false')
**console.log(propName);** //<--Right HERE
navigation.navigate('Home')
} catch (error) {
console.log(error)
}
}}
icon={<Icon name="send" size={15} color="white" />}
iconRight
titleStyle={{ fontWeight: 'bold' }}
title="Submit "
/>
<Button
buttonStyle={{
margin: 10,
backgroundColor: '#d9534f',
borderRadius: 4,
alignSelf: 'stretch',
}}
onPress={() => {
navigation.navigate('Home')
}}
icon={<Icon name="close" size={15} color="white" />}
iconRight
titleStyle={{ fontWeight: 'bold' }}
title={'Close '}
/>
</View>
</View>
</SafeAreaView>
)
}
export default LoginScreen
Whenever I console.log(propName), it says that its undefined.
Asad's Answer actually helped me get to this :
App.js (Navigation)
Here, we can add the 'initialParams' parameter to <Drawer.Screen/> :
<Drawer.Screen
name="Login"
component={LoginScreen}
initialParams={{ post: this.state.isAdmin }} //<-- Right here
/>
Then we can receive as such in LoginScreen.js as such :
const LoginScreen = ({ navigation, route }) => {
console.log(route.params.post)
return (
<Text>{route.params.post}</Text>
)
}
Another way:
<Drawer.Navigator
initialRouteName="Updates"
drawerContentOptions={{ style: { paddingVertical: 50 } }}>
<Drawer.Screen name="Updates" options={screenOptions}>
{props => (
<UpdatesScreen myProp={this.state.someProp} />
)}
</Drawer.Screen>
...
</Drawer.Navigator>

Categories