When clicking on a tab, the elements of the page in question are rendered within the drawer for all the positions except for Appbar which is rendered on top. How do I render it within the main page whereas the main page= 100% window size - (drawer+AppBar).
The element on all 4 pages are just one-word texts like yon the Home page shown below the main code for reference,
main code:
import React, {Fragment} from 'react';
import AppBar from '#material-ui/core/AppBar';
import CssBaseline from '#material-ui/core/CssBaseline';
import Drawer from '#material-ui/core/Drawer';
import Hidden from '#material-ui/core/Hidden';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import { makeStyles, withStyles } from '#material-ui/core/styles';
import SearchBar from '../TopBar/SearchBar'
import Home from '../Screens/Home'
import home from '../home.svg';
import Contact from '../Screens/Contact'
import contact from '../contact.svg';
import Profile from '../Screens/Profile'
import profile from '../profile.svg';
import Settings from '../Screens/Settings'
import settings from '../settings.svg'
import Tabs from "#material-ui/core/Tabs";
import Tab from "#material-ui/core/Tab";
import { Switch, Route, Link, BrowserRouter} from "react-router-dom";
const VerticalTabs = withStyles(theme => ({
flexContainer: {
flexDirection: "column"
},
indicator: {
display: "none"
},
root:{
position:"relative",
left:-70,
top:-40,
},
}))(Tabs);
const MyTab = withStyles(theme => ({
selected: {
color: "white",
borderRight: "none",
},
root: {
//minWidth: 121,
margin:0,
paddingBottom:119
},
'#media screen and (min-width: 600px) and (max-width: 1205px)':{
root: {
minWidth: 100,
}
}
}))(Tab);
const styles = theme => ({
root: {
flexGrow: 1,
marginTop: theme.spacing.unit * 3,
backgroundColor: theme.palette.background.paper,
},
tabRoot: {
minWidth: 10,
},
});
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
},
menuButton:{
visibility: "hidden"
},
appBar: {
marginLeft: 300,
},
drawerPaper: {
width: 100,
background: "#262A2C",
fontSize:65,
height: 2300,
top:-10
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
},
'#media screen and (min-width: 600px) and (max-width: 1205px)':{
drawerPaper: {
width: 80,
//background: "black"
},
},
'#media (max-width: 600px)':{
drawerPaper: {
width: 300,
//background: "black"
},
appBar: {
},
menuButton:{
visibility: "visible"
},
}
}));
function ResponsiveDrawer() {
const [value, setValue] = React.useState(0);
const classes = useStyles();
const [mobileOpen, setMobileOpen] = React.useState(false);
function handleChange(event, Value) {
setValue(Value);
}
function handleDrawerToggle() {
setMobileOpen(!mobileOpen);
}
const drawer = (
<BrowserRouter>
<Route
path="/"
render={({ location }) => (
<Fragment>
<nav>
<div className= "tabs" style={{ left: 70, position: "relative", marginTop: 40 ,}}>
<VerticalTabs value={location.pathname} variant="fullWidth" onChange={handleChange}
>
<MyTab
component={Link} to="../Screens/Home"
icon ={<img
className= "home"
src={home}
alt="home"
/*Pay FlatIcon or replace by design *//>}
label={<p className="home-Text" >
Home
</p>}
/>
<MyTab
component={Link} to="../Screens/Contact"
icon ={<img
className= "contact"
src={contact}
alt="contact"
/*Pay FlatIcon or replace by design *//>}
label={<p className="contacts-Text" >
Contact
</p>}
/>
<MyTab
component={Link} to="../Screens/Profile"
icon={<img
className= "profile"
src={profile}
alt="profile"
/*Pay FlatIcon or replace by design *//>}
label={<p className= "profile-Text" >
Profile
</p>}
/>
<MyTab
component={Link} to="../Screens/Settings"
icon = {<img
className= "settings"
src={settings}
alt="settings"
/*Pay FlatIcon or replace by design *//>}
label={<p className="hsettings-Text" >
Settings
</p>}
/>
</VerticalTabs>
<Switch>
<Route path="../Screens/Home" component={Home}/>
<Route path="../Screeens/Contact" component={Contact}/>
<Route path="../Screeens/Profile" component={Profile}/>
<Route path="../Screeens/Settings" component={Settings}/>
</Switch>
</div>
</nav>
</Fragment>
)}
/>
</BrowserRouter>
);
return (
<div className="aBar">
<CssBaseline />
<AppBar style={{position:"fixed"}} position="relative" style={{ background: 'transparent', boxShadow: 'none', color: "red"}}>
<Toolbar>
<IconButton
color="inherit"
aria-label="Open drawer"
edge="start"
onClick={handleDrawerToggle}
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
<SearchBar />
<div className="logo">
<Typography className= "logo-Spec" style={{fontSize:30}}>
Logo
</Typography>
</div>
</Toolbar>
</AppBar>
<nav className={classes.drawer}>
{/* The implementation can be swapped with js to avoid SEO duplication of links. */}
<Hidden smUp implementation="css">
<Drawer
style={{color:"black"}}
variant="temporary"
open={mobileOpen}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper,
}}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden xsDown implementation="css">
<Drawer
classes={{
paper: classes.drawerPaper,
}}
variant="permanent"
open
>
{drawer}
</Drawer>
</Hidden>
</nav>
</div>
);
}
export default withStyles(styles)(ResponsiveDrawer);
Home.js (same for all four pages link through tabs):
import React, {Component} from 'react';
export default class Home extends Component {
render(){
return (
<div>
<p style={{fontSize:60,position:"relative", left: 0,top:0}}>Home</p>
</div>
);
}
}
App.js:
import React, {Component} from 'react';
import FullMenu from "./Menu/FullMenu"
export default class App extends Component {
render(){
return (
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
</head>
<div>
<FullMenu/>
</div>
</html>
);
}
}
Related
I want to show only one component inside a white container that clicked but it is showing all components . how can I create an admin panel with fine routing ???
Like other admin panel, i just want to show proper routing But in my case, both components are displaying
App.js, main file
import { BrowserRouter, Route, Switch } from "react-router-dom"
import Home from "./Components/Home/Home"
import CreateAccount from "./Components/Create-Account/CreateAccount"
import PostRequest from "./Components/Post-request/PostRequest"
import New from "./new"
const App = () => {
return (
<BrowserRouter>
<Home />
<Route exact path="/" component={New} />
<Switch >
<Route exact path="/createAccount" component={CreateAccount} />
<Route exact path="/postRequests" component={PostRequest} />
</Switch>
</BrowserRouter>
)
}
export default App
And the Home page Component
import React from 'react';
import clsx from 'clsx';
import "./home.css"
import PostRequest from "../Post-request/PostRequest"
import CreateAccount from "../Create-Account/CreateAccount"
import { SidebarData } from "./sideBarData"
import { Link } from "react-router-dom"
import { makeStyles, useTheme } from '#material-ui/core/styles';
import Drawer from '#material-ui/core/Drawer';
import CssBaseline from '#material-ui/core/CssBaseline';
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 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';
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
},
appBar: {
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
appBarShift: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
},
menuButton: {
marginRight: theme.spacing(2),
},
hide: {
display: 'none',
},
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
drawerHeader: {
display: 'flex',
alignItems: 'center',
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
justifyContent: 'flex-end',
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: -drawerWidth,
},
contentShift: {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
marginLeft: 0,
},
}));
export default function PersistentDrawerLeft() {
const classes = useStyles();
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, open && classes.hide)}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
Master Panel
</Typography>
</Toolbar>
</AppBar>
<Drawer
className={classes.drawer}
variant="persistent"
anchor="left"
open={open}
classes={{
paper: classes.drawerPaper,
}}
>
<div className={classes.drawerHeader}>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
</IconButton>
</div>
<Divider />
<List>
<ul>
<h2>Admin</h2>
{SidebarData.map((item, index) => {
return (
<div>
<li key={index} className={item.cName}>
<Link className="textClass" to={item.path}>
<div className="listItem_Alignment container">
<span>{item.icon}</span>
<span className="titleLeftMargin">{item.title}</span>
</div>
</Link>
</li>
</div>
)
})}
</ul>
</List>
<Divider />
</Drawer>
<main
className={clsx(classes.content, {
[classes.contentShift]: open,
})}
>
<div className={classes.drawerHeader} />
<CreateAccount />
<PostRequest />
</main>
</div>
);
}
You can use nested routing for your admin panel. You take reference of below link.
Nested routing example
Trying to render a component conditionally. I have a drawHelper variable & a function to toggle it true or false. The component renders or not based on the initial value of drawHelper. (false, doesn't render, true it does).
The toggle function changes the value. I checked with console.log(drawHelper) But changing the value does not make the component appear or disappear.
Am I missing something here?
import React from 'react';
import AppBar from '#material-ui/core/AppBar';
import CssBaseline from '#material-ui/core/CssBaseline';
import Divider from '#material-ui/core/Divider';
import Drawer from '#material-ui/core/Drawer';
import Hidden from '#material-ui/core/Hidden';
import IconButton from '#material-ui/core/IconButton';
import List from '#material-ui/core/List';
import ListItem from '#material-ui/core/ListItem';
import ListItemIcon from '#material-ui/core/ListItemIcon';
import ListItemText from '#material-ui/core/ListItemText';
import DashboardIcon from '#material-ui/icons/Dashboard';
import MenuIcon from '#material-ui/icons/Menu';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import { makeStyles, useTheme, Theme, createStyles } from '#material-ui/core/styles';
import { User } from './User';
import { Draw } from "components/Layout/Countryballs/Draw";
const drawerWidth = 240;
export const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: 'flex',
color: '#fff',
},
drawer: {
[theme.breakpoints.up('sm')]: {
width: drawerWidth,
flexShrink: 0,
},
},
appBar: {
marginLeft: drawerWidth,
[theme.breakpoints.up('sm')]: {
width: `calc(100% - ${drawerWidth}px)`,
},
},
menuButton: {
marginRight: theme.spacing(2),
[theme.breakpoints.up('sm')]: {
display: 'none',
},
},
toolbar: theme.mixins.toolbar,
drawerPaper: {
width: drawerWidth,
backgroundColor: theme.palette.primary.main
},
content: {
flexGrow: 1,
},
menuItem: {
color: '#fff',
},
}),
);
export const Layout: React.FC<LayoutProps> = (props) => {
const { container } = props;
const classes = useStyles();
const theme = useTheme();
const [mobileOpen, setMobileOpen] = React.useState(false);
function handleDrawerToggle() {
setMobileOpen(!mobileOpen);
}
// Display Draw component
// 1 Create property
var drawHelper: Boolean = false;
function toggleDraw() {
console.log(drawHelper);
drawHelper = !drawHelper;
}
const drawer = (
<div>
<div className={classes.toolbar} />
<Divider />
<List>
{['Draw'].map((text) => (
<ListItem button key={text} onClick={toggleDraw} className={classes.menuItem}>
<ListItemIcon className={classes.menuItem}><DashboardIcon /></ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
</div>
);
return (
<div className={classes.root}>
<CssBaseline />
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
edge="start"
onClick={handleDrawerToggle}
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
Project name
</Typography>
<User/>
</Toolbar>
</AppBar>
<nav className={classes.drawer} aria-label="mailbox folders">
{/* The implementation can be swapped with js to avoid SEO duplication of links. */}
<Hidden smUp implementation="css">
<Drawer // this one is for mobile
container={container}
variant="temporary"
anchor={theme.direction === 'rtl' ? 'right' : 'left'}
open={mobileOpen}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper,
}}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden xsDown implementation="css">
<Drawer // This one is for desktop
classes={{
paper: classes.drawerPaper,
}}
variant="permanent"
open
>
{drawer}
</Drawer>
</Hidden>
</nav>
<main className={classes.content}>
{/* This is where my components renders */}
{
drawHelper === true && (<Draw/>)
}
<div className={classes.toolbar} />
{props.children}
</main>
</div>
);
}
The variable drawHelper in your code is instantiated on every render. You'd want to use React's state to make sure your drawHelper's value is preserved on the next re-renders.
const [drawHelper, toggleDrawHelper] = React.useState(false)
function toggleDraw() {
toggleDrawHelper(!drawHelper);
}
I am new to react js and i'm trying to create a dashboard layout where i want to render a sidebar(which will be common in all the routes) and based upon the click event of sidebar items i want to render different component. Although i have achieved this, but in first instance the sidebar is present with the loaded component but once i refresh the page, only the newly loaded component remains on the page and sidebar is vanished.
//This is my main page code;
import React, { Component } from 'react';
import './Dashboard.css'
import Header from "../Header/Header";
import Footer from "../Footer/Footer";
import Sidebar from "../SideBar/Sidebar";
import Charts from "../Charts/Charts";
import About from "../About/About"
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
class Dashboard extends Component {
constructor(props) {
super(props)
}
render() {
// this.state.aboutComponent = this.props.aboutComponent;
return (
<Router>
<div>
<Sidebar></Sidebar>
<Switch>
<Route exact path={"/"} component={Charts} />
<Route exact path={"/about"} component={About} />
</Switch>
<Footer></Footer>
</div>
</Router>
)
}
}
export default Dashboard
import React from 'react';
import clsx from 'clsx';
import './Sidebar.css';
import { makeStyles, useTheme } 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 Divider from '#material-ui/core/Divider';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import DeleteIcon from '#material-ui/icons/Delete';
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 Button from '#material-ui/core/Button';
import Menu from '#material-ui/core/Menu';
import MenuItem from '#material-ui/core/MenuItem';
import InfoIcon from '#material-ui/icons/Info';
import About from '../About/About';
// import { Link } from "react-router-dom";
import { useHistory } from "react-router-dom";
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
},
link: {
textDecoration: 'none',
color: theme.palette.text.primary
},
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),
},
}));
export default function Sidebar() {
const classes = useStyles();
const theme = useTheme();
const [open, setOpen] = React.useState(false);
const [component, setComponent] = React.useState('user')
const [anchorEl, setAnchorEl] = React.useState(null);
const history = useHistory();
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
// <Router>
<div className={classes.root}>
<AppBar
position="fixed"
className={clsx(classes.appBar, {
[classes.appBarShift]: open,
})}
>
<Toolbar>
<h1>SGGB</h1>
<div className="alignment">
<Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick}>
<h4>Menu</h4>
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
</div>
</Toolbar>
</AppBar>
<Drawer
variant="permanent"
className={clsx(classes.drawer, {
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
})}
classes={{
paper: clsx({
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
}),
}}
>
<List>
<ListItem>
<IconButton
className={clsx(classes.menuButton, {
[classes.hide]: !open,
})}
onClick={handleDrawerClose}>
{theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
</IconButton>
</ListItem>
<ListItem>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
className={clsx(classes.menuButton, {
[classes.hide]: open,
})}
>
<MenuIcon />
</IconButton>
</ListItem>
<Link to="/about" className={classes.link}>
<ListItem button key="about" >
<ListItemIcon>{<InfoIcon />}</ListItemIcon>
<ListItemText primary="About" />
</ListItem>
</Link>
</List>
</Drawer>
</div >
// </Router>
);
}
I have also referred to this post;
React Router display one component for all routes ( a header)
You have to put the Route component inside a Switch component like this :
<Router>
<div>
<Sidebar></Sidebar>
<Switch>
<Route exact path={"/"} component={Charts} />
<Route exact path={"/about"} component={About} />
</Switch>
<Footer></Footer>
</div>
</Router>
I'm trying to use a Drawer in Material UI.
I want the width of the main div to take up whatever available space is left in the viewport after the menu drawer has used its space.
This is my component. I've tried setting width to auto and inherit on the content class, but it doesn't change anything.
I want the main div (where the content for a list item in the drawer) is rendered, to take only as much space is available without scrolling horizontally.
This code sandbox shows the problem: https://codesandbox.io/s/material-tab-scrolling-h13pi?file=/test.jsx
import React, { useState, useEffect } from 'react';
import { Switch, Route, Link, BrowserRouter } from "react-router-dom";
import clsx from 'clsx';
import { makeStyles, useTheme } 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 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 Menu from '#material-ui/core/Menu';
import MenuItem from '#material-ui/core/MenuItem';
import Container from '#material-ui/core/Container'
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 AccountCircle from '#material-ui/icons/AccountCircle';
import PaletteIcon from '#material-ui/icons/Palette';
import CenterFocusWeakIcon from '#material-ui/icons/CenterFocusWeak';
import RoomServiceIcon from '#material-ui/icons/RoomService';
import StorefrontIcon from '#material-ui/icons/Storefront';
import AssignmentIcon from '#material-ui/icons/Assignment';
import NotificationsIcon from '#material-ui/icons/Notifications';
import AccountBoxIcon from '#material-ui/icons/AccountBox';
import ContactSupportIcon from '#material-ui/icons/ContactSupport';
import BookIcon from '#material-ui/icons/Book';
import TuneIcon from '#material-ui/icons/Tune';
import SettingsIcon from '#material-ui/icons/Settings';
import CloseIcon from '#material-ui/icons/Close';
import DashboardFooter from "./DashboardFooter";
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
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),
// autoWidth: false
},
container: {
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4),
},
}));
export default function MiniDrawer() {
const classes = useStyles();
const theme = useTheme();
const [open, setOpen] = React.useState(false);
// const { performingAction, user, userData, roles } = this.props;
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>
<Typography variant="h6" noWrap>
{process.env.REACT_APP_TITLE}
</Typography>
<IconButton color="inherit"><CloseIcon /></IconButton>
</Toolbar>
</AppBar>
<BrowserRouter>
<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>
<List>
<ListItem button key="1" component={Link} to={"/DSM" }>
<ListItemIcon><PaletteIcon /></ListItemIcon>
<ListItemText primary="DS"></ListItemText>
</ListItem>
<ListItem button key="2" component={Link} to={"/MMM" }>
<ListItemIcon><CenterFocusWeakIcon /></ListItemIcon>
<ListItemText>MM</ListItemText>
</ListItem>
<ListItem button key="3" component={Link} to={"/RCM" }>
<ListItemIcon><StorefrontIcon /></ListItemIcon>
<ListItemText>Centre</ListItemText>
</ListItem>
<ListItem button key="4" component={Link} to={"/TT" }>
<ListItemIcon><AssignmentIcon /></ListItemIcon>
<ListItemText>TT</ListItemText>
</ListItem>
</List>
<Divider />
<List>
<ListItem button key="5" component={Link} to={"/Profile" }>
<ListItemIcon> <AccountBoxIcon /></ListItemIcon>
<ListItemText>Profile</ListItemText>
</ListItem>
<ListItem button key="6" component={Link} to={"/Account" }>
<ListItemIcon> <SettingsIcon /></ListItemIcon>
<ListItemText>Account</ListItemText>
</ListItem>
<ListItem button key="7" component={Link} to={"/Mail" }>
<ListItemIcon> <MailIcon /></ListItemIcon>
<ListItemText>Mail</ListItemText>
</ListItem>
<ListItem button key="8" component={Link} to={"/Notifications" }>
<ListItemIcon> <NotificationsIcon /></ListItemIcon>
<ListItemText>Notifications</ListItemText>
</ListItem>
</List>
<Divider />
<List>
<ListItem button key="9" component={Link} to={"/CM" }>
<ListItemIcon> <BookIcon /></ListItemIcon>
<ListItemText>Centre</ListItemText>
</ListItem>
<ListItem button key="10" component={Link} to={"/DCM" }>
<ListItemIcon><RoomServiceIcon /></ListItemIcon>
<ListItemText>Desk</ListItemText>
</ListItem>
<ListItem button key="11" component={Link} to={"/Support" }>
<ListItemIcon> <ContactSupportIcon /></ListItemIcon>
<ListItemText>Help and Support</ListItemText>
</ListItem>
</List>
</Drawer>
<main className={classes.content}>
<div className={classes.toolbar} />
<Switch>
<Route path="/DCM" component={""} />
<Route path="/MMM" render={() => <div>Page mm</div>} />
</Switch>
<DashboardFooter />
</main>
</BrowserRouter>
</div>
);
}
The main issue is the following in dash.jsx:
root: {
display: 'flex',
},
This is somehow defeating the mechanism in Tabs for its "scrollable tabs" functionality and results in the Tabs taking up as much width as is needed to display all of its tab buttons instead of showing scroll buttons. display: 'flex' makes it a little easier to manage the content width (such that it automatically adjusts based on the drawer width), but it isn't difficult to manage this in other ways.
Alternative 1
In my modified version of your sandbox, to remediate the effects of removing display: 'flex' from the root, I'm adding padding-left to the content with the same width as the drawer:
content: {
padding: theme.spacing(3),
paddingLeft: theme.spacing(7) + 1,
[theme.breakpoints.up("sm")]: {
paddingLeft: theme.spacing(9) + 1
}
},
contentDrawerOpen: {
paddingLeft: drawerWidth
},
...
<main className={clsx(classes.content, {[classes.contentDrawerOpen]: open})}>
Alternative 2
Another alternative is to leave display: 'flex', but specify the max-width appropriately on the content.
content: {
padding: theme.spacing(3),
maxWidth: `calc(100vw - ${theme.spacing(7) + 1}px)`,
[theme.breakpoints.up("sm")]: {
maxWidth: `calc(100vw - ${theme.spacing(9) + 1}px)`
}
},
contentDrawerOpen: {
maxWidth: `calc(100vw - ${drawerWidth}px)`
},
Alternative 3 (inspired by Ahmed Mokhtar's answer)
It also appears to be sufficient to just add overflow: "auto" to the content class for the <main> element:
content: {
padding: theme.spacing(3),
overflow: "auto"
},
This last alternative is definitely the simplest.
I fixed that by adding overflow: auto to main which I changed to use the Container component:
container: {
overflow: "auto"
}
{/* I added overflow: auto to this container*/}
<Container
component="main"
maxWidth={false}
className={classes.container}
>
<div className={classes.toolbar} />
<Switch>
<Route path="/dash" component={Dash} />
<Route path="/MatchmakerMenu" component={Dash} />
</Switch>
</Container>
CodeSandbox
I am using Material UI tabs and React-Router, both are working fine visually but I realized while using Developer tools that there is an error every time I click on a tab or on the menu button in the case of phone size. The error says:
index.js:1375 Warning: Material-UI: the value provided/to the Tabs component is invalid. None of the Tabs children have this value. You can provide one of the following values: 0, 1, 2, 3, 4, 5.
I tried replacing the router with a state and active index structure but the error still persists. How to make sure that the error doesn't occur when clicking on the tab or the menu button? And how to make sure it keeps directing us to the concerned page smoothly with the concerned path? Thanks
PS: the screens they are directed to are all texts, for now, nothing in particular, I can edit the post if showing the code is required, though I doubt so. Thanks again
import React from 'react';
import AppBar from '#material-ui/core/AppBar';
import CssBaseline from '#material-ui/core/CssBaseline';
import Drawer from '#material-ui/core/Drawer';
import Hidden from '#material-ui/core/Hidden';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import { makeStyles, withStyles } from '#material-ui/core/styles';
import SearchBar from '../TopBar/SearchBar'
import Home from '../Screens/Home'
import home from '../home.svg';
import Contact from '../Screens/Contact'
import contact from '../contact.svg';
import Profile from '../Screens/Profile'
import profile from '../profile.svg';
import Settings from '../Screens/Settings'
import settings from '../settings.svg'
import Tabs from "#material-ui/core/Tabs";
import Tab from "#material-ui/core/Tab";
import { Switch, Route, Link, BrowserRouter} from "react-router-dom";
const VerticalTabs = withStyles(theme => ({
flexContainer: {
flexDirection: "column"
},
indicator: {
display: "red"
},
root:{
position:"fixed",
left:-70,
top:0,
},
}))(Tabs);
const MyTab = withStyles(theme => ({
selected: {
color: "white",
borderRight: "none",
},
root: {
//minWidth: 121,
margin:0,
paddingBottom:119
},
'#media screen and (min-width: 600px) and (max-width: 1205px)':{
root: {
minWidth: 151,
}
}
}))(Tab);
const styles = theme => ({
root: {
flexGrow: 1,
marginTop: theme.spacing(3),
backgroundColor: theme.palette.background.paper,
},
tabRoot: {
minWidth: 10,
},
});
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
},
menuButton:{
visibility: "hidden"
},
appBar: {
marginLeft: 300,
},
drawerPaper: {
width: 100,
background: "#262A2C",
fontSize:65,
height:"120%",
top:-10
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
},
'#media screen and (min-width: 600px) and (max-width: 1205px)':{
drawerPaper: {
width: 80,
//background: "black"
},
},
'#media (max-width: 600px)':{
drawerPaper: {
width: 300,
//background: "black"
},
appBar: {
},
menuButton:{
visibility: "visible"
},
}
}));
function ResponsiveDrawer() {
const [value, setValue] = React.useState(0);
const classes = useStyles();
const [mobileOpen, setMobileOpen] = React.useState(false);
function handleChange(event, Value) {
setValue(Value);
}
function handleDrawerToggle() {
setMobileOpen(!mobileOpen);
}
const drawer = (
<Route
path="/"
render={({ location }) => (
<nav>
<div style={{ left: 70, position: "relative", marginTop: 40 }}>
<VerticalTabs value={location.pathname} variant="fullWidth" onChange={handleChange}
>
<MyTab
component={Link} to="/"
icon ={<img
className= "home"
src={home}
alt="home"
/*Pay FlatIcon or replace by design *//>}
label={<p className="home-Text" >
Home
</p>}
/>
<MyTab
component={Link} to="/Screens/Contact"
icon ={<img
className= "contact"
src={contact}
alt="contact"
/*Pay FlatIcon or replace by design *//>}
label={<p className="contacts-Text" >
Contact
</p>}
/>
<MyTab
component={Link} to="/Screens/Profile"
icon={<img
className= "profile"
src={profile}
alt="profile"
/*Pay FlatIcon or replace by design *//>}
label={<p className= "profile-Text" >
Profile
</p>}
/>
<MyTab
component={Link} to="/Screens/Settings"
icon = {<img
className= "settings"
src={settings}
alt="settings"
/*Pay FlatIcon or replace by design *//>}
label={<p className="settings-Text" >
Settings
</p>}
/>
</VerticalTabs>
</div>
</nav>
)}
/>
);
return (
<nav>
<BrowserRouter>
<div className="aBar">
<CssBaseline />
<AppBar style={{position:"relative",background: 'transparent', boxShadow: 'none', color: "red"}}>
<Toolbar>
<IconButton
color="inherit"
aria-label="Open drawer"
edge="start"
onClick={handleDrawerToggle}
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
<SearchBar />
<div className="logo">
<Typography
component={Link}
to="/"
className= "logo-Spec"
style={{fontSize:30, textDecoration: 'none' }}
variant="h1"
//don't forget variant= "h1" if you want to modify logo style
>
Logo
</Typography>
</div>
</Toolbar>
</AppBar>
<nav className={classes.drawer}>
{/* The implementation can be swapped with js to avoid SEO duplication of links. */}
<Hidden smUp implementation="css">
<Drawer
style={{color:"black"}}
variant="temporary"
open={mobileOpen}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper,
}}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden xsDown implementation="css">
<Drawer
classes={{
paper: classes.drawerPaper,
}}
variant="permanent"
open
>
{drawer}
</Drawer>
</Hidden>
<Switch>
<Route path="/Screens/Contact" component={Contact} />
<Route path="/Screens/Settings" component={Settings} />
<Route path="/Screens/Profile" component={Profile} />
<Route path="/" component={Home} />
</Switch>
</nav>
</div>
</BrowserRouter>
</nav>
);
}
export default withStyles(styles)(ResponsiveDrawer);
On your Tabs element you have a value of location.pathname. This indicates that the "selected" Tab is the one with this value, but you aren’t specifying a value prop for any of your tabs. When no value is specified, the value of a Tab defaults to its index within the Tabs parent.
The error message is telling you that the value on Tabs (via VerticalTabs) does not match any of the values on your individual Tab elements (MyTab). To resolve this, you should specify the value in the to property also as the value property on the Tab elements.
References:
https://material-ui.com/api/tabs/
https://material-ui.com/api/tab/