1

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

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:

Edit Invisible Backdrop

DᴀʀᴛʜVᴀᴅᴇʀ
  • 7,681
  • 17
  • 73
  • 127

0 Answers0