init: add fuse-react v8.3.5 skeleton

This commit is contained in:
2023-05-30 21:07:44 +01:00
commit 3a760d2646
543 changed files with 102541 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
import FuseDialog from '@fuse/core/FuseDialog';
import { styled } from '@mui/material/styles';
import FuseMessage from '@fuse/core/FuseMessage';
import FuseSuspense from '@fuse/core/FuseSuspense';
import AppContext from 'app/AppContext';
import { memo, useContext } from 'react';
import { useSelector } from 'react-redux';
import { useRoutes } from 'react-router-dom';
import { selectFuseCurrentLayoutConfig } from 'app/store/fuse/settingsSlice';
import FooterLayout1 from './components/FooterLayout1';
import LeftSideLayout1 from './components/LeftSideLayout1';
import NavbarWrapperLayout1 from './components/NavbarWrapperLayout1';
import RightSideLayout1 from './components/RightSideLayout1';
import ToolbarLayout1 from './components/ToolbarLayout1';
import SettingsPanel from '../shared-components/SettingsPanel';
const Root = styled('div')(({ theme, config }) => ({
...(config.mode === 'boxed' && {
clipPath: 'inset(0)',
maxWidth: `${config.containerWidth}px`,
margin: '0 auto',
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
}),
...(config.mode === 'container' && {
'& .container': {
maxWidth: `${config.containerWidth}px`,
width: '100%',
margin: '0 auto',
},
}),
}));
function Layout1(props) {
const config = useSelector(selectFuseCurrentLayoutConfig);
const appContext = useContext(AppContext);
const { routes } = appContext;
return (
<Root id="fuse-layout" config={config} className="w-full flex">
{config.leftSidePanel.display && <LeftSideLayout1 />}
<div className="flex flex-auto min-w-0">
{config.navbar.display && config.navbar.position === 'left' && <NavbarWrapperLayout1 />}
<main id="fuse-main" className="flex flex-col flex-auto min-h-full min-w-0 relative z-10">
{config.toolbar.display && (
<ToolbarLayout1 className={config.toolbar.style === 'fixed' && 'sticky top-0'} />
)}
<div className="sticky top-0 z-99">
<SettingsPanel />
</div>
<div className="flex flex-col flex-auto min-h-0 relative z-10">
<FuseDialog />
<FuseSuspense>{useRoutes(routes)}</FuseSuspense>
{props.children}
</div>
{config.footer.display && (
<FooterLayout1 className={config.footer.style === 'fixed' && 'sticky bottom-0'} />
)}
</main>
{config.navbar.display && config.navbar.position === 'right' && <NavbarWrapperLayout1 />}
</div>
{config.rightSidePanel.display && <RightSideLayout1 />}
<FuseMessage />
</Root>
);
}
export default memo(Layout1);

View File

@@ -0,0 +1,152 @@
const config = {
title: 'Layout 1 - Vertical',
defaults: {
mode: 'container',
containerWidth: 1570,
navbar: {
display: true,
style: 'style-1',
folded: true,
position: 'left',
},
toolbar: {
display: true,
style: 'fixed',
},
footer: {
display: true,
style: 'fixed',
},
leftSidePanel: {
display: true,
},
rightSidePanel: {
display: true,
},
},
form: {
mode: {
title: 'Mode',
type: 'radio',
options: [
{
name: 'Boxed',
value: 'boxed',
},
{
name: 'Full Width',
value: 'fullwidth',
},
{
name: 'Container',
value: 'container',
},
],
},
containerWidth: {
title: 'Container Width (px)',
type: 'number',
},
navbar: {
type: 'group',
title: 'Navbar',
children: {
display: {
title: 'Display',
type: 'switch',
},
position: {
title: 'Position',
type: 'radio',
options: [
{
name: 'Left',
value: 'left',
},
{
name: 'Right',
value: 'right',
},
],
},
style: {
title: 'Style',
type: 'radio',
options: [
{
name: 'Slide (style-1)',
value: 'style-1',
},
{
name: 'Folded (style-2)',
value: 'style-2',
},
{
name: 'Tabbed (style-3)',
value: 'style-3',
},
{
name: 'Tabbed Dense (style-3-dense)',
value: 'style-3-dense',
},
],
},
folded: {
title: 'Folded (style-2, style-3)',
type: 'switch',
},
},
},
toolbar: {
type: 'group',
title: 'Toolbar',
children: {
display: {
title: 'Display',
type: 'switch',
},
style: {
title: 'Style',
type: 'radio',
options: [
{
name: 'Fixed',
value: 'fixed',
},
{
name: 'Static',
value: 'static',
},
],
},
},
},
footer: {
type: 'group',
title: 'Footer',
children: {
display: {
title: 'Display',
type: 'switch',
},
style: {
title: 'Style',
type: 'radio',
options: [
{
name: 'Fixed',
value: 'fixed',
},
{
name: 'Static',
value: 'static',
},
],
},
},
},
},
};
export default config;

View File

@@ -0,0 +1,33 @@
import AppBar from '@mui/material/AppBar';
import { ThemeProvider } from '@mui/material/styles';
import Toolbar from '@mui/material/Toolbar';
import { memo } from 'react';
import { useSelector } from 'react-redux';
import { selectFooterTheme } from 'app/store/fuse/settingsSlice';
import clsx from 'clsx';
function FooterLayout1(props) {
const footerTheme = useSelector(selectFooterTheme);
return (
<ThemeProvider theme={footerTheme}>
<AppBar
id="fuse-footer"
className={clsx('relative z-20 shadow-md', props.className)}
color="default"
sx={{
backgroundColor: (theme) =>
theme.palette.mode === 'light'
? footerTheme.palette.background.paper
: footerTheme.palette.background.default,
}}
>
<Toolbar className="min-h-48 md:min-h-64 px-8 sm:px-12 py-0 flex items-center overflow-x-auto">
Footer
</Toolbar>
</AppBar>
</ThemeProvider>
);
}
export default memo(FooterLayout1);

View File

@@ -0,0 +1,7 @@
import { memo } from 'react';
function LeftSideLayout1() {
return <></>;
}
export default memo(LeftSideLayout1);

View File

@@ -0,0 +1,33 @@
import { ThemeProvider } from '@mui/material/styles';
import { memo } from 'react';
import { useSelector } from 'react-redux';
import { selectFuseCurrentLayoutConfig, selectNavbarTheme } from 'app/store/fuse/settingsSlice';
import { selectFuseNavbar } from 'app/store/fuse/navbarSlice';
import NavbarStyle1 from './navbar/style-1/NavbarStyle1';
import NavbarStyle2 from './navbar/style-2/NavbarStyle2';
import NavbarStyle3 from './navbar/style-3/NavbarStyle3';
import NavbarToggleFab from '../../shared-components/NavbarToggleFab';
function NavbarWrapperLayout1(props) {
const config = useSelector(selectFuseCurrentLayoutConfig);
const navbar = useSelector(selectFuseNavbar);
const navbarTheme = useSelector(selectNavbarTheme);
return (
<>
<ThemeProvider theme={navbarTheme}>
<>
{config.navbar.style === 'style-1' && <NavbarStyle1 />}
{config.navbar.style === 'style-2' && <NavbarStyle2 />}
{config.navbar.style === 'style-3' && <NavbarStyle3 />}
{config.navbar.style === 'style-3-dense' && <NavbarStyle3 dense />}
</>
</ThemeProvider>
{config.navbar.display && !config.toolbar.display && !navbar.open && <NavbarToggleFab />}
</>
);
}
export default memo(NavbarWrapperLayout1);

View File

@@ -0,0 +1,15 @@
import { memo } from 'react';
import QuickPanel from '../../shared-components/quickPanel/QuickPanel';
import NotificationPanel from '../../shared-components/notificationPanel/NotificationPanel';
function RightSideLayout1(props) {
return (
<>
<QuickPanel />
<NotificationPanel />
</>
);
}
export default memo(RightSideLayout1);

View File

@@ -0,0 +1,103 @@
import { ThemeProvider } from '@mui/material/styles';
import AppBar from '@mui/material/AppBar';
import Hidden from '@mui/material/Hidden';
import Toolbar from '@mui/material/Toolbar';
import clsx from 'clsx';
import { memo } from 'react';
import { useSelector } from 'react-redux';
import { selectFuseCurrentLayoutConfig, selectToolbarTheme } from 'app/store/fuse/settingsSlice';
import { selectFuseNavbar } from 'app/store/fuse/navbarSlice';
import AdjustFontSize from '../../shared-components/AdjustFontSize';
import FullScreenToggle from '../../shared-components/FullScreenToggle';
import LanguageSwitcher from '../../shared-components/LanguageSwitcher';
import NotificationPanelToggleButton from '../../shared-components/notificationPanel/NotificationPanelToggleButton';
import NavigationShortcuts from '../../shared-components/NavigationShortcuts';
import NavigationSearch from '../../shared-components/NavigationSearch';
import NavbarToggleButton from '../../shared-components/NavbarToggleButton';
import UserMenu from '../../shared-components/UserMenu';
import QuickPanelToggleButton from '../../shared-components/quickPanel/QuickPanelToggleButton';
import ChatPanelToggleButton from '../../shared-components/chatPanel/ChatPanelToggleButton';
function ToolbarLayout1(props) {
const config = useSelector(selectFuseCurrentLayoutConfig);
const navbar = useSelector(selectFuseNavbar);
const toolbarTheme = useSelector(selectToolbarTheme);
return (
<ThemeProvider theme={toolbarTheme}>
<AppBar
id="fuse-toolbar"
className={clsx('flex relative z-20 shadow-md', props.className)}
color="default"
sx={{
backgroundColor: (theme) =>
theme.palette.mode === 'light'
? toolbarTheme.palette.background.paper
: toolbarTheme.palette.background.default,
}}
position="static"
>
<Toolbar className="p-0 min-h-48 md:min-h-64">
<div className="flex flex-1 px-16">
{config.navbar.display && config.navbar.position === 'left' && (
<>
<Hidden lgDown>
{(config.navbar.style === 'style-3' ||
config.navbar.style === 'style-3-dense') && (
<NavbarToggleButton className="w-40 h-40 p-0 mx-0" />
)}
{config.navbar.style === 'style-1' && !navbar.open && (
<NavbarToggleButton className="w-40 h-40 p-0 mx-0" />
)}
</Hidden>
<Hidden lgUp>
<NavbarToggleButton className="w-40 h-40 p-0 mx-0 sm:mx-8" />
</Hidden>
</>
)}
<Hidden lgDown>
<NavigationShortcuts />
</Hidden>
</div>
<div className="flex items-center px-8 h-full overflow-x-auto">
<LanguageSwitcher />
<AdjustFontSize />
<FullScreenToggle />
<NavigationSearch />
<Hidden lgUp>
<ChatPanelToggleButton />
</Hidden>
<QuickPanelToggleButton />
<NotificationPanelToggleButton />
<UserMenu />
</div>
{config.navbar.display && config.navbar.position === 'right' && (
<>
<Hidden lgDown>
{!navbar.open && <NavbarToggleButton className="w-40 h-40 p-0 mx-0" />}
</Hidden>
<Hidden lgUp>
<NavbarToggleButton className="w-40 h-40 p-0 mx-0 sm:mx-8" />
</Hidden>
</>
)}
</Toolbar>
</AppBar>
</ThemeProvider>
);
}
export default memo(ToolbarLayout1);

View File

@@ -0,0 +1,82 @@
import Hidden from '@mui/material/Hidden';
import { styled } from '@mui/material/styles';
import SwipeableDrawer from '@mui/material/SwipeableDrawer';
import { useDispatch, useSelector } from 'react-redux';
import { navbarCloseMobile, selectFuseNavbar } from 'app/store/fuse/navbarSlice';
import { selectFuseCurrentLayoutConfig } from 'app/store/fuse/settingsSlice';
import NavbarStyle1Content from './NavbarStyle1Content';
const navbarWidth = 280;
const StyledNavBar = styled('div')(({ theme, open, position }) => ({
minWidth: navbarWidth,
width: navbarWidth,
maxWidth: navbarWidth,
...(!open && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.leavingScreen,
}),
...(position === 'left' && {
marginLeft: `-${navbarWidth}px`,
}),
...(position === 'right' && {
marginRight: `-${navbarWidth}px`,
}),
}),
...(open && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
}),
}));
const StyledNavBarMobile = styled(SwipeableDrawer)(({ theme }) => ({
'& .MuiDrawer-paper': {
minWidth: navbarWidth,
width: navbarWidth,
maxWidth: navbarWidth,
},
}));
function NavbarStyle1(props) {
const dispatch = useDispatch();
const config = useSelector(selectFuseCurrentLayoutConfig);
const navbar = useSelector(selectFuseNavbar);
return (
<>
<Hidden lgDown>
<StyledNavBar
className="flex-col flex-auto sticky top-0 overflow-hidden h-screen shrink-0 z-20 shadow-5"
open={navbar.open}
position={config.navbar.position}
>
<NavbarStyle1Content />
</StyledNavBar>
</Hidden>
<Hidden lgUp>
<StyledNavBarMobile
classes={{
paper: 'flex-col flex-auto h-full',
}}
anchor={config.navbar.position}
variant="temporary"
open={navbar.mobileOpen}
onClose={() => dispatch(navbarCloseMobile())}
onOpen={() => {}}
disableSwipeToOpen
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
<NavbarStyle1Content />
</StyledNavBarMobile>
</Hidden>
</>
);
}
export default NavbarStyle1;

View File

@@ -0,0 +1,62 @@
import FuseScrollbars from '@fuse/core/FuseScrollbars';
import { styled } from '@mui/material/styles';
import clsx from 'clsx';
import { memo } from 'react';
import Logo from '../../../../shared-components/Logo';
import NavbarToggleButton from '../../../../shared-components/NavbarToggleButton';
import UserNavbarHeader from '../../../../shared-components/UserNavbarHeader';
import Navigation from '../../../../shared-components/Navigation';
const Root = styled('div')(({ theme }) => ({
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
'& ::-webkit-scrollbar-thumb': {
boxShadow: `inset 0 0 0 20px ${
theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.24)' : 'rgba(255, 255, 255, 0.24)'
}`,
},
'& ::-webkit-scrollbar-thumb:active': {
boxShadow: `inset 0 0 0 20px ${
theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.37)' : 'rgba(255, 255, 255, 0.37)'
}`,
},
}));
const StyledContent = styled(FuseScrollbars)(({ theme }) => ({
overscrollBehavior: 'contain',
overflowX: 'hidden',
overflowY: 'auto',
WebkitOverflowScrolling: 'touch',
backgroundRepeat: 'no-repeat',
backgroundSize: '100% 40px, 100% 10px',
backgroundAttachment: 'local, scroll',
}));
function NavbarStyle1Content(props) {
return (
<Root className={clsx('flex flex-auto flex-col overflow-hidden h-full', props.className)}>
<div className="flex flex-row items-center shrink-0 h-48 md:h-72 px-20">
<div className="flex flex-1 mx-4">
<Logo />
</div>
<NavbarToggleButton className="w-40 h-40 p-0" />
</div>
<StyledContent
className="flex flex-1 flex-col min-h-0"
option={{ suppressScrollX: true, wheelPropagation: false }}
>
<UserNavbarHeader />
<Navigation layout="vertical" />
<div className="flex flex-0 items-center justify-center py-48 opacity-10">
<img className="w-full max-w-64" src="assets/images/logo/logo.svg" alt="footer logo" />
</div>
</StyledContent>
</Root>
);
}
export default memo(NavbarStyle1Content);

View File

@@ -0,0 +1,171 @@
import Hidden from '@mui/material/Hidden';
import { styled } from '@mui/material/styles';
import SwipeableDrawer from '@mui/material/SwipeableDrawer';
import {
navbarCloseFolded,
navbarCloseMobile,
navbarOpenFolded,
selectFuseNavbar,
} from 'app/store/fuse/navbarSlice';
import { useDispatch, useSelector } from 'react-redux';
import { selectFuseCurrentLayoutConfig } from 'app/store/fuse/settingsSlice';
import NavbarStyle2Content from './NavbarStyle2Content';
const navbarWidth = 280;
const Root = styled('div')(({ theme, folded }) => ({
display: 'flex',
flexDirection: 'column',
zIndex: 4,
[theme.breakpoints.up('lg')]: {
width: navbarWidth,
minWidth: navbarWidth,
},
...(folded && {
[theme.breakpoints.up('lg')]: {
width: 76,
minWidth: 76,
},
}),
}));
const StyledNavbar = styled('div')(
({ theme, position, folded, foldedandopened, foldedandclosed }) => ({
minWidth: navbarWidth,
width: navbarWidth,
maxWidth: navbarWidth,
maxHeight: '100%',
transition: theme.transitions.create(['width', 'min-width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.shorter,
}),
...(position === 'left' && {
left: 0,
}),
...(position === 'right' && {
right: 0,
}),
...(folded && {
position: 'absolute',
width: 76,
minWidth: 76,
top: 0,
bottom: 0,
}),
...(foldedandopened && {
width: navbarWidth,
minWidth: navbarWidth,
}),
...(foldedandclosed && {
'& .NavbarStyle2-content': {
'& .logo-icon': {
width: 44,
height: 44,
},
'& .logo-text': {
opacity: 0,
},
'& .react-badge': {
opacity: 0,
},
'& .fuse-list-item': {
width: 56,
},
'& .fuse-list-item-text, & .arrow-icon, & .item-badge': {
opacity: 0,
},
'& .fuse-list-subheader .fuse-list-subheader-text': {
opacity: 0,
},
'& .fuse-list-subheader:before': {
content: '""',
display: 'block',
position: 'absolute',
minWidth: 16,
borderTop: '2px solid',
opacity: 0.2,
},
'& .collapse-children': {
display: 'none',
},
},
}),
})
);
const StyledNavbarMobile = styled(SwipeableDrawer)(({ theme, position }) => ({
'& > .MuiDrawer-paper': {
minWidth: navbarWidth,
width: navbarWidth,
maxWidth: navbarWidth,
maxHeight: '100%',
transition: theme.transitions.create(['width', 'min-width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.shorter,
}),
},
}));
function NavbarStyle2(props) {
const dispatch = useDispatch();
const config = useSelector(selectFuseCurrentLayoutConfig);
const navbar = useSelector(selectFuseNavbar);
// const folded = !navbar.open;
const { folded } = config.navbar;
const foldedandclosed = folded && !navbar.foldedOpen;
const foldedandopened = folded && navbar.foldedOpen;
return (
<Root
folded={folded ? 1 : 0}
open={navbar.open}
id="fuse-navbar"
className="sticky top-0 h-screen shrink-0 z-20 shadow-5"
>
<Hidden lgDown>
<StyledNavbar
className="flex-col flex-auto"
position={config.navbar.position}
folded={folded ? 1 : 0}
foldedandopened={foldedandopened ? 1 : 0}
foldedandclosed={foldedandclosed ? 1 : 0}
onMouseEnter={() => foldedandclosed && dispatch(navbarOpenFolded())}
onMouseLeave={() => foldedandopened && dispatch(navbarCloseFolded())}
>
<NavbarStyle2Content className="NavbarStyle2-content" />
</StyledNavbar>
</Hidden>
<Hidden lgUp>
<StyledNavbarMobile
classes={{
paper: 'flex-col flex-auto h-full',
}}
folded={folded ? 1 : 0}
foldedandopened={foldedandopened ? 1 : 0}
foldedandclosed={foldedandclosed ? 1 : 0}
anchor={config.navbar.position}
variant="temporary"
open={navbar.mobileOpen}
onClose={() => dispatch(navbarCloseMobile())}
onOpen={() => {}}
disableSwipeToOpen
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
<NavbarStyle2Content className="NavbarStyle2-content" />
</StyledNavbarMobile>
</Hidden>
</Root>
);
}
export default NavbarStyle2;

View File

@@ -0,0 +1,54 @@
import FuseScrollbars from '@fuse/core/FuseScrollbars';
import { styled } from '@mui/material/styles';
import clsx from 'clsx';
import { memo } from 'react';
import Logo from '../../../../shared-components/Logo';
import NavbarToggleButton from '../../../../shared-components/NavbarToggleButton';
import Navigation from '../../../../shared-components/Navigation';
const Root = styled('div')(({ theme }) => ({
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
'& ::-webkit-scrollbar-thumb': {
boxShadow: `inset 0 0 0 20px ${
theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.24)' : 'rgba(255, 255, 255, 0.24)'
}`,
},
'& ::-webkit-scrollbar-thumb:active': {
boxShadow: `inset 0 0 0 20px ${
theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.37)' : 'rgba(255, 255, 255, 0.37)'
}`,
},
}));
const StyledContent = styled(FuseScrollbars)(({ theme }) => ({
overscrollBehavior: 'contain',
overflowX: 'hidden',
overflowY: 'auto',
WebkitOverflowScrolling: 'touch',
background:
'linear-gradient(rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0) 30%), linear-gradient(rgba(0, 0, 0, 0.25) 0, rgba(0, 0, 0, 0) 40%)',
backgroundRepeat: 'no-repeat',
backgroundSize: '100% 40px, 100% 10px',
backgroundAttachment: 'local, scroll',
}));
function NavbarStyle2Content(props) {
return (
<Root className={clsx('flex flex-auto flex-col overflow-hidden h-full', props.className)}>
<div className="flex flex-row items-center shrink-0 h-48 md:h-76 px-12">
<div className="flex flex-1 mx-4">
<Logo />
</div>
<NavbarToggleButton className="w-40 h-40 p-0" />
</div>
<StyledContent option={{ suppressScrollX: true, wheelPropagation: false }}>
<Navigation layout="vertical" />
</StyledContent>
</Root>
);
}
export default memo(NavbarStyle2Content);

View File

@@ -0,0 +1,149 @@
import Hidden from '@mui/material/Hidden';
import { styled } from '@mui/material/styles';
import SwipeableDrawer from '@mui/material/SwipeableDrawer';
import { useDispatch, useSelector } from 'react-redux';
import { navbarCloseMobile, selectFuseNavbar } from 'app/store/fuse/navbarSlice';
import GlobalStyles from '@mui/material/GlobalStyles';
import { selectFuseCurrentLayoutConfig } from 'app/store/fuse/settingsSlice';
import NavbarStyle3Content from './NavbarStyle3Content';
const navbarWidth = 120;
const navbarWidthDense = 64;
const panelWidth = 280;
const StyledNavBar = styled('div')(({ theme, dense, open, folded, position }) => ({
minWidth: navbarWidth,
width: navbarWidth,
maxWidth: navbarWidth,
...(dense && {
minWidth: navbarWidthDense,
width: navbarWidthDense,
maxWidth: navbarWidthDense,
...(!open && {
...(position === 'left' && {
marginLeft: -navbarWidthDense,
}),
...(position === 'right' && {
marginRight: -navbarWidthDense,
}),
}),
}),
...(!folded && {
minWidth: dense ? navbarWidthDense + panelWidth : navbarWidth + panelWidth,
width: dense ? navbarWidthDense + panelWidth : navbarWidth + panelWidth,
maxWidth: dense ? navbarWidthDense + panelWidth : navbarWidth + panelWidth,
'& #fuse-navbar-panel': {
opacity: '1!important',
pointerEvents: 'initial!important',
},
...(!open && {
...(position === 'left' && {
marginLeft: -(dense ? navbarWidthDense + panelWidth : navbarWidth + panelWidth),
}),
...(position === 'right' && {
marginRight: -(dense ? navbarWidthDense + panelWidth : navbarWidth + panelWidth),
}),
}),
}),
...(!open && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.leavingScreen,
}),
...(position === 'left' && {
marginLeft: -(dense ? navbarWidthDense : navbarWidth),
}),
...(position === 'right' && {
marginRight: -(dense ? navbarWidthDense : navbarWidth),
}),
}),
...(open && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
}),
}));
const StyledNavBarMobile = styled(SwipeableDrawer)(({ theme }) => ({
'& .MuiDrawer-paper': {
'& #fuse-navbar-side-panel': {
minWidth: 'auto',
wdith: 'auto',
},
'& #fuse-navbar-panel': {
opacity: '1!important',
pointerEvents: 'initial!important',
},
},
}));
function NavbarStyle3(props) {
const dispatch = useDispatch();
const config = useSelector(selectFuseCurrentLayoutConfig);
const navbar = useSelector(selectFuseNavbar);
const { folded } = config.navbar;
return (
<>
<GlobalStyles
styles={(theme) => ({
'& #fuse-navbar-side-panel': {
width: props.dense ? navbarWidthDense : navbarWidth,
minWidth: props.dense ? navbarWidthDense : navbarWidth,
maxWidth: props.dense ? navbarWidthDense : navbarWidth,
},
'& #fuse-navbar-panel': {
maxWidth: '100%',
width: panelWidth,
[theme.breakpoints.up('lg')]: {
minWidth: panelWidth,
maxWidth: 'initial',
},
},
})}
/>
<Hidden lgDown>
<StyledNavBar
open={navbar.open}
dense={props.dense ? 1 : 0}
folded={folded ? 1 : 0}
position={config.navbar.position}
className="flex-col flex-auto sticky top-0 h-screen shrink-0 z-20 shadow-5"
>
<NavbarStyle3Content dense={props.dense ? 1 : 0} folded={folded ? 1 : 0} />
</StyledNavBar>
</Hidden>
<Hidden lgUp>
<StyledNavBarMobile
classes={{
paper: 'flex-col flex-auto h-screen max-w-full w-auto overflow-hidden',
}}
anchor={config.navbar.position}
variant="temporary"
open={navbar.mobileOpen}
onClose={() => dispatch(navbarCloseMobile())}
onOpen={() => {}}
disableSwipeToOpen
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
<NavbarStyle3Content dense={props.dense ? 1 : 0} folded={folded ? 1 : 0} />
</StyledNavBarMobile>
</Hidden>
</>
);
}
export default NavbarStyle3;

View File

@@ -0,0 +1,147 @@
import FuseScrollbars from '@fuse/core/FuseScrollbars';
import { styled, useTheme } from '@mui/material/styles';
import ClickAwayListener from '@mui/material/ClickAwayListener';
import clsx from 'clsx';
import { memo, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import FuseNavigation from '@fuse/core/FuseNavigation';
import { navbarCloseMobile } from 'app/store/fuse/navbarSlice';
import { selectContrastMainTheme } from 'app/store/fuse/settingsSlice';
import { useLocation } from 'react-router-dom';
import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery';
import { selectNavigation } from 'app/store/fuse/navigationSlice';
const Root = styled('div')(({ theme }) => ({
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
const StyledPanel = styled(FuseScrollbars)(({ theme, opened }) => ({
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
transition: theme.transitions.create(['opacity'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.shortest,
}),
opacity: 0,
pointerEvents: 'none',
...(opened && {
opacity: 1,
pointerEvents: 'initial',
}),
}));
function needsToBeOpened(location, item) {
return location && isUrlInChildren(item, location.pathname);
}
function isUrlInChildren(parent, url) {
if (!parent.children) {
return false;
}
for (let i = 0; i < parent.children.length; i += 1) {
if (parent.children[i].children) {
if (isUrlInChildren(parent.children[i], url)) {
return true;
}
}
if (parent.children[i].url === url || url.includes(parent.children[i].url)) {
return true;
}
}
return false;
}
function NavbarStyle3Content(props) {
const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg'));
const navigation = useSelector(selectNavigation);
const [selectedNavigation, setSelectedNavigation] = useState([]);
const [panelOpen, setPanelOpen] = useState(false);
const theme = useTheme();
const dispatch = useDispatch();
const contrastTheme = useSelector(selectContrastMainTheme(theme.palette.primary.main));
const location = useLocation();
useEffect(() => {
navigation?.forEach((item) => {
if (needsToBeOpened(location, item)) {
setSelectedNavigation([item]);
}
});
}, [navigation, location]);
function handleParentItemClick(selected) {
/** if there is no child item do not set/open panel
*/
if (!selected.children) {
setSelectedNavigation([]);
setPanelOpen(false);
return;
}
/**
* If navigation already selected toggle panel visibility
*/
if (selectedNavigation[0]?.id === selected.id) {
setPanelOpen(!panelOpen);
} else {
/**
* Set navigation and open panel
*/
setSelectedNavigation([selected]);
setPanelOpen(true);
}
}
function handleChildItemClick(selected) {
setPanelOpen(false);
if (isMobile) {
dispatch(navbarCloseMobile());
}
}
return (
<ClickAwayListener onClickAway={() => setPanelOpen(false)}>
<Root className={clsx('flex flex-auto flex h-full', props.className)}>
<div id="fuse-navbar-side-panel" className="flex shrink-0 flex-col items-center">
<img className="w-44 my-32" src="assets/images/logo/logo.svg" alt="logo" />
<FuseScrollbars
className="flex flex-1 min-h-0 justify-center w-full overflow-y-auto overflow-x-hidden"
option={{ suppressScrollX: true, wheelPropagation: false }}
>
<FuseNavigation
className={clsx('navigation')}
navigation={navigation}
layout="vertical-2"
onItemClick={handleParentItemClick}
firstLevel
selectedId={selectedNavigation[0]?.id}
dense={props.dense}
/>
</FuseScrollbars>
</div>
{selectedNavigation.length > 0 && (
<StyledPanel
id="fuse-navbar-panel"
opened={panelOpen}
className={clsx('shadow-5 overflow-y-auto overflow-x-hidden')}
option={{ suppressScrollX: true, wheelPropagation: false }}
>
<FuseNavigation
className={clsx('navigation')}
navigation={selectedNavigation}
layout="vertical"
onItemClick={handleChildItemClick}
/>
</StyledPanel>
)}
</Root>
</ClickAwayListener>
);
}
export default memo(NavbarStyle3Content);