Style Drawer menu toggle button in react native - react-native

I'm trying to add some background shade to the toggle button and also increase the size a little more, but I'm unable to find the right prop that targets the button.
Here's my code.
<Drawer.Navigator screenOptions={(navigation) => ({
drawerStyle:{width:280},
drawerItemStyle: {
borderRadius: 0,
width: '100%',
marginVertical: 0,
marginLeft: 0,
},
drawerLabelStyle: {
fontFamily: 'sans-serif',
fontWeight:'100'
},
drawerActiveTintColor: '#288df9',
drawerInactiveTintColor: '#444'
})}>
...
</Drawer.Navigator>
Any help on how to style the toggle button will be rightly appreciated.

If you check the implementation of this Drawer you can find that this button is an Image hardcoded inside: https://github.com/react-navigation/react-navigation/blob/b91c9b05ff96727f5fa6ef0bec51b5d7eac06600/packages/drawer/src/views/DrawerToggleButton.tsx#L37
export default function DrawerToggleButton({ tintColor, ...rest }: Props) {
const navigation = useNavigation<DrawerNavigationProp<ParamListBase>>();
return (
<PlatformPressable
{...rest}
accessible
accessibilityRole="button"
android_ripple={{ borderless: true }}
onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}
style={styles.touchable}
hitSlop={Platform.select({
ios: undefined,
default: { top: 16, right: 16, bottom: 16, left: 16 },
})}
>
<Image
style={[styles.icon, tintColor ? { tintColor } : null]}
source={require('./assets/toggle-drawer-icon.png')}
fadeDuration={0}
/>
</PlatformPressable>
);
}
I think what you can do is replace the image in your node_modules and using patch-package save it as a patch in your local repository.
Another way is to implement your own Button and use openDrawer/closeDrawer methods to control the drawer.

Related

Remove space between keyboard and composer in React-Native-Gifted-Chat

I'm using the react-native-gifted-chat package for my React Native application.
Somehow there is a space between the composer and the keyboard, although I did not customise the GiftedChat.
Marked orange in the attached screenshot:
I already tried to customise the composer or any other component, with not effect.
i'm also facing same problem after some time i find this solution and it's work for me.
<GiftedChat
isAnimated
messages={this.state.messages}
scrollToBottom={true}
renderUsernameOnMessage={true}
onSend={messages => this.onSend(messages)}
inverted={false}
isLoadingEarlier={true}
messagesContainerStyle={{ color: 'gray' }}
bottomOffset={0} // add this line and space is remove
renderBubble={props => {
return (
<Bubble
{...props}
textStyle={{
right: {
color: 'white',
},
left: {
color: '#24204F',
},
}}
wrapperStyle={{
left: {
backgroundColor: 'white',
},
right: {
backgroundColor: "#ff3b00", // red
},
}}
/>
);
}}
renderInputToolbar={props => {
return (<InputToolbar {...props} containerStyle={{ backgroundColor: '#e2e2e2' }} />);
}}
user={{
_id: 1
}}
/>
hope this willl work for you
bottomOffset={0} // add this line and space is remove
install react-native-iphone-x-helper
and add these lines according to your code.
import { getBottomSpace } from 'react-native-iphone-x-helper';
<GiftedChat
bottomOffset={getBottomSpace()}
...
/>
As found on the docs itself, simply get the insets:
const insets = useSafeAreaInsets();
<GiftedChat
bottomOffset={insets.bottom}
...
/>
This will fix your issue dynamically.

React Native Tab Bar white space under tabs

I am using a tab bar navigator with SafeAreaView.
If I comment out the tab bar nav the parent view covers the entire screen. However when I add a Tab bar it shows a small white view under the tab bar section.
const App = () => {
return (
<SafeAreaView style={styles.droidSafeArea}>
<View style={{ backgroundColor: "red", flex: 1 }}>
<TabNavigator key="MainTabNav" />
</View>
</SafeAreaView>
);
};
export default App;
const styles = StyleSheet.create({
droidSafeArea: {
flex: 1,
backgroundColor: "#2F3438",
}
});
Try this
screenOptions={{
tabBarStyle: {
paddingBottom:0,
},
}}
Please use the tab bar outside the safeAreaView else the safe area view will calculate the notch and will render the tab bar above the notch.
2.If you are using tab bar inside the safe area view use the force inset property of safe area view : <SafeAreaView forceInset = {bottom : 'never} this will make the safeareaview collide with bottom area and your tab bar will render properly.
Note : by using this method you would have to be a bit accurate in providing the styles.
const App = () => {
return (
<SafeAreaView style={styles.droidSafeArea} forceInset = {bottom : 'never'}>
<View style={{ backgroundColor: "red", flex: 1 }}>
<TabNavigator key="MainTabNav" />
</View>
</SafeAreaView>
);
};
export default App;
const styles = StyleSheet.create({
droidSafeArea: {
flex: 1,
backgroundColor: "#2F3438",
}
});
I had the exact same issue and what I did is not use SafeAreaView at all around the tab bar, but simply assigning the color I want the white space to have as the background color for the tab bar.
In your example that would be:
return (
<View>
<TabNavigator style={{ backgroundColor: "#2F3438" }} key="MainTabNav" />
</View>
);
<NavigationContainer>
<Tab.Navigator
tabBarOptions={{
activeTintColor: Colors.tabIconSelected,
inactiveTintColor: Colors.tabIconDefault,
style: styles.container
}}/>
</NavigationContainer>
const styles = StyleSheet.create({
container: {
backgroundColor: Colors.darkBackgroundColor,
borderTopWidth: 0
}
});
Note : borderTopWidth: 0 worked for me
For react native navigation V5
<Tab.Navigator
tabBarOptions={{
style: {
borderTopWidth: 0
}
}}
>
<Tab.Screen/>
<Tab.Navigator>
Note: this is for bottom tab
When I was implementing floating button on bottomTabNavigation followed this post, I faced similar issue that tabBar has dirty white space with shadow(I used shadow in style of component).
I used React navigation v6.
issue image1, issue image2 (Sorry, It's my first Answer I post, I can't embed image yet)
I tried to remove it with borderWidth: 0, but not worked.
My case, below is worked for me.
Try this
borderRadius: 25 // some much number that near tabbar height
on
<Tab.Navigator
tabBar={(props) => (
<View style={styles.navigatorContainer}>
<BottomTabBar {...props} />
{isIphoneX() && (
<View
style={[
styles.xFillLine,
{ backgroundColor: "#fff" },
]}
/>
)}
</View>
)}
screenOptions={{
headerShown: false,
tabBarShowLabel: false,
tabBarStyle: {
borderRadius: 25, // add here
borderTopWidth: 0,
borderRadius: 25,
backgroundColor: "transparent",
elevation: 30,
},
tabBarItemStyle: { backgroundColor: "#fff" },
}}
>
...
Then result image is this.
I don't understand why It was worked, but I hope it works for someone.
I had this issue when i was using the TabBarIcon property within the Tab.Screen
Tab being const Tab = createBottomTabNavigator()
I couldn't solve the issue no matter how i used the SafeAreaView.
I solved it by not using the TabBarIcon property and instead making a custom component for the tabBar property on the higher level Tab.Navigator as outlined in the react native docs https://reactnavigation.org/docs/bottom-tab-navigator/
When i created the custom tabBar component it all worked as expected, no funky use of SafeAreaView.

React-Native onPress doesn't work, when touch the icon

I'am using react-native-element to create a button group, that embedded an Icon from react-native-vector-icons .
the problem is that when the icon is touched, onPress does not get triggered
constructor(props) {
super(props);
this.state = { selectedIndex: 0 };
this.SetSelected = this.SetSelected.bind(this);
}
SetSelected(index) {
this.setState({ selectedIndex: index });
}
return(
<ButtonGroup
selectedIndex={this.state.selectedIndex}
onPress={this.SetSelected}
selectedButtonStyle={{ backgroundColor: 'blue' }}
buttons={[
{
element: () => (
<Icon.Button
name="slack"
style={{ backgroundColor: 'white' }}
color={'black'}
size={30}
title="Inbox"
>
<Text style={{ color: 'black', fontSize: 15, textAlignVertical: 'center', textAlign: 'center' }}
>
All
</Text>
</Icon.Button>
),
})
Thanks to Kyle Roach,
the reason is
because I am using an Icon.Button which is touchable. So when I try to tap to change the ButtonGroup, the touch event will be caught by Icon.Button instead of the button for the buttonGroup.
I should use Icon instead of Icon.Button.
Try making it a function.
onPress={() => {this.SetSelected()}}
If it doesn't work please provide the this.SetSelected function.

Define right button of NavBar in component, not in Scene (react-native-router-flux)

I'm using react-native-router-flux for navigation in my app.
I want to define right button of NavBar in component, not in Scene, how should I do this?
Here is the code of the Scene:
<Scene
navBar={PlatformNavbar}
leftElement={ <Text style={{color: Colors.white, marginLeft: 25, fontWeight:'500' }}>Go Back</Text> }
key='nodScreen'
component={NodScreen}
hideNavBar={false}
/>
I'm using my custom navBar, I have functions for rendering right and left element: leftElement, rightElement.
In order to render right element in the component, I was using this code, however, it didn't render anything.
componentDidMount() {
Actions.refresh({rightElement: this.renderRightElement
}) }
renderRightElement = () => {
return ( <TouchableOpacity onPress={() => {} }>
<Image style={{height: 24, width: 24, marginRight: 16}} source={{uri: 'score_progress_empty'}} resizeMode='contain'/>
</TouchableOpacity>)
}
Have you tried using right instead of rightElement
componentDidMount() {
Actions.refresh({
right : this.renderRightElement,
})
}
Check out this issue on RNRF page for more details

React Native TabNavigator change TabStyle to follow according to the text

I am using expo v27.0, react native 0.55 and I as you can see in the picture that the tab have somewhat a fixed width like a default width from the tab navigation, and the text wrap into three lines, I want the text to be in 1 line and nowrap, and i have tried styling (flexWrap:
'nowrap', flex: 1) in TabStyle, LabelStyle in TabBarOptions, but still can't get the tab to have the width according to the text inside the tab.
I populate the text for the tabs dynamically from json using fetch, therefore all tabs will have different width according to the text. How to I make the tab to follow the width of the text ?
All answers are greatly welcomed.
Thank you in advance.
Solved, turns out just need to set the width to auto as follows:
tabBarOptions: {
tabStyle: {
width: 'auto'
}
}
You can use render label in render header and in that you can return your Text component and Text is having numberOfLines props that will be 1 and it will add ... at end of the text after one line.
Check example snippet:
_renderLabel = props => {
let preparedProps = {
style: {
fontFamily: fonts.Regular,
marginVertical: 8
},
fontType: props.focused ? "Medium" : "Light"
};
return (
<Text
{...preparedProps}
numberOfLines={1}
ref={ref => {
ref && this.props.addAppTourTarget(ref, props.route.key);
}}
>
{props.route.type === "free" && this.state.is_premium_member
? this.labels.premium
: props.route.title}
</Text>
);
};
_renderHeader = props => (
<TabBar
{...props}
bounces={true}
style={{
backgroundColor: colors.cardBlue
}}
indicatorStyle={{
backgroundColor: colors.radicalRed,
height: 1,
borderRightWidth: initialLayout.width * 0.1,
borderLeftWidth: initialLayout.width * 0.1,
borderColor: colors.cardBlue
}}
tabStyle={{
padding: 0,
borderTopColor: "transparent",
borderWidth: 0
}}
renderLabel={this._renderLabel}
/>
);
_handleIndexChange = index => this.setState({ index });
_renderScene = ({ route, focused }) => {
switch (route.key) {
case "a":
return <One {...this.props} route={route} focused={focused} />;
case "b":
return (
<Two {...this.props} isSeries={true} focused={focused} />
);
case "c":
return <Three {...this.props} route={route} focused={focused} />;
default:
return null;
}
};