Goal: I want to make it so that when I click a button in my navbar, it takes the user to a page and a section of the page.
This is how I would do it with regular html.
<a href="secondpage#section"/>
But how can this be accomplished with React-router-dom?
Here is what I have tried so far but it wont scroll to the correct section on click:
https://codesandbox.io/s/hopeful-night-q06msw
import { AppBar, Button, Toolbar } from "#mui/material";
import React from "react";
import { Link } from "react-router-dom";
export default function Navbar() {
return (
<AppBar position="fixed">
<Toolbar>
<Button component={Link} to="/" sx={{ color: "#fff" }}>
Hello
</Button>
<Button component={Link} to="/second" sx={{ color: "#fff" }}>
SecondpageTop
</Button>
<Button
component={Link}
to={{ pathname: "/second", hash: "#sectiontwo" }}
sx={{ color: "#fff" }}
>
SecondpageSectionwo
</Button>
</Toolbar>
</AppBar>
);
}
import { Box, Typography } from "#mui/material";
import React from "react";
import Navbar from "./Navbar";
export default function () {
return (
<>
<Navbar></Navbar>
<Typography sx={{ mt: "50px", color: "red" }}>Sup</Typography>
<Box
sx={{
width: "150px",
height: "150px",
mb: "1000px",
backgroundColor: "red"
}}
>
<Typography sx={{ color: "#fff" }}>This is the top box</Typography>
</Box>
<div
id="sectiontwo"
style={{ width: "150px", height: "150px", backgroundColor: "blue" }}
>
<Typography sx={{ color: "#fff" }}>
This is where to scroll to
</Typography>
</div>
</>
);
}
Related
On this MUI AppBar/Drawer sample, I have added a MUI Menu to edit profile, with an anchor on a div. It's located on the top right corner. I like to be able to click on the username or the profile icon to pop the menu out. For some reason the menu never disappear. I have try to add console.log in the callbacks. It shows the open callback is called right after the close one. Can someone explain why and how to close the menu ?
Here is my code, and the full project on Codesandbox :
import React from "react";
import Box from "#mui/material/Box";
import Grid from "#mui/material/Grid";
import IconButton from "#mui/material/IconButton";
import Menu from "#mui/material/Menu";
import MenuIcon from "#mui/icons-material/Menu";
import MenuItem from "#mui/material/MenuItem";
import Toolbar from "#mui/material/Toolbar";
import AccountCircle from "#mui/icons-material/AccountCircle";
import { styled } from "#mui/material/styles";
import { useNavigate } from "react-router-dom";
export default function TopBar(props) {
const navigate = useNavigate();
const [anchorEl, setAnchorEl] = React.useState(null);
const handleMenuOpen = (event) => {
console.log("set menu open");
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
console.log("set menu close");
setAnchorEl(null);
};
const UserName = styled("div")(({ theme }) => ({
fontSize: "1em",
marginRight: "0.7em",
display: "inline",
height: "100%",
textAlign: "center",
cursor: "pointer"
}));
const Logo = styled("img")(({ theme }) => ({
height: "42px",
width: "42px",
backgroundColor: "#FFF",
marginRight: "0.7em"
}));
return (
<Toolbar>
<Grid
style={{ justifyContent: "space-between", alignItems: "center" }}
container
>
<Grid item style={{ display: "inline-flex", alignItems: "center" }}>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={props.handleDrawerOpen}
edge="start"
sx={{
...(props.drawerOpen && {
display: {
xs: "block",
sm: "none"
}
})
}}
>
<MenuIcon />
</IconButton>
</Grid>
<Grid item style={{ display: "inline-flex", alignItems: "center" }}>
<Logo
src=""
alt="logo"
onClick={() => {
props.handleDrawerClose();
navigate("/");
}}
/>
<Box
sx={{
whiteSpace: "nowrap",
fontSize: { xs: "1em", sm: "1.25em" },
fontWeight: { xs: 400, sm: 500 }
}}
>
Toolbar test
</Box>
</Grid>
<Grid item style={{ display: "flex", alignItems: "center" }}>
<div
style={{ display: "inline-flex", alignItems: "center" }}
onClick={handleMenuOpen}
>
<UserName sx={{ display: { xs: "none", sm: "block" } }}>
{props.userName}
</UserName>
<IconButton
color="inherit"
aria-label="user"
edge="start"
size="large"
>
<AccountCircle />
</IconButton>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem
onClick={() => {
props.handleDrawerClose();
navigate("/test");
}}
>
My Profile
</MenuItem>
<MenuItem
onClick={() => {
props.handleDrawerClose();
navigate("/logout");
}}
>
Logout
</MenuItem>
</Menu>
</div>
</Grid>
</Grid>
</Toolbar>
);
}
You somehow managed that when you trigger the onClose event, you are simultaneously triggering handleMenuOpen function. I would suggest you use a button base to handle opening the menu.
Something like this:
<ButtonBase onClick={handleMenuOpen}>
<UserName sx={{ display: { xs: "none", sm: "block" } }}>
{props.userName}
</UserName>
<AccountCircle />
</ButtonBase>
And dont forget to remove the onClick event from your div.
You can also take a look of the fork that i made.
guys so I'm trying to create a navbar with a set of private navbar links that will be only visible to the user when they log in. Otherwise, the only pages before logging in with a JWT are the register and login page and the register page is set as the '/' directory.
I would like the user prior to registering to see only the /Register, and /Login pages
if the user is logged in I want them to see the /Balance, /Deposit, /Withdraw, and Alldata page
I can't seem to figure this out on MUI can someone help me out, please? Here is my code.
import * as React from 'react';
import AppBar from '#mui/material/AppBar';
import Box from '#mui/material/Box';
import Toolbar from '#mui/material/Toolbar';
import IconButton from '#mui/material/IconButton';
import Typography from '#mui/material/Typography';
import Menu from '#mui/material/Menu';
import MenuIcon from '#mui/icons-material/Menu';
import Container from '#mui/material/Container';
import Avatar from '#mui/material/Avatar';
import Button from '#mui/material/Button';
import Tooltip from '#mui/material/Tooltip';
import MenuItem from '#mui/material/MenuItem';
import AdbIcon from '#mui/icons-material/Adb';
import { Link, useNavigate } from 'react-router-dom'
import { logout, reset } from '../features/auth/authSlice'
import { useSelector, useDispatch } from 'react-redux'
const Navigation = () => {
const navigate = useNavigate()
const dispatch = useDispatch()
const { user } = useSelector((state) => state.auth)
const pages = ['Register', 'Login', 'Deposit', 'Withdraw', 'Alldata'];
const settings = ['Balance', 'Logout'];
const onLogout = () => {
dispatch(logout())
dispatch(reset())
navigate('/')
}
const [anchorElNav, setAnchorElNav] = React.useState(null);
const [anchorElUser, setAnchorElUser] = React.useState(null);
const handleOpenNavMenu = (event) => {
setAnchorElNav(event.currentTarget);
};
const handleOpenUserMenu = (event) => {
setAnchorElUser(event.currentTarget);
};
const handleCloseNavMenu = () => {
setAnchorElNav(null);
};
const handleCloseUserMenu = () => {
setAnchorElUser(null);
};
return (
<AppBar position="static">
<Container maxWidth="xl">
<Toolbar disableGutters>
<AdbIcon sx={{ display: { xs: 'none', md: 'flex' }, mr: 1 }} />
<Typography
variant="h6"
noWrap
component="a"
href="/"
sx={{
mr: 2,
display: { xs: 'none', md: 'flex' },
fontFamily: 'monospace',
fontWeight: 700,
letterSpacing: '.3rem',
color: 'inherit',
textDecoration: 'none',
}}
>
LOGO
</Typography>
<Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={handleOpenNavMenu}
color="inherit"
>
<MenuIcon />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorElNav}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
open={Boolean(anchorElNav)}
onClose={handleCloseNavMenu}
sx={{
display: { xs: 'block', md: 'none' },
}}
>
{pages.map((page) => (
<MenuItem key={page} onClick={handleCloseNavMenu}>
<Typography textAlign="center">
<Link to={`/${page}`}>
{page}
</Link>
</Typography>
</MenuItem>
)
)}
</Menu>
</Box>
<AdbIcon sx={{ display: { xs: 'flex', md: 'none' }, mr: 1 }} />
<Typography
variant="h5"
noWrap
component="a"
href=""
sx={{
mr: 2,
display: { xs: 'flex', md: 'none' },
flexGrow: 1,
fontFamily: 'monospace',
fontWeight: 700,
letterSpacing: '.3rem',
color: 'inherit',
textDecoration: 'none',
}}
>
BADBANK
</Typography>
<Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}>
{pages.map((page) => (
<Button
key={page}
onClick={handleCloseNavMenu}
sx={{ my: 2, color: 'white', display: 'block' }}
>
<Link to={`/${page}`}>
{page}
</Link>
</Button>
))}
</Box>
<Box sx={{ flexGrow: 0 }}>
<Tooltip title="Open settings">
<IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
<Avatar alt="Remy Sharp" src="/static/images/avatar/2.jpg" />
</IconButton>
</Tooltip>
<Menu
sx={{ mt: '45px' }}
id="menu-appbar"
anchorEl={anchorElUser}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu}
>
{settings.map((setting) => (
<MenuItem
key={setting}
onClick={onLogout}>
<Typography textAlign="center">{setting}</Typography>
</MenuItem>
))}
</Menu>
</Box>
</Toolbar>
</Container>
</AppBar>
);
};
export default Navigation;
you can make a conditional statement on links array based on auth state
const pages = user ? ['Deposit', 'Withdraw', 'Alldata'] : ['Register', 'Login'];
During my running project, I was using Material UI. I was designing a dashboard for my site.
Then I noticed that my scroll bar was being blocked while every time I opened the menu list.
Just like the following image:
I copied this code from MaterialUI official webiste. I still its blocking the scroll bar. Where is the code:
import * as React from 'react';
import AppBar from '#mui/material/AppBar';
import Box from '#mui/material/Box';
import Toolbar from '#mui/material/Toolbar';
import IconButton from '#mui/material/IconButton';
import Typography from '#mui/material/Typography';
import Menu from '#mui/material/Menu';
import MenuIcon from '#mui/icons-material/Menu';
import Container from '#mui/material/Container';
import Avatar from '#mui/material/Avatar';
import Button from '#mui/material/Button';
import Tooltip from '#mui/material/Tooltip';
import MenuItem from '#mui/material/MenuItem';
const pages = ['Products', 'Pricing', 'Blog'];
const settings = ['Profile', 'Account', 'Dashboard', 'Logout'];
const ResponsiveAppBar = () => {
const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null);
const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null);
const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorElNav(event.currentTarget);
};
const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorElUser(event.currentTarget);
};
const handleCloseNavMenu = () => {
setAnchorElNav(null);
};
const handleCloseUserMenu = () => {
setAnchorElUser(null);
};
return (
<AppBar position="static">
<Container maxWidth="xl">
<Toolbar disableGutters>
<Typography
variant="h6"
noWrap
component="div"
sx={{ mr: 2, display: { xs: 'none', md: 'flex' } }}
>
LOGO
</Typography>
<Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={handleOpenNavMenu}
color="inherit"
>
<MenuIcon />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorElNav}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
open={Boolean(anchorElNav)}
onClose={handleCloseNavMenu}
sx={{
display: { xs: 'block', md: 'none' },
}}
>
{pages.map((page) => (
<MenuItem key={page} onClick={handleCloseNavMenu}>
<Typography textAlign="center">{page}</Typography>
</MenuItem>
))}
</Menu>
</Box>
<Typography
variant="h6"
noWrap
component="div"
sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}
>
LOGO
</Typography>
<Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}>
{pages.map((page) => (
<Button
key={page}
onClick={handleCloseNavMenu}
sx={{ my: 2, color: 'white', display: 'block' }}
>
{page}
</Button>
))}
</Box>
<Box sx={{ flexGrow: 0 }}>
<Tooltip title="Open settings">
<IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
<Avatar alt="Remy Sharp" src="/static/images/avatar/2.jpg" />
</IconButton>
</Tooltip>
<Menu
sx={{ mt: '45px' }}
id="menu-appbar"
anchorEl={anchorElUser}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu}
>
{settings.map((setting) => (
<MenuItem key={setting} onClick={handleCloseNavMenu}>
<Typography textAlign="center">{setting}</Typography>
</MenuItem>
))}
</Menu>
</Box>
</Toolbar>
</Container>
</AppBar>
);
};
export default ResponsiveAppBar;
What I have to do to fix this bug?
The issue is from the Menu component, when it is open it styles the body element overflow to hidden.
To stop that, Set the disableScrollLock prop to true.
<Menu
...others
disableScrollLock={true}
>
</Menu>
I'm not sure if this is a problem with your AppBar as much as your other code, which we cannot see.
But I'm guessing you have something like this:
export default function App(){
return (
<div className="root">
<ResponsiveAppBar />
<div className="image-background-1">
<h1>Some text</h1>
</div>
<div className="image-background-2">
<h1>Some text</h1>
</div>
<div className="image-background-3">
<h1>Some text</h1>
</div>
</div>
)
}
In this scenario, the whole "root" div is scrolling, but in your design we really just want to scroll through the divs with the image background.
To fix this, wrap those divs in a div that has overflow-y: scroll:
export default function App(){
return (
<div className="root">
<ResponsiveAppBar />
<div style={{overflowY: "scroll"}}>
<div className="image-background-1">
<h1>Some text</h1>
</div>
<div className="image-background-2">
<h1>Some text</h1>
</div>
<div className="image-background-3">
<h1>Some text</h1>
</div>
</div>
</div>
)
}
You might need to set overflow: "hidden" on the root div as well.
I'm using the material-ui and material-ui icons for my react project. I'm in new in react.
Can someone please guide me how to make icons with label? I want to place the label just below the icon. For example, text "Home" written under "Home Icons". I'm trying to implement something similar to what Microsoft Team has implemented in sidebar navigation (web version)
I read the API, and I found there's a prop Component. I try to experiment, however, whenever I'm using it icons disappear.
Please visit this link https://codesandbox.io/s/material-demo-forked-nohsm?file=/demo.js I'm getting this result:
Here's my code
import React from "react";
import AppBar from "#material-ui/core/AppBar";
import Drawer from "#material-ui/core/Drawer";
import { makeStyles, useTheme } from "#material-ui/core/styles";
import NotificationsIcon from "#material-ui/icons/Notifications";
import { ListItem, Toolbar } from "#material-ui/core";
import List from "#material-ui/core/List";
import ListItemIcon from "#material-ui/core/ListItemIcon";
const drawerWidth = 72;
const useStyles = makeStyles((theme) => ({
root: {
display: "flex"
},
drawer: {
width: drawerWidth,
alignItems: "center",
justifyContent: "center",
paddingTop: theme.spacing(5)
},
drawerPaper: {
width: drawerWidth
}
}));
export default function Demo() {
const classes = useStyles();
return (
<div className={classes.root}>
<AppBar position="fixed" color="primary">
<Toolbar></Toolbar>
</AppBar>
<Drawer
classes={{
paper: classes.drawerPaper
}}
variant="permanent"
className={classes.drawer}
>
{/* <NotificationsIcon size="large" /> */}
<List>
<ListItem>
<ListItemIcon>
<NotificationsIcon color="primary" fontSize="large" />
Activity
</ListItemIcon>
</ListItem>
</List>
</Drawer>
</div>
);
}
I want to similar to this one:
Please help. Thank you.
sometimes it's not MUI at all but pure CSS. MUI already provides icon and label, you just have to work CSS a bit, this one may work just customizing ListItemIcon styles with flex properties (see listItemIcon class rules):
const useStyles = makeStyles((theme) => ({
root: {
display: "flex"
},
listItemIcon: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column'
},
drawer: {
width: drawerWidth,
alignItems: "center",
justifyContent: "center",
paddingTop: theme.spacing(5)
},
drawerPaper: {
width: drawerWidth
}
}));
export default function Demo() {
const classes = useStyles();
return (
<div className={classes.root}>
<AppBar position="fixed" color="primary">
<Toolbar></Toolbar>
</AppBar>
<Drawer
classes={{
paper: classes.drawerPaper
}}
variant="permanent"
className={classes.drawer}
>
{/* <NotificationsIcon size="large" /> */}
<List>
<ListItem>
<ListItemIcon className={classes.listItemIcon}>
<NotificationsIcon color="primary" fontSize="large" />
Activity
</ListItemIcon>
</ListItem>
</List>
</Drawer>
</div>
);
}
When MUI does not provide default styles for it, you can always use flex-box
I tried this way, and it worked. Need to wrap the Icons in a div and it will work.
<List>
<ListItem style={{ textAlign: "center" }}>
<div>
<NotificationsIcon color="primary" fontSize="large" />
Activity
</div>
</ListItem>
<ListItem style={{ textAlign: "center" }}>
<div>
<NotificationsIcon color="primary" fontSize="large" />
Activity
</div>
</ListItem>
</List>
https://codesandbox.io/s/material-demo-forked-b73ds?file=/demo.js
I using ReactJS and Material-UI in my web application. When I define props search for search bar, it's working except borderRadius. I checked Style tab in the Developer Tools (F12), border-radius property was overwritten but search bar not change. Please help me.
My code:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from './../actions/index';
import AppBar from '#material-ui/core/AppBar';
import Badge from '#material-ui/core/Badge';
import IconButton from '#material-ui/core/IconButton';
import Tooltip from '#material-ui/core/Tooltip';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import { withStyles } from '#material-ui/core/styles';
import InputBase from '#material-ui/core/InputBase';
import { fade } from '#material-ui/core/styles/colorManipulator';
import MenuIcon from '#material-ui/icons/Menu';
import MailIcon from '#material-ui/icons/Mail';
import HomeIcon from '#material-ui/icons/Home';
import QuestionIcon from '#material-ui/icons/QuestionAnswer';
import CartIcon from '#material-ui/icons/ShoppingCart';
import PersonIcon from '#material-ui/icons/Person';
import SearchIcon from '#material-ui/icons/Search';
const styles = theme => ({
root: {
width: '100%',
},
grow: {
flexGrow: 1,
},
appBar: {
zIndex: 1300,
},
//search props for search bar
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginRight: theme.spacing.unit * 2,
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing.unit * 3,
width: 'auto',
},
},
searchIcon: {
width: theme.spacing.unit * 9,
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot: {
color: 'inherit',
width: '100%',
backgroundColor: '#EAE9E8'
},
inputInput: {
paddingTop: theme.spacing.unit,
paddingRight: theme.spacing.unit,
paddingBottom: theme.spacing.unit,
paddingLeft: theme.spacing.unit * 10,
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('md')]: {
width: 200,
},
},
})
class Header extends Component {
onToggleNav = () => {
this.props.onToggleNav()
}
render() {
const { classes } = this.props;
return (
<header className={classes.root}>
<AppBar color="inherit" className={classes.appBar}>
<Toolbar>
<IconButton color="inherit" className={"remove_outline"} onClick={this.onToggleNav}>
<MenuIcon />
</IconButton>
<Typography variant="h6" color="inherit" noWrap>
Watch Shop
</Typography>
{/* search bar */}
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
/>
</div>
<div className={classes.grow} />
<div>
<Tooltip title="Trang chủ">
<IconButton className="remove_outline">
<HomeIcon />
</IconButton>
</Tooltip>
<Tooltip title="Hỗ trợ">
<IconButton className="remove_outline">
<QuestionIcon />
</IconButton>
</Tooltip>
<Tooltip title="Phản hồi">
<IconButton className="remove_outline">
<MailIcon />
</IconButton>
</Tooltip>
<Tooltip title="Tài khoản">
<IconButton className="remove_outline">
<PersonIcon />
</IconButton>
</Tooltip>
<Tooltip title="Giỏ đồ">
<IconButton className="remove_outline">
<Badge badgeContent={4} color="secondary">
<CartIcon />
</Badge>
</IconButton>
</Tooltip>
</div>
</Toolbar>
</AppBar>
</header>
);
}
}
const mapDispatchToProps = (dispatch, props) => {
return {
onToggleNav: () => {
dispatch(actions.isShowNav())
}
}
}
export default connect(null, mapDispatchToProps)(withStyles(styles)(Header));
Style tab in the Developer Tools
Style tab in the Developer Tools
Search bar:
Search bar