New to Material UI I'm trying to create a sticky div
with a set width similar to how Material UI has their side nav
on the right of their docs. For some reason I'm unable to get the div
to stick. Per research and the docs I've read through several questions and here are my attempts:
Attempt 1
I tried utilizing Box
but it scrolls with the page:
import React from 'react'
import { Hidden, Box, List,ListItem } from '@material-ui/core/'
import { makeStyles } from '@material-ui/core/styles'
const useStyles = makeStyles(theme => ({
box: {
background: 'red',
position: 'sticky',
top: 70,
bottom: 20,
paddingTop: 100,
marginTop: theme.spacing(2),
width: 300,
},
sub: {
display: 'block',
overflow: 'auto',
},
}))
const SideToc = ({ nav }) => {
const { box, sub } = useStyles()
return (
<>
<Hidden smDown>
<Box className={box}>
Contents
<List className={sub} component="nav" aria-label="main mailbox folders">
<ListItem button>Monday</ListItem>
<ListItem button>Tuesday</ListItem>
<ListItem button>Wednesday</ListItem>
</List>
</Box>
</Hidden>
</>
)
}
export default SideToc
Attempt 2
after research I've found a few mentions of Drawer
but when I deploy the below component my green drawerPaper
is fixed to the left and my blue Drawer
is to the right a correct width.
import React from 'react'
import Drawer from '@material-ui/core/Drawer'
import Hidden from '@material-ui/core/Hidden'
import List from '@material-ui/core/List'
import ListItem from '@material-ui/core/ListItem'
import { makeStyles } from '@material-ui/core/styles'
const SideToc = ({ nav }) => {
const useStyles = makeStyles(theme => ({
toolbar: theme.mixins.toolbar, // necessary for content to be below app bar
drawer: {
background: 'blue',
width: 300,
flexShrink: 0,
},
drawerPaper: {
marginTop: 120,
background: 'green',
},
}))
const { toolbar, drawer, drawerPaper } = useStyles()
return (
<>
<div className={toolbar} />
<Hidden smDown>
<nav className={drawer} aria-label="mailbox folders">
<Drawer
classes={{
paper: drawerPaper,
}}
variant="permanent"
>
Contents
<List component="nav" aria-label="main mailbox folders">
<ListItem button>Monday</ListItem>
<ListItem button>Tuesday</ListItem>
<ListItem button>Wednesday</ListItem>
</List>
</Drawer>
</nav>
</Hidden>
</>
)
}
export default SideToc
Here is my parent component that has the content with the set width nav
:
import React from 'react'
import { makeStyles } from '@material-ui/core/styles'
// Components
import SideToc from './SideToc'
const useStyles = makeStyles(theme => ({
toolbar: theme.mixins.toolbar, // necessary for content to be below app bar
content: {
flexGrow: 1,
padding: theme.spacing(3),
overflow: 'hidden',
background: 'orange',
},
}))
const Parent = ({ nav, children }) => {
const { content, toolbar } = useStyles()
return (
<>
<main className={content}>
<div className={toolbar} />
{children}
</main>
<SideToc className={toolbar} nav={nav} />
</>
)
}
export default Parent
Research
- How to make a Material UI grid element sticky?
- Reactjs Material-ui hide appBar sticky or static
- Make a React Material-UI component to stick to the bottom-right of the screen
- React Material-Ui Sticky Table Header with Dynamic Height
In Material UI if I want a div
to be sticky that will not scroll and have a fixed width how should that be done? Is my issue due to my parent? Should I be using Material's Grid
in this approach?
Edit
After further testing I am able to get the side nav
to stick but the content, if outside the viewport, will not allow scrolling. The parent component has been modified with just a div
surrounding the SideToc
component:
<>
<main className={content}>
<div className={toolbar} />
{children}
</main>
<div>
<SideToc toc={toc} />
</div>
</>
SideToc Component:
import React from 'react'
import { Hidden, Box, List, ListItem } from '@material-ui/core/'
import { makeStyles } from '@material-ui/core/styles'
const useStyles = makeStyles(theme => ({
box: {
marginTop: theme.spacing(8),
top: theme.spacing(8),
width: 250,
position: 'sticky',
right: 0,
overflowY: 'auto',
flexShrink: 0,
},
}))
const SideToc = ({ nav }) => {
const { box } = useStyles()
return (
<>
<Hidden smDown>
<Box className={box} component="nav">
Contents
<List component="nav">
<ListItem button>Monday</ListItem>
<ListItem button>Tuesday</ListItem>
<ListItem button>Wednesday</ListItem>
</List>
</Box>
</Hidden>
</>
)
}
export default SideToc
Per request: