How to grey out the background while spinner is running in React - css

How to grey out the background application or screen while spinner is running in React.
Everything is working fine but screen is not grey out in code
{
loading ? <Spinner animation="border" variant="success" /> : (<Modal></Modal>)
}
my css part is
.spinner-border{
width: 6rem !important;
height: 6rem !important;
left: 880px;
position: absolute;
top: 33%
}

Enclose everything in a view and place the backgroundColor in rgba, if necessary, place the view with zindex -1
<View style={{ flex: 1, backgroundColor: 'rgba(0,0,0,0.6)', alignItems: "center", justifyContent: "center" }}>
<Spinner animation="border" variant="success" />
</View>

You need to use opacity - you can't do it with a backgroundColor unless you position the whole View over your original View with position: absolute which will be difficult especially if your View is dynamic.
Just enclose everything in this and spinning will decide if you grey out or not:
React Native:
<View
pointerEvents={spinning > 0 ? 'none' : 'auto'}
style={{ flex: 1, opacity: spinning > 0 ? 0.25 : 1}}>
<...usual components />
</View>
pointerEvents will disable all touch events
React.js:
<div
style={{
opacity: spinning > 0 ? 0.25 : 1,
pointerEvents: spinning > 0 ? 'none' : 'auto'
}}>
<...usual components />
</div>

Related

Centering Buttons in Material-UI and React

I have successfully centered the Hello There button.
But my problem is, a little bit of lines are appearing on it.
I could put a background-color: white to solve it, but is there a better way to do this and a better coding? Like not using position: absolute etc....?
CLICK HERE FOR CODESANDBOX
<Stack
alignItems={"center"}
sx={{
marginTop: 2,
position: "absolute",
display: "flex",
left: 0,
right: 0
}}
>
<Button variant="outlined">Hello There</Button>
</Stack>
The Button variant you are using is the varian="outlined" which has a transparent background. So when is positioned above the dashed border they are shown behind it. In this case if you wan to keep this style of Button you have to add a background-colour of white to it.
Another option would be to use the contained variant like below but this would change the style of the button.
<Button variant="contained">
Hello there
</Button>
UPDATED:
or (for any reason you don't want to add the background colour to the button) you can add using :after or :before at the button, an element that will be behind the button and hide the dashed border. As a solution is not optimal as this will not work for dynamic backgrounds, or if they have an image or even a gradient color.
<Button
variant="outlined"
sx={{
position: "relative",
zIndex: "1",
"&:before": {
content: `''`,
background: "white",
width: "100%",
height: "10px",
position: "absolute",
zIndex: "-1"
}
}}
>
Hello There
</Button>
I think your question should be clearer but here is the answer of what I am thinking.
<Stack
sx={{
marginTop: 2,
position: "absolute",
width: "100%"
}}
>
<Button
variant="outlined"
sx={{
margin: "0px auto"
}}
>
Hello There
</Button>

Next.js Image Fill in Masonry List

I'm facing issue where normal HTML img tag works just fine inside my Masonry List, but when I'm using Next.js Image Component with layout fill, it doesn't render anything.
My Styles:
const ImageList = styled('ul', {
columnCount: 3,
columnGap: 10,
display: 'block',
listStyleType: 'none',
overflowY: 'auto',
padding: 0,
margin: 0
})
const ImageListItem = styled('li', {
position: 'relative',
display: 'inline-block',
lineHeight: 0,
height: 'auto',
marginBottom: 10
})
HTML Skeleton:
<ImageList>
{detailImage.map((image, idx) => {
return (
<ImageListItem key={`_${idx}`}>
<Image
src={image.src}
alt={image.alt}
blurDataURL={image.blurDataURL}
placeholder={'blur'}
layout={'fill'}
objectFit={'cover'}
/>
{/* <img
src={image.src}
style={{
width: '100%',
height: '100%',
objectFit: 'cover'
}}
/> */}
</ImageListItem>
)
})}
</ImageList>
EDIT
Because I'm getting all images from CMS and have width/height I used the padding-top trick to create box and then I use next/image with object-fit: cover.
Code Example:
<ImageListItem key={`_${idx}`}>
<Box
css={{
display: 'inline-flex',
pt: `${100 / (image.width! / image.height!)}%`
}}
>
<Box css={{ position: 'absolute', inset: 0, m: 0 }} as={'figure'}>
<Image
src={image.src}
alt={image.alt}
blurDataURL={image.blurDataURL}
placeholder={'blur'}
layout={'fill'}
objectFit={'cover'}
/>
</Box>
</Box>
</ImageListItem>
When you use layout='fill' it's necesary a parent container for each image and this container needs to have position: relative;. Maybe it doesn't show anything because its parent elements don't have the width property.
This is the description in the documentation:
When fill, the image will stretch both width and height to the
dimensions of the parent element, provided the parent element is
relative. This is usually paired with the objectFit property. Ensure
the parent element has position: relative in their stylesheet.

MUI Card text overlay

I'm using the MUI Card and CardMedia components in my app but can't figure out how to overlay text on top of the image. This is a simplified example of what I'm trying:
<Card>
<CardMedia image={this.props.preview} style={styles.media}/>
<div style={styles.overlay}>
this text should overlay the image
</div>
</Card>
const styles = {
media: {
height: 0,
paddingTop: '56.25%' // 16:9
},
overlay: {
position: 'relative',
top: '20px',
left: '20px',
color: 'black',
backgroundColor: 'white'
}
}
I've tried placing the text div in above the CardMedia, below it, inside it, outside the Card entirely, and using different position values but can't figure this out at all. The beta versions of MUI included an overlay property on the CardMedia, but the v1 library doesn't seem to have anything like that.
Any know how to properly do this? Thanks in advance for any help!
Your CSS is off, you'll want to absolutely position the styles.overlay, and make sure the Card is position relative
Try something like this:
<Card style={styles.card}>
<CardMedia image={this.props.preview} style={styles.media}/>
<div style={styles.overlay}>
this text should overlay the image
</div>
</Card>
const styles = {
media: {
height: 0,
paddingTop: '56.25%' // 16:9
},
card: {
position: 'relative',
},
overlay: {
position: 'absolute',
top: '20px',
left: '20px',
color: 'black',
backgroundColor: 'white'
}
}
Use the code below if you want to have an overlay like the Card in version 0. Remember to set the position of the container to relative so the absolute position of the overlay can take effect:
<Card sx={{ maxWidth: 345 }}>
<Box sx={{ position: 'relative' }}>
<CardMedia
component="img"
height="200"
image="https://mui.com/static/images/cards/contemplative-reptile.jpg"
/>
<Box
sx={{
position: 'absolute',
bottom: 0,
left: 0,
width: '100%',
bgcolor: 'rgba(0, 0, 0, 0.54)',
color: 'white',
padding: '10px',
}}
>
<Typography variant="h5">Lizard</Typography>
<Typography variant="body2">Subtitle</Typography>
</Box>
</Box>
{...}
</Card>

How do I create this layout in Flexbox?

I'm trying to create this layout in Flexbox (and React Native) but I can't get it to work. Specifically, the Left and Right buttons refuse to expand to 50% of the width of the container no matter what I do. They are always the size of their content.
I'm using nested containers. The buttons are in a columnar Flex container which is nested in a row Flex container that also contains the image.
Here is my JSX:
<View style={{
display: 'flex',
flex: 1,
flexDirection: 'column'}}>
<Image
style={{flex: 1, zIndex: 1, width: '100%', height: '100%'}}
resizeMode='cover'
resizeMethod='resize'
source={require('./thumbs/barry.jpg')}
/>
<View style={{
display: 'flex',
flexDirection: 'row',
flex: 0,
width: '100%',
height: 100}} >
<Button style='flex: 1' title="LEFT" onPress={() => {}} />
<Button style='flex: 1' title="RIGHT" onPress={() => {}} />
</View>
</View>
All replies are much appreciated...
Maybe this will help you:
.container{
display: flex;
flex-wrap: wrap;
width: 500px;
}
.image{
height: 500px;
flex-basis: 100%;
background-color: green;
}
.button{
box-sizing: border-box;
flex-basis: 50%;
height: 100px;
background-color: red;
border: solid 1px black;
}
<div class="container">
<div class="image"></div>
<div class="button"></div>
<div class="button"></div>
</div>
If you ever have issues with using flexbox, use this resource, it's really helpful for solving flexbox issues. Hopefully you can solve your problem now.
You dont want to use height properties, but using it is a good way to achieve what you want. Here is an example:
You set the image to 90% of the screen height and the buttons container to 10%.
Each button has 50% width
HTML
<div class="container">
<div class="image"></div>
<div class="buttons-container">
<button>Action 1</button><button>Action 2</button>
</div>
</div>
CSS
* {
box-sizing: border-box;
}
body, html {
height: 100%;
margin: 0;
}
.container {
position: relative;
width: 100%;
height: 100%;
}
.container .image {
width: 100%;
height: 90%;
background-image: url('path/to/image');
position: relative;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.container .buttons-container {
display: flex;
height: 10%;
}
.container .buttons-container button {
width: 50%;
}
Check the example working - https://codepen.io/kaiten/pen/YaYqZO
In consideration of the fact that your code is required in react-native and not react, try this piece of code
<View style={flex:1}>
<Image source={require(path)} style={flex:1}>
<View style={flex:1}>
<View style={flex:1}>
<Button style={flex:1,height:100} title='Left'/>
</View>
<View style={flex:1}>
<Button style={flex:1,height:100} title='Right'/>
</View>
</View>
</View>
Explanation : In react-native you do not need to mention display:flex in your styles since react-native always uses flexBox. When you do flex:1 your container always takes the 100% of the width and the height of it's parents hence doing flex:1,height:'100%',width:'100%' is invalid.
In your
<View style={{
display: 'flex',
flexDirection: 'row',
flex: 0,
width: '100%',
height: 100}} >
you've done flex:0 so this is the equivalent of width:'0%',height:'0%'
Hope this gives you some clarity on the code required.
PS: There might be a possibility that the code i wrote might not work properly due to the <Image> width and height. For eg : If the height of the image decreases and you've given fixed height to your buttons then there might be some white space below your buttons since the height of the <Image> plus the height of the <Button> will not add up to the height of the screen visible.
It seems like Button component do not take style as prop if we look at the codebase of React Native. So the problem is button is not accepting style. So I wrapped button with a view.
Here is sample of working code:
<View style={{
flex: 1,
}}>
<Image
style={{ flex:1, zIndex: 1, width: '100%', height: '100%'}}
resizeMode='cover'
resizeMethod='resize'
source={require('./thumbs/barry.jpg')}
/>
<View style={{
flexDirection: 'row',
height: 100}} >
<View style={{flex:1}}>
<Button title="LEFT" onPress={() => {}} />
</View>
<View style={{flex:1}}>
<Button title="RIGHT" onPress={() => {}} />
</View>
</View>
</View>

MUI Progress Indicator center align horizontally

Stack: Meteor + React + MUI
Here's my full code of my 'main' renderer components:
// Sorry for not giving material-UI CSS,
// cause it cannot be served as stand-alone CSS
render() {
return (
<div className = "container">
<AppBar title = "test" />
<Tabs /> // Tab contents goes here
<RefreshIndicator
left={70} // Required properties
top={0} // Required properties
status="loading"
style={{
display: 'inline-block',
position: 'relative',
margin: '0 auto' }} />
</div>
);
},
I want to make Refresh Indicator horizontally center aligned beneath of myTabs like this whirling circle in this picture :
In the document of MUI here, this indicator comes with following styles:
display: 'inline-block',
position: 'relative',
With this styles I cant align it center horizontally, and without this styles, I can`t even locate it where I wanted.
What I have tried :
margin: 0 auto --> failed
text-align: center --> failed
display: flex --> failed
combination of 1 & 2 --> failed
left={$(window).width/2-20} --> This works but I'd like to use CSS only
The solution below centres progress indicator without any hacky calculations that cause element to be offset:
<div style={{display: 'flex', justifyContent: 'center'}}>
<RefreshIndicator status="loading" />
</div>
Here is how I did to ensure it's horizontally centered. Works great for me.
Set the parent component style to position: 'relative'.
Set the refresh indicator style to marginLeft: '50%', and left={-20} (assuming the size is 40).
here is the code (I put it in a CardText component).
...
<CardText style={{position: 'relative'}}>
<RefreshIndicator
size={40}
left={-20}
top={10}
status={'loading'}
style={{marginLeft: '50%'}}
/>
</CardText>
...
In MUI v5, there is a Stack component which serves as a flexbox container. By default the direction is column, to center it horizontally you can set alignItems to center:
<Stack alignItems="center">
<CircularProgress />
</Stack>
Live Demo
circularprocess in material ui and text middle of page stackoverflow
<div style={{ alignItems: "center", display: "flex", justifyContent: "center", height: "100vh", width: "100vw" }}>
<CircularProgress />
<span style={{ justifyContent: "center", position: "fixed", top: "55%" }}>Loading...please wait</span>
</div>[![enter image description here][1]][1]
The Backdrop Component will place the progress indicator in the center and also can add a dimmed layer over your application. This component is available with MUI V5.
<Backdrop open={enabled} sx={{ color: '#fff', zIndex: (theme) => theme.zIndex.drawer + 1 }}><CircularProgress color="secondary" /></Backdrop>

Resources