// ** React Import import { useRef, useState } from 'react' // ** MUI Imports import List from '@mui/material/List' import Box, { BoxProps } from '@mui/material/Box' import { createTheme, responsiveFontSizes, styled, ThemeProvider } from '@mui/material/styles' // ** Third Party Components import PerfectScrollbar from 'react-perfect-scrollbar' // ** Type Import import { LayoutProps } from 'src/@core/layouts/types' // ** Theme Config import themeConfig from 'src/configs/themeConfig' // ** Component Imports import Drawer from './Drawer' import VerticalNavItems from './VerticalNavItems' import VerticalNavHeader from './VerticalNavHeader' // ** Theme Options import themeOptions from 'src/@core/theme/ThemeOptions' // ** Util Import import { hexToRGBA } from 'src/@core/utils/hex-to-rgba' interface Props { navWidth: number navVisible: boolean collapsedNavWidth: number hidden: LayoutProps['hidden'] navigationBorderWidth: number toggleNavVisibility: () => void settings: LayoutProps['settings'] children: LayoutProps['children'] setNavVisible: (value: boolean) => void saveSettings: LayoutProps['saveSettings'] navMenuContent: LayoutProps['verticalLayoutProps']['navMenu']['content'] navMenuBranding: LayoutProps['verticalLayoutProps']['navMenu']['branding'] menuLockedIcon: LayoutProps['verticalLayoutProps']['navMenu']['lockedIcon'] verticalNavItems: LayoutProps['verticalLayoutProps']['navMenu']['navItems'] navMenuProps: LayoutProps['verticalLayoutProps']['navMenu']['componentProps'] menuUnlockedIcon: LayoutProps['verticalLayoutProps']['navMenu']['unlockedIcon'] afterNavMenuContent: LayoutProps['verticalLayoutProps']['navMenu']['afterContent'] beforeNavMenuContent: LayoutProps['verticalLayoutProps']['navMenu']['beforeContent'] } const StyledBoxForShadow = styled(Box)(({ theme }) => ({ top: 60, left: -8, zIndex: 2, opacity: 0, position: 'absolute', pointerEvents: 'none', width: 'calc(100% + 15px)', height: theme.mixins.toolbar.minHeight, transition: 'opacity .15s ease-in-out', background: `linear-gradient(${theme.palette.background.default} ${ theme.direction === 'rtl' ? '95%' : '5%' },${hexToRGBA(theme.palette.background.default, 0.85)} 30%,${hexToRGBA( theme.palette.background.default, 0.5 )} 65%,${hexToRGBA(theme.palette.background.default, 0.3)} 75%,transparent)`, '&.scrolled': { opacity: 1 } })) const Navigation = (props: Props) => { // ** Props const { hidden, settings, afterNavMenuContent, beforeNavMenuContent, navMenuContent: userNavMenuContent } = props // ** States const [navHover, setNavHover] = useState(false) const [groupActive, setGroupActive] = useState([]) const [currentActiveGroup, setCurrentActiveGroup] = useState([]) // ** Ref const shadowRef = useRef(null) // ** Var const { afterVerticalNavMenuContentPosition, beforeVerticalNavMenuContentPosition } = themeConfig const navMenuContentProps = { ...props, navHover, groupActive, setGroupActive, currentActiveGroup, setCurrentActiveGroup } // ** Create new theme for the navigation menu when mode is `semi-dark` let darkTheme = createTheme(themeOptions(settings, 'dark')) // ** Set responsive font sizes to true if (themeConfig.responsiveFontSizes) { darkTheme = responsiveFontSizes(darkTheme) } // ** Fixes Navigation InfiniteScroll const handleInfiniteScroll = (ref: HTMLElement) => { 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: any) => { if (beforeVerticalNavMenuContentPosition === 'static' || !beforeNavMenuContent) { container = hidden ? container.target : container if (shadowRef && container.scrollTop > 0) { // @ts-ignore if (!shadowRef.current.classList.contains('scrolled')) { // @ts-ignore shadowRef.current.classList.add('scrolled') } } else { // @ts-ignore shadowRef.current.classList.remove('scrolled') } } } const ScrollWrapper = hidden ? Box : PerfectScrollbar return ( {beforeNavMenuContent && beforeVerticalNavMenuContentPosition === 'fixed' ? beforeNavMenuContent(navMenuContentProps) : null} {(beforeVerticalNavMenuContentPosition === 'static' || !beforeNavMenuContent) && ( )} {/* @ts-ignore */} scrollMenu(container), sx: { height: '100%', overflowY: 'auto', overflowX: 'hidden' } } : { options: { wheelPropagation: false }, onScrollY: (container: any) => scrollMenu(container), containerRef: (ref: any) => handleInfiniteScroll(ref) })} > {beforeNavMenuContent && beforeVerticalNavMenuContentPosition === 'static' ? beforeNavMenuContent(navMenuContentProps) : null} {userNavMenuContent ? ( userNavMenuContent(navMenuContentProps) ) : ( :first-child': { mt: '0' } }}> )} {afterNavMenuContent && afterVerticalNavMenuContentPosition === 'static' ? afterNavMenuContent(navMenuContentProps) : null} {afterNavMenuContent && afterVerticalNavMenuContentPosition === 'fixed' ? afterNavMenuContent(navMenuContentProps) : null} ) } export default Navigation