I have created a web app with the base coming from the Material-UI Example on a responsive drawer
I am trying to get a table to resize responsively to the screen width, but, for some reason, the ResponsiveDrawer
container provided by Material-UI is breaking the responsiveness of the contents (i.e. the table)
Here is an example that I wrote that is perfectly responsive:
App.js
import React from "react";
import ReactDOM from "react-dom";
import Table from "@material-ui/core/Table/Table";
import TableHead from "@material-ui/core/TableHead/TableHead";
import TableRow from "@material-ui/core/TableRow/TableRow";
import TableCell from "@material-ui/core/TableCell/TableCell";
import TableBody from "@material-ui/core/TableBody/TableBody";
import Paper from "@material-ui/core/Paper/Paper";
import Grid from "@material-ui/core/Grid/Grid";
import "./styles.css";
function App() {
return (
<div className="App">
<Grid container justify={"center"}>
<Grid item xs={12} md={10} style={{ padding: "8px" }}>
<Paper style={{ overflowX: "auto" }}>
<Table style={{ minWidth: "340px" }}>
<TableHead>
<TableRow>
<TableCell>Name</TableCell>
<TableCell>Column</TableCell>
<TableCell>Operating System</TableCell>
<TableCell>Status</TableCell>
<TableCell>CPU Cores</TableCell>
<TableCell>Memory (MB)</TableCell>
<TableCell>IP Address</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
</TableRow>
<TableRow>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
</TableRow>
</TableBody>
</Table>
</Paper>
</Grid>
</Grid>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
And here is that same example using a modified (changed the content to this.props.children
instead of static) version of Material-UI’s ResponsiveDrawer
ResponsiveDrawer.js
import React from "react";
import PropTypes from "prop-types";
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 InboxIcon from "@material-ui/icons/MoveToInbox";
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 MailIcon from "@material-ui/icons/Mail";
import MenuIcon from "@material-ui/icons/Menu";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import { withStyles } from "@material-ui/core/styles";
const drawerWidth = 240;
const styles = theme => ({
root: {
display: "flex"
},
drawer: {
[theme.breakpoints.up("sm")]: {
width: drawerWidth,
flexShrink: 0
}
},
appBar: {
marginLeft: drawerWidth,
[theme.breakpoints.up("sm")]: {
width: `calc(100% - ${drawerWidth}px)`
}
},
menuButton: {
marginRight: 20,
[theme.breakpoints.up("sm")]: {
display: "none"
}
},
toolbar: theme.mixins.toolbar,
drawerPaper: {
width: drawerWidth
},
content: {
flexGrow: 1,
padding: theme.spacing.unit * 3
}
});
class ResponsiveDrawer extends React.Component {
state = {
mobileOpen: false
};
handleDrawerToggle = () => {
this.setState(state => ({ mobileOpen: !state.mobileOpen }));
};
render() {
const { classes, theme } = this.props;
const drawer = (
<div>
<div className={classes.toolbar} />
<Divider />
<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>
</div>
);
return (
<div className={classes.root}>
<CssBaseline />
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<IconButton
color="inherit"
aria-label="Open drawer"
onClick={this.handleDrawerToggle}
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" color="inherit" noWrap>
Responsive drawer
</Typography>
</Toolbar>
</AppBar>
<nav className={classes.drawer}>
{/* The implementation can be swapped with js to avoid SEO duplication of links. */}
<Hidden smUp implementation="css">
<Drawer
container={this.props.container}
variant="temporary"
anchor={theme.direction === "rtl" ? "right" : "left"}
open={this.state.mobileOpen}
onClose={this.handleDrawerToggle}
classes={{
paper: classes.drawerPaper
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden xsDown implementation="css">
<Drawer
classes={{
paper: classes.drawerPaper
}}
variant="permanent"
open
>
{drawer}
</Drawer>
</Hidden>
</nav>
<main className={classes.content}>
<div className={classes.toolbar} />
{this.props.children}
</main>
</div>
);
}
}
ResponsiveDrawer.propTypes = {
classes: PropTypes.object.isRequired,
// Injected by the documentation to work in an iframe.
// You won't need it on your project.
container: PropTypes.object,
theme: PropTypes.object.isRequired
};
export default withStyles(styles, { withTheme: true })(ResponsiveDrawer);
App.js
import React from "react";
import ReactDOM from "react-dom";
import Table from "@material-ui/core/Table/Table";
import TableHead from "@material-ui/core/TableHead/TableHead";
import TableRow from "@material-ui/core/TableRow/TableRow";
import TableCell from "@material-ui/core/TableCell/TableCell";
import TableBody from "@material-ui/core/TableBody/TableBody";
import Paper from "@material-ui/core/Paper/Paper";
import ResponsiveDrawer from "./ResponsiveDrawer";
import Grid from "@material-ui/core/Grid/Grid";
import "./styles.css";
function App() {
return (
<div className="App">
<ResponsiveDrawer>
<Grid container justify={"center"}>
<Grid item xs={12} md={10} style={{ padding: "8px" }}>
<Paper style={{ overflowX: "auto" }}>
<Table style={{ minWidth: "340px" }}>
<TableHead>
<TableRow>
<TableCell>Name</TableCell>
<TableCell>Column</TableCell>
<TableCell>Operating System</TableCell>
<TableCell>Status</TableCell>
<TableCell>CPU Cores</TableCell>
<TableCell>Memory (MB)</TableCell>
<TableCell>IP Address</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
</TableRow>
<TableRow>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
<TableCell>Content</TableCell>
</TableRow>
</TableBody>
</Table>
</Paper>
</Grid>
</Grid>
</ResponsiveDrawer>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
I just can’t seem to figure out what it is inside the ResponsiveDrawer
container that is causing the responsiveness to break.
All help appreciated.
UPDATE (1/7/2019):
It looks like removing display: flex
from the root solves the issue, but then I have the issue of it not honoring the left drawer.
UPDATE (1/9/2019):
As suggested by @Gaurav Rana, I have added width: 100%;
to the main element and it has half solved the problem. Now, the table will overflow / scroll properly when the sidebar is not visible. But, when the sidebar is still visible but the screen isn’t wide enough for the whole table, the table scrolls under the sidebar.
3
Answers
After a bit of troubleshooting, I have come up with a solution:
The styles for
content
need to be updated as follows (This will force the width of the content element to fit the width of the screen minus the drawer if necessary):And
display: flex
needs to be removed fromroot
https://codesandbox.io/s/1zxp2qjmoj
add style below style in your styles.css . hope this will solve your issue.
this is a problem width css width. You must specify whole parents
width: 100%
like this