Stretch height to fit content in react native - javascript

I want to change the height of the modal to fit to the content. It always just goes to the height of the screen:
jsx:
<Modal style={styles.modal}
isVisible={props.categories.some(x => showModal(x))}>
<Container style={styles.modalView}>
<Header style={styles.header}>
<Left>
<Title
style={styles.title}>{getDisplayedCategoryLabel(props.categories)}
</Title>
</Left>
<Right>
<Button
small
transparent
danger
rounded
icon
onPress={() => props.setAllShowSubcategoriesToFalse()}>
<Icon name="times" size={20} color='#9E9E9E' />
</Button>
</Right>
</Header>
<Content >
<SelectMultiple
labelStyle={styles.label}
items={getDisplaySubcategories(props.categories)}
selectedItems={
props.categories.filter(category => category.selected)
}
onSelectionsChange={props.toggleSubcategory} />
</Content>
</Container>
</Modal>
styles:
const styles = {
modalView: {
flex: 1,
backgroundColor: '#FFFFFF',
padding: 20,
borderRadius: 8,
height: 100
},
modal: {
padding: 10,
height: 100
}
}
Changing the height of modal style doesn't do anything. I can't seem to change the height at all. What should I be doing to affect the height?
I'm using react-native-modal

How about something like:
<Modal transparent>
<View style={{ flex: 1, alignItems: 'center', backgroundColor: 'rgba(0,0,0,0.5)' }}>
{/* fill space at the top */}
<View style={{ flex: 1, justifyContent: 'flex-start' }} />
<View style={{ flex: 1, backgroundColor: 'white' }}>
{/* content goes here */}
</View>
{/* fill space at the bottom*/}
<View style={{ flex: 1, justifyContent: 'flex-end' }} />
</View>
</Modal>

This is just a guess but how about you give paddingTop a value of 0 and see how that works out. Remove the generic padding you have and specify it exactly using paddingLeft, paddingRight, paddingBottom according to the style you want to achieve.
Hopefully, that helps some bit

Related

react-native-paper Modal not hiding all others elements when visible

My modal does not go completely above all the other components under Android but works well under Ios.
I tried to change hierarchy of my components, play with zIndex and absolute position but my green button is always visible but not touchable when modal show up.
Modal not visible (Android & Ios):
Modal visible (Android) button is still visible:
Modal visible (Ios) button is NOT visible:
My component:
<View style={styles.container}>
<Spinner
visible={spinner}
textContent={'Recherche de jardins...'}
textStyle={styles.spinnerTextStyle}
/>
<View style={[styles.noThreadContainer, {flex: 5}]}>
<View style={styles.noThreadView}>
<Title style={styles.noThreadTitle}>
Personne autour de vous à {toKm(finalDistance)} km
</Title>
<Button icon="map-marker-distance" mode="contained" onPress={showModal}>
Modifier la distance
</Button>
</View>
</View>
<SliderModal style={{flex: 1}} />
</View>;
SliderModal:
const SliderModal = () => {
const minValue = 5000;
const maxValue = 200000;
const [kmValue, setKmValue] = useState(finalDistance || 5000);
return (
<Provider>
<Portal>
<Modal
visible={visible}
dismissable={false}
onDismiss={hideModal}
contentContainerStyle={styles.sliderContainer}>
<Title style={{alignSelf: 'center', marginBottom: 40}}>
Modifier la distance
</Title>
<View style={styles.kmContainer}>
<Text>{toKm(minValue)} km</Text>
<Title>{toKm(kmValue)} km</Title>
<Text>{toKm(maxValue)} km</Text>
</View>
<Slider
onValueChange={setKmValue}
value={finalDistance}
step={5000}
style={styles.slider}
minimumValue={minValue}
maximumValue={maxValue}
minimumTrackTintColor="brown"
maximumTrackTintColor="#77DD77"
/>
<View style={[styles.kmContainer, styles.buttonContainer]}>
<Button color="brown" onPress={hideModal}>
Fermer
</Button>
<Button
labelStyle={{color: 'white'}}
color="#77DD77"
mode="contained"
onPress={() => {
hideModal();
setFinalDistance(kmValue);
}}>
Valider
</Button>
</View>
</Modal>
</Portal>
</Provider>
);
};
StyleSheet:
const styles = StyleSheet.create({
container: {
flex: 1,
},
sliderContainer: {backgroundColor: 'white', padding: 20},
slider: {width: '100%', height: 40},
kmContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
},
buttonContainer: {
marginTop: 30,
},
noThreadView: {
alignSelf: 'center',
justifyContent: 'center',
width: width * 0.8,
},
noThreadContainer: {
flex: 1,
alignContent: 'center',
justifyContent: 'center',
},
noThreadTitle: {
marginBottom: 15,
alignSelf: 'center',
},
spinnerTextStyle: {
color: '#FFF',
},
});
Just before button add !visible, like this:
{ !visible && <Button icon="map-marker-distance" mode="contained" onPress={showModal}>
Modifier la distance
</Button>
}
Use react-native-modal Modal instead of react-native-paper Modal. The problem will gone after.
> npm i react-native-modal
import Modal from 'react-native-modal';
Close the server and re-run commmand
> npm run android
Or
> npx react-native run-android

.map() function displays my hidden animated view for each child in React Native. And I am using keys and id

I have a hidden animated view that displays when you click on the specific account name. Currently, when you click an account name, the animated hidden view displays for all the children in the .map() function. I tried adding the key and id to the animated view as well but that does not work either. Still shows the hidden animated view for all the children in the map.
<ScrollView style={{flex: 1}} showsVerticalScrollIndicator={true}>
{accounts.map(account => (
<View key={account.id} id={account.id}>
<View
style={{
width: '100%',
backgroundColor: colors.primary,
borderRadius: 10,
padding: 10,
marginBottom: 10,
marginTop: 10,
zIndex: 1,
}}>
<View
style={{
flex: 1,
flexDirection: 'row',
}}>
<Text
onPress={() => setHidden(!hidden)}
style={{
fontSize: 30,
textAlign: 'left',
flex: 1,
marginTop: 'auto',
marginBottom: 'auto',
}}>
{account.name}
</Text>
<View>
<Text
style={{
fontSize: 30,
textAlign: 'right',
flex: 1,
marginBottom: 10,
}}>
{account.amount}
</Text>
<View
style={{
flexDirection: 'row',
justifyContent: 'flex-end',
}}>
<DeleteAccount account={account.name} />
<Icon name="wrench" size={25} color="#000000" />
</View>
</View>
</View>
</View>
{hidden ? (
<Animated.View
key={account.id}
id={account.id}
style={[
styles.subView,
{transform: [{translateY: bounceValue}]},
]}>
<Text>{account.name}</Text>
</Animated.View>
) : null}
</View>
))}
</ScrollView>```

is there way to put text "cancel" and "ok" below the avatar buttons ? i mean that the avatar and the text need to be pressable when click

is there a way to put the text "cancel" and "ok" below the avatar button? I mean that the avatar and the text need to be pressable when click.
I can't put the text below to every button and I don't understand what is my mistake.
this is what I get now
but I need the text below to every button and also must be also pressable same the image (it should be part of the button)
this is my example of code :
const OrderInformationScreen = props => {
return (
<View
style={{
backgroundColor: '#00BFFF',
alignItems: 'flex-start',
justifyContent: 'center',
marginTop: 30,
borderBottomWidth: 2,
borderColor: 'blue',
flexDirection: "row",
justifyContent: 'space-evenly'
}}
>
<Avatar
size='large'
containerStyle={{ marginTop: 30 }}
activeOpacity={0.2}
rounded
source={require('../assets/down.png')} style={{ height: 80, width: 80 }}
onPress={() => console.log("cancel!")}
/>
<View >
<Text style={{ fontSize: 30 }}>cancel</Text>
</View>
<Avatar
size='large'
activeOpacity={0.2}
rounded
source={require('../assets/up.png')} style={{ height: 80, width: 80 }}
onPress={() => console.log("Works!")}
/>
<View>
<Text style={{ fontSize: 30 }}>ok</Text>
</View>
</View>
);
};
I think the best option is wrapping the avatar and the text by TouchableOpacity.
<TouchableOpacity onPress={() => console.log("cancel!")}>
<Avatar
size='large'
containerStyle={{ marginTop: 30 }}
activeOpacity={0.2}
rounded
source={require('../assets/down.png')} style={{ height: 80, width: 80 }}
/>
<View >
<Text style={{ fontSize: 30 }}>cancel</Text>
</View>
</TouchableOpacity>
I recommend to write your own styles by using basic react native elements. Try to use least number of 3rd party plugins. Good luck.
It is like that because of the styles you have given to view. You have given a flex direction row which will place all your elements in a row. You have given four elements in your root view which has style flex-direction row so all four elements in that view (2 Avatar component and 2 text) will be placed side by side in a row.
if you want text below image i thin you should put avatar and text box in a view and give that a view a flex-direction column like:
<View style={{flexDirection: 'row', justifyContent: 'space-evenly'}}>
<TouchableOpacity onPress={() => console.log("cancel!")>
<View style={{flexDirection: 'column', justifyContent: 'space-evenly'}}>
<Avatar>
<View>
<Text />
</View>
<View>
</TouchableOpacity>
<TouchableOpacity onPress={() => console.log("works!")>
<View style={{flexDirection: 'column', justifyContent: 'space-evenly'}}>
<Avatar>
<View>
<Text />
</View>
<View>
</TouchableOpacity>
<View>
hope this helps in someway :)
The best option is Wrapping the avatar and text with TouchableOpacity. and Add some more Styles like below
<TouchableOpacity style={{
backgroundColor: '#00BFFF',
display : "flex",
alignItems: 'flex-start',
justifyContent: 'center',
marginTop: 30,
borderBottomWidth: 2,
borderColor: 'blue',
}} onPress={() => {}>
<Avatar
size='large'
containerStyle={{ marginTop: 30 }}
activeOpacity={0.2}
rounded
source={require('../assets/down.png')} style={{ height: 80, width: 80 }}
/>
<View >
<Text style={{ fontSize: 30 }}>cancel || ok</Text>
</View>
</TouchableOpacity>

Vertically align items in the center inside flew direction row

I have some icon buttons inside a view which is pushed to the right of the container by flex direction row on the parent. Currently I cannot align them vertically in the middle of the container. Here is the code I have:
JSX:
<View style={styles.groupContainer}>
<View style={styles.groupTextContainer}>
<Text style={styles.groupText}>{title.toUpperCase()}</Text>
</View>
<View style={styles.groupButtonsContainer}>
<Icon
key={name + type}
onPress={onPress}
style={{marginLeft: 8}}
name={name}
type={type}
color='silver' />
<Icon
key={name + type}
onPress={onPress}
style={{marginLeft: 8}}
name={name}
type={type}
color='silver' />
</View>
</View>
styles:
groupContainer: {
backgroundColor: '#ddd',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
groupText: {
fontWeight: 'bold',
color: '#808080',
},
groupTextContainer: {
padding: 10,
alignSelf: 'flex-start',
},
groupButtonsContainer: {
alignSelf: 'flex-end',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
}
UPDATE
Forgot to mention that Icon is a react-native-elements component.
I need it to look like this:
But I get this:
<View style={styles.groupContainer}>
<View style={styles.groupButtonsContainer}>
<Text style={styles.groupText}>{title.toUpperCase()}</Text>
<Icon
key={name + type}
onPress={onPress}
style={{marginLeft: 8}}
name={name}
type={type}
color='silver' />
</View>
</View>
mybe you can follow this code and you restyle from text

React-native view auto width by text inside

As far as I know, react-native stylesheet doesn't supports min-width/max-width property.
I have a view and text inside. The view in auto width doesn't resize by inherit text element.
How to fix that issue and make view width automatically set using text width?
My code is:
<View style={{backgroundColor: '#000000'}}>
<Text style={{color: '#ffffff'}}>Sample text here</Text>
</View>
In common HTML/CSS I would realize so:
<div style="background-color: #000; display: inline;">Sample text here</div>
Notice: flex: 1 on parent view is not helpful for me.
Text appears as
"Sam"
"ple"
"Tex"
"t"
"alignSelf" does the same as 'display: inline-block' would in common HTML/CSS and it works very well for me.
<View style={{backgroundColor: '#000000', alignSelf: 'flex-start' }}>
<Text style={{color: '#ffffff'}}>
Sample text here
</Text>
</View>
Two Solutions
Text component fits the text content
https://facebook.github.io/react-native/docs/text.html#containers
You can wrap <Text> components into another <Text> component.
By doing this everything inside is no longer using the flexbox layout but using text layout.
<Text>
<Text>{'Your text here'}</Text>
</Text>
View container adapt to nested Text component's content
In that case you need to use the props alignSelf in order to see the container shrink to the size of its content.
<View>
<View style={{ alignSelf: 'center', padding: 12}} >
<Text>{'Your text here'}</Text>
</View>
</View>
tldr: set alignItems to any value other than 'stretch' for the style of the parent View of your View containing Text
The issue your facing is likely related to React Native's default value for alignItems: 'stretch' on a <View /> element. Basically, all <View /> elements by default cause their children to stretch along the cross axis (axis opposite to the flexDirection). Setting alignItems to any value other than "stretch" ("baseline", "flex-start", "flex-end", or "center") on the parent View prevents this behavior and addresses your problem.
Below is an example where there are two View elements contained inside of a parent View with a blue border. The two View elements each contain a View wrapped around a Text element. In the case of the first View with default styling, the yellow child View expands horizontally to fill the entire width. In the second View where alignItems: 'baseline', the pink View does not expand and stays the size of it's child Text element.
<View style={{ borderWidth: 5, borderColor: 'blue' }}>
<View>
<View style={{ backgroundColor: 'yellow' }}>
<Text style={{ fontSize: 30 }}>Hello</Text>
</View>
</View>
<View style={{ alignItems: 'baseline' }}>
<View style={{ backgroundColor: 'pink' }}>
<Text style={{ fontSize: 30 }}>Hello</Text>
</View>
</View>
</View>
The align-items property is explained well here.
If you want to apply width to View based on <Text> , you can do something like this :
<View style={styles.container}>
<Text>
{text}
</Text>
</View>
const styles = StyleSheet.create({
container: {
flexDirection:"row",
alignSelf:"flex-start",
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
}
});
WORKING DEMO
This work for me.
<View style={{alignSelf: 'flex-start', backgroundColor: 'red'}}>
<Text>abc</Text>
</View>
Or simply:
<Text style={{color: '#ffffff', alignSelf: 'center'}}>Sample text here</Text>
Try this way for your requirement:
Here my height is Constant and i am enlarging the width by the length of text.
<View style={{flexDirection: 'row'}}>
<View style={{
height: 30, width: 'auto', justifyContent:'center',
alignItems: 'center'}}>
<Text style={{color:'white'}}>Now View will enlarge byitself</Text>
</View>
</View>
For Both Height and Width Try Changing the height inside the View style to 'auto' full code bellow:
<View style={{flexDirection: 'row'}}>
<View style={{
height: 'auto', width: 'auto', justifyContent:'center',
alignItems: 'center'}}>
<Text style={{color:'white'}}>Now View will enlarge byitself</Text>
</View>
</View>
Also try Giving padding to the View for arrange the text properly.
It works with Nicholas answer unless you want to center the view somewhere. In that case, you could add a wrapper view around the view to obtain the width of its content and set alignItems: 'center'. Like this:
<View style={{ flex: 1, alignItems: 'center' }}>
<View style={{ justifyContent: 'center', alignItems: 'center', backgroundColor: 'red' }}>
<Text>{'Your text is here'}</Text>
</View>
</View>
The background color is added to show the size of the inner view
Just add alignSelf to the text style, it won't take the whole width
<View style={{flex: 1}}>
<Text style={{alignSelf: 'center'}}>{'Your text here'}</Text>
<Text style={{alignSelf: 'baseline'}}>{'Your text here'}</Text>
<Text style={{alignSelf: 'flex-end'}}>{'Your text here'}</Text>
<Text style={{alignSelf: 'flex-start'}}>{'Your text here'}</Text>
</View>
These worked for me
<View style={styles.imageCancel}>
<TouchableOpacity onPress={() => { this.setModalVisible(!this.state.visible) }}>
<Text style={styles.textCancel} >Close</Text>
</TouchableOpacity>
</View>
const styles = StyleSheet.create({
imageCancel: {
height: 'auto',
width: 'auto',
justifyContent:'center',
backgroundColor: '#000000',
alignItems: 'flex-end',
},
textCancel: {
paddingTop:25,
paddingRight:25,
fontSize : 18,
color : "#ffffff",
height: 50,
},
}};

Categories

Resources