materio-mui-react-nextjs-admin-template-free
Version:
Most Powerful & Comprehensive Free MUI React NextJS Admin Dashboard Template built for developers! 🚀
132 lines (117 loc) • 3.86 kB
JavaScript
// ** React Import
import { useRef, useState } from 'react'
// ** MUI Import
import List from '@mui/material/List'
import Box from '@mui/material/Box'
import { styled, useTheme } from '@mui/material/styles'
// ** Third Party Components
import PerfectScrollbar from 'react-perfect-scrollbar'
// ** Component Imports
import Drawer from './Drawer'
import VerticalNavItems from './VerticalNavItems'
import VerticalNavHeader from './VerticalNavHeader'
// ** Util Import
import { hexToRGBA } from 'src/@core/utils/hex-to-rgba'
const StyledBoxForShadow = styled(Box)({
top: 50,
left: -8,
zIndex: 2,
height: 75,
display: 'none',
position: 'absolute',
pointerEvents: 'none',
width: 'calc(100% + 15px)',
'&.d-block': {
display: 'block'
}
})
const Navigation = props => {
// ** Props
const {
hidden,
afterVerticalNavMenuContent,
beforeVerticalNavMenuContent,
verticalNavMenuContent: userVerticalNavMenuContent
} = props
// ** States
const [groupActive, setGroupActive] = useState([])
const [currentActiveGroup, setCurrentActiveGroup] = useState([])
// ** Ref
const shadowRef = useRef(null)
// ** Hooks
const theme = useTheme()
// ** Fixes Navigation InfiniteScroll
const handleInfiniteScroll = ref => {
if (ref) {
// @ts-ignore
ref._getBoundingClientRect = ref.getBoundingClientRect
ref.getBoundingClientRect = () => {
// @ts-ignore
const original = ref._getBoundingClientRect()
return { ...original, height: Math.floor(original.height) }
}
}
}
// ** Scroll Menu
const scrollMenu = container => {
container = hidden ? container.target : container
if (shadowRef && container.scrollTop > 0) {
// @ts-ignore
if (!shadowRef.current.classList.contains('d-block')) {
// @ts-ignore
shadowRef.current.classList.add('d-block')
}
} else {
// @ts-ignore
shadowRef.current.classList.remove('d-block')
}
}
const ScrollWrapper = hidden ? Box : PerfectScrollbar
return (
<Drawer {...props}>
<VerticalNavHeader {...props} />
<StyledBoxForShadow
ref={shadowRef}
sx={{
background: `linear-gradient(${theme.palette.background.default} 40%,${hexToRGBA(
theme.palette.background.default,
0.1
)} 95%,${hexToRGBA(theme.palette.background.default, 0.05)})`
}}
/>
<Box sx={{ height: '100%', position: 'relative', overflow: 'hidden' }}>
<ScrollWrapper
containerRef={ref => handleInfiniteScroll(ref)}
{...(hidden
? {
onScroll: container => scrollMenu(container),
sx: { height: '100%', overflowY: 'auto', overflowX: 'hidden' }
}
: {
options: { wheelPropagation: false },
onScrollY: container => scrollMenu(container)
})}
>
{beforeVerticalNavMenuContent ? beforeVerticalNavMenuContent(props) : null}
<Box sx={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
{userVerticalNavMenuContent ? (
userVerticalNavMenuContent(props)
) : (
<List className='nav-items' sx={{ transition: 'padding .25s ease', pr: 4.5 }}>
<VerticalNavItems
groupActive={groupActive}
setGroupActive={setGroupActive}
currentActiveGroup={currentActiveGroup}
setCurrentActiveGroup={setCurrentActiveGroup}
{...props}
/>
</List>
)}
</Box>
</ScrollWrapper>
</Box>
{afterVerticalNavMenuContent ? afterVerticalNavMenuContent(props) : null}
</Drawer>
)
}
export default Navigation