React Navigation Bottom Tabs occupying the whole screen in React Native Web - react-native

I'm trying to use React-Navigation bottom tabs in React-Native-Web, the result is the expected in the device:
result in device
But in the web it gets like this:
result in the browser
If I inspect the page I can find the elements of main in there.
and here is the code:
src/App.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* #format
* #flow strict-local
*/
import React from 'react';
import {StatusBar} from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import Main from './pages/Main/index';
const Tab = createBottomTabNavigator();
const App = () => {
return (
<>
<StatusBar
backgroundColor="transparent"
translucent
barStyle="light-content"
/>
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Main" component={Main} />
</Tab.Navigator>
</NavigationContainer>
</>
);
};
export default App;
src/pages/Main/index.js
import React, {useState, useEffect} from 'react';
import {View, Dimensions} from 'react-native';
// import api from '../../services/api';
import Company from '../../components/Company';
import {Container, Title, List} from './styles';
export default function Main() {
//...
return (
<View
style={{
display: 'flex',
flexDirection: 'column',
height: Dimensions.get('window').height,
justifyContent: 'center',
}}>
<Container>
<Title>Empresas Cadastradas</Title>
<List
keyboardShoulPersistTaps="handled"
data={companies}
keyExtractor={(item) => String(item.id)}
renderItem={({item}) => <Company data={item} />}
/>
</Container>
</View>
);
}
src/pages/Main/styles.js
import styled from 'styled-components/native';
export const Container = styled.View`
background-color: #7159c1;
padding-top: 30px;
flex: 1;
`;
export const Title = styled.Text`
font-size: 32px;
color: #fff;
font-weight: bold;
padding: 0 20px;
margin-bottom: 10px;
`;
export const List = styled.FlatList.attrs({
contentContainerStyle: {paddingHorizontal: 10},
showsVerticalScrollIndicator: false,
})`
margin-top: 20px;
`;

I've encountered the same problem, and the solution is to add index.css somewhere in your src, load it in your index.js or index.web.js, then put this:
html,
body {
height: 100%;
}
/* These styles disable body scrolling if you are using <ScrollView> */
body {
overflow: hidden;
}
/* These styles make the root element full-height */
#root {
display: flex;
height: 100%;
}
Found the solution in the following discussion:
https://github.com/react-navigation/react-navigation/issues/9187

Related

React native background image - styled-components

i am currently learning react-native, very new to it.
i get the below error when i place in the styled-components style background-image: url(${img});:
Invariant Violation: "backgroundImage" is not a valid style property.
StyleSheet generated: {
"backgroundColor": "#FD5656",
"backgroundImage": "url(undefined)"
}
could one kindly advise me what i am doing wrong?
File: Login.js screen - sampleApp/rn-sample-app/screens/Login.js
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Container, InnerContainer, ScrollArea } from './../constants/layout-styles';
import { Text, View } from 'react-native';
const Login = () => {
return(
<ScrollArea loginbkgrd={true}>
<Container>
<InnerContainer>
<View>
<Text>Login page</Text>
<Text>form</Text>
</View>
</InnerContainer>
</Container>
</ScrollArea>
);
};
export default Login;
File: layout-styles - sampleApp/rn-sample-app/constants/layout-styles.js
import styled from 'styled-components';
import { View, ScrollView } from 'react-native';
import Constants from 'expo-constants';
import { colors } from './colours';
import { img } from './../assets/images/bkgrd.png';
const StatusBarHeight = Constants.statusBarHeight;
export const Container = styled.View`
flex: 1;
padding: 25px;
padding-top: ${StatusBarHeight + 10}px;
background-color: ${colors.transparent};
`;
export const InnerContainer = styled.View`
flex: 1;
width: 100%;
align-items: center;
`;
export const ScrollArea = styled.ScrollView`
${(props) => (props.loginbkgrd == true && `
background-color: ${colors.primary};
background-image: url(${img});
`)};
`;
If you want to use a background Image, you should go with react-native ImageBackground
<ImageBackground
source={{uri: 'YOUR URL HERE'}}
style={{ flex: 1}}
>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Your Contents</Text>
</View>
</ImageBackground >

React-Navigation: How to implement multi-independant viewstacks with react-navigation (React-Native)

Good morning, good afternoon or good evening
I want to archive this navigation interface (for desktop / tablet screen size):
https://photos.app.goo.gl/ZEna1uozQP1UnVWm6
Each viewstack should be fully dependent to only one navigation; I am using react-navigation.
However, with my following code, the the pane view (the card) is completely hidden / gone on the main page.
How should I do this in order to archive the results on the prototype / video.
Below are my codes.
Thank you!
App.js (Main navigation)
import React, { FC } from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { ThemeProvider } from '#emotion/react';
import setTheme from '#lib/theme';
import changeNavigationBarColor from 'react-native-navigation-bar-color';
import {
Home as Billing,
Customers,
} from '#components/5-pages';
const theme = setTheme('light');
const Stack = createStackNavigator();
changeNavigationBarColor("black", false, true);
type Props = {};
const App: FC<Props> = ({...props}) => {
return (
<ThemeProvider theme={theme}>
<NavigationContainer>
<Stack.Navigator initialRouteName={"billing"} screenOptions={{ headerShown: false }}>
<Stack.Screen name="billing" component={ Billing } />
<Stack.Screen name="customers" component={ Customers } />
</Stack.Navigator>
</NavigationContainer>
</ThemeProvider>
);
};
export default App;
Card.js (Pane / Inner navigation)
import React, { FC }from 'react';
import styled from '#emotion/native';
import Text from './Text';
import setTheme from '#lib/theme';
import { NavigationContainer, useNavigation } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { ThemeProvider } from '#emotion/react';
const Container = styled.View`
background: ${({ theme }: any) => theme.colors.white };
border-radius: 6px;
flex-direction: column;
padding: 6px 12px;
margin: 6px 12px;
width: 320px;
`;
const Content = styled.View`
align-items: center;
flex-direction: column;
padding-left: 6px;
`;
const Title = styled(Text)`
font-size: 15px;
font-weight: bold;
color: #404040;
line-height: 49px;
`;
const Stack = createStackNavigator();
const theme = setTheme('light');
const Card: FC<Props> = ({ children, modal, title, ...props }) => {
const List : FC<Props>= () => {
const navigation = useNavigation();
return (
<Container {...props} >
<Title>{title}</Title>
<Content onModal={()=>{navigation.push("modal", props)}}>
{children}
</Content>
</Container>
)};
const Modal : FC<Props>= () => {
return (
<Container {...props} >
<Title>{title}</Title>
<Content>
{modal}
</Content>
</Container>
)};
return (
<NavigationContainer independent={true}>
<Stack.Navigator initialRouteName={"list"} screenOptions={{ headerShown: false }}>
<Stack.Screen name="list" component={ List } />
<Stack.Screen name="modal" component={ Modal } />
</Stack.Navigator>
</NavigationContainer>
);
}
type Props = {
title?: string;
children?: React.ReactNode;
modal?: React.ReactNode;
};
export default Card;

onPress event not working on TouchableOpacity on Android

Before I begin, I have checked out other common solutions to this problem, like importing TouchableOpacity from 'react-native' instead of 'react-gesture-handler' (I don't even have it installed), or changing z-index/absolute positioning. None of them work.
I'm a beginner in react native. I'm trying to follow along with a react native course, but I'm stuck on this issue. I'm using Expo on a real Android. I don't use emulators. Haven't tested on iOS as I don't have access to one. When I add onPress to TouchableOpacity, most of the time it gives feedback when clicked (opacity changes), but it won't fire the onPress event. Sometimes, however, it works. When I press on the right edge, sometimes the event fires. Here's an example:
index.js
import React from "react";
import Options from "./screens/Options";
export default function App() {
return <Options />;
}
Options.js
import React from "react";
import { View, StyleSheet } from "react-native";
import RowItem from "../components/RowItem";
import Constants from "expo-constants";
import styled from "styled-components";
import colors from "../constants/colors";
import { Entypo } from "#expo/vector-icons";
const SSeparator = styled.View`
background: ${colors.border};
height: ${StyleSheet.hairlineWidth}px;
margin-left: 20px;
`;
const SView = styled.View`
margin-top: ${Constants.statusBarHeight}px;
`;
export default () => {
return (
<SView>
<RowItem
title="Themes"
icon={
<Entypo
name="chevron-left"
size={20}
color={colors.blue}
onPress={() => alert("click")}
/>
}
/>
<SSeparator />
</SView>
);
};
RowItem.js
import React from "react";
import { TouchableOpacity, Text } from "react-native";
import styled from "styled-components";
import colors from "../constants/colors";
const SText = styled.Text`
font-size: 16px;
`;
const STouchableOpacity = styled.TouchableOpacity`
margin: 16px 20px;
flex-direction: row;
align-items: center;
justify-content: space-between;
`;
export default ({ title, icon, onPress }) => {
return (
<STouchableOpacity onPress={onPress}>
<SText>{title}</SText>
{icon}
</STouchableOpacity>
);
};
Any ideas?
can you try like this:
export default () => {
const testFunc = () =>{
alert('test')
}
return (
<SView>
<RowItem
title="Themes"
icon={
<Entypo
name="chevron-left"
size={20}
color={colors.blue}
onPress={testFunc}
/>
}
/>
<SSeparator />
</SView>
);
};
and then :
<STouchableOpacity onPress={()=>onPress()}>
<SText>{title}</SText>
{icon}
</STouchableOpacity>
Okay, so I finally noticed the mistake, and I feel ashamed for not noticing it. I kept reading the code but I couldn't see the obvious.
I mistakenly copied the onPress event into the icon instead of putting it directly inside RowItem.
Instead of this:
<RowItem
title="Themes"
icon={
<Entypo
name="chevron-left"
size={20}
color={colors.blue}
onPress={() => alert("click")}
/>
}
/>
It should be this:
<RowItem
title="Themes"
handlePress={() => alert("test")}
icon={<Entypo name="chevron-left" size={20} color={colors.blue} />}
/>
And inside RowItem.js:
export default ({ title, icon, handlePress }) => {
return (
<STouchableOpacity onPress={() => handlePress()}>
<Text>{title}</Text>
{icon}
</STouchableOpacity>
);
};
And now the app works as intended.

react-responsive Invalid-hook-call

I 'm trying to use react-responsive in a monorepos with styled-component and react-native-web.
I've a workspace like my ui lib and i define my component like that:
import styled from 'styled-components/native';
import { theme } from '#components/theme';
import MediaQuery from 'react-responsive';
interface CardProps {
children: React.ReactNode;
tag: string;
}
const Card = (props: CardProps) => {
console.log("Card -> props", props)
return (
<Container>
<MediaQuery minDeviceWidth={1000}>
<Tag>'blablabla</Tag>
</MediaQuery>
<TagContainer>
<Tag>{props.tag}</Tag>
</TagContainer>
<MainContent>{props.children}</MainContent>
</Container>
);
}
I define the style like that:
const Container = styled.View`
display: flex;
flexDirection: column;
minWidth: ${theme.width.minCard};
maxWidth: ${theme.width.maxCard};
height: ${theme.height.card};
boxShadow: 0 0 10px ${theme.colors.primaryGrey};
border: 1px solid ${theme.colors.primaryYellow};
borderRadius: ${theme.borderRadius.rectangular};
marginBottom: ${theme.margins.medium};
`;
const TagContainer = styled.View`
display: flex;
flexDirection: row-reverse;
`;
I'm trying to use this component in my react-native app located in another workspace like this:
return (
<View>
<Specialist
key={psychologist.uuid}
img={psychologist.avatar.url}
name={psychologist.fullname}
job={psychologist.job_name}
description={psychologist.description}
/>
</View>
);
Each time, I find myself blocked by this error:
however my component is indeed a functional component...
Any idea ?
the package you are using is only for react.js.
For React Native you can use
React Native Responsive Screen
example given in react-native-responsive-screen
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';
class Login extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.textWrapper}>
<Text style={styles.myText}>Login</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: { flex: 1 },
textWrapper: {
height: hp('70%'), // 70% of height device screen
width: wp('80%') // 80% of width device screen
},
myText: {
fontSize: hp('5%') // End result looks like the provided UI mockup
}
});
export default Login;

React Native TextInput loses focus on call hook from useState

Environment
react-native: "0.61.5",
"styled-components": "4.4.1"
Reproduction
Snack example: https://snack.expo.io/BJSfYqlCS
import * as React from 'react';
import styled from 'styled-components'
import {View} from 'react-native'
export default () => {
const [text, setText] = React.useState('');
const StyledInput = styled.TextInput`
background-color: red;
border-color: black;
`
return (
<View>
<StyledInput value={text} onChangeText={text => setText(text)} />
</View>
);
}
Steps to reproduce
type something in styled TextInput
Expected Behavior
Just plain typing
Actual Behavior
lost focus
Get styles out of function
import * as React from 'react';
import styled from 'styled-components'
import {View} from 'react-native'
const StyledInput = styled.TextInput`
background-color: red;
border-color: black;
`
export default () => {
const [text, setText] = React.useState('');
return (
<View>
<StyledInput value={text} onChangeText={text => setText(text)} />
</View>
);
}
Check expo shack
So the problem is pretty tricky , It looks like the problem is that you're defining your StyledInput inside it's parent return method and then calling the parent's setText method directly (instead of passing through props), which causes rerender that you don't want.
Better approach would be to use direct text input and apply styling to it. Please see below code and also ive shared a working example in expo snack. do check that.
import * as React from 'react';
import styled from 'styled-components'
import {TextInput,View} from 'react-native';
export default () => {
const [text, setText] = React.useState('');
const StyledView = styled.View`
flex: 1;
align-items:center;
justify-content: center;
background-color: papayawhip;
`
const StyledInput = styled.TextInput`
background-color: white;
`
const StyledText = styled.Text`
color: palevioletred;
`
return (
<View>
<StyledText>Hello World!</StyledText>
<TextInput style={{height:50,width:50,backgroundColor:'red'}} value={text} onChangeText={text => setText(text)} />
</View>
);
}
expo snack expo url
Hope it helps. feel free for doubts