Как использовать постоянный/постоянный компонент ящика, когда компоненты панели приложений и содержимого не находятся в одном компоненте?

#reactjs #flexbox #material-ui #navigation-drawer

Вопрос:

Я не уверен, как заставить содержимое «отодвинуться» в сторону, если ящик находится не в том же компоненте/контейнере. Мне нужно, чтобы ящик находился под панелью приложений, а содержимое страницы «отталкивалось» от ящика (чтобы оно не находилось под ним или не перекрывалось).

Я также не могу получить доступ к объекту темы makeStyles (даже после ознакомления с документами). Кто-нибудь знает, как получить доступ theme.zIndex.drawer внутрь makeStyles в MUI v5?

Мой файл _app.tsx:

 import '../styles/globals.scss'
import '@fortawesome/fontawesome-svg-core/styles.css'
import { Provider } from 'react-redux'
import { ThemeProvider } from '@material-ui/core'
import { useStore }from '../store'
import type { AppProps } from 'next/app'
import theme from '../styles/theme'
import { AnimatePresence, motion } from 'framer-motion'
import { useRouter } from 'next/router'
import { useEffect, useRef, useState } from 'react'
import NavBar from '../components/NavBar'
import Footer from '../components/Footer'
import MenuDrawer from '../components/MenuDrawer'
import { useResizeDetector } from 'react-resize-detector'
import { Grid } from '@material-ui/core'
import Head from 'next/head'

function MyApp({ Component, pageProps }: AppProps) {
  const router = useRouter()
  const store = useStore(pageProps.initialReduxState)
  const headerRef = useRef()
  const { width, height, ref } = useResizeDetector()

  useEffect(() => {
    if ((global.window as any).Cypress) {
      global.window.store = store
      console.log("Cypress store is running and linked to global document")
    }
  },[])

  return(
    <Provider store={store}>
      <Head>
        <meta content='width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no' name='viewport' />
      </Head>
      <ThemeProvider theme={theme}>
      <NavBar />
      <MenuDrawer />
        <AnimatePresence exitBeforeEnter>
          <Grid container justifyContent="center" component={motion.div} key={router.pathname} initial={{opacity: 0, y: 20}} animate={{opacity: 1, y: 0}} exit={{opacity: 0, y: -20}}>
            <Component {...pageProps} />
          </Grid>
        </AnimatePresence>
      <Footer />
      </ThemeProvider>
    </Provider>
  )
}
export default MyApp
 

Мой компонент навигационной панели:

 import { AppBar, Drawer, Grid, IconButton, MenuItem, MenuList, Slide, Toolbar, Typography, useMediaQuery, useScrollTrigger } from '@material-ui/core'
import { makeStyles, useTheme } from '@material-ui/styles'
import { Menu as MenuIcon, ArrowBackRounded as LeftArrow, Close as CloseIcon } from '@material-ui/icons'
import { useRef, useState } from 'react'
import HappeningNow from '../components/HappeningNow'

const theme: any = makeStyles((theme) => void {
  drawer: {
    width: 'min(100vw, 300px)'
  },
  navBar: {
    borderBottom: 'solid 2px #666666',
    zIndex: theme.zIndex.drawer   1
  },
  leftArrow: {
    color: '#ffffff',
  },
  listItem: {

  },
  menuList: {
    'amp; li': {
      padding: '.5rem'
    }
  }
})

// This will eventually control the auto show/hide of the header element. Need to program the react-resize-detector with ref to ensure that content falls *below* the header on resize events
function HideOnScroll(props: any) {
  const trigger = useScrollTrigger();

  return (
    <Slide appear={false} direction="down" in={!trigger}>
      {props.children}
    </Slide>
  );
}

const NavBar = (props: any) => {
  // We can declare stuff before the return
  const [happeningNowOpen, setHappeningNowOpen] = useState(false)
  const defaultTheme = useTheme()
  const styles = theme(defaultTheme)
  return(
    <>
      <HideOnScroll {...props}>
        <AppBar className={styles.navBar} color="navBar" position="static" elevation={0}>
          <Toolbar>
            <Grid container alignItems="center" justifyContent="space-between">
              <Grid container alignItems="center" item xs={3}><Typography variant="h5" sx={{textTransform: 'uppercase'}}><b>TEST</b></Typography></Grid>
              <Grid item xs={9} textAlign="right"><IconButton sx={{backgroundColor: '#000000', borderRadius: '50%'}} onClick={() => setHappeningNowOpen(prev => true)}><LeftArrow sx={{color: '#eeeeee'}} /></IconButton><HappeningNow open={happeningNowOpen} setOpen={setHappeningNowOpen} /></Grid>
            </Grid>
          </Toolbar>
        </AppBar>
      </HideOnScroll>
    </>
  )
}

export default NavBar
 

The Drawer component:

 import { Drawer, Typography } from '@material-ui/core'
import { makeStyles, StylesContext } from '@material-ui/styles'

const theme = makeStyles({
  drawer: {
    width: 240
  },
  drawerPaper: {
    width: 240
  }
})

export default function MenuDrawer() {
  const styles = theme()
  return(
    <Drawer
      classes={{ paper: styles.drawerPaper }}
      variant="permanent"
    >
      <Typography>TEST</Typography>
      <Typography>TEST</Typography>
      <Typography>TEST</Typography>
      <Typography>TEST</Typography>
      <Typography>TEST</Typography>
      <Typography>TEST</Typography>
    </Drawer>
  )
}