React: Blur background when Material-UI Dialog appeared - javascript

Is there any way I can blur the background content when an MUI dialog appears? (the default action is darkening the background, but I need to blur it).
Here's what I am looking for:

One way to solve this is to use a backdropFilter on the dialog backdrop, which can blur the background. The backdropFilter css property is a relatively new css feature but it works well on Chrome, Edge, Samsung Internet and Safari. It doesn't work on Firefox at this time. But maybe that's suitable for you? Here's a code example:
import React from "react";
import { Dialog, DialogContent, makeStyles, Theme, Typography } from "#material-ui/core";
const useStyles = makeStyles((theme: Theme) => ({
backDrop: {
backdropFilter: "blur(3px)",
backgroundColor:'rgba(0,0,30,0.4)'
},
}));
export default function ExampleDialogComponent() {
const classes = useStyles();
return (
<Dialog
open={true}
BackdropProps={{
classes: {
root: classes.backDrop,
},
}}
onClose={() => {}}
>
<DialogContent style={{ textAlign: "center" }}>
<Typography variant="body1">Example Dialog</Typography>
</DialogContent>
</Dialog>
);
}
Update for Material UI 5
In the upcoming version of Material UI 5, you could use a styled component like this:
import Box from "#material-ui/core/Box";
import { experimentalStyled as styled } from "#material-ui/core/styles";
import Dialog, { DialogProps } from "#material-ui/core/Dialog";
import DialogTitle from "#material-ui/core/DialogTitle";
import DialogContent from "#material-ui/core/DialogContent";
import DialogActions from "#material-ui/core/DialogActions";
import Button from "#material-ui/core/Button";
import CssBaseline from "#material-ui/core/CssBaseline";
const BlurryDialog = styled(Dialog)<DialogProps>(({ theme }) => ({
backdropFilter: "blur(5px)",
// other styles here...
}));
export default function ExampleNextDialog() {
return (
<>
<CssBaseline />
<BlurryDialog fullWidth onClose={() => {}} open={true} maxWidth="xs">
<DialogTitle>Example Dialog</DialogTitle>
<DialogContent>Example Content Here</DialogContent>
<DialogActions>
<Button>ooooh.</Button>
</DialogActions>
</BlurryDialog>
<Box
sx={{
minHeight: "100vh",
background:
"url(https://source.unsplash.com/random) no-repeat center center",
backgroundSize: "cover",
}}
></Box>
</>
);
}
Or use the sx prop like this:
import Box from "#material-ui/core/Box";
import Dialog from "#material-ui/core/Dialog";
import DialogTitle from "#material-ui/core/DialogTitle";
import DialogContent from "#material-ui/core/DialogContent";
import DialogActions from "#material-ui/core/DialogActions";
import Button from "#material-ui/core/Button";
import CssBaseline from "#material-ui/core/CssBaseline";
export default function ExampleNextDialog() {
return (
<>
<CssBaseline />
<Dialog
fullWidth
onClose={() => {}}
open={true}
maxWidth="xs"
sx={{
backdropFilter: "blur(5px)",
//other styles here
}}
>
<DialogTitle>Example Dialog</DialogTitle>
<DialogContent>Example Content Here</DialogContent>
<DialogActions>
<Button>ooooh.</Button>
</DialogActions>
</Dialog>
<Box
sx={{
minHeight: "100vh",
background:
"url(https://source.unsplash.com/random) no-repeat center center",
backgroundSize: "cover",
}}
></Box>
</>
);
}

You need to add some class to your content root block after dialog opens and add filter styles for that class: filter: blur(3px);

Related

How to link 2 different components from 2 different pages in React/MUI?

I have 2 pages, first Appbar.js that I have my topside appbar and also a Navigation Menu Icon Button that when I press that, I want my Drawer (Material UI) in TempDrawer.js to show up.
It worked when I put all the codes just in Appbar.js file, but I want to link these two pages somehow to have button in Appbar.js but function and return in the TempDrawer.js.
That's because I called TemporaryDrawer() as a tag (<TemporaryDrawer/>) in another file.
Appbar.js :
import * as React from 'react';
import Box from '#mui/material/Box';
import Drawer from '#mui/material/Drawer';
import Toolbar from '#mui/material/Toolbar';
import Button from '#mui/material/Button';
import List from '#mui/material/List';
import Divider from '#mui/material/Divider';
import ListItem from '#mui/material/ListItem';
import ListItemIcon from '#mui/material/ListItemIcon';
import ListItemText from '#mui/material/ListItemText';
import InboxIcon from '#mui/icons-material/MoveToInbox';
import MailIcon from '#mui/icons-material/Mail';
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
sx={{ mr: 2 }}
>
<MenuIcon />
</IconButton>
TempDrawer.js :
import * as React from 'react';
import AppBar from '#mui/material/AppBar';
import Box from '#mui/material/Box';
import Toolbar from '#mui/material/Toolbar';
import Button from '#mui/material/Button';
import IconButton from '#mui/material/IconButton';
import MenuIcon from '#mui/icons-material/Menu';
export default function TemporaryDrawer() {
return (
<Drawer
variant="temporary"
open
sx={{
width: drawerWidth,
flexShrink: 0,
[`& .MuiDrawer-paper`]: { width: drawerWidth, boxSizing: 'border-box' },
}}
>
<Toolbar />
<Box sx={{ overflow: 'auto' }}>
<List>
{['Inbox', 'Starred', 'Send email', 'Drafts'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
<Divider />
<List>
{['All mail', 'Trash', 'Spam'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
</Box>
</Drawer>
);
}
I am asuming you want to open drawer from App Bar or any other page and pass the function and state to it.
below is minimum working example.
Appbar.js :
import TempDrawer from "./TempDrawer";
export default function Appbar() {
const [open, setOpen] = React.useState(false);
const ToggleDrawer = () => {
setOpen(!open);
};
return (
<>
<Button onClick={ToggleDrawer}>click me</Button>
<TempDrawer open={open} ToggleDrawer={ToggleDrawer}/>
</>
);
}
TempDrawer.js :
export default function TemporaryDrawer({open,ToggleDrawer}) {
...
return (
<Drawer
open={open}
variant="temporary"
onClose={ToggleDrawer}
...
>
<Toolbar />
<Button onClick={ToggleDrawer}>Close</Button>
...
</Drawer>
);
}

ReactJS: Make Material UI Dialog Box Pop Up Full Screen

When I click on a button, I have a Material UI dialog box pop up successfully (yay!). Now I just want it to be full screen rather than only a small portion of the screen. I am trying to follow along in the Material UI API for the dialog box, but my box is not appearing full screen. Is there some sort of disconnect that I am missing here? Thanks a lot in advance (sorry if this is a noob question).
import React from 'react';
import { makeStyles } from '#material-ui/styles';
import Button from '#material-ui/core/Button';
import TextField from '#material-ui/core/TextField';
import Dialog from '#material-ui/core/Dialog';
import DialogActions from '#material-ui/core/DialogActions';
import DialogContent from '#material-ui/core/DialogContent';
import DialogContentText from '#material-ui/core/DialogContentText';
import DialogTitle from '#material-ui/core/DialogTitle';
import PhotoScrolling from './PhotoScrolling';
/* const useStyles = makeStyles({
imageSlider: {
backgroundColor: 'yellow',
color: 'black',
width: 400,
},
}); */
export default function FormDialog() {
// const classes = useStyles();
const [open, setOpen] = React.useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
<Button variant="outlined" color="primary" onClick={handleClickOpen}>
Open form dialog
</Button>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title"
fullScreen={true}
fullWidth={true}
>Section Title</DialogTitle>
<PhotoScrolling></PhotoScrolling>
<DialogActions>
<Button onClick={handleClose} color="primary">
Close
</Button>
</DialogActions>
</Dialog>
</div>
);
}
Try calling fullscreen={fullscreen} inside <Dialog fullscreen={fullscreen}/> it will work fine.
You are making mistake by calling it inside <DialogTitle/>.
Hope this will work.
return
(
<div>
<Button variant="outlined" color="primary" onClick={handleClickOpen}>
Open form dialog
</Button>
<Dialog
open={open}
onClose={handleClose}
fullScreen={true}//Here you need to add the function
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title"
fullWidth={true}
>Section Title</DialogTitle>
<PhotoScrolling></PhotoScrolling>
<DialogActions>
<Button onClick={handleClose} color="primary">
Close
</Button>
</DialogActions>
</Dialog>
</div>
)

Material UI dialog changes style of other components when opening

I have this Dialog component which I am showing from a button on my AppBar component.
Whenever I open that dialog, the margin on my navbar elements changes and I cant figure why. Upon inspecting the html using the dev tools nothing changes, no css changes on either of the elements on my components.
Any suggestions on how to debug this properly or where in the MUI docs to look is helpfull.
Edit: class .MuiTouchRipple-root is attached to my AddCircle component.
import React from 'react';
import Navbar from './components/Navbar';
import Home from './pages/Home';
import Box from '#mui/material/Box';
import {
BrowserRouter as Router,
Switch,
Route
} from "react-router-dom";
import { useState } from 'react';
import SelectInvoiceDialog from './components/SelectInvoiceDialog';
import ProcessInvoice from './pages/ProcessInvoice';
function App() {
const [open, setOpen] = useState(false);
const openSelectDialog = () => setOpen(true);
const closeSelectDialog = () => setOpen(false);
return (
<Router>
<Box>
<Navbar openDialog={openSelectDialog}/>
<Switch>
<Route exact path="/process">
<ProcessInvoice />
</Route>
<Route exact path="/">
<Home />
</Route>
</Switch>
</Box>
<SelectInvoiceDialog open={open} closeAction={closeSelectDialog}/>
</Router>
);
}
export default App;
import React from "react";
import AppBar from '#mui/material/AppBar';
import Box from '#mui/material/Box';
import Toolbar from '#mui/material/Toolbar';
import Typography from '#mui/material/Typography';
import AddCircle from '#material-ui/icons/AddCircle'
import IconButton from '#mui/material/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import { makeStyles, createStyles } from "#material-ui/core";
const useStyles = makeStyles((theme) => createStyles({
navBarStyle: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
display: 'flex',
flexDirection: 'row',
color: 'white'
}
}));
export default function Navbar ({ openDialog }) {
const classes = useStyles();
return (
<Box>
<AppBar position="static">
<Toolbar className={classes.navBarStyle}>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
>
<MenuIcon />
</IconButton>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>Invoice processor</Typography>
<IconButton
size="large"
color="inherit"
onClick={openDialog}
>
<AddCircle />
</IconButton>
</Toolbar>
</AppBar>
</Box>
);
}
import Button from '#material-ui/core/Button';
import Dialog from '#material-ui/core/Dialog';
import DialogActions from '#material-ui/core/DialogActions';
import DialogContent from '#material-ui/core/DialogContent';
import { DialogTitle, Select, MenuItem, FormControl, InputLabel, Box, TextField, Typography} from "#mui/material";
import { Link } from 'react-router-dom'
import { useState } from 'react';
export default function SelectInvoiceDialog ({ open, closeAction }) {
const [filePath, setFilePath] = useState('');
const [selection, setSelection] = useState('');
const handleChange = (e) => setSelection(e.target.value)
return (
<Dialog
open={open}
onClose={closeAction}
fullWidth
disableEnforceFocus
>
<DialogTitle>Process Invoice</DialogTitle>
<DialogContent>
<FormControl fullWidth>
<InputLabel id="selectTemplateLabel">Template</InputLabel>
<Select
labelId="selectTemplateLabel"
id="selectTemplate"
value={selection}
onChange={handleChange}
label="Template"
>
<MenuItem value={'DELL'}>DELL</MenuItem>
<MenuItem value={'AI'}>Automatic AI</MenuItem>
<MenuItem value={'30'}>Thirty</MenuItem>
</Select>
</FormControl>
<FormControl fullWidth>
<TextField label="Debtor Number"/>
</FormControl>
<FormControl>
<Typography>{filePath ? 'File name:' : ''} {filePath}</Typography>
<Button
variant="contained"
component="label"
size="large"
>
SELECT FILE
<input type="file" hidden onChange={(e) => setFilePath(e.target.files[0].name)}/>
</Button>
</FormControl>
<DialogActions>
<Button
variant="contained"
onClick={() => {
closeAction();
setFilePath('');
}}
component={Link}
to={'/process'}
>Process</Button>
</DialogActions>
</DialogContent>
</Dialog>
);
}
There is a good chance it is due to your mixing of #mui and #material-ui.
I got the fix by adding some css to the html body.
body {
margin: 0;
padding: 0;
}

MaterialUI show an other view after onclick event

I'm completely new in MaterialUI. I'm working on my first project right now and trying to make use of templates form its page. I've loaded two .tsx files with log in view and main dashboard view. I'd like to show main dashboard view after clicking Login button on log in view. Both files have its own export default function FnName() function with const classes = useStyles(); and it seems to cause my problems. The way of using hooks is the issue here I guess. But how to pass this function to onClick handler event button? You can see my project here:
https://codesandbox.io/s/adoring-leftpad-6nwv2?file=/src/SignIn.tsx
Somebody can help?
Please check this example:
App Component
import React, {useEffect, useState} from 'react';
import SignIn from "./material-ui/signin-template/SignIn";
import {BrowserRouter as Router, Switch, Route} from "react-router-dom";
import { createBrowserHistory as history} from 'history';
import MiniDrawer from "./material-ui/signin-template/Dashboard";
class App extends React.Component {
render() {
return (
<div>
<Router history={history}>
<Switch>
<Route path="/" exact component={SignIn}/>
<Route path="/dashboard" component={MiniDrawer}/>
</Switch>
</Router>
</div>
)
}
}
export default App;
SingIn Component
import React from "react";
import Avatar from "#material-ui/core/Avatar";
import Button from "#material-ui/core/Button";
import CssBaseline from "#material-ui/core/CssBaseline";
import TextField from "#material-ui/core/TextField";
import FormControlLabel from "#material-ui/core/FormControlLabel";
import Checkbox from "#material-ui/core/Checkbox";
import Link from "#material-ui/core/Link";
import Grid from "#material-ui/core/Grid";
import Box from "#material-ui/core/Box";
import LockOutlinedIcon from "#material-ui/icons/LockOutlined";
import Typography from "#material-ui/core/Typography";
import {makeStyles} from "#material-ui/core/styles";
import Container from "#material-ui/core/Container";
import {Redirect, useHistory} from "react-router-dom";
function Copyright() {
return (
<Typography variant="body2" color="textSecondary" align="center">
{"Copyright © "}
<Link color="inherit" href="https://material-ui.com/">
Your Website
</Link>{" "}
{new Date().getFullYear()}
{"."}
</Typography>
);
}
const useStyles = makeStyles(theme => ({
paper: {
marginTop: theme.spacing(8),
display: "flex",
flexDirection: "column",
alignItems: "center"
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main
},
form: {
width: "100%", // Fix IE 11 issue.
marginTop: theme.spacing(1)
},
submit: {
margin: theme.spacing(3, 0, 2)
}
}));
export default function SignIn() {
const classes = useStyles();
let history = useHistory();
return (
<Container component="main" maxWidth="xs">
<CssBaseline/>
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon/>
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form className={classes.form} noValidate>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
/>
<FormControlLabel
control={<Checkbox value="remember" color="primary"/>}
label="Remember me"
/>
<Button
onClick={()=>{
history.push('/dashboard')
}}
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign In
</Button>
<Grid container>
<Grid item xs>
<Link href="#" variant="body2">
Forgot password?
</Link>
</Grid>
<Grid item>
<Link href="#" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</form>
</div>
<Box mt={8}>
<Copyright/>
</Box>
</Container>
);
}
Dashboard Component
import React from "react";
import clsx from "clsx";
import {
createStyles,
makeStyles,
useTheme,
Theme
} from "#material-ui/core/styles";
import Button from "#material-ui/core/Button";
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 CssBaseline from "#material-ui/core/CssBaseline";
import Typography from "#material-ui/core/Typography";
import Divider from "#material-ui/core/Divider";
import IconButton from "#material-ui/core/IconButton";
import MenuIcon from "#material-ui/icons/Menu";
import ChevronLeftIcon from "#material-ui/icons/ChevronLeft";
import ChevronRightIcon from "#material-ui/icons/ChevronRight";
import ListItem from "#material-ui/core/ListItem";
import ListItemIcon from "#material-ui/core/ListItemIcon";
import ListItemText from "#material-ui/core/ListItemText";
import InboxIcon from "#material-ui/icons/MoveToInbox";
import MailIcon from "#material-ui/icons/Mail";
import MapOutlinedIcon from "#material-ui/icons/MapOutlined";
import DriveEtaOutlinedIcon from "#material-ui/icons/DriveEtaOutlined";
import PeopleAltOutlinedIcon from "#material-ui/icons/PeopleAltOutlined";
import DirectionsOutlinedIcon from "#material-ui/icons/DirectionsOutlined";
import AssessmentOutlinedIcon from "#material-ui/icons/AssessmentOutlined";
import ReportProblemOutlinedIcon from "#material-ui/icons/ReportProblemOutlined";
import AccountCircleOutlinedIcon from "#material-ui/icons/AccountCircleOutlined";
import { Redirect, useHistory } from "react-router-dom";
import ExitToAppIcon from "#material-ui/icons/ExitToApp";
const drawerWidth = 240;
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: "flex"
},
appBar: {
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(["width", "margin"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
})
},
appBarShift: {
marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`,
transition: theme.transitions.create(["width", "margin"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen
})
},
menuButton: {
marginRight: 36
},
hide: {
display: "none"
},
drawer: {
width: drawerWidth,
flexShrink: 0,
whiteSpace: "nowrap"
},
drawerOpen: {
width: drawerWidth,
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen
})
},
drawerClose: {
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
}),
overflowX: "hidden",
width: theme.spacing(7) + 1,
[theme.breakpoints.up("sm")]: {
width: theme.spacing(9) + 1
}
},
toolbar: {
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar
},
content: {
flexGrow: 1,
padding: theme.spacing(3)
}
})
);
function MiniDrawer() {
const classes = useStyles();
let history = useHistory();
const theme = useTheme();
const [open, setOpen] = React.useState(false);
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
return (
<div className={classes.root}>
<CssBaseline />
<AppBar
position="fixed"
className={clsx(classes.appBar, {
[classes.appBarShift]: open
})}
>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
className={clsx(classes.menuButton, {
[classes.hide]: open
})}
>
<MenuIcon />
</IconButton>
</Toolbar>
</AppBar>
<Drawer
variant="permanent"
className={clsx(classes.drawer, {
[classes.drawerOpen]: open,
[classes.drawerClose]: !open
})}
classes={{
paper: clsx({
[classes.drawerOpen]: open,
[classes.drawerClose]: !open
})
}}
>
<div className={classes.toolbar}>
<IconButton onClick={handleDrawerClose}>
{theme.direction === "rtl" ? (
<ChevronRightIcon />
) : (
<ChevronLeftIcon />
)}
</IconButton>
</div>
<div className={classes.toolbar} />
<div className={classes.toolbar} />
<div className={classes.toolbar} />
<IconButton
onClick={() => {
history.push("/");
}}
>
<ExitToAppIcon />
</IconButton>
<Divider />
<List>
{["Mapa", "Pojazdy", "Kierowcy", "Trasy", "Raporty", "Alerty"].map(
(text, index) => (
<ListItem
button
key={text}
onClick={event => {
console.log(event.currentTarget);
history.push("/");
}}
>
<ListItemIcon>
{index === 0 && <MapOutlinedIcon />}
{index === 1 && <DriveEtaOutlinedIcon />}
{index === 2 && <PeopleAltOutlinedIcon />}
{index === 3 && <DirectionsOutlinedIcon />}
{index === 4 && <AssessmentOutlinedIcon />}
{index === 5 && <ReportProblemOutlinedIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
)
)}
</List>
</Drawer>
<main className={classes.content}>
<div className={classes.toolbar} />
<Typography paragraph />
</main>
</div>
);
}
export default MiniDrawer;
Here is the Code Sandbox

Material Ui menu taking full width of the page

I have created a menu but i can't change its height and width and its width taking full page width
import React, { Component } from "react";
import Menu from "#material-ui/core/Menu";
import MenuItem from "#material-ui/core/MenuItem";
import EditIcon from "#material-ui/icons/Edit";
import DeleteIcon from "#material-ui/icons/Delete";
import IconButton from "#material-ui/core/IconButton";
import withStyles from "#material-ui/core/styles/withStyles";
const styles = theme => ({
menu: {
marginLeft: "-8.8%",
width: "180px",
height: "30",
backgroundColor: "red"
},
mainmenu: {
width: "180px",
height: "30"
}
});
class BlogOptions extends Component {
render() {
const { anchorEl, handleClose, classes } = this.props;
return (
<div className={classes.menu}>
<Menu
id="simple-menu"
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleClose}
className={classes.mainMenu}
>
<MenuItem onClick={handleClose} className={classes.menuItem}>
<IconButton>
<EditIcon />
Edit
</IconButton>
</MenuItem>
<MenuItem onClick={handleClose}>
<IconButton>
<DeleteIcon />
Delete
</IconButton>
</MenuItem>
</Menu>
</div>
);
}
}
export default withStyles(styles)(BlogOptions);
is there any fix or any other component which can be better than menu?
How can i achieve something like menu with items?
You must specify an unit for height
height: "30",

Categories