I have the following APP. I'm having trouble with the spacing of components within the return of the App class.
I would like to move the 'Reset' up a little bit and the 'Start' down a little. It would be nice if there was an easy way to control the vertical placement
import React from 'react';
import { Button,StyleSheet, Text, View } from 'react-native';
export class Timers extends React.Component{
constructor(props){
super(props)
this.state={work:{min:this.props.min,
sec:this.props.sec,
buttton:this.props.button,
period:this.props.period,},
play:{min:this.props.min,
sec:this.props.sec,
buttton:this.props.button,
start:this.props.start,
period:this.props.period,}
}
}
render(){
return(
<View style={styles.timer}>
<Text>{this.props.name}</Text>
<Text>{'min: ' + this.props.min + ' sec: ' + this.props.sec }</Text>
<Text>{this.props.period}</Text>
</View>
)
}
}
export default class App extends React.Component {
constructor(){
super()
this.state={start:'Start'}
}
parentState(){
if(this.state.start === 'Start') startStop = 'Stop'
else startStop = 'Start'
this.setState({start:startStop})
}
buttonPress(x){
if(x === 'Start' || x === 'Stop')this.parentState()
console.log(x)
}
render() {
return (
<View style={styles.container}>
<Button style={styles.top} title='Reset'onPress=
{()=>this.buttonPress(this.state.start)}/>
<View style={styles.row}>
<Timers
name={'WORK'}
min={'25'}
sec={'00'}
button={'Reset'}
period={'tbd'} >
</Timers>
<Timers
name={'PLAY'}
min={'25'}
sec={'00'}
period={'tbd'} >
</Timers>
</View>
<Button title={this.state.start} onPress=
{()=>this.buttonPress(this.state.start)}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection:'column',
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
timer:{
flex:1,
flexDirection:'column',
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
row:{
flex:0,
flexDirection:'row',
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
apply marginTop and MarginBottom to styles.row does the trick
Related
Ok, so I'm extremely new to react, so sorry if this question is really dumb.
I've been working on a react application using electron and expo, and don't fully understand how to solve this warning which is showing in my developer console.
Warning: Failed prop type: Invalid props.style key `WebkitAppRegion` supplied to `View`.
Bad object: {
"display": "flex",
"flexDirection": "row",
"height": 20,
"backgroundColor": "#0e0e11",
"margin": 0,
"borderBottomWidth": 0.5,
"borderColor": "#060607",
"WebkitAppRegion": "drag"
}
When I originally built the design for this UI, I did so with standard html and SCSS, and now I'm attempting to change it to react as my first big project. So having done some googling, I found the information that to include my -webkit-app-region: drag all I needed to do was CammelCase and remove the "-"'s. Except it's now throwing this error, it does the function as intended but how does one solve the "invalid props style" issue?
Some shitty code for ya to critique xD
//app.tsx
import React from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import { SplashScreen } from 'expo';
import * as Font from 'expo-font';
import * as styles from './assets/styles/main'
SplashScreen.preventAutoHide();
setTimeout(SplashScreen.hide, 10000);
export default class App extends React.Component {
state = {
fontLoaded: false,
};
async componentDidMount() {
await Font.loadAsync(styles.fontList);
this.setState({ fontLoaded: true });
}
render() {
return (
this.state.fontLoaded ? (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'stretch', backgroundColor: styles.colors.dark1 }}>
<this.DisplayHandles />
</View>
) : null
);
}
DisplayHandles() {
if (Platform.OS === 'web' && process.versions.electron) {
return ([
<View style={[styles.electron.header, {WebkitAppRegion: 'drag'}]}>
<View style={styles.electron.titleContainer}>
<Text key='title' style={[styles.electron.title, {WebkitAppRegion: 'no-drag', 'userSelect': 'none'}]}> Smartcloud</Text>
</View>
<View style={styles.electron.controlContainer}>
<Text key='minimize' style={[styles.electron.button, {WebkitAppRegion: 'no-drag', 'userSelect': 'none'}]} onClick={handleClick}>-</Text>
<Text key='maximize' style={[styles.electron.button, {WebkitAppRegion: 'no-drag', 'userSelect': 'none'}]} onClick={handleClick}>+</Text>
<Text key='close' style={[styles.electron.button, {WebkitAppRegion: 'no-drag', 'userSelect': 'none'}]} onClick={handleClick}>x</Text>
</View>
</View>,
<View style={{ flex: 1}}>
<Content.CreateHandles />
</View>
]
)
}
return <Content.Container/>
}
}
function handleClick(e) {
e.preventDefault();
console.log('I was clicked')
}
class Content {
static CreateHandles() {
return (
<View>
<Content.Container />
</View>
)
}
static Container () {
return (
<View style={{alignItems: 'center',}}>
<Content.TestingText />
</View>
)
}
static TestingText() {
if (Platform.OS === 'web') {
if (process.versions.electron) {
return (<Text style={{fontSize: 60, color: styles.colors.light5, fontFamily: styles.rubik.medium} }> This is a Electron {process.versions.electron} + {Platform.OS} version </Text>)
}
return (<Text style={{fontSize: 60, color: styles.colors.light5, fontFamily: styles.rubik.medium}}> This is a {Platform.OS} version </Text>)
}
return <Text style={{fontSize: 20, color: styles.colors.light5, fontFamily: styles.rubik.medium}}> This is a {Platform.OS} version</Text>
}
}
// ./assets/styles/main.tsx
export const electron = StyleSheet.create({
header: {
display: 'flex',
flexDirection: 'row',
height: 20,
backgroundColor: colors.dark4,
margin: 0,
borderBottomWidth: 0.5,
borderColor: colors.dark5,
},
titleContainer: {
display: 'flex',
alignItems: 'flex-start',
flexGrow: 1,
},
controlContainer: {
display: 'flex',
justifyContent: 'flex-end',
flexDirection: 'row',
alignItems: 'center',
},
title: {
color: colors.purple,
margin: 0,
marginLeft: 10,
fontSize: 14,
fontFamily: rubik.black,
},
button: {
width: 25,
margin: 0,
marginLeft: 10,
color: colors.purple,
textAlign: 'center',
fontSize: 14,
fontFamily: rubik.black,
}
})
I discovered flexbox recently and I'm struggling to make it work, I'm surely missed some concept that make me hard time to understands it's mechanics so here is what I have:
It's a preview camera screen
with a back button on the top right
A text in the middle
and a record button to shoot some images
Here is what I have at the moment:
this is done with this React native component (style included)
import React from "react";
import { RNCamera } from "react-native-camera";
import { StyleSheet, TouchableOpacity, View, Platform} from "react-native";
import {Icon, Text} from "native-base";
import RequestPermissions from "../components/Permissions/RequestPermissions";
import I18n from "../i18n/i18n";
/**
* This is the component which allows the user to film his own film
*/
export default class CameraScreen extends React.Component
{
constructor(props) {
super(props);
this.camera = null;
}
state = {
isRecording: false,
iconVid: "record",
iconMode: null,
overlay: true
};
/**
* With RNCamera, it seems that permission is always asked to the user... Maybe this code is then irrelevant
*/
componentWillMount() {
if (Platform.OS === "android") {
RequestPermissions().then(() => {
console.log("granted");
}).then((err) => {
console.log(err)
});
}
}
componentWillUnmount() {
this.stopRecording();
};
stopRecording = () => {
if (this.camera) {
this.camera.stopRecording();
this.setState({
isRecording: false,
iconVid: "record"
});
}
};
renderCamera = () => {
return (
<View style={styles.container}>
<RNCamera
ref={cam => {
this.camera = cam;
}}
style={styles.preview}
>
<View style={styles.controlsContainer}>
<View style={styles.topRightButton}>
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<Icon name={"arrow-left"} type={"Feather"} style={styles.iconFurtive}/>
</TouchableOpacity>
</View>
<View style={styles.middleContainer}>
<Text style={styles.actionText}>{I18n.t("action_text").toUpperCase()}</Text>
</View>
<View style={styles.leftContainer}>
<TouchableOpacity onPress={() => this.recordVideo()}>
<Icon name={this.state.iconVid} type={"MaterialCommunityIcons"} style={styles.iconCamera}/>
</TouchableOpacity>
</View>
</View>
</RNCamera>
</View>
);
};
/**
* For more options
* https://github.com/react-native-community/react-native-camera/blob/master/docs/RNCamera.md#recordasyncoptions-promise
*/
recordVideo = () => {
if (this.camera) {
this.setState({ isRecording: true, iconVid: "stop" });
// Show the overlay
console.log("Device is Recording");
this.camera.recordAsync({maxDuration: 15}).then(data => {
this.stopRecording();
console.log("Stop Recording");
console.log(data);
}).catch((err) => {
console.log(err);
this.stopRecording();
});
}
};
render() {
return this.renderCamera()
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop:30,
},
controlsContainer: {
flex: 1,
flexDirection: "column"
},
topRightButton: {
flex: 1,
justifyContent: 'flex-start',
alignItems: 'flex-start',
},
middleContainer: {
flex: 0.5,
justifyContent: 'center',
alignItems: 'center',
},
leftContainer: {
flex: 0.5,
justifyContent: 'center',
alignItems: 'flex-end',
},
actionText: {
color: "#fff",
fontSize: 72
},
preview: {
flex: 1,
},
iconCamera: {
color: "#ff4459",
marginBottom: 50,
padding: 25,
backgroundColor: "#fff",
borderRadius: 50,
},
iconFurtive: {
color: "#fff",
marginTop: 50,
marginLeft: 50,
}
});
Here is what I want:
How to do that with flexbox? What am I missing?
Code changed at View with {styles.topRightButton}
return (
<View style={styles.container}>
<RNCamera
ref={cam => {
this.camera = cam;
}}
style={styles.preview}
>
<View style={styles.controlsContainer}>
<View style={{justifyContent: 'flex-start', alignItems: 'flex-start',}}>
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<Icon name={"arrow-left"} type={"Feather"} style={styles.iconFurtive}/>
</TouchableOpacity>
</View>
<View style={{flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-around'}}>
<View style ={{height: 50, width: 50, backgroundColor: 'transparent'}} />
<Text style={styles.actionText}>{I18n.t("action_text").toUpperCase()}</Text>
<TouchableOpacity onPress={() => this.recordVideo()}>
<Icon name={this.state.iconVid} type={"MaterialCommunityIcons"}/>
</TouchableOpacity>
</View>
</View>
</RNCamera>
</View>
);
For middle and left the content should be in the same div with that div having a flexDrirection: 'row'. This puts them in the same row.
The controls container can have justifyContent: 'center', and alignItems: 'center'.
The topRightButton should override the parents style.
So I want to use a Modal to disable all interactions on a screen but I still want everything on the screen to be visible. It's odd because it was working just fine for me earlier, then I tried to make the Modal its own component, but as soon as I did that, it stopped working properly. I then went back to what I originally did but still having the same issue. I should've committed it when it worked.
Any idea where I went wrong?
Here's my code:
import React, { Component } from 'react';
import { View, Image, Modal, Text, Button, TouchableHighlight } from 'react-native';
constructor(props) {
super(props);
this.state = {
modalVisible: true,
};
}
openModal() {
this.setState({modalVisible: true});
}
closeModal() {
this.setState({modalVisible: false});
}
render() {
return (
<View style={styles.container}>
<Modal
visible={this.state.modalVisible}
onRequestClose={() => this.closeModal()}
>
<TouchableHighlight
style={styles.modalContainer}
onPress={() => this.closeModal()}
>
<Text>"Words n stuff"</Text>
</TouchableHighlight>
</Modal>
<View
style={styles.upperContainer}
/>
<View
style={styles.lowerContainer}
/>
</View>
);
}
}
}
Styles:
modalContainer: {
flexGrow: 1,
justifyContent: 'center',
flexDirection: 'row',
backgroundColor: 'transparent',
},
container: {
flexGrow: 1,
justifyContent: 'space-around',
flexDirection: 'column',
alignItems: 'center',
},
upperContainer: {
flexGrow: 2,
alignItems: 'center',
justifyContent: 'flex-end',
paddingBottom: 18,
width: screenWidth,
marginTop: -140,
},
lowerContainer: {
flexGrow: 2,
alignItems: 'center',
justifyContent: 'space-around',
width: screenWidth,
},
Try to add transparentproperty to your Modal.
Example:
<Modal
transparent
...>
...
</Modal>
Doc: https://facebook.github.io/react-native/docs/modal.html#transparent
Try transparent={true} on <Modal />
My code is like this---
import React from 'react';
import {View,Text,Alert,StyleSheet} from 'react-native';
const data = ['All','Electronics','Baby and Child','Property'];
const styles=StyleSheet.create({
itemStyles: {
color: "#F456A3",
fontSize:30,
fontWeight:"bold",
},
CategoryStyle: {
flex:1,
justifyContent:'center',
flexDirection:'row'
}
});
export default class FilterScreen extends React.Component {
constructor(){
super();
this.test;
}
renderCategories = () =>{
//Alert.alert(data[0]);
this.test=data.map(item => {
return(
<View key={item} style={styles.CategoryStyle}>
<Text style={styles.itemStyles}>{item}</Text>
</View>
)
})
return this.test;
}
render(){
return(
<View>
<Text>hello world</Text>
{this.renderCategories()}
</View>
)
}
}
I have to apply styling to the Text present in render categories such that it should come with 2 text in a row. So, here there will be 2 rows with 2 texts.
How can that be done?
For styles.itemStyles set it to width: '50%' and add flexWrap to parent. Try this:
const styles=StyleSheet.create({
itemStyles: {
color: "#F456A3",
fontSize:30,
fontWeight:"bold",
width: '50%' ///////////////// i added this
},
CategoryStyle: {
flex:1,
justifyContent:'center',
flexDirection:'row',
flexWrap: 'wrap' ///////// added this
}
});
Here is a snack expo that works - https://snack.expo.io/BJY_WnrrG
import React, { Component } from 'react';
import { Text, View, StyleSheet } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Text style={[styles.text, styles.textPink]}>a</Text>
<Text style={[styles.text, styles.textBlue]}>b</Text>
<Text style={[styles.text, styles.textPink]}>c</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
height: '100%',
flexDirection: 'row',
justifyContent: 'flex-end',
flexWrap: 'wrap',
alignContent: 'space-around',
alignItems: 'flex-start',
backgroundColor: 'steelblue'
},
text: {
width: '50%'
},
textBlue: {
backgroundColor: 'skyblue'
},
textPink: {
backgroundColor: 'pink'
}
});
When items wrap, you get the new style property of alignContent check it out - http://facebook.github.io/react-native/docs/layout-props.html#aligncontent
Also when items wrap, justifyContent only affects rows where there is space left over, as seen in the third text item above.
I am having a problem rendering my component inside of a navigatorIOS, I am sure it is a style issue but I can't pinpoint where.
I have given flex : 1
removed backgroundColor
and I have given a margin
as suggested in other stack overflow questions.
If I throw MessageBoardTopics outside of the navigator it renders fine.
import MessageBoardTopics from './messageBoardTopics.js';
class MessageBoards extends React.Component{
constructor(props){
super(props);
}
componentDidMount(){
}
render() {
return (
<View style={styles.container}>
<NavigatorIOS
style={{flex: 1}}
initialRoute={{
component: MessageBoardTopics,
title: 'Forum',
}}/>
</View>
);
}
};
module.exports = MessageBoards;
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
var screenWidth = Dimensions.get('window').width;
class MessageBoardTopics extends React.Component{
constructor(props){
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var data = PostStore.getState().posts;
this.state={sortText: 'Sort by: Old',
dataSource: ds.cloneWithRows(data)};
}
componentDidMount() {
PostStore.listen(this.onChange);
}
componentWillUnmount() {
PostStore.unlisten(this.onChange);
}
onChange(state) {
this.setState(state);
}
replyToMessage(){
}
removeMessage(){
}
sortMessages(){
}
editMessage(){
}
pressRow(rowData){
this.props.navigator.push({
title: rowData.title,
component: Topic
});
}
render() {
return (
<View style={styles.container}>
<Text>fasfasdfafasdf</Text>
<View style={{flex: .2}}></View>
<View style={styles.buttonBar}>
<TouchableHighlight style={styles.centerButton} underlayColor={"lightred"} onPress={this.sortMessages}>
<Text>{this.state.sortText}</Text>
</TouchableHighlight>
<View style={styles.centerButton} underlayColor={"lightred"} onPress={this.newMessage}>
<ComposeModal reply={this.replyToMessage} index={null}/>
</View>
</View>
<ListView
dataSource={this.state.dataSource}
style={{borderTopWidth: 2}}
renderRow={(rowData) =>
<TouchableHighlight underlayColor="lightgrey" onPress={()=>this.pressRow(rowData)}>
<View style={styles.message}>
<Text style={styles.messageTitle}>{rowData.title}</Text>
<Text style={styles.messageAuthor}>By: <Text style={{color: 'blue', fontStyle: 'italic'}}>{rowData.author}</Text></Text>
</View>
</TouchableHighlight>}/>
</View>
);
}
};
module.exports = MessageBoardTopics;
var styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 80,
},
message: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
borderWidth: 1,
borderColor: "lightblue",
padding: 15,
},
messageTitle: {
color: 'grey',
textDecorationLine: 'underline',
fontWeight: 'bold',
},
messageAuthor: {
fontSize: 10,
},
buttonBar: {
flex: .1,
alignSelf: 'stretch',
alignItems: 'center',
flexDirection: 'row',
},
centerButton: {
flex: 1,
width: (screenWidth/2),
alignItems: 'center',
},
button: {
flex: 1,
textAlign: 'center',
},
});
I needed to set a width to a wrapper component for the navigatorIOS
Edit: When I upgraded from react-native 0.16 to 0.17 flex:1 was not working on the navigatorIOS. I had to create a wrapper component and give that a flex as well.
This did not work. This was in my index.ios.js file, which rendered the navigatorIOS on 0.16.
render() {
return (
<View style={styles.container}>
<NavigatorIOS
style={{flex: 1, alignSelf: 'stretch'}}
initialRoute={{
component: MessageBoardTopics,
title: 'Forum',
}}/>
</View>
);
}
};
on react-native 0.17 I had to create a wrapper component and give that a flex attribute. I had to change my index.ios.js to render this instead.
var forumComponent = React.createClass({
render: function() {
return (
<View style={styles.container}>
<MessageBoards style={{flex: 1}}/>
</View>
);
}
});