Responsive and split layout - reactjs

I started a project with react-splitter-layout and material ui library.
I would like to find a way to create responsive components, with material ui Grid or Box component
I encounter a problem with responsive, I would like my left panel to be responsive (use of xs / md / lg) with Grid component based on the size of the container (not window size), as you can see in the example below , this is not the case. It's use the viewport size. (I know it's normal because of media queries).
Here the code sample : https://codesandbox.io/s/material-demo-i04rr?file=/demo.js (recommended to open the rendering in a new tab to see the problem)
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";
import SplitterLayout from "react-splitter-layout";
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1
},
paper: {
padding: theme.spacing(2),
textAlign: "center",
color: theme.palette.text.secondary
}
}));
export default function CenteredGrid() {
const classes = useStyles();
return (
<SplitterLayout>
<div className={classes.root}>
<Grid container spacing={3}>
<Grid item xs={4} md={6} lg={8}>
<Paper className={classes.paper}>xs=3</Paper>
</Grid>
<Grid item xs={4} md={4} lg={2}>
<Paper className={classes.paper}>xs=3</Paper>
</Grid>
<Grid item xs={4} md={2} lg={2}>
<Paper className={classes.paper}>xs=3</Paper>
</Grid>
</Grid>
</div>
<div>Panel 2</div>
</SplitterLayout>
);
}
Anyone have a solution to this problem ?
Best regards,
EDIT
I also posted in material ui github https://github.com/mui-org/material-ui/issues/25189

This is one of my question when I started using material-UI or any CSS framework.
Material-UI currently supports almost cases you need especially for responsive, and I never use any other library/framework for responsive. First, you know that all xs, sm, md are based on screen size, not on their container.
Then, the problem here is how did you called a "container"? When you work with material-UI, you should layout everything based on screen size instead of a specific container. Because your "container" you are think about doesn't have any meaning in responsive. It just help you solve the layout problem.
To be honest, just change your mind, thinking in the way of Material-UI, and everything about responsive become easily.

Related

Accessing onAccept() function in react cookie consent from custom button

I have a gatsby-react application which uses gatsby-plugin-gdpr-cookies and react-cookie-consent packages to enable and disable cookies and implement cookie consent bar. Here is the part of the component:
import CookieConsent from "react-cookie-consent";
import ReactGA from "react-ga";
import styled from "styled-components";
import { Button, Grid, Link, NoSsr, Typography } from "#material-ui/core";
import { initializeAndTrack } from 'gatsby-plugin-gdpr-cookies';
<CookieConsent
location="none"
cookieName="gatsby-gdpr-google-analytics"
disableStyles = {true}
onAccept={() => {
console.log("cookies accepted");
ReactGA.initialize("UA-XXXXXXXX-XX");
}}
>
<StyledBanner container justify="center" alignItems="center">
<Grid item container direction="column" lg={9} xs={12}>
<StyledText>
This website uses cookies.
</StyledText>
</Grid>
<Grid
container
item
justify="center"
alignItems="center"
lg={3}
xs={12}
wrap={"nowrap"}
>
<Button
variant="outlined"
*onClick={this.onAccept}*
>
I Disagree
</Button>
<Button
variant="outlined"
*onClick={this.onAccept}*
>
I Agree
</Button>
</Grid>
</StyledBanner>
</CookieConsent>
I would really like to trigger the onAccept function in CookieConsent so that my cookies can be enabled. The reason I would like use a custom button is so that the color scheme and theme of my app is constant without having to redesign within the default CookieConsent buttons.
If this is not possible I would also like to explore the customButtonProps prop within CookieConsent option but I having a very difficult time in making that work.
I wanted to know if one of these two options are possible and take a look at small implementation.

How combine styled-system with react material?

I wanna use styled-system in my project which is the admin panel. I built project basing on React Material and I have a lot of different forms with inputs, selects, checkboxes and so on. In many places I have to set some margins/paddings for elements and I make this moment with some custom Box component, that uses styled-system functions (space, color, etc). But it the end I got a rather cumbersome structure something like this :
<Box>
<Box mb={10}>
<Box mr={2}><TextField/></Box>
<Box mr={2}><TextField/></Box>
<Box mr={2}><TextField/></Box>
</Box>
<Box>
<Box mr={2}><Select/></Box>
<Box mr={2}><Select/></Box>
<Box mr={2}><Select/></Box>
</Box>
</Box>
And it's just a little part of the component. I think, in this situation it would be good to create some wrapper around TextField/Select components which will add styled-system functions to components.
And then use them like :
<Box>
<Box mb={10}>
<TextField mr={2}/>
<TextField mr={2}/>
<TextField mr={2}/>
</Box>
<Box>
<Select mr={2}/>
<Select mr={2}/>
<Select mr={2}/>
</Box>
</Box>
But then I understand that react-material has a lot of components and what I have to do? Override all of them to have some similar style? Or what way can be more comfortable?
So what you are asking for can definitely be achieved without adding that much noise to the markup.
First off, the styled markup works for all material-ui components. Luckily, styled-system is ALSO interoperable with styled-components. So you can do this
const StyledButton = styled(TextField)`
color: red;
// to access theme in a styled-system way
${get("mt", 3)};
`;
That accessor called get is a little unique, it comes from this package. It allows you to use all the styled-system flavoured keys inside of a styled-component.
If you wanted inline props for all the material components, like you described, its a little more involved. You would need to wrap each component with the proper decorators that enable such inline props. Creating basically a shadow library.
import styled from 'styled-components';
import { variant, space, layout, position } from 'styled-system';
export default styled(TextField)(
position,
layout,
space,
// whatever else
);
Check out the official build-a-box tutorial for better insight.

Image Tag Not Displaying Image

I am working on a web app, using React.js and Material UI. I don't know why image is not displaying on my web, I have tried almost everything I can. Here is the code where I am using the image tag.
import { TextField, Grid, Typography } from '#material-ui/core';
import WFH1 from './images/WFH1.svg'
function IntroSection()
{
return(
<Grid container>
<Grid item xs={3}>
<image src={WFH1}/>
</Grid>
<Grid item xs={6} style={{color:'white', textAlign:'center'}}>
<Typography variant="h3">Get paid for the work</Typography>
<Typography variant="h3"> you <span style={{color:'#3ee8e5'}}>love</span> to do.</Typography>
</Grid>
<Grid item xs={3}></Grid>
</Grid>
);
}
export default IntroSection; ````
And here is the structure of my code:
[1]: https://i.stack.imgur.com/KwRbs.png
You should use the HTML img tag to actually display an image:
https://www.w3schools.com/tags/tag_img.asp
You are trying to use an HTML tag image, that not exists.
Image tag is not exists. You have to use img tag in html.
<img src={WFH1}/>

How do you repeat a character, after content, and fill it to 100% of width? JSX / React

I have been looking for designs and I stumbled upon Material Design - Basil
looking through the description I saw how Basil displays ingredients and was curious as to how that is done.
Link:
https://material.io/design/material-studies/basil.html#components
it is the first item under the Components section.
I tried something like
const varRecipeIngredientBuilder
= jsnIngredients =>(
<div>
<ListItem>
<Grid item xs={1}>
<Checkbox/>
</Grid>
<Grid item xs={9}>
<h5>{jsnIngredients.name}{" . ".repeat(38 - jsnIngredients.name.length )}</h5>
</Grid>
<Grid item xs={1}>
<h5>{jsnIngredients.quantity}</h5>
</Grid>
<Grid item xs={1}>
{jsnIngredients.measurement}
</Grid>
</ListItem>
</div>
)
function RecipeIngredients ({json}){
return(
<List>
{json.map(varRecipeIngredientBuilder)}
</List>
)
};
export default RecipeIngredients;
I feel that I am close... but maybe that "38" should be something else.
right now some items in the list line up and some dont (even by using "."). the end slightly jagged in maybe 10% of the list and not as seamless as the example.
who knows, maybe the . is throwing me off and it isnt a text repeat.
Disclaimer:
I have been using js/react for about 2 weeks now. I am a career data architect, so I understand design patterns... but it is still a new language to me. So to learn, I try and duplicate what i see.
Below is an example of one way to do this. The approach in my example is just to have more than enough dots to fill the available space, then use noWrap on the Typography so that the extra dots are hidden, and override the default noWrap styling to remove textOverflow: 'ellipsis'.
import React from "react";
import Grid from "#material-ui/core/Grid";
import List from "#material-ui/core/List";
import ListItem from "#material-ui/core/ListItem";
import Typography from "#material-ui/core/Typography";
import { withStyles } from "#material-ui/core/styles";
const ingredients = [
{ name: "Basil", amount: "6 tbsp" },
{ name: "Gluten-free Spaghetti", amount: "2 cups" },
{ name: "Garlic", amount: "1 tbsp" }
];
const dots = " . ".repeat(500);
const TypographyNoEllipsis = withStyles({ noWrap: { textOverflow: "unset" } })(
Typography
);
export default function App() {
return (
<List>
{ingredients.map(ingredient => {
return (
<ListItem>
<Grid container spacing={1}>
<Grid item xs={10}>
<TypographyNoEllipsis noWrap>
{ingredient.name}
{dots}
</TypographyNoEllipsis>
</Grid>
<Grid item xs={2}>
<Typography>{ingredient.amount}</Typography>
</Grid>
</Grid>
</ListItem>
);
})}
</List>
);
}

Centering button on extra small screen Material-UI React not working (justify-xs-center)

I tried everything but it seems that I'm missing something. I have been trying a lot of time to make a button center inside the grid when the screen is extra small.
This code works perfectly, but the problem is that i want my button to only center when the screen is extra small not on all sizes.
Working Code.
Grid item xs={12}>
<Grid container justify="center">
<Button color="primary" variant="raised">
Add Product
</Button>
</Grid>
</Grid>
Not working code...
Grid item xs={12}>
<Grid container className={"justify-xs-center"}>
<Button color="primary" variant="raised">
Add Product
</Button>
</Grid>
</Grid>
I have been reading the API documentation for the Grid, as i understand this is the correct way to add a predefined class in the component, but the effect seems not to work. When i inspect the element though the class justify-xs-center is found on the Grid container component as expected.
Any help is appreciated, Thank you.
Well it seems i have really misunderstood the CSS API of the Grid.
https://material-ui.com/api/grid/#css-api
My solution to this was to use the breakpoints offered by material-ui.
https://material-ui.com/layout/breakpoints/#theme-breakpoints-up-key-media-query
I created this CSS rule and applied it to the Grid container element that i wanted its contents to be centered.
const styles = theme => ({
addButtonContainer: {
[theme.breakpoints.down("xs")]: {
justifyContent: "center"
}
}
});
And this is the container that is being centered on extra small screens
<Grid item xs={12}>
<Grid container className={classes.addButtonContainer}>
<Button color="primary" variant="raised">
Add Product
</Button>
</Grid>
</Grid>

Resources