I want to know when Hidden works. I have a two component, categories and news.
When screen resolution is a xsUp i want to show boths. When categories is visible news component paddingLeft = categiries.Width, But xsDown i want to hide categories grid and news component paddingLeft make to 0.
This is how it works.
render() {
const { classes } = this.props;
let news = this.props.news.map((item, index) =>{
return (
<Zoom in={true} timeout={500}>
<Grid item lg={3} xs={12} sm={12} md={6} lg={4} key={item.uid} spacing={16}>
<Paper elevation={0} className={classes.paper}>
<RecipeReviewCard info={item} />
</Paper>
</Grid>
</Zoom>
)
});
return (
<div className={classes.root}>
<Grid container className={classes.root}>
<Grid item xs={12}>
<Grid
container
spacing={16}
className={classes.demo}
alignItems={this.state.alignItems}
direction={this.state.direction}
justify={this.state.justify}
>
<Hidden xsDown>
<Grid
item
lg={2}
md={4}
style={{
width: 270,
maxWidth: 280,
minWidth: 270,
position: 'absolute',
height: '100%',
zIndex: 1
}}>
<Categories />
</Grid>
</Hidden>
<Grid container item lg={12} md={12} spacing={16} style={{paddingLeft: 300, zIndex: 0}}
>
{news}
</Grid>
</Grid>
</Grid>
</Grid>
</div>
);
}
I found solution simple solution myself. I send my function for Categories component, And when Component didMounted or willUnmounted I send Boolean what happend.
Something like this:
Categories.js
componentDidMount = () => {
console.log('CREATED');
this.props.showFull(false);
};
componentWillUnmount = () => {
this.props.showFull(true);
}
Main.js
constructor(props) {
super(props);
this.state = {
direction: 'row',
justify: 'flex-start',
alignItems: 'stretch',
hidden: true
}
}
updateState = (ok) => {
this.setState({
hidden: ok,
});
console.log('updated ' + ' ' + ok);
}
return (
<div className={classes.root}>
<Grid container className={classes.root}>
<Grid
container
spacing={16}
className={classes.demo}
alignItems={this.state.alignItems}
direction={this.state.direction}
justify={this.state.justify}
>
<Hidden xsDown>
<Grid
item
lg={2}
md={4}
style={{
width: '100%',
maxWidth: 280,
minWidth: 0,
position: 'fixed',
height: '100%',
zIndex: 1,
}}>
<Categories showFull={this.updateState} />
</Grid>
</Hidden>
<Grid container item lg={12} md={12} spacing={16}
style={{paddingLeft: this.state.hidden ? 0 : 300, zIndex: 3}}
>
{news}
</Grid>
</Grid>
</Grid>
</div>
);
Related
I am very new to material UI, typescript, and react, so if I say something incorrect or use the wrong terminology please correct me. I have 4 boxes that I want to place on a page, but three boxes have to go in a row and stacking the 4th on the bottom of the box 1.
I currently have a grid as a parent that holds these boxes together as shown
<Grid container={true} spacing={1} justifyContent="center" alignItems='flex-start'>
<Box sx={{m: 1}} style={{width: '500px', height: '600px'}}>
<SomeData data={defaultDeploymentFrequencyData}/>
</Box>
<Box sx={{m: 1}} style={{width: '500px', height: '600px'}}>
<SomeData data={defaultDeploymentFrequencyData}/>
</Box>
<Box sx={{m: 1}} style={{width: '500px', height: '600px'}}>
<SomeData data={defaultDeploymentFrequencyData}/>
</Box>
<Box sx={{m: 1}} style={{width: '500px', height: '600px'}}>
<SomeData data={defaultDeploymentFrequencyData}/>
</Box>
</Grid>
Instead of using boxes all the time and editing them there, is there a way that i can call a method so that it aligns them correctly
export const BoxLayout = ():JSX.Element => {
return (
<Box>
sx={{
display: 'grid',
gap: 1,
gridTemplateColumns: 'repeat(2, 1fr)',
}}
</Box>
)
}
I am thinking this could be called when laying out the boxes, maybe like
<Grid container={true} spacing={1} justifyContent="center" alignItems='flex-start'>
<BoxLayout>
<SomeData data={defaultDeploymentFrequencyData}/>
<SomeData data={defaultDeploymentFrequencyData}/>
<SomeData data={defaultDeploymentFrequencyData}/>
<SomeData data={defaultDeploymentFrequencyData}/>
<BoxLayout>
</Grid>
You also need to wrap each Box inside <Grid item> component.
<Grid container spacing={1}>
<Grid item xs={4}>
<Box style={{ width: 50, height: 50}}>Box</Box>
</Grid>
<Grid item xs={4}>
<Box style={{ width: 50, height: 50}}>Box</Box>
</Grid>
<Grid item xs={4}>
<Box style={{ width: 50, height: 50}}>Box</Box>
</Grid>
<Grid item xs={4}>
<Box style={{ width: 50, height: 50}}>Box</Box>
</Grid>
</Grid>
Column widths are integer values between 1 and 12; they apply at any breakpoint and indicate how many columns are occupied by the component.
So by saying xs={4} you mean this box occupies 4/12 of the space or one third. Then last box goes to the next line under the first box.
I am facing this issue. I had attached the code and error is in the DOM. Tried to fix the issue in various methods and ways but it's not fixing.
I am not able to know why it's getting DOM nesting I don't understand the exact issue in the code. Could anyone help with the solution
import React, { useRef, useState } from "react";
import AvatarEditor from "react-avatar-editor";
import Avatar from "#material-ui/core/Avatar";
import {MuiThemeProvider} from "#material-ui/core/styles";
import Slider from "#material-ui/core/Slider";
import { Grid, Button, Paper } from "#material-ui/core";
import ImageIcon from "#material-ui/icons/Image";
export default function Image() {
const [ state, setState ] = useState({
cropperOpen: false,
img: null,
remove: "",
zoom: 1,
croppedImg: "",
});
const editorRef = useRef(null);
const inputRef = useRef(null);
function handleZoomSlider(event, value) {
setState((prev) => ({ ...prev, zoom: value }));
}
function handleRemove() {
setState((prev) => ({ ...prev, croppedImg: null }));
}
function handleFileChange(e) {
window.URL = window.URL || window.webkitURL;
let url = window.URL.createObjectURL(e.target.files[0]);
inputRef.current.value = "";
setState((prev) => ({ ...prev, img: url, cropperOpen: true }));
}
function handleCancel() {
setState((prev) => ({ ...prev, cropperOpen: false }));
}
function handleSave() {
if (editorRef.current) {
const canvasScaled = editorRef.current.getImageScaledToCanvas();
const croppedImg = canvasScaled.toDataURL();
setState((prev) => ({ ...prev, cropperOpen: false, croppedImg }));
}
}
return (
<MuiThemeProvider>
<Grid container spacing={2} alignItems="center">
<Grid item xs={2} sm={2} md={2} lg={2} xl={2}>
<Avatar style={{ width: "90px", height: "90px" }} src={state.croppedImg} />
</Grid>
<Grid item xs={5} sm={5} md={4} lg={4} xl={3}>
<input
accept="image/*"
ref={inputRef}
onChange={handleFileChange}
id="Upload an Image"
type="file"
multiple
hidden
/>
<label htmlFor="Upload an Image">
<Button fullWidth variant="contained" color="secondary" component={"span"}>
Upload an Image
</Button>
</label>
</Grid>
<Grid item xs={5} sm={5} md={4} lg={3} xl={3}>
<input accept="image/*" onChange={handleRemove} id="Remove Image" multiple hidden />
<label htmlFor="Remove Image">
<Button fullWidth variant="outlined" color="secondary" component={"span"} onClick={handleRemove}>
Remove Image
</Button>
</label>
</Grid>
</Grid>
{state.cropperOpen && (
<Paper
style={{
position: "absolute",
left: "440px",
right: "100px",
top: "100px",
width: "30%",
background: "rgba(200,200,200,.8)",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
zIndex: "1",
}}
>
<Grid container justify="center">
<Grid
item
xs={12}
style={{
fontFamily: "Campaign",
fontSize: "20px",
fontWeight: "bold",
fontStretch: "normal",
fontStyle: "normal",
lineHeight: "1.6",
letterSpacing: "normal",
textAlign: "center",
color: "#181d1e",
height: "60px",
padding: "20px",
background: "#FFFFFF",
}}
>
<span>Create Profile Image</span>
</Grid>
</Grid>
<AvatarEditor
ref={editorRef}
image={state.img}
width={370}
height={400}
disableBoundaryChecks={true}
disableHiDPIScaling={true}
opacity={10}
border={1}
color={[ 255, 255, 255, 0.6 ]}
scale={state.zoom}
borderRadius={200}
/>
<Grid container justify="center" style={{ background: "rgba(255,255,255,0.8)" }}>
<Grid item xs={8} display="flex" justify="center" alignItems="center" container height="55px">
<ImageIcon />
<Slider
min={1}
max={10}
step={0.1}
value={state.zoom}
onChange={handleZoomSlider}
style={{ width: "150px", marginLeft: "10px" }}
/>
<ImageIcon fontSize="large" />
</Grid>
</Grid>
<Grid
container
justify="space-evenly"
alignItems="center"
style={{ background: "#FFFFFF", height: "60px" }}
>
<Grid item xs={5} sm={5}>
<Button
fullWidth
type="button"
variant="outlined"
color="primary"
onClick={handleCancel}
width="100%"
>
Cancel
</Button>
</Grid>
<Grid item xs={5} sm={5}>
<Button
fullWidth
type="button"
variant="contained"
color="secondary"
onClick={handleSave}
width="100%"
>
Save
</Button>
</Grid>
</Grid>
</Paper>
)}
</MuiThemeProvider>
);
}
I ran into a problem on Safari browser where my Material UI Grid container does not hold its Grid item elements within it's boundaries. This seems to be a problem only for Safari browsers.
And here is my code for the page.
<Grid
item
container
direction="column"
justify="space-between"
className={classes.questionContainer}
>
<Grid item>
<Typography component="h1" variant="h1">
{question.text}
</Typography>
</Grid>
<Grid
item
container
xs={12}
justify="flex-start"
className={classes.btnBlock}
>
<Grid item xs={3} className={classes.btnContainer}>
<Button
variant="outlined"
color="primary"
className={classes.btn}
>
{customButtonTitle1 || 'Yes'}
</Button>
</Grid>
<Grid item xs={3} className={classes.btnContainer}>
<Button
variant="outlined"
color="primary"
className={classes.btn}
>
{customButtonTitle2 || 'No'}
</Button>
</Grid>
<Grid item xs={3} className={classes.btnContainer}>
<Button
variant="outlined"
color="primary"
className={classes.btn}
>
{customButtonTitle3}
</Button>
</Grid>
</Grid>
</Grid>
const useStyles = makeStyles((theme: Theme) => ({
questionContainer: {
padding: theme.spacing(6, 6),
minHeight: '340px',
},
btnBlock: {
flexBasis: 0,
},
btnContainer: {
marginRight: '12px',
},
btn: {
fontSize: '16px',
lineHeight: '24px',
color: theme.palette.text.secondary,
padding: '10px 0',
width: '100%',
margin: '0 12px',
},
}))
Why is this happening and how can I fix that for Safari and not break for other browser?
Unfortunately, I do not have access to a Mac OS to test it myself properly
Can you try remove "item" in your Grid container?
<Grid
container
direction="column"
justify="space-between"
className={classes.questionContainer}
>
I'm having issues with the Card rendering using Material UI in a GRANDstack application I'm building.
When I set the cards up with static data they render as expected:
const getMemsCard = (memID) => {
return (
<>
<Grid item xs={12} sm={4} lg={4} key={memID}>
<Card style={{ paddingTop: "5px" }}>
<CardMedia
className={classes.cardMedia}
image={require('../img/historyHead.png')}
style={{ width: "130px", height: "130px" }}
/>
<CardContent className={classes.cardContent}>
<Typography>Hi</Typography>
</CardContent>
</Card>
</Grid>
</>
);
};
<Grid container spacing={2} className={classes.memsGridContainer} >
{getMemsCard()}
</Grid >
However, when I set them up with dynamic data from GraphQL they are rendering vertically as opposed to being in a grid:
const getMemsCard = (memID) => {
return (
<>
<Grid item xs={12} sm={4} lg={4} key={memID}>
{data.Mem.map(memID => (
<Card style={{ padding: "5px" }}>
<CardMedia
className={classes.cardMedia}
image={require('../img/historyHead.png')}
style={{ width: "130px", height: "130px" }}
/>
<CardContent className={classes.cardContent}>
{memID.mem}
{memID.emoji}
</CardContent>
</Card>
))}
</Grid>
</>
);
};
<Grid container spacing={2} className={classes.memsGridContainer} >
{getMemsCard()}
</Grid >
When I add a "row" property to the grid container to try and get them displayed in a grid, it makes them even worse:
const getMemsCard = (memID) => {
return (
<>
<Grid container direction: "row" item xs={12} sm={4} lg={4} key={memID}>
{data.Mem.map(memID => (
<Card style={{ padding: "5px" }}>
<CardMedia
className={classes.cardMedia}
image={require('../img/historyHead.png')}
style={{ width: "130px", height: "130px" }}
/>
<CardContent className={classes.cardContent}>
{memID.mem}
{memID.emoji}
</CardContent>
</Card>
))}
</Grid>
</>
);
};
<Grid container spacing={2} className={classes.memsGridContainer} >
{getMemsCard()}
</Grid >
I would like to get the cards to display like they do with the static data when I have added the dynamic data from GraphQL.
You are using {data.Mem.map(memID => ...)} inside an grid item so that's why it's not rendered as expected. Try this:
const getMemsCard = (memID) => {
return data.Mem.map(memID => (
<Grid item xs={12} sm={4} lg={4} key={memID}>
<Card style={{ padding: "5px" }}>
<CardMedia
className={classes.cardMedia}
image={require('../img/historyHead.png')}
style={{ width: "130px", height: "130px" }}
/>
<CardContent className={classes.cardContent}>
{memID.mem}
{memID.emoji}
</CardContent>
</Card>
</Grid>
))
};
<Grid container spacing={2} className={classes.memsGridContainer} >
{getMemsCard()}
</Grid >
I am working through this code:
demo.js
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Grid from '#material-ui/core/Grid';
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
},
paper2: {
height: "100%",
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
},
}));
export default function FullWidthGrid() {
const classes = useStyles();
return (
<div className={classes.root}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Paper className={classes.paper}>xs=12</Paper>
</Grid>
<Grid item xs={12} sm={6}>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
<Paper className={classes.paper}>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={12} sm={6} >
<Paper className={classes.paper2}>xs=12 sm=6</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=6</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=6</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
<Grid item xs={6} sm={3}>
<Paper className={classes.paper}>xs=6 sm=3</Paper>
</Grid>
</Grid>
</div>
);
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Demo from './demo';
ReactDOM.render(<Demo />, document.querySelector('#root'));
But I am getting the following formatting for the box layout:
(1) Is there a way to make the right grid not overlap with the boxes on the bottom row ?
(2) I need the box on the right to be of same height as the total number of grids on left which is dynamic in number.
Add box-sizing: border-box to .paper2:
paper2: {
height: "100%",
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
boxSizing: 'border-box'
}
Demo:
.makeStyles-paper2-3 { has a padding of 16px along-with height:100% which is causing the right div to overflow. Remove the padding and it will not overflow.
However, if you want to provide the padding to your content inside, you can do so by using a child div
Try this:
<Grid item xs={12} sm={6} >
<Paper className={classes.paper2} style={{padding: '0'}} > {/*Removed padding from here*/}
<div style={{padding: '16px'}}>xs=12 sm=6</div> {/* Added padding here */}
</Paper>
</Grid>
Hope it helps. Cheers!!