Text Component exists as below.
const Text = ({
color,
fontSize,
fontWeight,
children,
}: Props) => {
return (
<Root // styled-component
color={color}
fontSize={fontSize}
fontWeight={fontWeight}
>
{children}
</Root>
);
};
const Root = styled.div`
${props => `color: ${props.color};`}
${props => `font-size: ${props.fontSize};`}
${props => `font-weight: ${props.fontWeight};`}
`;
export default Text;
Color, fontSize, and fontWeight are externally managed in the form of objects.
export const color = {
purple: "#683CED",
light_purple: "#925CE9",
orange: "#F58229",
light_gray1: "#DDDDDD",
light_gray2: "#EEEEEE",
light_gray3: "#F9F9F9",
light_gray4: "#D9D9D9",
gray: "#666666",
dark_gray: "#999999",
black: "#000000",
white: "#FFFFFF",
};
export const font = {
size: {
menubar: "10px",
xs: "11px",
s: "12px",
m: "13px",
content: "14px",
title: "16px",
header: "18px",
},
weight: {
regular: "400",
bold: "700",
},
};
When using that component:
import { color, font } from "example-path"
<Text color={color.black} fontSize{font.size.s} fontWeight={font.weight.regular}>Example Text</Text>
This use seems to significantly increase the length of the code where the Text component is used. So, I would like to create in advance all cases of fontSize and fontWeight values that Text components can have and use them as follows.
<Text.T1 color={color.black}>T1</Text> // fontSize = xs and fontWeight = regular
<Text.T2 color={color.black}>T2</Text> // fontSize = s and fontWeight = regular
<Text.T3 color={color.black}>T3</Text> // fontSize = m and fontWeight = regular
....
When a Text component and a font object are given, is there a way to create all possible combinations of font values in advance and group them with the Text component as in the example above?
Related
Why is my paddingHorizontal not working in react native? I have used paddingHorizontal: 0 in the following code, But the buttons are not responding?
Not sure what I'm doing wrong.
import React from "react";
import { StyleSheet, TouchableOpacity, Text } from "react-native";
import PropTypes from "prop-types";
const Button = ({ title, varient }) => {
return (
<TouchableOpacity
style={[
styles.buttonContainer,
{
backgroundColor: varient === "primary" ? "black" : "transparent",
// paddingHorizontal: varient === "primary" ? 16 : 0,
},
]}
>
<Text
style={[
styles.buttonLabel,
{ color: varient === "primary" ? "white" : "black" },
]}
>
{title}
</Text>
</TouchableOpacity>
);
};
const { string } = PropTypes;
Button.propTypes = {
title: string,
varient: string,
};
const styles = StyleSheet.create({
buttonContainer: {
paddingVertical: 12,
paddingHorizontal: 0,
borderRadius: 6,
},
buttonLabel: {
fontSize: 18,
},
});
export default Button;
I have added the screen as following:
I want to create an input box like this:
But I designed it like this, and I don't know how to add the label on the input border
My Code is:
<InputBox label="Email" icon={true} keyboardType="email-address" defaultValue={emailId} onChangeText={text => setEmailId(text)} />
Input Component:
import React from 'react';
import {View, StyleSheet, TextInput, Text} from 'react-native';
import {COLORS} from '../constants/colors';
import {FONT_FAMILY} from '../constants/font-family';
export default function InputBox(props) {
return (
<View style={styles.container}>
<View style={{flex: 1}}>
<Text style={styles.label}>{props.label}</Text>
<TextInput
placeholder={props.placeholder}
placeholderTextColor="#9F9F9F"
style={styles.input}
keyboardType={props.keyboardType}
secureTextEntry={false}
defaultValue={props.defaultValue}
onChangeText={props.onChangeText}
editable={props.editable}
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 20,
paddingTop: 7.5,
paddingHorizontal: 12.5,
paddingBottom: 2.5,
borderRadius: 5,
borderWidth: 0.75,
borderColor: COLORS.WHITE,
},
input: {
fontFamily: FONT_FAMILY.primaryMedium,
fontSize: 14,
height: 37,
color: COLORS.WHITE,
},
label: {
fontFamily: FONT_FAMILY.primary,
marginLeft: 5,
color: COLORS.WHITE,
fontSize: 12,
// marginTop: -30,
},
});
By using react-native-paper, when I add transparent background color it looks like this:
I was able to get this accomplished purely in React Native without any dependencies. The trick was to put the Text in a View with a background color the same as the screen's and position the Text absolutely. My example code hardcodes a lot of values, but if you want it to be responsive you'll need to come up with your own way of figuring those values out. The code:
import { View, Text, TextInput, StyleSheet } from "react-native";
const Input = () => {
return (
<View>
<View style={styles.labelContainer}>
<Text>Email Address</Text>
</View>
<View style={styles.inputContainer}>
<TextInput placeholder="Enter email address" />
</View>
</View>
);
}
const styles = StyleSheet.create({
labelContainer: {
backgroundColor: "white", // Same color as background
alignSelf: "flex-start", // Have View be same width as Text inside
paddingHorizontal: 3, // Amount of spacing between border and first/last letter
marginStart: 10, // How far right do you want the label to start
zIndex: 1, // Label must overlap border
elevation: 1, // Needed for android
shadowColor: "white", // Same as background color because elevation: 1 creates a shadow that we don't want
position: "absolute", // Needed to be able to precisely overlap label with border
top: -12, // Vertical position of label. Eyeball it to see where label intersects border.
},
inputContainer: {
borderWidth: 1, // Create border
borderRadius: 8, // Not needed. Just make it look nicer.
padding: 8, // Also used to make it look nicer
zIndex: 0, // Ensure border has z-index of 0
},
});
export default Input;
This is what it looks like on my device (Samsung Galaxy S10+):
If you have to use a material ui styled components you may wanna use reactnativepaper
hi there you cna use this code to achive
import React from 'react';
import {View, StyleSheet, Text} from 'react-native';
import { TextInput } from 'react-native-paper';
export default function InputBox(props) {
return (
<View style={styles.container}>
<TextInput
mode="outlined"
label="Email"
style={{width:'90%'}}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
justifyContent:'center',alignItems:'center',
flex:1
// borderColor: COLORS.WHITE,
},
input: {
// fontFamily: FONT_FAMILY.primaryMedium,
fontSize: 14,
height: 37,
// color: COLORS.WHITE,
},
label: {
// fontFamily: FONT_FAMILY.primary,
marginLeft: 5,
// color: COLORS.WHITE,
fontSize: 12,
// marginTop: -30,
},
});
you can test it on Snack
Also you can read more about props here react-native-paper
Im building a component that show some icons so the user can choose the color, the component is just a <View> and inside of it theres a flatlist showing the icons: heres the code:
class Color extends Component {
icons_config = {name: "square-full", size: 80, color: "black"};
show_hide_ = false;
options_array = [
{option_icon: <FontAwesome5 name = {this.icons_config.name} size = {this.icons_config.size} color = "red"/>, key: "red"},
{option_icon: <FontAwesome5 name = {this.icons_config.name} size={this.icons_config.size} color = "blue"/>, key: "blue"},
{option_icon: <FontAwesome5 name = {this.icons_config.name} size={this.icons_config.size} color = "green"/>, key: "green"},
{option_icon: <FontAwesome5 name = {this.icons_config.name} size={this.icons_config.size} color = "yellow"/>, key: "yellow"},
{option_icon: <FontAwesome5 name = {this.icons_config.name} size={this.icons_config.size} color = "purple"/>, key: "purple"},
{option_icon: <FontAwesome5 name = {this.icons_config.name} size={this.icons_config.size} color = "black"/>, key: "rgba(0,0,0,0.7)"},
{option_icon: <FontAwesome5 name = {this.icons_config.name} size={this.icons_config.size} color = "gray"/>, key: "gray"},
{option_icon: <FontAwesome5 name = {this.icons_config.name} size={this.icons_config.size} color = "orange"/>, key: "orange"},
{option_icon: <AntDesign name="closesquareo" size={80} color="black" />, key: ""}, //x icon for delete color
];
window_width = Dimensions.get("window").width;
window_height = Dimensions.get("window").height;
render() {
return (
<>
<View style = {this.styles.container}>
{this.options_array.map((option) => {
return (
<View key = {option.key} style = {this.styles.options}>
<TouchableOpacity style = {this.styles.touchable} onPress = {() => this.choose_color(option.key)}>
<Text>{option.option_icon}</Text>
</TouchableOpacity>
</View>
);
})}
</View>
</>
);
}
and the stylesheet code:
styles = StyleSheet.create({
container: {
position: "absolute",
justifyContent: "space-around",
width: Math.round(this.window_width) * 0.8,
height: Math.round(this.window_width) * 0.8,
flexWrap: "wrap",
flexDirection: "row",
alignSelf: "center",
//backgroundColor: "#DCDCDC",
backgroundColor: "red",
marginTop: 200,
},
options: {
paddingTop: Math.round(this.window_width) * 0.025,
justifyContent: "center",
}
});
the problem now, is that im using Dimensions.get("window").width in width and height to create a responsive square for all devices, the problem is that it isnt working in my xiaomi mi 9T, but it does in my one plus 7 pro and on my huawei p9 plus, here Im goint to post some captures so you can see it:
Xiaomi mi 9t:
One plus 7 pro:
Huawei p9 plus:
I guess it has something to do with the icons size, but for one plus and huawei theres no problem, how can I solve this?
You can get the screen width or height using window prop and set the card width and height.
Following example will help you,
import { StyleSheet, Dimensions } from 'react-native';
const window = Dimensions.get('window');
styles = StyleSheet.create({
container: {
width: (window.width) * 0.8,
height: (window.width) * 0.8
},
});
I have the following ui-component:
...
import stylePropType from 'react-style-proptype';
const Heading = ({
...
marginBottom,
strong
}) => (
<Header
style={{
marginBottom,
fontWeight: strong ? 'bold' : 'normal',
}}
>....
</Header>
);
Heading.defaultProps = {
children: <div />,
marginBottom: 4,
strong: false,
style: {},
};
Heading.propTypes = {
children: PropTypes.node,
marginBottom: PropTypes.number,
strong: PropTypes.bool,
style: stylePropType,
};
How can I combine the current style logic (marginBottom and fontWeight) with optionally additional styles passed in as a prop? Is there a way to combine the two or merge them?
You can use the spread syntax (...) on your passed in styles:
<Header
style={{
marginBottom,
fontWeight: strong ? 'bold' : 'normal',
...this.props.style
}}
>....
</Header>
Its base on https://github.com/react-native-training/reactxp-starter
Also I am new to TypeScript!
The renderIf is a regular js function, for some reason I got the error with type. I am not really clear where the type should have been to let the renderIf function run. Any thought or pointer will be great! Since ReactXP is really a thin wrapper above React Native.
Thanks!
/*
* This file demonstrates a basic ReactXP app.
*/
import RX = require('reactxp');
import renderIf = require('./util/renderIf');
//import { VirtualListView, VirtualListViewItemInfo } from 'virtuallistview';
const styles = {
container: RX.Styles.createViewStyle({
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#0a84c1'
}),
helloWorld: RX.Styles.createTextStyle({
color: 'white',
fontSize: 48,
fontWeight: 'bold',
marginBottom: 28
}),
welcome: RX.Styles.createTextStyle({
color: 'white',
fontSize: 32,
marginBottom: 12
}),
instructions: RX.Styles.createTextStyle({
fontSize: 16,
color: '#aaa',
marginBottom: 40
}),
docLink: RX.Styles.createLinkStyle({
fontSize: 16,
color: 'blue'
}),
emotionalInput: RX.Styles.createLinkStyle({
fontSize: 32,
height: 32,
}),
questionPage: RX.Styles.createTextStyle({
color: 'white',
fontSize: 48,
fontWeight: 'bold',
marginBottom: 28
}),
questionPageShow: RX.Styles.createTextStyle({
color: 'white',
fontSize: 48,
fontWeight: 'bold',
marginBottom: 28
}),
questionPageHide: RX.Styles.createTextStyle({
color: 'white',
fontSize: 48,
fontWeight: 'bold',
marginBottom: 28,
}),
};
// interface QuestionItem extends VirtualListViewItemInfo {
// text: string;
// }
interface QuestionProps {
}
interface QuestionState {
questionNow: number;
}
class App extends RX.Component<QuestionProps, QuestionState> {
private _translationValue: RX.Animated.Value;
private _translationValue2: RX.Animated.Value;
private _animatedStyle: RX.Types.AnimatedTextStyleRuleSet;
private _animatedStyleNextQuestion: RX.Types.AnimatedTextStyleRuleSet;
constructor() {
super();
this.state = {
questionNow: 1,
};
this._translationValue = new RX.Animated.Value(-100);
this._animatedStyle = RX.Styles.createAnimatedTextStyle({
transform: [
{
translateY: this._translationValue
}
]
});
this._translationValue2 = new RX.Animated.Value(-100);
this._animatedStyleNextQuestion = RX.Styles.createAnimatedTextStyle({
transform: [
{
translateY: this._translationValue2
}
]
});
}
componentDidMount() {
// let animation = RX.Animated.timing(this._translationValue, {
// toValue: 0,
// easing: RX.Animated.Easing.OutBack(),
// duration: 500
// }
// );
// animation.start();
let animationParalle = RX.Animated.parallel([
RX.Animated.timing(this._translationValue, {
toValue: 0,
easing: RX.Animated.Easing.OutBack(),
duration: 1000
}),
RX.Animated.timing(this._translationValue2, {
toValue: 0,
easing: RX.Animated.Easing.OutBack(),
duration: 3000
}),
]);
animationParalle.start();
}
guessResult(e: any) {
console.log(e);
}
pressAction(e: any) {
console.log(e);
}
goNext(event: any) {
console.log(event);
const newCount = this.state.questionNow + 1;
this.setState({
questionNow: newCount,
});
console.log(newCount);
}
render(): JSX.Element | null {
console.log(renderIf);
return (
<RX.View style={ styles.container }>
<RX.Animated.Text style={ [styles.helloWorld, this._animatedStyle] }>
Go Go Go
</RX.Animated.Text>
<RX.Animated.Text style={ [styles.questionPage, this._animatedStyleNextQuestion] }>
NEXT Question!
</RX.Animated.Text>
{renderIf(
this.state.questionNow === 1,
<RX.Text> New Stuff</RX.Text>
)}
{/*
Question 1
*/}
<RX.Text style={ styles.welcome }>
Question {this.state.questionNow}
How are you?
<RX.Button
style={ styles.welcome }
onPressOut={this.goNext.bind(this)}>
Great!
</RX.Button>
<RX.Button
style={ styles.welcome }
onPressOut={this.goNext.bind(this)}>
Great!
</RX.Button>
</RX.Text>
{/*
Question 2
*/}
<RX.Text style={ styles.welcome }>
Question {this.state.questionNow}
How are you?
<RX.Button
style={ styles.welcome }
onPressOut={this.goNext.bind(this)}>
Great!
</RX.Button>
<RX.Button
style={ styles.welcome }
onPressOut={this.goNext.bind(this)}>
Great!
</RX.Button>
</RX.Text>
<RX.TextInput style={ styles.emotionalInput } onChangeText={this.guessResult}/>
<RX.Text>Text</RX.Text>
</RX.View>
);
}
}
export = App;
error
ERROR in [at-loader] ./src/App.tsx:154:18
TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'typeof "/Users/app/src/util/renderIf"' has no compatible call signatures.
renderIf.ts
export default function renderIf(condition: any, content: any) {
if (condition) {
return content;
} else {
return null;
}
}
Wow.... its crazy, actually its because I did not add .default when I call renderIf.... BUT I can't really even do import renderIf = require('./util/renderIf').default; so I have to do import renderIf = require('./util/renderIf');.. which is strange