Making the card component responsive using material ui - css

I am trying to make my card responsive to mobile applications
const styles = {
edit: {
width: "40%",
marginLeft: 270,
background: "#76ff03"
},
add: {
width: "100%",
background: "#18ffff",
size: "large"
},
root: {
minHeight: 210,
minWidth: 100
}
};
<Container maxWidth="md">
{/*marginTop:15*/}
<Typography component="div" style={{ borderColor:'#00c853' }}>
{/*style={{ height: '30vh' }}*/}
<Card style={styles.root}>
<Typography variant="overline" color="secondary" style={{fontFamily:'Roboto',margin:10}}>
All about your needs
</Typography>
<form onSubmit={this.validateItem} autoComplete='off'>
<TextField id="outlined-full-width" label="Input" style={{ width:'90%',marginTop:30 ,marginLeft:40 }}
placeholder="Add A Todo Item " margin="normal" InputLabelProps={{
shrink: true,
}} error={this.state.errorState} helperText={ this.state.errorState
&& "Item name can't be blank" } size="large" variant="outlined" value={newItem} onChange={handleInput} />
<Grid container justify='center' alignContent='center'>
<Grid item xs={12} md={6}>
{buttonChange()}
</Grid>
</Grid>
</form>
</Card>
</Typography>
</Container>
</div>
The above code is the user interface for the card component , i am trying to make the card component mobile responsive , but the interface i get instead is given below
The card and the text field should be able to be responsive to the screen size, but i am unable to make it work. Is there a way i can make it happen?

Hello and thank you for asking your question,
you can use the breakpoint of [theme.breakpoints.down("(XS, sm,md, lg, xl,)")] : {
maxWidth: 200 // you can change the size of your card component.
}
Here is a clearer example from the material ui Card component
Here is the component from the material UI Card component page, I only added the useTheme and useMediaQuery imports, and added a medium breakpoint inside useStyle under classes.root Here is a useful link on "useMediaQuery" https://material-ui.com/components/use-media-query/#usemediaquery
import { useTheme } from "#material-ui/styles";
import useMediaQuery from "#material-ui/core/useMediaQuery";
const useStyles = makeStyles(theme => ({
root: {
maxWidth: 345,
[theme.breakpoints.down("md")] : {
maxWidth: 200
}
},
media: {
height: 140
}
}));
const Card = () => {
const classes = useStyles();
const theme = useTheme();
const matches = useMediaQuery(theme.breakpoints.up("sm"));
return (
<Card className={classes.root}>
<CardActionArea>
<CardMedia
className={classes.media}
title="Contemplative Reptile"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
Lizard
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
Lizards are a widespread group of squamate reptiles, with over 6,000
species, ranging across all continents except Antarctica
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Button size="small" color="primary">
Share
</Button>
<Button size="small" color="primary">
Learn More
</Button>
</CardActions>
</Card>
);
}
Hope this helps

Related

Two components overlap each other when screen size is reduced

My site has a component (NavPanel) that consists of two components (a back button (BackToButton ) and a search field (SearchTextField )). With a standard screen size, they are positioned as they should be, but if the screen sizes are reduced, then these two components overlap each other.
The most optimal for me would be if, with a compressed screen size, the second component (SearchTextField ) will be located under the first (BackToButton ). Tell me how you can solve this problem?
const Style = {
paddingLeft: '8%',
paddingRight: '8%',
minHeight: '70px',
alignItems: 'center',
flexWrap: 'nowrap',
whiteSpace: 'nowrap'
}
export default function NavPanel() {
return (
<Grid container sx={Style}>
<BackToButton />
<SearchTextField />
</Grid>
);
}
Here you go...
You didn't use the grid correctly.
See the forked snippet here.
EDIT 1
A:
B:
EDIT 2
You can change the breakpoint from sm to md. It means that PageNameBackToButton and FilterButtonSearchTextField will be stacked earlier, but A will not happen.
See the forked snippet here.
PageNameBackToButton.jsx
import React from "react";
import { Tooltip } from "#mui/material";
import BackToButton from "./BackToButton";
const PageName = {
color: "#000000",
fontSize: "20px",
fontWeight: "700",
letterSpacing: "0.2px",
paddingRight: "20px"
};
const PageNameBackToButtonContainerStyle = {
width: "50%",
justifyContent: "start",
alignContent: "center"
};
export default function PageNameBackToButton(props) {
return (
<div sx={PageNameBackToButtonContainerStyle}>
<BackToButton />
<div style={{ marginTop: "5px", display: "inline-block" }}>
<span style={PageName}>Some Text</span>
<span>
<Tooltip title={`Here long long text`} placement="right">
<span
style={{ fontSize: "18px", color: "#ef1400", userSelect: "none" }}
>
Live
</span>
</Tooltip>
</span>
</div>
</div>
);
}
FilterButtonSearchTextField.jsx
import { TextField } from "#mui/material";
const FilterButtonSearchTextFieldContainerStyle = {};
const SearchTextField = {};
export default function FilterButtonSearchTextField() {
return (
<div sx={FilterButtonSearchTextFieldContainerStyle}>
<TextField
required
label="Search Search"
size="small"
style={SearchTextField}
/>
</div>
);
}
Filter.jsx
import React from "react";
import { Grid } from "#mui/material";
import FilterButtonSearchTextField from "./FilterButtonSearchTextField";
import PageNameBackToButton from "./PageNameBackToButton";
import { styled } from "#mui/material/styles";
const FilterContainerStyle = {};
const Root = styled("div")(({ theme }) => ({
padding: theme.spacing(1),
[theme.breakpoints.up("md")]: {
display: "flex",
justifyContent: "flex-end"
}
}));
export default function Filter(props) {
const pageName = props.pageName !== undefined ? props.pageName : "";
const showBackToButton =
props.showBackToButton !== undefined ? props.showBackToButton : false;
return (
<Grid container spacing={2} sx={FilterContainerStyle}>
<Grid item md={6} xs={12}>
<PageNameBackToButton
showBackToButton={showBackToButton}
pageName={pageName}
/>
</Grid>
<Grid item md={6} xs={12}>
<Root>
<FilterButtonSearchTextField table={props.table} />
</Root>
</Grid>
</Grid>
);
}
<Grid container> is meaningless without some <Grid item>s inside it.
Just like the Bootstrap,
The grid creates visual consistency between layouts while allowing flexibility across a wide variety of designs. Material Design's responsive UI is based on a 12-column grid layout.
Your code would be like this:
<Grid container spacing={1} sx={Style}>
<Grid item xs={12} sm={6}>
<BackToButton />
</Grid>
<Grid item xs={12} sm={6}>
<SearchTextField />
</Grid>
</Grid>
I strongly recommend reading the MUI Grid Docs.

custom accordion in Mui Nextjs and mui

there is quite a new component introduced in #mui/lab which is Masonary which deals with accordions on the sidebar but not the one I posted above. so far I have achieved
import React from 'react';
import IconButton from '#mui/material/IconButton';
import FavoriteIcon from '#mui/icons-material/Favorite';
import Devider from '#mui/material/Divider';
import ExpandMoreIcon from '#mui/icons-material/ExpandMore';
import { styled } from '#mui/material/styles';
import { css } from '#emotion/react';
import { Rating, Paper, Card, Box, CardHeader, CardContent, CardMedia, CardActions, Toolbar, Typography, Collapse } from '#mui/material';
const ExpandMore = styled((props) => {
const { expand, ...other } = props;
return <IconButton {...other} />;
})(({ theme, expand }) => ({
transform: !expand ? 'rotate(0deg)' : 'rotate(180deg)',
marginLeft: 'auto',
transition: theme.transitions.create('transform', {
duration: theme.transitions.duration.shortest,
}),
}));
const DropDownPaperSection = ({ Pages, error }) => {
const [expanded, setExpanded] = React.useState(false);
const handleExpandClick = () => {
setExpanded(!expanded);
};
if (error) {
return <div className={style.Container} >An error occured: {error.message}</div>;
}
return (
<>
<Toolbar sx={{ bgcolor : '#f4f4f8'}}>
{Pages.data.map(Pages => (
//<div classname={style.main}>
<Box key={`$Pages.id`} variant='outlined' spacing={2 } elevation={1} style={{ margin: "16px 0px", border: "1px solid black" }}
css={css`
color: #20b2aa;
:hover {
color: #2e8b57;
}
`}>
{/* {Pages.attributes.Title}
{Pages.attributes.createdAt}
*/}
<Box>
<Typography variant="body2" color="text.secondary" className="hover:bg-violet-300">
{Pages.attributes.Title}</Typography>
</Box>
<Box enableSpacing>
<ExpandMore
expand={expanded}
onClick={handleExpandClick}
aria-expanded={expanded}
aria-label="show more"
>
<ExpandMoreIcon />
</ExpandMore>
</Box>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<Typography paragraph padding="10px">
<Box sx={{ my: 8, spacing: 10, margin: 2 }} key={`$Pages.id`}> {Pages.attributes.Description} </Box></Typography>
<Devider />
<Box sx={{ my: 8, spacing: 10, margin: 2 }} key={`$Pages.id`}> {Pages.attributes.Content} </Box>
</Collapse>
</Box>
))} </Toolbar>
</>
)
}
export default DropDownPaperSection
But I am stuck with detaching those two elements as seen in the picture.
if you need you may find the rest of the code in github is there any possible way to achieve the closest one? I am not very sure how can i proceed next to detach this accordion. Maybe I am missing very evil details to detach them.
EDIT :
if we somehow use the portal and update the component it comes out as a combined section of multiple rows of data But not the desired output that I want.
```..........
<Collapse in={expanded} timeout="auto" unmountOnExit>
<Portal container={container.current} key={`$Pages.id`}>
<Typography paragraph padding="10px">
<Box sx={{ my: 8, spacing: 10, margin: 2 }} key={`$Pages.id`}> {Pages.attributes.Description} </Box></Typography>
<Devider />
<Box sx={{ my: 8, spacing: 10, margin: 2 }} key={`$Pages.id`}> {Pages.attributes.Content} </Box>
</Portal>
</Collapse>
<Box sx={{ p: 1, my: 1, border: '1px solid' }} key={`$Pages.id`} ref={container} />
</Box>
))} </Toolbar>
</React.Fragment> ```

How to move Icons in Material UI

How can I move my components on the image by using material UI ? I want to move my heart component to the top right corner of my image and ratings on the bottom of my image.
import image from "../../Assets/pic.jpg";
import React, { useState } from "react";
import { makeStyles } from "#material-ui/core/styles";
import Card from "#material-ui/core/Card";
import CardActionArea from "#material-ui/core/CardActionArea";
import FavoriteBorderIcon from "#material-ui/icons/FavoriteBorder";
import CardContent from "#material-ui/core/CardContent";
import CardMedia from "#material-ui/core/CardMedia";
import Typography from "#material-ui/core/Typography";
import Grid from "#material-ui/core/Grid";
import styles from "./Cards.module.css";
import Stars from "../Stars/Stars";
const useStyles = makeStyles({
root: {
maxWidth: 345,
display: "flex",
},
text: {
textAlign: "center",
color: "#333333",
},
textCardBottom: {
display: "flex",
justifyContent: "center",
},
textPrice: { color: "#333333" },
textStrike: { margin: "0px 10px 0px 10px" },
textDiscount: { color: "#ff6a6a" },
stars: {
right: 9,
},
ratings: {},
});
const Cards = () => {
const [showComponent, setShowComponent] = useState(false);
const classes = useStyles();
const handleToggleHoverIn = (event) => {
event.preventDefault();
setShowComponent(true);
};
const handleToggleHoverOut = (event) => {
event.preventDefault();
setShowComponent(false);
};
console.log("The state showComponent value is ", showComponent);
return (
<Card
onMouseEnter={handleToggleHoverIn}
onMouseLeave={handleToggleHoverOut}
className={classes.root}
>
<CardActionArea>
<CardMedia
component="img"
alt=""
image={image}
title="Contemplative Reptile"
/>
{/* {showComponent ? ( */}
<Grid container>
<Stars right="40%" /> // want this rating component on the centre of my image
<FavoriteBorderIcon fontSize="large" /> // want this heart to the top right corner
</Grid>
{/* ) : null} */}
<CardContent>
<Typography
gutterBottom
variant="h5"
component="h2"
className={classes.text}
>
Printed round Neck
</Typography>
<Typography
variant="body2"
color="textSecondary"
component="div"
className={classes.textCardBottom}
>
<Typography
variant="body2"
color="textSecondary"
component="b"
className={classes.textPrice}
>
Rs. 454
</Typography>
<Typography
variant="body2"
color="textSecondary"
component="strike"
className={classes.textStrike}
>
Rs. 699
</Typography>
<Typography
variant="body2"
color="textSecondary"
component="span"
className={classes.textDiscount}
>
(35 % off)
</Typography>
{/* <p>
<b>Rs. 454</b>
<strike>Rs. 699</strike>
<span style={{ color: "#FF7F7F" }}> (35 % off) </span>
</p> */}
</Typography>
</CardContent>
</CardActionArea>
</Card>
);
};
export default Cards;
I tried to use the position property of material UI but I wasn't able to move the components. I tried the Material UI docs but couldn't find properties that could help me moving the components.
did you tried to add inline styles like this:
<FavoriteBorderIcon fontSize="large" style={{ position: "absolute", top: "5px", right: "5px" }}/>
<Stars right="40%" style={{ position: "absolute", bottom: "5px" }}/>
and perhaps you need also add some position to Grid as well
<Grid style={{ position: "relative" }}>

AppBar overlaps with other elements

I am starting to use React/Material-UI, and also new to CSS etc...
I have a simple page layout with an APPBar. Unfortunately this AppBar overlaps the elements which are meant to go below it.
I have found this answer:
AppBar Material UI questions
But this feels completely wrong. What if my AppBar has a variable height, depending on the icons, display modes etc...?
I have tried to create a vertical grid, to wrap the elements in different items, made the top container a flex one and play with flex settings, nothing seems to work, the app bar always sits on top of the text.
The code is very simple:
import React from 'react';
import { AppBar, Typography, Box } from '#material-ui/core';
function App() {
return (
<div>
<AppBar>
<Typography variant='h3'>
AppBar
</Typography>
</AppBar>
<Box>
<Typography variant='h1' style={{ border: '1px solid black' }}>
Hello
</Typography>
</Box>
</div>
)
}
export default App;
The "Hello" text chunk is only half visible:
This is happening because the MaterialUI App Bar defaults to position="fixed". This separates it from the standard DOM's layout to allow content to scroll beneath it, but as a result no space is made for it on the page.
You can get around this by wrapping all content below it in a div and specifying enough margin, or by changing the position property of <AppBar> so it's no longer "fixed". In your example, you could also just apply the styles to <Box> if that's the only content below the <AppBar>.
e.g.
import React from 'react';
import { AppBar, Typography, Box } from '#material-ui/core';
function App() {
return (
<div>
<AppBar>
<Typography variant='h3'>
AppBar
</Typography>
</AppBar>
<div style={{marginTop: 80}}>
<Box>
<Typography variant='h1' style={{ border: '1px solid black' }}>
Hello
</Typography>
</Box>
</div>
</div>
)
}
export default App;
MaterialUI provides a theme mixin for the AppBar that can help. Not sure if you're using the recomended JSS setup, but you can do something like this:
import withStyles from '#material-ui/core/styles/withStyles';
const styles = theme => ({
appBarSpacer: theme.mixins.toolbar
});
const style = withStyles(styles)
function MyScreen ({ classes }) {
<AppBar></AppBar>
<div className={classes.appBarSpacer}></div>
<Box></Box>
}
export default style(MyScreen)
The mixin will give that div the same height as your AppBar, pushing down the other content.
According to Material-ui, there are 3 solutions to this problem.
https://material-ui.com/components/app-bar/#fixed-placement
You can use position="sticky" instead of fixed. ⚠️ sticky is not supported by IE 11.
You can render a second component
You can use theme.mixins.toolbar CSS
I personally enjoy using the 2nd solution like this.
return (
<>
<AppBar position="fixed">
<Toolbar>{/* content */}</Toolbar>
</AppBar>
<Toolbar />
</>
);
<AppBar position='static'>
use this it will do it and content won't hide under Appear
I think having a good app setup is opinianted, but I would recommend the following
import React from "react";
import ReactDOM from "react-dom";
import {
AppBar,
Typography,
Box,
CssBaseline,
makeStyles,
Container,
Grid,
Toolbar
} from "#material-ui/core";
const useStyles = makeStyles(theme => ({
content: {
flexGrow: 1,
height: "100vh",
overflow: "auto"
},
appBarSpacer: theme.mixins.toolbar,
title: {
flexGrow: 1
},
container: {
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4)
}
}));
function App() {
const classes = useStyles();
return (
<div className={classes.root}>
<CssBaseline />
<AppBar position="absolute">
<Toolbar className={classes.toolbar}>
<Typography
component="h1"
variant="h6"
color="inherit"
noWrap
className={classes.title}
>
AppBar
</Typography>
</Toolbar>
</AppBar>
<main className={classes.content}>
<div className={classes.appBarSpacer} />
<Container maxWidth="lg" className={classes.container}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Box>
<Typography variant="h1" style={{ border: "1px solid black" }}>
Hello
</Typography>
</Box>
</Grid>
</Grid>
</Container>
</main>
</div>
);
}
try this!
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
[theme.breakpoints.down('sm')]: {
marginBottom: 56,
},
[theme.breakpoints.up('sm')]: {
marginBottom: 64,
},
},
menuButton: {
marginRight: theme.spacing(1),
},
title: {
flexGrow: 1,
}, }))
You can add the above to your code like this
const Navbar = () => {
const classes = useStyles()
return (
<div className={classes.root}>
<AppBar position='fixed' color='primary'>
<Toolbar>
<IconButton
edge='start'
className={classes.menuButton}
color='inherit'
aria-label='menu'>
<MenuIcon />
</IconButton>
<Typography variant='h6' className={classes.title}>
News
</Typography>
<Button color='inherit'>Login</Button>
</Toolbar>
</AppBar>
</div>
)}
For more documentation visit material-ui breakpoint customization

How to increase the vertical spacing between a Material UI FormLabel and Slider?

I'm working on a map with an image overlay that has adjustable opacity. Here is the component code:
import React from 'react'
import PropTypes from 'prop-types'
import { MapWithGroundOverlay } from './MapWithGroundOverlay'
import { withStyles } from '#material-ui/core/styles'
import Box from '#material-ui/core/Box'
import FormLabel from '#material-ui/core/FormLabel'
import Slider from '#material-ui/lab/Slider'
import Grid from '#material-ui/core/Grid'
import Paper from '#material-ui/core/Paper'
const styles = theme => ({
root: {
flexGrow: 1,
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
},
label: {
padding: theme.spacing(3),
}
})
class AdjustableGroundoverlay extends React.PureComponent {
constructor(props, context) {
super(props, context)
this.state = {opacity: 0.5}
this.handleChange = this.handleChange.bind(this);
}
handleChange(event, value) {
this.setState(state => ({
opacity: value
}));
}
render() {
return (
<Grid container className={this.props.classes.root} spacing={2}>
<Grid item xs={12}>
<MapWithGroundOverlay
googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLE_MAPS_API_KEY}&v=3.exp&libraries=geometry,drawing,places`}
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `600px` }} />}
mapElement={<div style={{ height: `100%` }} />}
opacity={this.state.opacity}
/>
</Grid>
<Grid item xs={6}>
<Paper className={this.props.classes.paper}>
<Box flexDirection="column">
<FormLabel className={this.props.classes.label}>Overlay opacity</FormLabel>
<Slider
value={this.state.opacity}
min={0}
max={1}
onChange={this.handleChange}
/>
</Box>
</Paper>
</Grid>
</Grid>
);
}
}
AdjustableGroundoverlay.propTypes = {
classes: PropTypes.object.isRequired,
}
export default withStyles(styles)(AdjustableGroundoverlay)
The problem is that the FormLabel and Slider are too close together. If I hover over them, I see that the Slider has a negative margin of -24px:
It seems like the content of the FormLabel therefore sits directly on top of it:
I've tried to change the styling of the Slider by adding these classes to the component in accordance with https://material-ui.com/api/slider/#css:
<Slider
classes={{container: {marginTop: -12}}}
value={this.state.opacity}
min={0}
max={1}
onChange={this.handleChange}
/>
but the spacing between the FormLabel and the Slider remains the same. Any idea what is wrong with this implementation?
Update
I've noticed in the console that there is this error:
I'm not sure why the key 'container' is not valid though since it is mentioned in https://material-ui.com/api/slider/#css.
I resolved this by putting the slider in a Box with mt set to 1:
<Paper className={this.props.classes.paper}>
<Box flexDirection="column">
<FormLabel className={this.props.classes.label}>Overlay opacity</FormLabel>
<Box mt={1}>
<Slider
value={this.state.opacity}
min={0}
max={1}
onChange={this.handleChange}
/>
</Box>
</Box>
</Paper>
Now there is more spacing between the label and the slider:

Resources