From 1830e12d6006497023f55f822f4cb8e8cb90f211 Mon Sep 17 00:00:00 2001 From: MorganeLecurieux Date: Tue, 2 Aug 2022 11:57:22 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=97=83=20DS=20-=20Drawer=20compon?= =?UTF-8?q?ent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/designSystem/Drawer.tsx | 116 +++++++++++++++++++++++++ src/components/designSystem/index.ts | 1 + src/layouts/SideNavLayout.tsx | 4 +- src/pages/__devOnly/DesignSystem.tsx | 58 ++++++++++++- 4 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 src/components/designSystem/Drawer.tsx diff --git a/src/components/designSystem/Drawer.tsx b/src/components/designSystem/Drawer.tsx new file mode 100644 index 000000000..59f394f9f --- /dev/null +++ b/src/components/designSystem/Drawer.tsx @@ -0,0 +1,116 @@ +import { Drawer as MuiDrawer, DrawerProps as MuiDrawerProps, alpha } from '@mui/material' +import { + cloneElement, + forwardRef, + ReactElement, + useImperativeHandle, + useState, + ReactNode, +} from 'react' +import styled from 'styled-components' + +import { Button, Typography } from '~/components/designSystem' +import { theme, NAV_HEIGHT } from '~/styles' + +export interface DrawerProps extends Pick { + className?: string + title: string | ReactNode + opener?: ReactElement + forceOpen?: boolean + children: (({ closeDrawer }: { closeDrawer: () => void }) => ReactNode) | ReactNode + onClose?: () => void +} + +export interface DrawerRef { + openDrawer: () => unknown + closeDrawer: () => unknown +} + +export const Drawer = forwardRef( + ({ forceOpen = false, children, opener, anchor = 'right', title, onClose }: DrawerProps, ref) => { + const [isOpen, setIsOpen] = useState(forceOpen) + + useImperativeHandle(ref, () => ({ + openDrawer: () => setIsOpen(true), + closeDrawer: () => setIsOpen(false), + })) + + return ( + <> + {!!opener && cloneElement(opener, { onClick: () => setIsOpen((prev) => !prev) })} + { + onClose && onClose() + setIsOpen(false) + }} + transitionDuration={250} + PaperProps={{ className: 'drawerPaper' }} + > +
+ {typeof title === 'string' ? ( + + {title} + + ) : ( + title + )} +
+ + {typeof children === 'function' + ? children({ closeDrawer: () => setIsOpen(false) }) + : children} + +
+ + ) + } +) + +Drawer.displayName = 'Drawer' + +const StyledDrawer = styled(MuiDrawer)` + .drawerPaper { + max-width: 816px; + width: calc(100vw - ${theme.spacing(12)}); + + ${theme.breakpoints.down('md')} { + width: 100%; + } + } + + .MuiBackdrop-root { + background-color: ${alpha(theme.palette.grey[700], 0.4)}; + } +` + +const Header = styled.div` + height: ${NAV_HEIGHT}px; + box-shadow: ${theme.shadows[7]}; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 ${theme.spacing(12)}; + + ${theme.breakpoints.down('md')} { + padding: 0 ${theme.spacing(4)}; + } +` + +const Content = styled.div` + padding: ${theme.spacing(12)} ${theme.spacing(12)} ${theme.spacing(20)}; + + ${theme.breakpoints.down('md')} { + padding: ${theme.spacing(12)} ${theme.spacing(4)} ${theme.spacing(20)} ${theme.spacing(4)}; + } +` diff --git a/src/components/designSystem/index.ts b/src/components/designSystem/index.ts index e54419f1f..4fbf1586f 100644 --- a/src/components/designSystem/index.ts +++ b/src/components/designSystem/index.ts @@ -4,6 +4,7 @@ export * from './Button' export * from './ButtonLink' export * from './Chip' export * from './Dialog' +export * from './Drawer' export * from './Icon' export * from './InfiniteScroll' export * from './Popper' diff --git a/src/layouts/SideNavLayout.tsx b/src/layouts/SideNavLayout.tsx index 0aa093d63..e0a57bcac 100644 --- a/src/layouts/SideNavLayout.tsx +++ b/src/layouts/SideNavLayout.tsx @@ -254,7 +254,7 @@ const Container = styled.div` const BurgerButton = styled(Button)` && { position: absolute; - z-index: ${theme.zIndex.drawer + 1}; + z-index: ${theme.zIndex.drawer}; left: ${theme.spacing(4)}; top: ${theme.spacing(4)}; @@ -276,7 +276,7 @@ const Drawer = styled.div<{ $open: boolean }>` ${theme.breakpoints.down('md')} { position: absolute; - z-index: ${theme.zIndex.drawer}; + z-index: ${theme.zIndex.drawer - 1}; left: ${({ $open }) => ($open ? 0 : -NAV_WIDTH)}px; } ` diff --git a/src/pages/__devOnly/DesignSystem.tsx b/src/pages/__devOnly/DesignSystem.tsx index 26c8a34a7..16256337b 100644 --- a/src/pages/__devOnly/DesignSystem.tsx +++ b/src/pages/__devOnly/DesignSystem.tsx @@ -2,13 +2,21 @@ import styled, { css } from 'styled-components' import { useFormik } from 'formik' import { generatePath } from 'react-router-dom' -import { Typography, ButtonLink, NavigationTab } from '~/components/designSystem' +import { + Typography, + ButtonLink, + NavigationTab, + Drawer, + Button, + Dialog, +} from '~/components/designSystem' import { theme, PageHeader } from '~/styles' import { DatePickerField } from '~/components/form' import { ONLY_DEV_DESIGN_SYSTEM_ROUTE, ONLY_DEV_DESIGN_SYSTEM_TAB_ROUTE } from '~/core/router' const FORM_TAB_URL = generatePath(ONLY_DEV_DESIGN_SYSTEM_TAB_ROUTE, { tab: 'form' }) const LINK_TAB_URL = generatePath(ONLY_DEV_DESIGN_SYSTEM_TAB_ROUTE, { tab: 'links' }) +const POPPERS_TAB_URL = generatePath(ONLY_DEV_DESIGN_SYSTEM_TAB_ROUTE, { tab: 'poppers' }) const DesignSystem = () => { const formikProps = useFormik({ @@ -29,11 +37,57 @@ const DesignSystem = () => { + Poppers + + Drawer}> + + + Dialog} + title="Imma dialog" + description="And I'm happy to see you" + actions={({ closeDialog }) => ( + <> + + + + )} + > + + + + + + + ), + }, { title: 'Form', icon: 'switch', link: FORM_TAB_URL, - match: [FORM_TAB_URL, ONLY_DEV_DESIGN_SYSTEM_ROUTE], component: (
e.preventDefault()}>