Make <TabPanel> content full width and hight as parent - javascript

I am using React with material-ui. I am using appbar with tabs and I want to be able when I pick some of the tabs the content of the tab to be full width and height.
Here is the sandbox example: https://codesandbox.io/s/vigorous-cookies-4dmf2?file=/src/App.js
As you can see the provided picture the content of the tab does not fill the whole page under the bar. How I can do it to fill it?

If you inspect your marked div in your screenshot. You will find out the padding style is related to MuiTabPanel-root. On Material's official website, they introduced a few ways to override component's styles. Here is one of the ways you can do, to overide component's style by rule names. You can also find each component's rule name under Component API section on their website.
const useStyles = makeStyles({
tabPanelRoot: {
padding: 0
},
});
usage:
export default function App() {
const classes = useStyles();
return(
...
<TabPanel value="1" classes={{ root: classes.tabPanelRoot}}>
...
)
}
See edited code here.

since the parent container is not of full height so, the tanpanel is not of full height. to make the tabpanel of full height pass a class to the root of the tabpanel. Pass the required height to tabpanelRoot class. (here I've neglected the height of the appbar)
export default function App() {
const classes= useStyles()
const [value, setValue] = React.useState("1");
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<Box style={{height:'100%', background:'red'}}>
<TabContext value={value}>
<AppBar position="static">
<TabList
variant="scrollable"
onChange={handleChange}
aria-label="simple tabs example"
>
<Tab label="Business Info" value="1" icon={<ContactMailIcon />} />
<Tab label="Financial" value="2" icon={<MonetizationOnIcon />} />
<Tab label="Participants" value="3" icon={<AccessibilityIcon />} />
</TabList>
</AppBar>
<Box style={{height:'100%', background:'red'}}>
<TabPanel value="1" classes={{root:classes.tabpanelRoot}}>
<Box style={{height:'100%', backgroundColor: "red" }}>Content 1</Box>
</TabPanel>
<TabPanel value="2" classes={{root:classes.tabpanelRoot}}>
<Box style={{height:'100%', backgroundColor: "green" }}>Content 2</Box>
</TabPanel>
<TabPanel value="3" classes={{root:classes.tabpanelRoot}}>
<Box style={{height:'100%', backgroundColor: "blue" }}>Content 3</Box>
</TabPanel>
</Box>
</TabContext>
</Box>
);
}
const useStyles = makeStyles((theme) => ({
tabpanelRoot: {
padding:0,
height: `calc(100vh - 52px)`
},
}));
Here is the codesandbox link:- https://codesandbox.io/s/angry-noether-huxvz

Try this
Updated code with useStyle hook.
App.js
import React from "react";
import "./styles.css";
import AppBar from "#material-ui/core/AppBar";
import Tab from "#material-ui/core/Tab";
import TabContext from "#material-ui/lab/TabContext";
import TabList from "#material-ui/lab/TabList";
import TabPanel from "#material-ui/lab/TabPanel";
import Box from "#material-ui/core/Box";
import MonetizationOnIcon from "#material-ui/icons/MonetizationOn";
import ContactMailIcon from "#material-ui/icons/ContactMail";
import AccessibilityIcon from "#material-ui/icons/Accessibility";
import { makeStyles } from "#material-ui/core";
const useStyles = makeStyles({
appContainer: {
display: "flex",
flexDirection: "column",
width: "100vw",
height: "100vh"
},
container: {
display: "flex",
height: "100%",
width: "100%"
},
panel: {
width: "100%"
}
});
export default function App() {
const [value, setValue] = React.useState("1");
const classes = useStyles();
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<Box className={classes.appContainer}>
<TabContext value={value}>
<AppBar position="static">
<TabList
variant="scrollable"
onChange={handleChange}
aria-label="simple tabs example"
>
<Tab label="Business Info" value="1" icon={<ContactMailIcon />} />
<Tab label="Financial" value="2" icon={<MonetizationOnIcon />} />
<Tab label="Participants" value="3" icon={<AccessibilityIcon />} />
</TabList>
</AppBar>
<Box className={classes.container}>
<TabPanel value="1" className={classes.panel}>
<Box
className={classes.container}
style={{ backgroundColor: "red" }}
>
Content 1
</Box>
</TabPanel>
<TabPanel value="2" className={classes.panel}>
<Box style={{ backgroundColor: "green" }} className={classes.container} >Content 2</Box>
</TabPanel>
<TabPanel value="3" className={classes.panel}>
<Box className={classes.container} style={{ backgroundColor: "blue" }}>Content 3</Box>
</TabPanel>
</Box>
</TabContext>
</Box>
);
}
Here is the sandbox link - https://codesandbox.io/s/shy-voice-nih2s

import * as React from 'react';
import Box from '#mui/material/Box';
import Tab from '#mui/material/Tab';
import TabContext from '#mui/lab/TabContext';
import TabList from '#mui/lab/TabList';
import TabPanel from '#mui/lab/TabPanel';
export default function LabTabs() {
const [value, setValue] = React.useState('1');
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<Box sx={{ width: '100%', typography: 'body1' }}>
<TabContext value={value}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<TabList onChange={handleChange} aria-label="lab API tabs example">
<Tab label="Item One" value="1" />
<Tab label="Item Two" value="2" />
<Tab label="Item Three" value="3" />
</TabList>
</Box>
<TabPanel sx={{pl: 1,pt:1}} value="1">Item One</TabPanel>
<TabPanel sx={{pl: 1,pt:1}} value="2">Item Two</TabPanel>
<TabPanel sx={{pl: 1,pt:1}} value="3">Item Three</TabPanel>
</TabContext>
</Box>
);
}

Tabs Height can be changed by .MuiTabs-root
const AntTab = styled((props: StyledTabProps) => (
<Tab disableRipple {...props} />
))(() => ({
**minHeight: '33px',
maxHeight: '33px',**
color: '#718296',
fontFamily: 'Montserrat',
}))

Related

Selecting another mui tab breaks css from Google code prettify CDN

This is my site with this issue.
I'm coding a blog in ReactJS. In this article section, I use a mui Tabs and three mui Tabs like this to take apart an article into description, code and others parts. In description and code parts, I use google-code-prettify.
It works when I load the description page but it doesn't work when I click code or others page and then back to the description page.
BasicTabs.js
import React, { useState } from 'react';
import Box from '#mui/material/Box';
import Tab from '#mui/material/Tab';
import Tabs from '#mui/material/Tabs';
import CreateTabPanel from "./TabPanel";
export default function CreateBasicTabs(props) {
const [value, setValue] = useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
function a11yProps(index) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
const boxSx = {
position: 'sticky',
top: props.breadcrumbsHeight + 9.5,
borderBottomLeftRadius: 10,
borderBottomRightRadius: 10,
}
const boxSxForTablet = {
position: 'sticky',
top: props.appBarHeight - 0.5,
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
}
return (
<Box sx={{ width: '100%' }}>
<Box
sx={props.isTablet ? boxSxForTablet : boxSx}
className={`pop-up ${props.isScrolling && 'active shadow-active'}`}
>
<Tabs
value={value}
onChange={handleChange}
aria-label="basic tabs example"
sx={{ paddingLeft: 4 }}
>
<Tab label="Detail" {...a11yProps(0)} sx={{ textTransform: 'none' }} />
<Tab label="Code" {...a11yProps(1)} sx={{ textTransform: 'none' }} />
<Tab label="Others" {...a11yProps(2)} sx={{ textTransform: 'none' }} />
</Tabs>
</Box>
<CreateTabPanel value={value} />
</Box >
);
}
TabPanel.js
import React from 'react';
import Box from '#mui/material/Box';
import PropTypes from 'prop-types';
import Typography from '#mui/material/Typography';
import { data } from "../assets/data";
import { useSearchParams } from "react-router-dom";
function getArticleContent() {
const [searchParams] = useSearchParams();
const articleTitle = searchParams.get('title');
for (const item of data) {
if (articleTitle === item.query) {
return item.content;
}
}
}
function TabPanel(tabProps) {
const { children, value, index, ...other } = tabProps;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
style={{
backgroundColor: 'rgb(255, 255, 255)',
borderRadius: 10,
marginLeft: 30,
marginRight: 30,
marginBottom: 30,
}}
{...other}
className='shadow-active'
>
{value === index && (
<Box
sx={{
p: 3,
marginBottom: 10,
}}
>
<Typography>
{children}
</Typography>
</Box>
)}
</div>
);
}
export default function CreateTabPanel(props) {
return (
<>
<TabPanel value={props.value} index={0}>
<div
dangerouslySetInnerHTML={{ __html: getArticleContent() }}
/>
</TabPanel>
<TabPanel value={props.value} index={1}>
<div
dangerouslySetInnerHTML={{ __html: getArticleContent() }}
/>
</TabPanel>
<TabPanel value={props.value} index={2}>
Item Three
</TabPanel>
</>
);
}
CreateTabPanel.propTypes = {
children: PropTypes.node,
index: PropTypes.number.isRequired,
value: PropTypes.number.isRequired,
};
These are screen captures of when it is loaded and when I back to the page.
The second capture looks like blackout but this is because it's css from google-code-prettify works
pre.prettyprint {
border: 0 solid #888;
}
.prettyprint {
background: #000;
}
Could you tell me why it does not work?

how to update parent component when changing child component?

I have two components. A parent component which englobes table of items and an edit component which is opend when only one item is selected to be modified.
this is the parent component:
import * as React from 'react';
import Table from '#mui/material/Table';
import TableBody from '#mui/material/TableBody';
import TableCell from '#mui/material/TableCell';
import TableHead from '#mui/material/TableHead';
import TableRow from '#mui/material/TableRow';
import Title from './Title';
import Grid from '#mui/material/Grid';
import Paper from '#mui/material/Paper';
import Box from '#mui/material/Box';
import Toolbar from '#mui/material/Toolbar';
import Container from '#mui/material/Container';
import { useState, useEffect } from "react";
import ReportDataService from "../services/report";
import FormDialogAdd from "./add-report";
import DeleteDialog from "./delete-report";
import FormDialogEdit from "./edit-report";
const ReportsList = props => {
const [reports, setReports] = useState([]);
// console.log("salut",reports)
const retrieveReports = () => {
ReportDataService.getAll()
.then(response => {
// console.log(response.data);
setReports(response.data.reports);
})
.catch(e => {
console.log(e);
});
};
// update dom after changes were made
useEffect(() => {
retrieveReports();
}, []);
return (
<Box
component="main"
sx={{
backgroundColor: (theme) =>
theme.palette.mode === 'light'
? theme.palette.grey[100]
: theme.palette.grey[900],
flexGrow: 1,
height: '100vh',
overflow: 'auto',
}}
>
<Toolbar />
<Container maxWidth="lg" sx={{ mt: 4, mb: 4 }}>
<Grid container spacing={3}>
{/* Recent Orders */}
<Grid item xs={12}>
<Paper sx={{ p: 2, display: 'flex', flexDirection: 'column' }}>
<React.Fragment>
<Title>Reports</Title>
<Table size="small">
<TableHead>
<TableRow>
<TableCell>name</TableCell>
<TableCell>ecu</TableCell>
<TableCell>category</TableCell>
<TableCell>lastModified</TableCell>
<TableCell>comment</TableCell>
<TableCell>reviewed</TableCell>
</TableRow>
</TableHead>
<TableBody>
{reports.map((report, index) => (
<TableRow key={index}>
<TableCell required>{report.name}</TableCell>
<TableCell>{report.ecu}</TableCell>
<TableCell>{report.category}</TableCell>
<TableCell>{report.lastModified.slice(0,10)}</TableCell>
<TableCell>{report.comment}</TableCell>
<TableCell>{report.reviewd ? "True" : "False"}</TableCell>
<Box sx={{ display: 'flex' }}>
<FormDialogEdit reportId={report._id}/>
<DeleteDialog reportId={report._id} />
</Box>
</TableRow>
))}
</TableBody>
</Table>
</React.Fragment>
</Paper>
<FormDialogAdd/>
</Grid>
</Grid>
</Container>
</Box>
);
};
export default ReportsList;
and this code is for the child component for edit:
import * as React from 'react';
import Button from '#mui/material/Button';
import TextField from '#mui/material/TextField';
import Dialog from '#mui/material/Dialog';
import DialogActions from '#mui/material/DialogActions';
import DialogContent from '#mui/material/DialogContent';
import DialogContentText from '#mui/material/DialogContentText';
import ListItemButton from '#mui/material/ListItemButton';
import FormControlLabel from '#mui/material/FormControlLabel';
import Switch from '#mui/material/Switch';
import ListItemText from '#mui/material/ListItemText';
import DialogTitle from '#mui/material/DialogTitle';
import Fab from '#mui/material/Fab';
import EditIcon from '#mui/icons-material/Edit';
import ReportDataService from "../services/report";
import Box from '#mui/material/Box';
import { useState, useEffect } from "react";
export default function FormDialogEdit(props) {
const [open, setOpen] = React.useState(false);
const handleClose = () => {
setOpen(false);
};
const getSingleReport = (reportId) => {
setOpen(true);
// console.log(reportId)
ReportDataService.get(reportId)
.then(response => {
// console.log("data",response.data);
setReport(response.data);
})
.catch(e => {
console.log(e);
});
};
let initialReportState = ""
const [report, setReport] = useState(initialReportState);
// begins always false=> not convincing param=> should be updated like reviewd
const [manualTest, setManualTest] = React.useState(false);
const handleChangeTestManual = (event) =>{
setManualTest(event.target.checked)
}
const [inputs, setInputs] = useState({});
console.log(inputs);
const handleChange = e => setInputs(prevState => ({ ...prevState, [e.target.name]: e.target.value }));
const handleChangeReviewed= e => setInputs(prevState => ({ ...prevState, [e.target.name]: e.target.checked }));
// console.log("hi",inputs)
const saveReport = () => {
ReportDataService.updateReport(inputs)
.then(response => {
// console.log(response.data);
})
.catch(e => {
console.log(e);
});
};
useEffect(() => {
setInputs(report)
}, [report]);
return (
<div>
<Fab size="small" sx={{ m: 1}} color="primary" aria-label="edit" onClick={() => getSingleReport(props.reportId)}>
<EditIcon />
</Fab>
<Dialog open={open} onClose={handleClose}>
<DialogTitle>Edit report</DialogTitle>
<DialogContent>
<DialogContentText>
You can see here all informations about a report and modify parameters
</DialogContentText>
<Box sx={{ border: 1, borderColor: 'grey.500', borderRadius: 2, marginTop:2}}>
<ListItemButton>
<TextField
autoFocus
margin="dense"
id="name"
label="Name"
name="name"
type="text"
value={inputs.name}
onChange={handleChange}
fullWidth
variant="standard"
/>
</ListItemButton>
<ListItemButton>
<TextField
autoFocus
margin="dense"
id="name"
label="Ecu"
name="ecu"
value={inputs.ecu}
onChange={handleChange}
type="text"
fullWidth
variant="standard"
/>
</ListItemButton>
<ListItemButton>
<TextField
autoFocus
margin="dense"
id="name"
label="Category"
name="category"
value={inputs.category}
onChange={handleChange}
type="text"
fullWidth
variant="standard"
/>
</ListItemButton>
<ListItemButton>
<TextField
autoFocus
margin="dense"
id="name"
label="Comment"
name="comment"
value={inputs.comment}
onChange={handleChange}
type="text"
fullWidth
variant="standard"
/>
</ListItemButton>
<ListItemButton>
<FormControlLabel
control={
<Switch
checked= {manualTest}
onChange={handleChangeTestManual}
/>
}
label="Manual test" />
</ListItemButton>
<ListItemButton>
<FormControlLabel
control={
<Switch
checked= {inputs.reviewd}
name="reviewd"
onChange={handleChangeReviewed}
/>
} label="Reviewed" />
</ListItemButton>
</Box>
<Box sx={{ border: 1, borderColor: 'grey.500', borderRadius: 2, marginTop:2}}>
<ListItemButton>
<ListItemText primary="Last Modified by" secondary={report.lastModifiedBy} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Last Modified" secondary={report.lastModified} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Rating" secondary={report.rating} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Error injection" secondary={report.errorInjection} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Simulation" secondary={report.simulation} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Test cases" secondary={report.testCases} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Last run" secondary={report.lastRun} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="File" secondary={report.file} />
</ListItemButton>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
<Button onClick={() =>{
saveReport();
handleClose();
}}>
Update</Button>
</DialogActions>
</Dialog>
</div>
);
}
I want to be able to update the parent component when clicking on the update button in the child component. In other world I want the parent component to refresh and modify changes directly. The solution from what i saw is with useEffect but i didn`t know how to use it. So can anyone help? How to notify the parent that a changment has been made so that the table should be updated as soon as the update button in the child is clicked?
Add a props into your child component
like this props.func('updated');
import * as React from 'react';
import Button from '#mui/material/Button';
import TextField from '#mui/material/TextField';
import Dialog from '#mui/material/Dialog';
import DialogActions from '#mui/material/DialogActions';
import DialogContent from '#mui/material/DialogContent';
import DialogContentText from '#mui/material/DialogContentText';
import ListItemButton from '#mui/material/ListItemButton';
import FormControlLabel from '#mui/material/FormControlLabel';
import Switch from '#mui/material/Switch';
import ListItemText from '#mui/material/ListItemText';
import DialogTitle from '#mui/material/DialogTitle';
import Fab from '#mui/material/Fab';
import EditIcon from '#mui/icons-material/Edit';
import ReportDataService from "../services/report";
import Box from '#mui/material/Box';
import { useState, useEffect } from "react";
export default function FormDialogEdit(props) {
props.func('updated');
const [open, setOpen] = React.useState(false);
const handleClose = () => {
setOpen(false);
};
const getSingleReport = (reportId) => {
setOpen(true);
// console.log(reportId)
ReportDataService.get(reportId)
.then(response => {
// console.log("data",response.data);
setReport(response.data);
})
.catch(e => {
console.log(e);
});
};
let initialReportState = ""
const [report, setReport] = useState(initialReportState);
// begins always false=> not convincing param=> should be updated like reviewd
const [manualTest, setManualTest] = React.useState(false);
const handleChangeTestManual = (event) =>{
setManualTest(event.target.checked)
}
const [inputs, setInputs] = useState({});
console.log(inputs);
const handleChange = e => setInputs(prevState => ({ ...prevState, [e.target.name]: e.target.value }));
const handleChangeReviewed= e => setInputs(prevState => ({ ...prevState, [e.target.name]: e.target.checked }));
// console.log("hi",inputs)
const saveReport = () => {
ReportDataService.updateReport(inputs)
.then(response => {
// console.log(response.data);
})
.catch(e => {
console.log(e);
});
};
useEffect(() => {
setInputs(report)
}, [report]);
return (
<div>
<Fab size="small" sx={{ m: 1}} color="primary" aria-label="edit" onClick={() => getSingleReport(props.reportId)}>
<EditIcon />
</Fab>
<Dialog open={open} onClose={handleClose}>
<DialogTitle>Edit report</DialogTitle>
<DialogContent>
<DialogContentText>
You can see here all informations about a report and modify parameters
</DialogContentText>
<Box sx={{ border: 1, borderColor: 'grey.500', borderRadius: 2, marginTop:2}}>
<ListItemButton>
<TextField
autoFocus
margin="dense"
id="name"
label="Name"
name="name"
type="text"
value={inputs.name}
onChange={handleChange}
fullWidth
variant="standard"
/>
</ListItemButton>
<ListItemButton>
<TextField
autoFocus
margin="dense"
id="name"
label="Ecu"
name="ecu"
value={inputs.ecu}
onChange={handleChange}
type="text"
fullWidth
variant="standard"
/>
</ListItemButton>
<ListItemButton>
<TextField
autoFocus
margin="dense"
id="name"
label="Category"
name="category"
value={inputs.category}
onChange={handleChange}
type="text"
fullWidth
variant="standard"
/>
</ListItemButton>
<ListItemButton>
<TextField
autoFocus
margin="dense"
id="name"
label="Comment"
name="comment"
value={inputs.comment}
onChange={handleChange}
type="text"
fullWidth
variant="standard"
/>
</ListItemButton>
<ListItemButton>
<FormControlLabel
control={
<Switch
checked= {manualTest}
onChange={handleChangeTestManual}
/>
}
label="Manual test" />
</ListItemButton>
<ListItemButton>
<FormControlLabel
control={
<Switch
checked= {inputs.reviewd}
name="reviewd"
onChange={handleChangeReviewed}
/>
} label="Reviewed" />
</ListItemButton>
</Box>
<Box sx={{ border: 1, borderColor: 'grey.500', borderRadius: 2, marginTop:2}}>
<ListItemButton>
<ListItemText primary="Last Modified by" secondary={report.lastModifiedBy} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Last Modified" secondary={report.lastModified} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Rating" secondary={report.rating} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Error injection" secondary={report.errorInjection} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Simulation" secondary={report.simulation} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Test cases" secondary={report.testCases} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="Last run" secondary={report.lastRun} />
</ListItemButton>
<ListItemButton>
<ListItemText primary="File" secondary={report.file} />
</ListItemButton>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
<Button onClick={() =>{
saveReport();
handleClose();
}}>
Update</Button>
</DialogActions>
</Dialog>
</div>
);
}
**And in Parent component **
use that props like this
import Container from '#mui/material/Container';
import { useState, useEffect } from "react";
import ReportDataService from "../services/report";
import FormDialogAdd from "./add-report";
import DeleteDialog from "./delete-report";
import FormDialogEdit from "./edit-report";
const ReportsList = props => {
const [reports, setReports] = useState([]);
// console.log("salut",reports)
const retrieveReports = () => {
ReportDataService.getAll()
.then(response => {
// console.log(response.data);
setReports(response.data.reports);
})
.catch(e => {
console.log(e);
});
};
// update dom after changes were made
useEffect(() => {
retrieveReports();
}, []);
return (
<Box
component="main"
sx={{
backgroundColor: (theme) =>
theme.palette.mode === 'light'
? theme.palette.grey[100]
: theme.palette.grey[900],
flexGrow: 1,
height: '100vh',
overflow: 'auto',
}}
>
<Toolbar />
<Container maxWidth="lg" sx={{ mt: 4, mb: 4 }}>
<Grid container spacing={3}>
{/* Recent Orders */}
<Grid item xs={12}>
<Paper sx={{ p: 2, display: 'flex', flexDirection: 'column' }}>
<React.Fragment>
<Title>Reports</Title>
<Table size="small">
<TableHead>
<TableRow>
<TableCell>name</TableCell>
<TableCell>ecu</TableCell>
<TableCell>category</TableCell>
<TableCell>lastModified</TableCell>
<TableCell>comment</TableCell>
<TableCell>reviewed</TableCell>
</TableRow>
</TableHead>
<TableBody>
{reports.map((report, index) => (
<TableRow key={index}>
<TableCell required>{report.name}</TableCell>
<TableCell>{report.ecu}</TableCell>
<TableCell>{report.category}</TableCell>
<TableCell>{report.lastModified.slice(0,10)}</TableCell>
<TableCell>{report.comment}</TableCell>
<TableCell>{report.reviewd ? "True" : "False"}</TableCell>
<Box sx={{ display: 'flex' }}>
<FormDialogEdit reportId={report._id} func={retrieveReports}/>
<DeleteDialog reportId={report._id} />
</Box>
</TableRow>
))}
</TableBody>
</Table>
</React.Fragment>
</Paper>
<FormDialogAdd/>
</Grid>
</Grid>
</Container>
</Box>
);
};
export default ReportsList;
add a new prop to the child component which passes retrieveReports , this can then be called within the child component and the state will update within the parent making it refresh
<FormDialogEdit reportId={report._id} retrieveReports={retrieveReports}/>
Called within child with : props.retrieveReports()

Material-UI popover triggered by onMouseOver is blocking onClick event of button - React.js

This is Header.js where I have the button <ReactSvg>, inside <IconButton> when you click it, it will change the page theme with the switchTheme() function. When you hover over the button it also has a popover where it declares the function of the button (ex. switch theme).
For some reason I hover the button the popover comes out but doesn't let me click on the button even if I click very fast and vigorously. Somehow the popover has disabled the button.
Header file where the button is rendered:
import React, { useState } from 'react'
import ReactSvg from './reactSvg'
import { Box, Typography, Link, Container, IconButton } from '#material-ui/core'
import PhoneIcon from '#material-ui/icons/Phone'
import EmailIcon from '#material-ui/icons/Email'
import GitHubIcon from '#material-ui/icons/GitHub'
import LinkedInIcon from '#material-ui/icons/LinkedIn'
import { useStyles } from '../styles/customStyles'
import Image from 'material-ui-image'
import PopOver from './PopOver'
const styles = {
image: {
maxWidth: 200,
minWidth: 200,
},
}
export default function Header({ switchTheme }) {
const classes = useStyles()
const [anchorEl, setAnchorEl] = useState(null)
const handleTheme = () => {
switchTheme()
}
const handleHover = (e) => {
setAnchorEl(e.currentTarget)
}
return (
<>
<Box>
<IconButton onClick={() => handleTheme()} onMouseOver={(e) => handleHover(e)}>
<ReactSvg />
</IconButton>
<Typography variant="h3" color="primary">
Staz Christodoulakis
</Typography>
<Typography variant="body1" color="primary">
Software Engineer ยท Web/App
</Typography>
<hr className="solid" />
<Box
display="flex"
alignItems="center"
justifyContent="center"
className={classes.root}
flexWrap="wrap"
>
<Link color="secondary" variant="body1" href="tel: 650-409-6202">
<Box display="flex">
<PhoneIcon /> 650 409 6202
</Box>
</Link>
<Link color="secondary" variant="body1" href="mailto: staz.christo#gmail.com">
<Box display="flex">
<EmailIcon /> staz.christo#gmail.com
</Box>
</Link>
<Link href="https://github.com/stazcp" color="secondary" variant="body1">
<Box display="flex">
<GitHubIcon /> github.com/stazcp
</Box>
</Link>
<Link href="https://www.linkedin.com/in/staz-christo" color="secondary" variant="body1">
<Box display="flex">
<LinkedInIcon /> linkedin.com/in/staz-christo
</Box>
</Link>
</Box>
</Box>
<PopOver anchorEl={anchorEl} setAnchorEl={setAnchorEl} />
</>
)
}
Popover:
import React, { useState, useEffect } from 'react'
import { makeStyles } from '#material-ui/core/styles'
import Popover from '#material-ui/core/Popover'
import Typography from '#material-ui/core/Typography'
import Button from '#material-ui/core/Button'
const useStyles = makeStyles((theme) => ({
typography: {
padding: theme.spacing(2),
},
}))
export default function SimplePopover({ anchorEl, setAnchorEl }) {
const classes = useStyles()
const handleClose = () => {
setAnchorEl(null)
}
const open = Boolean(anchorEl)
const id = open ? 'simple-popover' : undefined
return (
<div>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
>
<Typography className={classes.typography}>
Click on React Symbol to change theme!
</Typography>
</Popover>
</div>
)
}
Why is that the onMouseOver event blocking the onClick event?
Can you try stopPropagation?
const handleHover = (e) => {
e.stopPropagation();
setAnchorEl(e.currentTarget)
}
So I found a solution to my problem by using a Tooltip provided by Material UI.
https://material-ui.com/components/tooltips/
Like this:
<Tooltip title="Click Me!" placement="right" arrow>
<IconButton
onClick={() => handleTheme()}
// onMouseOver={(e) => handleHover(e)}
>
<GetIcon icon={reactLogo} className="reactLogo" />
</IconButton>
</Tooltip>
if anyone has managed to use different methods for mouse events on Material UI buttons please post here.
Thanks!

Certain components show fail to show up on screen and inspect element isn't helping

I'm trying to design a UI that looks like this
So far what I have is this
The problem I'm having is getting the info icon to show up where it's supposed to be and getting the direct text and create icon on the top left corner. I also can't have the primary and general show up in my UI like Instagrams and the scrollbar on my drawer goes all the way up instead of stopping where the appbar is.
Here's my code
import React from "react";
import { makeStyles, withStyles } from "#material-ui/core/styles";
import Drawer from "#material-ui/core/Drawer";
import AppBar from "#material-ui/core/AppBar";
import Toolbar from "#material-ui/core/Toolbar";
import List from "#material-ui/core/List";
import Typography from "#material-ui/core/Typography";
import Divider from "#material-ui/core/Divider";
import ListItem from "#material-ui/core/ListItem";
import ListItemText from "#material-ui/core/ListItemText";
import Avatar from "#material-ui/core/Avatar";
import PersonIcon from "#material-ui/icons/Person";
import Badge from "#material-ui/core/Badge";
import InfoIcon from "#material-ui/icons/Info";
import ListItemAvatar from "#material-ui/core/ListItemAvatar";
import { connect } from "react-redux";
function mapStateToProps(state) {
return {};
}
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
},
appBar: {
width: `calc(100% - ${drawerWidth}px)`,
backgroundColor: "#fff",
},
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
// necessary for content to be below app bar
toolbar: theme.mixins.toolbar,
content: {
flexGrow: 1,
backgroundColor: theme.palette.background.default,
padding: theme.spacing(3),
},
}));
const SmallAvatar = withStyles((theme) => ({
root: {
width: 11,
height: 11,
color: "green",
backgroundColor: "green",
},
}))(Avatar);
const Messaging = () => {
const classes = useStyles();
const dummy = "Active now";
return (
<div className={classes.root}>
<AppBar position='fixed' className={classes.appBar}>
<Toolbar style={{ width: "100%" }}>
<Avatar>
<PersonIcon />
</Avatar>
<Typography variant='h6'>adib.akm</Typography>
<InfoIcon />
</Toolbar>
</AppBar>
<Drawer
className={classes.drawer}
variant='permanent'
classes={{
paper: classes.drawerPaper,
}}
anchor='left'>
<div className={classes.toolbar} />
<Divider />
<List>
<ListItem>
<ListItemAvatar>
<Badge
overlap='circle'
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
badgeContent={<SmallAvatar />}>
<Avatar>
<PersonIcon />
</Avatar>
</Badge>
</ListItemAvatar>
<ListItemText primary='Photos' secondary={dummy} />
</ListItem>
<ListItem>
<ListItemAvatar>
<Badge
overlap='circle'
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
badgeContent={<SmallAvatar />}>
<Avatar>
<PersonIcon />
</Avatar>
</Badge>
</ListItemAvatar>
<ListItemText primary='Work' secondary={dummy} />
</ListItem>
<ListItem>
<ListItemAvatar>
<Badge
overlap='circle'
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
badgeContent={<SmallAvatar />}>
<Avatar>
<PersonIcon />
</Avatar>
</Badge>
</ListItemAvatar>
<ListItemText primary='Vacation' secondary={dummy} />
</ListItem>
</List>
</Drawer>
</div>
);
};
export default connect(mapStateToProps)(Messaging);
This is the codesandbox https://codesandbox.io/s/mutable-monad-dsvf8?file=/src/index.js

How to position content perfectly within the left center of Paper component and remain that way on smaller devices?

I am putting together a component for my Goal Sharing social media app. This is what I have so far:
I'm trying to position the Avatar component as well as the two typography components beneath the Avatar component within the center of the left section of this Paper component. I have tried doing this by altering marginLeft and marginTop as you can see in the code below, but the issue when I do this is the components in this Goal component jumble on top of each other when I switch over to smaller devices. So, what's the best way to position these components in the center of the left section, and to ensure they remain that way on smaller devices?
This is the parent component file:
import React, { useEffect } from "react";
import Moment from "react-moment";
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import { getGoals } from "../../actions/goal";
import Spinner from "../layout/Spinner";
import Navbar from "../dashboard/Navbar";
import ThumbUpAltIcon from "#material-ui/icons/ThumbUpAlt";
import ThumbDownAltIcon from "#material-ui/icons/ThumbDownAlt";
import ChatIcon from "#material-ui/icons/Chat";
import DeleteIcon from "#material-ui/icons/Delete";
import DoneIcon from "#material-ui/icons/Done";
import {
Typography,
Container,
CssBaseline,
makeStyles,
Grid,
Card,
Avatar,
CardContent,
CardActions
} from "#material-ui/core";
const useStyles = makeStyles(theme => ({
paper: {
marginTop: theme.spacing(8),
display: "flex",
flexDirection: "column",
alignItems: "center"
},
submit: {
margin: theme.spacing(2, 0, 2)
},
form: {
marginTop: theme.spacing(5)
},
cardGrid: {
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4)
},
card: {
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center"
},
cardContent: {
flexGrow: 1
},
profileHeader: {
textAlign: "center",
marginBottom: 10
},
avatar: {
width: theme.spacing(10),
height: theme.spacing(10),
marginLeft: "2.5vw",
marginTop: "5vh"
},
name: {
textAlign: "center",
marginLeft: "2vw"
},
goalText: {
marginTop: "5vh",
marginLeft: "3vw"
},
postedOn: {
marginLeft: "2vw"
}
}));
const Goals = ({ getGoals, auth, goal: { goals, user, loading } }) => {
useEffect(() => {
getGoals();
}, [getGoals]);
const classes = useStyles();
return loading ? (
<>
<Navbar />
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Spinner />
</div>
</Container>
</>
) : (
<>
<CssBaseline />
<Navbar />
<main>
<Container className={classes.cardGrid} maxWidth="md">
<Typography variant="h2" className={classes.profileHeader}>
Goals
</Typography>
<Grid container spacing={4}>
{goals.map(singleGoal => (
<Grid item key={singleGoal._id} xs={12}>
<Card fullwidth="true" className={classes.card}>
<Grid container spacing={2}>
<Grid item>
<Avatar
className={classes.avatar}
src={singleGoal.avatar}
/>
<Typography variant="subtitle2" className={classes.name}>
{singleGoal.first_name} {singleGoal.last_name}
</Typography>
<Typography
variant="caption"
className={classes.postedOn}
>
Posted on{" "}
<Moment format="MM/DD/YYYY">{singleGoal.date}</Moment>
</Typography>
</Grid>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<Typography
className={classes.goalText}
variant="body1"
gutterBottom
>
{singleGoal.text}
</Typography>
<Typography variant="h5"></Typography>
</Grid>
</Grid>
</Grid>
</Grid>
<CardContent className={classes.cardContent}></CardContent>
<CardActions>
<ThumbUpAltIcon />
<Typography variant="caption">
{singleGoal.likes.length}
</Typography>
<ThumbDownAltIcon />
<Link to={`/goal/${singleGoal.user}`}>
<ChatIcon />
</Link>
<Typography variant="caption">
{singleGoal.comments.length}
</Typography>
{!auth.loading && singleGoal.user === auth.user._id && (
<DoneIcon />
)}
{!auth.loading && singleGoal.user === auth.user._id && (
<DeleteIcon />
)}
</CardActions>
</Card>
</Grid>
))}
</Grid>
</Container>
</main>
</>
);
};
Goals.propTypes = {
getGoals: PropTypes.func.isRequired,
goal: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
goal: state.goal,
auth: state.auth
});
export default connect(mapStateToProps, { getGoals })(Goals);
Try this
card: {
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center"
},

Categories

Resources