diff --git a/.eslintrc b/.eslintrc index bb0c4e1..eb80a2e 100644 --- a/.eslintrc +++ b/.eslintrc @@ -99,6 +99,11 @@ "**/.eslintrc.[j|t]s" ], "optionalDependencies": false + }], + "react/function-component-definition": [ + "error", { + "namedComponents": "arrow-function", + "unnamedComponents": "arrow-function" }] } } diff --git a/offline_node_modules/@react-spring-animated-npm-9.7.3-4aff527e22-5151da4fa7.zip b/offline_node_modules/@react-spring-animated-npm-9.7.3-4aff527e22-5151da4fa7.zip new file mode 100644 index 0000000..6373e32 Binary files /dev/null and b/offline_node_modules/@react-spring-animated-npm-9.7.3-4aff527e22-5151da4fa7.zip differ diff --git a/offline_node_modules/@react-spring-core-npm-9.7.3-00b8dd52b3-e28c05de84.zip b/offline_node_modules/@react-spring-core-npm-9.7.3-00b8dd52b3-e28c05de84.zip new file mode 100644 index 0000000..9b8cacc Binary files /dev/null and b/offline_node_modules/@react-spring-core-npm-9.7.3-00b8dd52b3-e28c05de84.zip differ diff --git a/offline_node_modules/@react-spring-shared-npm-9.7.3-cefcfdc40d-afb03ed28c.zip b/offline_node_modules/@react-spring-shared-npm-9.7.3-cefcfdc40d-afb03ed28c.zip new file mode 100644 index 0000000..98b9eaa Binary files /dev/null and b/offline_node_modules/@react-spring-shared-npm-9.7.3-cefcfdc40d-afb03ed28c.zip differ diff --git a/offline_node_modules/@react-spring-types-npm-9.7.3-f9de91ab6e-d645044f3c.zip b/offline_node_modules/@react-spring-types-npm-9.7.3-f9de91ab6e-d645044f3c.zip new file mode 100644 index 0000000..99c00b5 Binary files /dev/null and b/offline_node_modules/@react-spring-types-npm-9.7.3-f9de91ab6e-d645044f3c.zip differ diff --git a/offline_node_modules/@react-spring-web-npm-9.7.3-95390d075a-a5b4847a29.zip b/offline_node_modules/@react-spring-web-npm-9.7.3-95390d075a-a5b4847a29.zip new file mode 100644 index 0000000..17eb392 Binary files /dev/null and b/offline_node_modules/@react-spring-web-npm-9.7.3-95390d075a-a5b4847a29.zip differ diff --git a/package.json b/package.json index f88e1a2..7df13d9 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@emotion/styled": "11.11.5", "@mui/icons-material": "^5.15.19", "@mui/material": "5.15.19", + "@react-spring/web": "9.7.3", "classnames": "2.5.1", "notistack": "3.0.1", "prop-types": "15.8.1", diff --git a/src/apps/MoneyControllApp/model/providers/RouterProvider/index.tsx b/src/apps/MoneyControllApp/model/providers/RouterProvider/index.tsx index fe5b5aa..5798b35 100644 --- a/src/apps/MoneyControllApp/model/providers/RouterProvider/index.tsx +++ b/src/apps/MoneyControllApp/model/providers/RouterProvider/index.tsx @@ -1,11 +1,10 @@ import CalendarMonthIcon from '@mui/icons-material/CalendarMonth'; import FormatListBulletedIcon from '@mui/icons-material/FormatListBulleted'; import PieChartIcon from '@mui/icons-material/PieChart'; -import { CircularProgress } from '@mui/material'; +import CircularProgress from '@mui/material/CircularProgress'; import { Suspense } from 'react'; import { createBrowserRouter, Navigate, RouterProvider as RRDRouterProvider } from 'react-router-dom'; -// todo lazy & access import { AnalyzePage, AnalyzePageToolbar } from 'pages/AnalyzePage'; import { ErrorPage, ErrorPageToolbar } from 'pages/ErrorPage'; import { PaymentsPage, PaymentsPageToolbar } from 'pages/PaymentsPage'; diff --git a/src/pages/SchedulePage/ui/SchedulePage.spec.tsx b/src/pages/SchedulePage/ui/SchedulePage.spec.tsx index dfb306d..9219e8d 100644 --- a/src/pages/SchedulePage/ui/SchedulePage.spec.tsx +++ b/src/pages/SchedulePage/ui/SchedulePage.spec.tsx @@ -1,4 +1,4 @@ -import { render, screen } from '@testing-library/react'; +import { render, screen, waitFor } from '@testing-library/react'; import { SchedulePage, SchedulePageToolbar } from 'pages/SchedulePage'; @@ -7,12 +7,15 @@ describe('Test SchedulePage', () => { , ); - test('should render correctly', () => { + test('should render correctly', async () => { setup(); - const pageElem = screen.getByTestId('schedule-page'); - expect(pageElem).toBeVisible(); - expect(pageElem).toHaveTextContent('Schedule Page'); + await waitFor(() => { + const pageElem = screen.getByTestId('schedule-page'); + expect(pageElem).toBeVisible(); + // eslint-disable-next-line testing-library/no-wait-for-multiple-assertions + expect(pageElem).toHaveTextContent('Schedule Page'); + }); }); }); diff --git a/src/shared/hoc/withProvider/ui/withProvider.ui.tsx b/src/shared/hoc/withProvider/ui/withProvider.ui.tsx index d4385c7..c7c14de 100644 --- a/src/shared/hoc/withProvider/ui/withProvider.ui.tsx +++ b/src/shared/hoc/withProvider/ui/withProvider.ui.tsx @@ -1,8 +1,5 @@ -// todo fix eslint - import type { FC, PropsWithChildren } from 'react'; -// eslint-disable-next-line react/function-component-definition const withProvider = (Provider: FC) => (Component: FC) => (...params: T[]) => ( {/* @ts-ignore */} diff --git a/src/widgets/AsideMenuLayout/ui/AsideMenuLayout.spec.tsx b/src/widgets/AsideMenuLayout/ui/AsideMenuLayout.spec.tsx index f349181..59868c9 100644 --- a/src/widgets/AsideMenuLayout/ui/AsideMenuLayout.spec.tsx +++ b/src/widgets/AsideMenuLayout/ui/AsideMenuLayout.spec.tsx @@ -1,7 +1,7 @@ import { renderWithProvider } from '__spec__/custon-renders'; import PieChartIcon from '@mui/icons-material/PieChart'; -import { fireEvent, screen } from '@testing-library/react'; +import { fireEvent, screen, waitFor } from '@testing-library/react'; import AsideMenuLayout from './AsideMenuLayout.ui'; @@ -41,10 +41,6 @@ describe('Test AsideMenuLayout', () => { } data-testid="aside-menu-layout" - DrawerSwitcherProps={{ - // @ts-ignore - 'data-testid': 'drawer-switcher', - }} pages={pages} Toolbar={} />, @@ -58,18 +54,22 @@ describe('Test AsideMenuLayout', () => { expect(layoutElem).toBeVisible(); }); - test('should render toolbar', () => { + test('should render toolbar', async () => { setup(); - const toolbarElem = screen.getByText('Test Toolbar'); - expect(toolbarElem).toBeVisible(); + await waitFor(() => { + const toolbarElem = screen.getByText('Test Toolbar'); + expect(toolbarElem).toBeVisible(); + }); }); - test('should render content', () => { + test('should render content', async () => { setup(); - const toolbarElem = screen.getByText('Test Content'); - expect(toolbarElem).toBeVisible(); + await waitFor(() => { + const toolbarElem = screen.getByText('Test Content'); + expect(toolbarElem).toBeVisible(); + }); }); test('should render navigation routes', () => { diff --git a/src/widgets/AsideMenuLayout/ui/AsideMenuLayout.ui.tsx b/src/widgets/AsideMenuLayout/ui/AsideMenuLayout.ui.tsx index e94bc10..f2fdb6a 100644 --- a/src/widgets/AsideMenuLayout/ui/AsideMenuLayout.ui.tsx +++ b/src/widgets/AsideMenuLayout/ui/AsideMenuLayout.ui.tsx @@ -1,104 +1,137 @@ -import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; -import MenuIcon from '@mui/icons-material/Menu'; +import { useMediaQuery } from '@mui/material'; import Box from '@mui/material/Box'; -import CssBaseline from '@mui/material/CssBaseline'; -import Divider from '@mui/material/Divider'; import List from '@mui/material/List'; -import { useState } from 'react'; +import { useTheme } from '@mui/material/styles'; +import Tooltip from '@mui/material/Tooltip'; +import { animated, useTransition } from '@react-spring/web'; +import { useContext } from 'react'; +import { useLocation } from 'react-router-dom'; -import AppBar from './components/AppBar'; -import Drawer from './components/Drawer'; -import DrawerHeader from './components/DrawerMenu'; -import DrawerSwitcher from './components/DrawerSwitcher'; -import MenuItem from './components/MenuItem/MenuItem.ui'; +import { DesktopAppBar, MobileAppBar } from './components/AppBar'; +import { AsideMenuContext, AsideMenuProvider } from './components/AsideMenuProvider'; +import { DesktopDrawer } from './components/DesktopDrawer'; +import { MenuItem } from './components/MenuItem'; +import { MobileDrawer } from './components/MobileDrawer'; -import type { MenuItemProps } from './components/MenuItem/MenuItem.ui'; +import type { MenuItemProps } from './components/MenuItem/ui/MenuItem.ui'; import type { BoxProps } from '@mui/material/Box/Box'; -import type { - FC, - ReactNode, - DetailedHTMLProps, - HTMLAttributes, -} from 'react'; +import type { FC, ReactNode } from 'react'; -const drawerWidth = 250; +export const DESKTOP_DRAWER_WIDTH = 250; +export const MOBILE_DRAWER_WIDTH = 250; -type AsideMenuLayoutProps = BoxProps & { +export type AsideMenuLayoutProps = BoxProps & { pages: MenuItemProps['page'][]; Content: ReactNode; Toolbar?: ReactNode; - DrawerSwitcherProps?: DetailedHTMLProps, HTMLDivElement>; }; const AsideMenuLayout: FC = (props) => { const { pages, Content, Toolbar, - DrawerSwitcherProps, ...restProps } = props; - const [isOpen, setIsOpen] = useState(true); + const { desktopDrawerOpen, setMobileDrawerOpen } = useContext(AsideMenuContext); + const theme = useTheme(); + const isMobileView = useMediaQuery(theme.breakpoints.down('sm')); - const handleDrawerOpen = () => { - setIsOpen(true); - }; - const handleDrawerClose = () => { - setIsOpen(false); - }; + const location = useLocation(); + const transitions = useTransition(location, { + from: { opacity: 0 }, + enter: { opacity: 1 }, + leave: { opacity: 0 }, + unique: true, + reset: true, + }); + + const AnimatedContent = ( + <> + {transitions((styles) => ( + + {Content} + + ))} + + ); + + const AnimatedToolBar = ( + <> + {transitions((styles) => ( + + {Toolbar} + + ))} + + ); + + if (isMobileView) { + return ( + + { + Boolean(Toolbar) && ( + + + + {pages.map((page) => ( + { setMobileDrawerOpen(false); }} + /> + ))} + + + + {AnimatedToolBar} + + ) + } + + + {AnimatedContent} + + + ); + } return ( - - - - - - { isOpen ? : } - - - - - + {pages.map((page) => ( - - ))} + desktopDrawerOpen + ? ( + + ) + : ( + + + + )))} - + - - { - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - Toolbar - ? ( - <> - - {Toolbar} - + + { Boolean(Toolbar) && ( + + {AnimatedToolBar} + + )} - - - ) - : null - } - - {Content} + + {AnimatedContent} + ); }; -export default AsideMenuLayout; +const withProvider = (Component: FC) => (props: AsideMenuLayoutProps) => ( + + + +); + +export default withProvider(AsideMenuLayout); diff --git a/src/widgets/AsideMenuLayout/ui/components/AppBar/index.tsx b/src/widgets/AsideMenuLayout/ui/components/AppBar/index.tsx index 582417b..318a896 100644 --- a/src/widgets/AsideMenuLayout/ui/components/AppBar/index.tsx +++ b/src/widgets/AsideMenuLayout/ui/components/AppBar/index.tsx @@ -1,30 +1,21 @@ import MuiAppBar from '@mui/material/AppBar'; import { styled } from '@mui/material/styles'; -import type { AppBarProps as MuiAppBarProps } from '@mui/material/AppBar/AppBar'; - -type AppBarProps = MuiAppBarProps & { - open?: boolean; - drawerWidth: number; -}; - -const AppBar = styled(MuiAppBar, { shouldForwardProp: (prop) => !['open', 'drawerWidth'].includes(prop as string) })( - ({ theme, open, drawerWidth }) => ({ +export const DesktopAppBar = styled(MuiAppBar)( + ({ theme }) => ({ transition: theme.transitions.create(['width', 'margin'], { easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.leavingScreen, }), - marginLeft: `calc(${theme.spacing(7)} + 1px)`, - width: `calc(100% - calc(${theme.spacing(7)} + 1px))`, - ...Boolean(open) && { - marginLeft: drawerWidth, - width: `calc(100% - ${drawerWidth}px)`, - transition: theme.transitions.create(['width', 'margin'], { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen, - }), - }, + display: 'flex', + flexDirection: 'row', + alignItems: 'center', }), ); -export default AppBar; +export const MobileAppBar = styled(MuiAppBar)(() => ({ + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + padding: '0 24px', +})); diff --git a/src/widgets/AsideMenuLayout/ui/components/AsideMenuProvider/index.ts b/src/widgets/AsideMenuLayout/ui/components/AsideMenuProvider/index.ts new file mode 100644 index 0000000..0cfea09 --- /dev/null +++ b/src/widgets/AsideMenuLayout/ui/components/AsideMenuProvider/index.ts @@ -0,0 +1,2 @@ +export { default as AsideMenuProvider } from './ui/AsideMenuProvider.ui'; +export { AsideMenuContext } from './model/context'; diff --git a/src/widgets/AsideMenuLayout/ui/components/AsideMenuProvider/model/context.ts b/src/widgets/AsideMenuLayout/ui/components/AsideMenuProvider/model/context.ts new file mode 100644 index 0000000..3856b8d --- /dev/null +++ b/src/widgets/AsideMenuLayout/ui/components/AsideMenuProvider/model/context.ts @@ -0,0 +1,10 @@ +import { createContext } from 'react'; + +export type AsideMenuContextType = { + desktopDrawerOpen: boolean; + setDesktopDrawerOpen: (isOpen: boolean) => void; + mobileDrawerOpen: boolean; + setMobileDrawerOpen: (isOpen: boolean) => void; +}; + +export const AsideMenuContext = createContext({} as AsideMenuContextType); diff --git a/src/widgets/AsideMenuLayout/ui/components/AsideMenuProvider/ui/AsideMenuProvider.ui.tsx b/src/widgets/AsideMenuLayout/ui/components/AsideMenuProvider/ui/AsideMenuProvider.ui.tsx new file mode 100644 index 0000000..01e59ae --- /dev/null +++ b/src/widgets/AsideMenuLayout/ui/components/AsideMenuProvider/ui/AsideMenuProvider.ui.tsx @@ -0,0 +1,31 @@ +import { useMemo, useState } from 'react'; + +import { AsideMenuContext, type AsideMenuContextType } from '../model/context'; + +import type { FC, ReactNode } from 'react'; + +type AsideMenuProviderProps = { + children: ReactNode; +}; +const AsideMenuProvider: FC = (props) => { + const { children } = props; + + // todo desktop from default value localstorage + const [desktopDrawerOpen, setDesktopDrawerOpen] = useState(true); + const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false); + + const value = useMemo(() => ({ + desktopDrawerOpen, + setDesktopDrawerOpen, + mobileDrawerOpen, + setMobileDrawerOpen, + }), [desktopDrawerOpen, mobileDrawerOpen]); + + return ( + + {children} + + ); +}; + +export default AsideMenuProvider; diff --git a/src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/index.ts b/src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/index.ts new file mode 100644 index 0000000..37f7bda --- /dev/null +++ b/src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/index.ts @@ -0,0 +1,2 @@ +export type { DesktopDrawerProps } from './ui/DesktopDrawer.ui'; +export { default as DesktopDrawer } from './ui/DesktopDrawer.ui'; diff --git a/src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/ui/DesktopDrawer.ui.tsx b/src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/ui/DesktopDrawer.ui.tsx new file mode 100644 index 0000000..01883b0 --- /dev/null +++ b/src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/ui/DesktopDrawer.ui.tsx @@ -0,0 +1,53 @@ +import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; +import MenuIcon from '@mui/icons-material/Menu'; +import Divider from '@mui/material/Divider'; +import { useContext } from 'react'; + +import { AsideMenuContext } from '../../AsideMenuProvider'; + +import Drawer from './components/Drawer'; +import DrawerHeader from './components/DrawerMenu'; +import DrawerSwitcher from './components/DrawerSwitcher'; + +import type { FC, ReactNode } from 'react'; + +export type DesktopDrawerProps = { + width: number; + children: ReactNode; +}; + +const DesktopDrawer: FC = (props) => { + const { + width, + children, + } = props; + + const { desktopDrawerOpen, setDesktopDrawerOpen } = useContext(AsideMenuContext); + + const handleDrawerOpen = () => { + setDesktopDrawerOpen(true); + }; + const handleDrawerClose = () => { + setDesktopDrawerOpen(false); + }; + + return ( + + + + { desktopDrawerOpen ? : } + + + + + + {children} + + ); +}; + +export default DesktopDrawer; diff --git a/src/widgets/AsideMenuLayout/ui/components/Drawer/index.tsx b/src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/ui/components/Drawer/index.tsx similarity index 70% rename from src/widgets/AsideMenuLayout/ui/components/Drawer/index.tsx rename to src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/ui/components/Drawer/index.tsx index f09dbcd..e8b0ad1 100644 --- a/src/widgets/AsideMenuLayout/ui/components/Drawer/index.tsx +++ b/src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/ui/components/Drawer/index.tsx @@ -3,11 +3,11 @@ import { type CSSObject, styled, type Theme } from '@mui/material/styles'; type DrawerProps = { open: boolean; - drawerWidth: number; + width: number; }; -const openedMixin = (theme: Theme, { drawerWidth }: Pick): CSSObject => ({ - width: drawerWidth, +const openedMixin = (theme: Theme, { width }: Pick): CSSObject => ({ + width, transition: theme.transitions.create('width', { easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.enteringScreen, @@ -24,15 +24,15 @@ const closedMixin = (theme: Theme): CSSObject => ({ width: `calc(${theme.spacing(8)} + 1px)`, }); -const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => !['open', 'drawerWidth'].includes(prop as string) })( - ({ theme, open, drawerWidth }) => ({ - width: drawerWidth, +const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => !['open', 'width'].includes(prop as string) })( + ({ theme, open, width }) => ({ + width, flexShrink: 0, whiteSpace: 'nowrap', boxSizing: 'border-box', ...open && { - ...openedMixin(theme, { drawerWidth }), - '& .MuiDrawer-paper': openedMixin(theme, { drawerWidth }), + ...openedMixin(theme, { width }), + '& .MuiDrawer-paper': openedMixin(theme, { width }), }, ...!open && { ...closedMixin(theme), diff --git a/src/widgets/AsideMenuLayout/ui/components/DrawerMenu/index.tsx b/src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/ui/components/DrawerMenu/index.tsx similarity index 100% rename from src/widgets/AsideMenuLayout/ui/components/DrawerMenu/index.tsx rename to src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/ui/components/DrawerMenu/index.tsx diff --git a/src/widgets/AsideMenuLayout/ui/components/DrawerSwitcher/index.tsx b/src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/ui/components/DrawerSwitcher/index.tsx similarity index 100% rename from src/widgets/AsideMenuLayout/ui/components/DrawerSwitcher/index.tsx rename to src/widgets/AsideMenuLayout/ui/components/DesktopDrawer/ui/components/DrawerSwitcher/index.tsx diff --git a/src/widgets/AsideMenuLayout/ui/components/MenuItem/index.ts b/src/widgets/AsideMenuLayout/ui/components/MenuItem/index.ts new file mode 100644 index 0000000..4a6ccb6 --- /dev/null +++ b/src/widgets/AsideMenuLayout/ui/components/MenuItem/index.ts @@ -0,0 +1 @@ +export { default as MenuItem } from './ui/MenuItem.ui'; diff --git a/src/widgets/AsideMenuLayout/ui/components/MenuItem/MenuItem.spec.tsx b/src/widgets/AsideMenuLayout/ui/components/MenuItem/ui/MenuItem.spec.tsx similarity index 100% rename from src/widgets/AsideMenuLayout/ui/components/MenuItem/MenuItem.spec.tsx rename to src/widgets/AsideMenuLayout/ui/components/MenuItem/ui/MenuItem.spec.tsx diff --git a/src/widgets/AsideMenuLayout/ui/components/MenuItem/MenuItem.ui.tsx b/src/widgets/AsideMenuLayout/ui/components/MenuItem/ui/MenuItem.ui.tsx similarity index 90% rename from src/widgets/AsideMenuLayout/ui/components/MenuItem/MenuItem.ui.tsx rename to src/widgets/AsideMenuLayout/ui/components/MenuItem/ui/MenuItem.ui.tsx index b46e5db..bfc057a 100644 --- a/src/widgets/AsideMenuLayout/ui/components/MenuItem/MenuItem.ui.tsx +++ b/src/widgets/AsideMenuLayout/ui/components/MenuItem/ui/MenuItem.ui.tsx @@ -4,10 +4,11 @@ import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import { styled, useTheme } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; +import { forwardRef } from 'react'; import { NavLink as RRDNavLink } from 'react-router-dom'; import type { ListItemProps } from '@mui/material/ListItem/ListItem'; -import type { FC, ReactNode } from 'react'; +import type { ReactNode } from 'react'; import type { NavLinkProps } from 'react-router-dom'; const NavLink = styled(RRDNavLink)(({ theme }) => ({ @@ -26,7 +27,7 @@ export type MenuItemProps = ListItemProps & { NavLinkProps?: NavLinkProps; }; -const MenuItem: FC = (props) => { +const MenuItem = forwardRef((props, ref) => { const { page, isOpen = true, @@ -36,7 +37,7 @@ const MenuItem: FC = (props) => { const theme = useTheme(); return ( - + {({ isActive }) => ( = (props) => { ); -}; +}); export default MenuItem; diff --git a/src/widgets/AsideMenuLayout/ui/components/MobileDrawer/index.ts b/src/widgets/AsideMenuLayout/ui/components/MobileDrawer/index.ts new file mode 100644 index 0000000..d8563e5 --- /dev/null +++ b/src/widgets/AsideMenuLayout/ui/components/MobileDrawer/index.ts @@ -0,0 +1 @@ +export { default as MobileDrawer } from './ui/MobileDrawer.ui'; diff --git a/src/widgets/AsideMenuLayout/ui/components/MobileDrawer/ui/MobileDrawer.ui.tsx b/src/widgets/AsideMenuLayout/ui/components/MobileDrawer/ui/MobileDrawer.ui.tsx new file mode 100644 index 0000000..abdaad8 --- /dev/null +++ b/src/widgets/AsideMenuLayout/ui/components/MobileDrawer/ui/MobileDrawer.ui.tsx @@ -0,0 +1,56 @@ +import MenuIcon from '@mui/icons-material/Menu'; +import MuiDrawer from '@mui/material/Drawer'; +import IconButton from '@mui/material/IconButton'; +import { useContext } from 'react'; + +import { AsideMenuContext } from '../../AsideMenuProvider'; + +import type { FC, ReactNode } from 'react'; + +type MobileDrawerProps = { + children: ReactNode; + width: number; + + onOpen?: () => void; + onClose?: () => void; +}; + +const MobileDrawer: FC = (props) => { + const { + children, + width, + onOpen, + onClose, + } = props; + + const { mobileDrawerOpen, setMobileDrawerOpen } = useContext(AsideMenuContext); + + const handleDrawerOpen = () => { + setMobileDrawerOpen(true); + onOpen?.(); + }; + + const handleDrawerClose = () => { + setMobileDrawerOpen(false); + onClose?.(); + }; + + return ( + <> + + + + + + {children} + + + + ); +}; + +export default MobileDrawer; diff --git a/yarn.lock b/yarn.lock index 1da2e33..6a8414d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4496,6 +4496,64 @@ __metadata: languageName: node linkType: hard +"@react-spring/animated@npm:~9.7.3": + version: 9.7.3 + resolution: "@react-spring/animated@npm:9.7.3" + dependencies: + "@react-spring/shared": "npm:~9.7.3" + "@react-spring/types": "npm:~9.7.3" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/5151da4fa7da010bb2edbee05871aa7a4aea8763fe617389d17605810aa0dd817374205e5fb3930b650f4a7f25fcdf23205fdfb7365686ff75888bdfd0b39839 + languageName: node + linkType: hard + +"@react-spring/core@npm:~9.7.3": + version: 9.7.3 + resolution: "@react-spring/core@npm:9.7.3" + dependencies: + "@react-spring/animated": "npm:~9.7.3" + "@react-spring/shared": "npm:~9.7.3" + "@react-spring/types": "npm:~9.7.3" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/e28c05de8435bf2eaf8481f8acdf093909d4be9881a9a854c51dfac7c2d5562088d0fb2ce04e2f07e1b3bf621d8da3ab57bf6fedb4fdc954e3aa263bc1e393af + languageName: node + linkType: hard + +"@react-spring/shared@npm:~9.7.3": + version: 9.7.3 + resolution: "@react-spring/shared@npm:9.7.3" + dependencies: + "@react-spring/types": "npm:~9.7.3" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/afb03ed28ccf62efa4012e531c3659999bb364d1e0eb0fb729b962f9bd21a0b772a2d98e862062c9c32c06edf72327afcc45984d9eb22fdd961706b6ddf6950d + languageName: node + linkType: hard + +"@react-spring/types@npm:~9.7.3": + version: 9.7.3 + resolution: "@react-spring/types@npm:9.7.3" + checksum: 10c0/d645044f3cc9ceb7c4f6c4d061aaf6660018568a1553d05638f56b3328c5f91597ee4118334abe22fc8f07f5ee02f054340170c1d52e11b3faea22888b5170d4 + languageName: node + linkType: hard + +"@react-spring/web@npm:9.7.3": + version: 9.7.3 + resolution: "@react-spring/web@npm:9.7.3" + dependencies: + "@react-spring/animated": "npm:~9.7.3" + "@react-spring/core": "npm:~9.7.3" + "@react-spring/shared": "npm:~9.7.3" + "@react-spring/types": "npm:~9.7.3" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/a5b4847a2921a29a3e8ce569f4951abeb268b6e8eb230f8c49d98709216b2b3a23ba1e58628c51c9eaa0bd20d83f9d7b8f8f03df98215e933de4c66c39e17fe1 + languageName: node + linkType: hard + "@remix-run/router@npm:1.16.1": version: 1.16.1 resolution: "@remix-run/router@npm:1.16.1" @@ -12874,6 +12932,7 @@ __metadata: "@emotion/styled": "npm:11.11.5" "@mui/icons-material": "npm:^5.15.19" "@mui/material": "npm:5.15.19" + "@react-spring/web": "npm:9.7.3" "@testing-library/jest-dom": "npm:6.4.2" "@testing-library/react": "npm:14.3.1" "@testing-library/user-event": "npm:^14.5.2"