How to make something like this in material ui react? - material-ui

How can i make this in material ui react?
The main problem i have is i don't know how to make the right part with the refresh icon.

This question is kinds an amateur question. But I can give you little insights how you can start with little basics and you can later make it stateful component.
const styles = theme => ({
margin: {
margin: theme.spacing.unit,
},
roundBorder : {
borderRadius: '25px',
borderColor: '#80bdff',
border: '1px solid #ced4da',
}
});
function App(props) {
const { classes } = props;
return (
<div>
<div className={classes.margin}>
<Grid container spacing={8} alignItems="flex-end">
<Grid item>
<TextField className={classes.roundBorder} id="input-with-icon-grid" label="With a grid" />
</Grid>
<Grid item>
<AccountCircle />
</Grid>
</Grid>
</div>
</div>
);
}
This will create something like this:

Check this sample which has searching with icon, just align icon to the right:
https://codesandbox.io/s/material-demo-jhy9f

Related

MUI dropdown react application

I am using MUI to develop my dashboard.
I am using MUI dropdown component to select the vendor details and there are two options for the Vendor dropdown. i.e "Surya Kumar Yadav", "Eswar". I used the same dropdown in all my cards. When I select the one of the dropdown in any card, it is reflected in all the other cards.
import React from "react";
import {
Box,
Card,
CardContent,
Typography,
Button,
CardActionArea,
CardActions,
Grid,
Select,
MenuItem,
FormControl,
InputLabel,
} from "#mui/material";
import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { HttpClient } from "../http/http";
import { ConfirmDialog, confirmDialog } from "./ConfirmDialog";
const Services = () => {
const [services, setServices] = useState([]);
const [vendors, setVednors] = useState([]);
const [selectedVendor, setSelectedVendor] = useState("");
const PF =
"https://firebasestorage.googleapis.com/v0/b/mern-stack-service-app.appspot.com/o/";
const navigate = useNavigate();
useEffect(() => {
init();
}, []);
const init = () => fetchServices();
const fetchServices = async () => {
const services = await HttpClient.get(`services`);
const vendors = await HttpClient.get(`vendor`);
setVednors(vendors);
setServices(services);
};
const handleChange = (event) => {
setSelectedVendor(event.target.value);
};
console.log(services);
return services.length === 0 ? (
<Grid>
<Typography
sx={{
fontSize: 32,
color: "blue",
display: "flex",
justifyContent: "center",
alignItems: "center",
textDecoration: "underline",
}}
>
Loading your services.....
</Typography>
</Grid>
) : (
<Grid container>
<ConfirmDialog />
<Grid container item xs={12} columnGap={2}>
<Box sx={{ float: "right" }}>
<Button
variant="outlined"
onClick={() => {
confirmDialog("Are you sure want to logout?", () => {
localStorage.clear();
navigate("/login");
});
}}
>
Logout
</Button>
</Box>
</Grid>
<Grid container item xs={12} rowGap={2}>
{services.map((service, index) => (
<Grid item xs={12} sm={6} md={4} key={index}>
<Card>
<CardActionArea>
<CardContent>
<Grid
component="img"
sx={{
height: 150,
width: 350,
maxHeight: { xs: 150, md: 175 },
maxWidth: { xs: 350, md: 375 },
objectFit: "cover",
}}
alt="The house from the offer."
src={
PF +
service.photo +
"?alt=media&token=c19f2d0a-f254-4391-b589-ef7ee3cad9f5"
}
></Grid>
<Grid item xs={12}>
<Typography textAlign="center">
{service.service}
</Typography>
</Grid>
<Grid item xs={12}>
<FormControl sx={{ minWidth: 120 }} size="small" fullWidth>
<InputLabel id="demo-select-small">
Select Vendor
</InputLabel>
<Select
size="small"
labelId="demo-select-small"
id="demo-select-small"
value={selectedVendor}
label="Select Vendor"
onChange={handleChange}
>
{vendors.map((vendor) => (
<MenuItem
key={vendor._id}
value={vendor.name}
id={vendor.name}
>
{vendor.name}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
</CardContent>
</CardActionArea>
<CardActions>
<Grid item xs={12}>
<Button variant="outlined" color="primary" fullWidth>
Book Service
</Button>
</Grid>
</CardActions>
</Card>
</Grid>
))}
</Grid>
</Grid>
);
};
export default Services;
I want the dropdown action reflect in the selected card.
It's because all of your mapped Select elements get their value from selectedVendor. you can change the code like this using these steps:
First:
Change the selectingVendor useState like this:
const [selectedVendors, setSelectedVendors] = useState([]);
Second:
And the handleChange function
const handleChange = (event,index) => {
const currentSelectedVendors = [...selectedVendors];
currentSelectedVendors[index] = event.target.value
setSelectedVendors(currentSelectedVendors);
};
Third:
You need to change the Select Mui component props.
<Select
size="small"
labelId="demo-select-small"
id="demo-select-small"
value={selectedVendors[index] || ""}
label="Select Vendor"
onChange={(e) => handleChange(e,index)}
>
Although there is another solution for this problem and you can pull <Select> logic out of Services component , I mean it's selectingVendor hook and it's change handler and create a new separate component which handles it.
PS: I think it should be better to use vendor._id as the value prop of your MenuItems

#mui grid items of equal height

Using the React #mui package, I want to create a grid of items that all stretch to the same height as the tallest item. I've tried searching for similar questions but have not found a working solution, and using #mui v5. Here's my example, also found on Sandbox https://codesandbox.io/s/happy-moon-y5lugj?file=/src/App.js. I prefer a solution (if possible) using the #mui components rather than grid css directly. Also I cannot fix the number of columns, it needs to be responsive.
import * as React from "react";
import {
Box,
Card,
Container,
Grid,
Paper,
Table,
TableBody,
TableRow,
TableCell,
Typography
} from "#mui/material";
export default function App() {
const createTable = (rows) => {
return (
<Table>
<TableBody>
{[...Array(rows).keys()].map((n) => {
return (
<TableRow key={n}>
<TableCell>Aaaaa</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
);
};
return (
<Box p={3}>
<Container maxWidth="sm" height="100%">
<Grid container spacing={2} height="100%">
<Grid item height="100%">
<Paper height="100%" elevation={3} sx={{ p: 3 }}>
<Typography variant="h4">Something</Typography>
{createTable(5)}
</Paper>
</Grid>
<Grid item height="100%">
<Paper height="100%" elevation={3} sx={{ p: 3 }}>
<Typography variant="h4">More things</Typography>
{createTable(3)}
</Paper>
</Grid>
</Grid>
</Container>
</Box>
);
}
This is what I get now. I want the shorter item to be padded on the bottom so its the same height as the first.
Please use this code from the box downwards. You can read more about how to work with grid items on the mui website here.
const StackOverflow = () => {
const createTable = (rows) => {
return (
<Table>
<TableBody>
{[...Array(rows).keys()].map((n) => {
return (
<TableRow key={n}>
<TableCell>Aaaaa</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
);
};
return (
<Box p={3}>
<Container maxWidth="sm">
<Grid container spacing={2}>
<Grid item xs={6}>
<Paper elevation={3} sx={{ p: 3, height: "100%" }}>
<Typography variant="h4">Something</Typography>
{createTable(5)}
</Paper>
</Grid>
<Grid item xs={6}>
<Paper elevation={3} sx={{ p: 3, height: "100%" }}>
<Typography variant="h4">More things</Typography>
{createTable(3)}
</Paper>
</Grid>
</Grid>
</Container>
</Box>
);
};
Something that worked good for me was to use the following in the Papers sx prop:
{{height: "100%", display: "flex", alignItems: "center"}}

Material UI: Apply the fullwidth feature to the Textfield

I have a staff monitoring project that contains many components and among these components is "creating a workspace" and how clear in the picture I made a component and put many elements in it, but the problem is that the "TextField" I want it to be until the end of the page And although I put "Full Width", it is only complete in the middle.
How can I solve the problem?
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
flexGrow: 1
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
},
resize:{
fontSize:24
}
}),
);
const Settings: FC = () => {
const classes = useStyles();
return (
<div className={classes.root}>
{/*<Container maxWidth="lg" style={{backgroundColor: 'red'}}>*/}
<Grid container direction="row">
<Grid item>
<Avatar style={{width: '5rem', height: '5rem'}} alt="Remy Sharp"
src="/static/images/avatar/1.jpg"/>
</Grid>
<Grid item >
<TextField
fullWidth
name="workspaceName"
placeholder="Workspace Name"
variant="standard"
style={{
paddingLeft: '1.4rem',
transition: ' all .2s cubic-bezier(.785,.135,.15,.86) 0s',
display: 'flex',
alignItems: 'center',
flexGrow: 1,
position: 'relative',
color: '#828588',
}}
InputProps={{
classes: {
input: classes.resize,
},
}}
defaultValue="nameeeee"
/>
</Grid>
</Grid>
<Grid container spacing={5} direction="row" mt={14}>
<Grid item xs>
<Button style={{
minWidth: '10rem',
fontSize: '1.5rem',
height: '44px',
fontWeight: 400,
textShadow: 'none',
color: '#fd71af',
border: 0,
background: 'none'
}}>Delete Workspace</Button>
</Grid>
<Grid item >
<Button
color="primary"
component={RouterLink}
to="/dashboard/workspaces/1"
variant="contained"
style={{
minWidth: '13rem',
minHeight: '4.3rem',
fontSize: '1.4rem',
backgroundColor: '#7b68ee',
borderRadius: 6,
marginLeft:'60rem'
}}
>
Saved
</Button>
</Grid>
</Grid>
{/*</Container>*/}
</div>
);
}
export default Settings;
The fullWidth attribute sets the width to 100% of its parent. Its parent (The <Grid> component) isn't occupying the full space. Add css style { flexGrow: 1 } to the <TextField>'s <Grid> parent or set the xs attribute for the <Grid>
Check this part of the docs for reference

Material UI Grid alignment

How can I align items vertically in material UI?
https://codesandbox.io/s/material-demo-forked-wrn9x
Here I want put Start element and top, Center element at center and End element at bottom
I am looking for clearest and best solution
If you using grid just do this :
<Grid
container
direction="column"
justify="center"
alignItems="center"
spacing={3}
className={classes.container}
>
you can use the interactive tool of MUI doc for play around and get the props you have to pass for create all the layout you need in the future.
https://material-ui.com/components/grid/#grid
Here is the code that will make three grids - start, centre and end to appear in a column one after another. This layout will remain the same across all screen resolutions/breakpoints.
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,
border: '2px solid #969292',
}
}));
export default function CenteredGrid() {
const classes = useStyles();
return (
<div className={classes.root}>
<Grid>
<Grid item xs={12}>
<Paper className={classes.paper}>Start</Paper>
</Grid>
<Grid item item xs={12}>
<Paper className={classes.paper}>Center</Paper>
</Grid>
<Grid item item xs={12}>
<Paper className={classes.paper}>End</Paper>
</Grid>
</Grid>
</div>
);
}
This code will generate a layout like below:

Classnames mismatch using Material-UI and NextJS

Using Intersection Observer API I'm trying to render a Material-UI Component by visibility on the viewport.
export default function Index() {
const [onScreen, theRef] = useOnScreen({
rootMargin: "-300px",
ssr: true
});
const classes = useStyles();
return (
<Container maxWidth="sm">
<DummyContainer />
<div
ref={theRef}
style={{
height: "100vh",
padding: "20px",
backgroundColor: "green",
transition: "all .5s ease-in"
}}
>
{onScreen && (
<Box className={classes.rootBox} my={16}>
<Typography variant="h2" gutterBottom>
Content Lazy using Intersection Observer
</Typography>
<Copyright />
</Box>
)}
</div>
<Box className={classes.rootBox} my={4}>
<Typography variant="h2" gutterBottom>
Content no lazy, why this Box loses margin?
</Typography>
<Typography gutterBottom>
If you request this page with JavaScript disabled, you will notice
that has been properly rendered in SSR
</Typography>
</Box>
</Container>
);
}
Basic stuff, onScreen is a toggled boolean using Intersection Observer
In order to be "SEO friendly" I'm using NextJS and I wanted this component to always be visible in SSR and conditional visible in CSR.
The problem arises during rehydration in CSR, it's seems that some classnames after the lazy component are recreated and I'm losing styling in second Box component.
I've created this CodeSandbox to have a look : https://codesandbox.io/s/nextjsmaterialuiclassnamemismatch-1j4oi
Is this a bug in MaterialUI, JSS? Or most probably I'm doing something wrong?