Files
HKSingleParty/03_source/frontend/src/layouts/dashboard/nav-vertical.tsx
louiscklaw 834f58bde1 update,
2025-05-30 01:14:10 +08:00

114 lines
3.5 KiB
TypeScript

import Box from '@mui/material/Box';
import type { Breakpoint } from '@mui/material/styles';
import { styled } from '@mui/material/styles';
import { mergeClasses, varAlpha } from 'minimal-shared/utils';
import { Logo } from 'src/components/logo';
import type { NavSectionProps } from 'src/components/nav-section';
import { NavSectionMini, NavSectionVertical } from 'src/components/nav-section';
import { Scrollbar } from 'src/components/scrollbar';
import { NavToggleButton } from '../components/nav-toggle-button';
import { NavUpgrade } from '../components/nav-upgrade';
import { layoutClasses } from '../core/classes';
// ----------------------------------------------------------------------
export type NavVerticalProps = React.ComponentProps<'div'> &
NavSectionProps & {
isNavMini: boolean;
layoutQuery?: Breakpoint;
onToggleNav: () => void;
slots?: {
topArea?: React.ReactNode;
bottomArea?: React.ReactNode;
};
};
export function NavVertical({ sx, data, slots, cssVars, className, isNavMini, onToggleNav, checkPermissions, layoutQuery = 'md', ...other }: NavVerticalProps) {
const renderNavVertical = () => (
<>
{slots?.topArea ?? (
<Box sx={{ pl: 3.5, pt: 2.5, pb: 1 }}>
<Logo />
</Box>
)}
<Scrollbar fillContent>
<NavSectionVertical data={data} cssVars={cssVars} checkPermissions={checkPermissions} sx={{ px: 2, flex: '1 1 auto' }} />
{slots?.bottomArea ?? <NavUpgrade />}
</Scrollbar>
</>
);
const renderNavMini = () => (
<>
{slots?.topArea ?? (
<Box sx={{ display: 'flex', justifyContent: 'center', py: 2.5 }}>
<Logo />
</Box>
)}
<NavSectionMini
data={data}
cssVars={cssVars}
checkPermissions={checkPermissions}
sx={[
(theme) => ({
...theme.mixins.hideScrollY,
pb: 2,
px: 0.5,
flex: '1 1 auto',
overflowY: 'auto',
}),
]}
/>
{slots?.bottomArea}
</>
);
return (
<NavRoot
isNavMini={isNavMini}
layoutQuery={layoutQuery}
className={mergeClasses([layoutClasses.nav.root, layoutClasses.nav.vertical, className])}
sx={sx}
{...other}
>
<NavToggleButton
isNavMini={isNavMini}
onClick={onToggleNav}
sx={[
(theme) => ({
display: 'none',
[theme.breakpoints.up(layoutQuery)]: { display: 'inline-flex' },
}),
]}
/>
{isNavMini ? renderNavMini() : renderNavVertical()}
</NavRoot>
);
}
// ----------------------------------------------------------------------
const NavRoot = styled('div', {
shouldForwardProp: (prop: string) => !['isNavMini', 'layoutQuery', 'sx'].includes(prop),
})<Pick<NavVerticalProps, 'isNavMini' | 'layoutQuery'>>(({ isNavMini, layoutQuery = 'md', theme }) => ({
top: 0,
left: 0,
height: '100%',
display: 'none',
position: 'fixed',
flexDirection: 'column',
zIndex: 'var(--layout-nav-zIndex)',
backgroundColor: 'var(--layout-nav-bg)',
width: isNavMini ? 'var(--layout-nav-mini-width)' : 'var(--layout-nav-vertical-width)',
borderRight: `1px solid var(--layout-nav-border-color, ${varAlpha(theme.vars.palette.grey['500Channel'], 0.12)})`,
transition: theme.transitions.create(['width'], {
easing: 'var(--layout-transition-easing)',
duration: 'var(--layout-transition-duration)',
}),
[theme.breakpoints.up(layoutQuery)]: { display: 'flex' },
}));