Can't format Quran page in react native - reactjs

I am making an app to read Quran, using react native (expo). I am having some problems formatting the text.
Problems:
Random spacing
Text resize automatically
Text aligns on the left side at the end.
Here is my code:
function Read(){
return (
<SafeAreaView style={styles.container}>
<HeaderSurahScreen navigation={navigation} route={route} />
<Divider
orientation="vertical"
width={5}
style={{ borderBottomColor: "#545353" }}
/>
{/* create a logic here to display tranlition or arabic */}
<ScrollView style={styles.scroll}>
<Text style={styles.surahPage} adjustsFontSizeToFit>
{surah &&
surah.map((ayat, index) => (
<Text key={index} allowFontScaling={false} selectable={true}>
<Text selectable={true} style={styles.ayat}>
{ayat.text}
</Text>
<Text style={styles.number}>{toArabic(ayat.id)}۝</Text>
</Text>
))}
</Text>
</ScrollView>
<StatusBar style="auto" />
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: DEFAULT_BACKGROUND_COLOR_THEME,
},
scroll: {
flex: 1,
padding: 7,
},
surahPage: {
flex: 1,
marginTop: 15,
textAlign: "justify",
},
ayat: {
flex: 1,
fontFamily: ARABIC_FONT,
color: DEFAULT_COLOR_THEME,
fontSize: 30,
},
number: {
fontSize: 18,
color: DEFAULT_COLOR_THEME,
},
});
Screenshots(3):
The result I am looking for:

To make the text align in your text, you need to use justify to make all the lines have the same length, but also you need to add one attribute direction to make the justification to the right side.
direction: "rtl";
textAlign: "justify"
You may want to have a look at this:
http://jsfiddle.net/aew75/
Unfortunately, I fear I know no way of fixing the problem of the spaces between words coming from justify. There is no way to expand the letters size and width as in the mushaf. This can be a revolutionary idea of arabic fonts usage on the web and dispalys in general.
Maybe give it a shot and have other muslim / arab developers contribute :)

justify will do the job (except the last line) ,i think this what you are asking for
To solve this you should import I18nManager library from react-native,then:
In useEffect write this line :
I18nManager.forceRTL(true);
considering big spaces between words , i used to manage it as possible in styling the text like this :
letterSpacing: -3
change -3 to any other values below 0 ,this will narrow spaces between words as possible
that worked for me

Related

In NativeBase, how can I avoid inline styling props of component and write it separately and then pass it

I am just trying to write a clean code and avoid lots thing in same tag. For example: Text and Box component have could have so many styling props, So is there any way I can write it separately and they pass it as a whole object as style.
import { Box, extendTheme, NativeBaseProvider, Progress, Text, View } from 'native-base'
import React, { FC } from 'react'
const TrainingList: FC = () => {
return (
<NativeBaseProvider>
<Box my="2">
<Text fontSize="16" lineHeight="21.8" bold> Annual Training </Text>
<View my="2" >
<Text fontSize="14" lineHeight="19.8"> Due in 2 days (01/12/22) </Text>
<Text fontSize="14" lineHeight="19.8"> 50% complete / 10 hrs left </Text>
</View>
<Progress rounded="12" colorScheme="warning" bg="#D7D7D7" size="sm" value={65} mx={0} />
</Box>
<Box mt="5">
This is Box2
</Box>
</NativeBaseProvider>
)
}
export default TrainingList
In my eyes, the best approach will be to add variants to the NativeBase Text and Box component. It'll keep your code but also you'll be able to share consistent style throughout the codebase.
And if you wanna know HOW? I'm sharing a few resources to follow.
Resource:
Official Docs: First place to go.
Snack: A demo snack to show how to add variants.
Blog: To better understand how to effectively customise NativeBase components.
You can use StyleSheet for that. You can use what you defined under styles on components.
import React from "react";
import { StyleSheet, Text, View } from "react-native";
const App = () => (
<View style={styles.container}>
<Text style={styles.title}>React Native</Text>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 24,
backgroundColor: "#eaeaea"
},
title: {
marginTop: 16,
paddingVertical: 8,
borderWidth: 4,
borderColor: "#20232a",
borderRadius: 6,
backgroundColor: "#61dafb",
color: "#20232a",
textAlign: "center",
fontSize: 30,
fontWeight: "bold"
}
});
export default App;
Yes, that's possible using styled components. You can accept props inside of your styling. Alternatively, I prefer using stylesheets as it's simpler and still keeps your code clean. Ex:
<Box style={styles.boxMain}>
<Text style={styles.textOneStyle}> Annual Training </Text>
<View my="2">
<Text style={styles.textTwoStyle}> Due in 2 days (01/12/22) </Text>
<Text style={styles.textTwoStyle}> 50% complete / 10 hrs left </Text>
</View>
</Box>
);
};
const styles = StyleSheet.create({
textOneStyle: {
fontSize: 16,
lineHeight: 21.8,
fontWeight: "bold"
},
textTwoStyle: {
fontSize: 14,
lineHeight: 19.8,
},
});

Why react-native-calendar-picker is wrapping other elements in itself?

Hi I am new to react native. I was trying to add a calendar date picker to the app which worked fine with
react-native-calendar-picker
However I tried adding another view below it, but, elements are not adding outside, instead, the calendar element is getting longer in height and hiding whatever i add after it.
<ScrollView style={styles.scrollMain} >
<Text style={{fontSize:15}}>Mark the dates and time you are available</Text>
<View style={styles.nurseCalendar} >
<CalendarPicker
dayShape='circle'
todayBackgroundColor={'#88B3F9'}
selectedDayTextColor={"#FFFFFF"}
selectedDayStyle={styles.calendarStyle}
nextTitle='>>>'
width={340}
height={342}
restrictMonthNavigation={true}
minDate={Date.now()}
onDateChange={this.handleDateChange}
previousTitle='<<<'
></CalendarPicker>
</View>
<View>/** no matter what i add here won't show however the view above will increase in height **/</View>
</ScrollView>
Here are the style properties i am using:
scrollMain:{
alignContent:'center',
flexDirection:'column',
paddingTop:25,
paddingLeft:25,
paddingRight:25,
backgroundColor:'#F7F9FC'
},
nurseCalendar:{
width:'90%',
alignSelf:'center',
marginTop:25,
height:'100%',
backgroundColor:'#fff',
flexWrap:'wrap'
},
calendarStyle:{
borderColor: '#6574CF',
backgroundColor: 'dodgerblue',
color: 'white',
borderWidth: 2,
borderRadius: 50,
}

Create a dynamic width TextInput that is centered to the middle of the screen

I have a certain problem that I am facing and would like to see whether or not what I am facing is a react-native bug that needs submission to the react-native issues or if it is an error on my part.
I am trying to create a TextInput that is centered to my screen and is supposed to be able to grow in width as one types into it, once enough text is written it wraps to the next line. I am facing a problem that as one types in the TextInput the text appears first and then changes the size of the view causing a flicker and words typed to disappear and then reappear. Eventually the UI settles correctly and appears correct, but as one types the previous written characters can flow to be greater than the width of the View despite the View has no limit to width. I know I have figured out this is due to the parent have a alignItems property that makes the children (in this case the TextInput) centered.
The goal is to make the view expanded in width along side the text being written without this flickering bug.
return (
<KeyboardAvoidingView behavior="height" keyboardVerticalOffset={Platform.OS === 'ios' > 0 : 24} style={styles.flex1}>
<View style={styles.addingText}>
<TextInput
multiline
returnKeyType="done"
blurOnSubmit={true}
textAlignVertical="center"
style={styles.defaultAddingText}
autoFocus={addingText}
selectionColor="#3C99FF"
underlineColorAndroid="transparent"
value={text}
onChangeText={handleTextChange}
onSubmitEditing={handleSubmit}
/>
</View>
</KeyboardAvoidingView>
);
const styles = StyleSheet.create({
flex1: {
flex: 1,
},
addingText: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
zIndex: 100,
},
defaultAddingText: {
paddingHorizontal: 10,
borderRadius: 10,
},
});
Give a height to your defalutAddingText style as following,
const styles = StyleSheet.create({
flex1: {
flex: 1,
},
addingText: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
zIndex: 100,
},
defaultAddingText: {
height:auto,
paddingHorizontal: 10,
borderRadius: 10,
},
});

Dynamic view according to the length of the text

I am developing an App with react native and I have graphical problem. I need to have a dynamic yellow bar(which is in a view) for my text as below:
So, it means that if I have a longer text, the bar should be longer and if the text is shorter, the bar also should be shorter and fit for it. By now I use the static method. I give 90 as the width to the bar which is not good. Here is the code:
<View style={[styles.rowSep, {width:90}]}/>
<Text style={[commonStyle.normalItem , {marginBottom:10}]}>
{I18n.t("Il_Museum_Modena")}
</Text>
Here is the style:
rowSep: {
height: 7,
marginVertical: 4,
//width: Dimensions.get('window').width,
backgroundColor: '#FABB00',
marginBottom:12,
},
Can you help me to have dynamic yellow bar based on the length of the text. Thanks in advance.
You can wrap Text with View and set view StyleSheet to get effect what you want.
Example:
<View style={styles.textwrapper}>
<Text>Just test</Text>
</View>
Style:
textwrapper: {
borderBottomWidth: 5px,
borderBottomColor: #234532,
borderStyle: 'solid'
}
I haven't test this code, but I hope this give you some hints.

React-Native Button style not work

Import_this
import {AppRegistry, Text, View, Button, StyleSheet} from 'react-native';
This my React Button code But style not working Hare ...
<Button
onPress={this.onPress.bind(this)}
title={"Go Back"}
style={{color: 'red', marginTop: 10, padding: 10}}
/>
Also I was try by this code
<Button
containerStyle={{padding:10, height:45, overflow:'hidden',
borderRadius:4, backgroundColor: 'white'}}
style={{fontSize: 20, color: 'green'}}
onPress={this.onPress.bind(this)} title={"Go Back"}
> Press me!
</Button>
Update Question:
Also I was try by This way..
<Button
onPress={this.onPress.bind(this)}
title={"Go Back"}
style={styles.buttonStyle}
>ku ka</Button>
Style
const styles = StyleSheet.create({
buttonStyle: {
color: 'red',
marginTop: 20,
padding: 20,
backgroundColor: 'green'
}
});
But No out put:
Screenshot of my phone:-
The React Native Button is very limited in what you can do, see; Button
It does not have a style prop, and you don't set text the "web-way" like <Button>txt</Button> but via the title property <Button title="txt" />
If you want to have more control over the appearance you should use one of the TouchableXXXX' components like TouchableOpacity
They are really easy to use :-)
I had an issue with margin and padding with a Button. I added Button inside a View component and apply your properties to the View.
<View style={{margin:10}}>
<Button
title="Decrypt Data"
color="orange"
accessibilityLabel="Tap to Decrypt Data"
onPress={() => {
Alert.alert('You tapped the Decrypt button!');
}}
/>
</View>
React Native buttons are very limited in the option they provide.You can use TouchableHighlight or TouchableOpacity by styling these element and wrapping your buttons with it like this
<TouchableHighlight
style ={{
height: 40,
width:160,
borderRadius:10,
backgroundColor : "yellow",
marginLeft :50,
marginRight:50,
marginTop :20
}}>
<Button onPress={this._onPressButton}
title="SAVE"
accessibilityLabel="Learn more about this button"
/>
</TouchableHighlight>
You can also use react library for customised button .One nice library is react-native-button (https://www.npmjs.com/package/react-native-button)
If you do not want to create your own button component, a quick and dirty solution is to wrap the button in a view, which allows you to at least apply layout styling.
For example this would create a row of buttons:
<View style={{flexDirection: 'row'}}>
<View style={{flex:1 , marginRight:10}} >
<Button title="Save" onPress={() => {}}></Button>
</View>
<View style={{flex:1}} >
<Button title="Cancel" onPress={() => {}}></Button>
</View>
</View>
Instead of using button . you can use Text in react native and then make in touchable
<TouchableOpacity onPress={this._onPressButton}>
<Text style = {'your custome style'}>
button name
</Text>
</TouchableOpacity >
Style in button will not work, You have to give style to the view.
<View style={styles.styleLoginBtn}>
<Button
color="orange" //button color
onPress={this.onPressButton}
title="Login"
/>
</View>
Give this style to view
const styles = StyleSheet.create({
styleLoginBtn: {
marginTop: 30,
marginLeft: 50,
marginRight: 50,
borderWidth: 2,
borderRadius: 20,
borderColor: "black", //button background/border color
overflow: "hidden",
marginBottom: 10,
},
});
Only learning myself, but wrapping in a View may allow you to add styles around the button.
const Stack = StackNavigator({
Home: {
screen: HomeView,
navigationOptions: {
title: 'Home View'
}
},
CoolView: {
screen: CoolView,
navigationOptions: ({navigation}) => ({
title: 'Cool View',
headerRight: (<View style={{marginRight: 16}}><Button
title="Cool"
onPress={() => alert('cool')}
/></View>
)
})
}
})
Try This one
<TouchableOpacity onPress={() => this._onPressAppoimentButton()} style={styles.Btn}>
<Button title="Order Online" style={styles.Btn} > </Button>
</TouchableOpacity>
You can use Pressable with Text instead of button.
import { StyleSheet, Text, View, Pressable } from 'react-native';
<Pressable style={styles.button} onPress = {() => console.log("button pressed")}>
<Text style={styles.text}>Press me</Text>
</Pressable>
Example Style:
const styles = StyleSheet.create({
button: {
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 12,
paddingHorizontal: 32,
borderRadius: 4,
elevation: 3,
backgroundColor: 'red'
},
text: {
fontSize: 16,
lineHeight: 21,
fontWeight: 'bold',
letterSpacing: 0.25,
color: 'white',
},
});
We can use buttonStyle prop now.
https://react-native-training.github.io/react-native-elements/docs/button.html#buttonstyle
React-native button is very limited, it won't allow styling. use react native elements button or create custom button
button styles does'nt work in react-native, to style your button in react-native easy way is to put it inside the View block like this:
<View
style={styles.buttonStyle}>
<Button
title={"Sign Up"}
color={"#F31801"}/>
</View>
style.buttonStyle be like this:
style.buttonStyle{
marginTop:30,
marginLeft:50,
marginRight:50,
borderWidth:2,
borderRadius:20,
borderColor:'#F31801',
overflow:"hidden",
marginBottom:10,
}
, it will make you able to use designs with buttons
As the answer by #plaul mentions TouchableOpacity, here is an example of how you can use that;
<TouchableOpacity
style={someStyles}
onPress={doSomething}
>
<Text>Press Here</Text>
</TouchableOpacity>
SUGGESTION:
I will recommend using react-native-paper components as they are modified and can be modified much more than react-native components.
To install;
npm install react-native-paper
Then you can simply import them and use.
More details here Here
Wrap the button component inside a view component and change the styles of the view component, it should work. Please refer to the snippet below
<View style={{width: 150, alignSelf: 'center'}}>
<Button onPress={demoFunction} title="clickMe!!" />
</View>
I know this is necro-posting, but I found a real easy way to just add the margin-top and margin-bottom to the button itself without having to build anything else.
When you create the styles, whether inline or by creating an object to pass, you can do this:
var buttonStyle = {
marginTop: "1px",
marginBottom: "1px"
}
It seems that adding the quotes around the value makes it work. I don't know if this is because it's a later version of React versus what was posted two years ago, but I know that it works now.

Resources