@campxdev/shared 1.4.18 → 1.4.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campxdev/shared",
3
- "version": "1.4.18",
3
+ "version": "1.4.20",
4
4
  "main": "./exports.ts",
5
5
  "scripts": {
6
6
  "start": "react-scripts start",
@@ -0,0 +1,44 @@
1
+ import { KeyboardArrowDown } from '@mui/icons-material'
2
+ import { CircularProgress } from '@mui/material'
3
+ import { StyledDropDownButton, StyledIconButton } from './styles'
4
+
5
+ export default function AnchorElement({
6
+ button,
7
+ icon,
8
+ handleClick,
9
+ loading,
10
+ anchor,
11
+ }) {
12
+ if (anchor) return <>{anchor({ open: handleClick })}</>
13
+
14
+ if (button)
15
+ return (
16
+ <StyledDropDownButton
17
+ onClick={handleClick}
18
+ variant="outlined"
19
+ disabled={loading}
20
+ endIcon={
21
+ loading ? (
22
+ <CircularProgress size="20px" thickness={1.7} />
23
+ ) : (
24
+ <KeyboardArrowDown />
25
+ )
26
+ }
27
+ {...button?.buttonProps}
28
+ >
29
+ {button?.label}
30
+ </StyledDropDownButton>
31
+ )
32
+
33
+ if (!button && !anchor) {
34
+ return (
35
+ <StyledIconButton
36
+ outlined={icon?.outlined ?? false}
37
+ onClick={handleClick}
38
+ {...icon.iconProps}
39
+ >
40
+ {icon.icon}
41
+ </StyledIconButton>
42
+ )
43
+ }
44
+ }
@@ -1,30 +1,21 @@
1
- import { KeyboardArrowDown, MoreVert } from '@mui/icons-material'
1
+ import { MoreVert } from '@mui/icons-material'
2
2
  import {
3
3
  ButtonProps,
4
- CircularProgress,
5
4
  IconButtonProps,
6
- ListItemIcon,
7
- ListItemText,
8
- Menu,
9
- MenuItem,
10
5
  MenuListProps,
11
6
  MenuProps,
12
7
  } from '@mui/material'
13
8
  import { ReactNode, useState } from 'react'
9
+ import { useImmer } from 'use-immer'
10
+ import { CustomDialog } from '../ModalButtons/DialogButton'
11
+ import { CustomDrawer } from '../ModalButtons/DrawerButton'
12
+ import AnchorElement from './AnchorElement'
14
13
  import {
15
- StyledDropDownButton,
16
- StyledIconButton,
17
- StyledMenu,
18
- StyledMenuItem,
19
- } from './styles'
20
-
21
- type MenuItem =
22
- | {
23
- label: string | ReactNode
24
- icon?: ReactNode
25
- onClick: (props?: any) => any
26
- }
27
- | { customButton?: ReactNode }
14
+ IMenuItemProps,
15
+ MenuItemType,
16
+ RenderMenuItem,
17
+ } from './DropdownMenuItem'
18
+ import { StyledMenu } from './styles'
28
19
 
29
20
  interface DropDownButtonProps {
30
21
  icon?: {
@@ -38,48 +29,20 @@ interface DropDownButtonProps {
38
29
  }
39
30
  anchor?: (props: { open: () => void }) => ReactNode
40
31
  loading?: boolean
41
- menu: MenuItem[]
32
+ menu: IMenuItemProps[]
42
33
  menuProps?: Omit<MenuProps, 'open'>
43
34
  menuListProps?: MenuListProps
44
35
  }
36
+
45
37
  const defaultIcon = {
46
38
  icon: <MoreVert color="primary" />,
47
39
  outlined: true,
48
40
  }
49
41
 
50
- const RenderAnchor = ({ button, icon, handleClick, loading, anchor }) => {
51
- if (anchor) return <>{anchor({ open: handleClick })}</>
52
-
53
- if (button)
54
- return (
55
- <StyledDropDownButton
56
- onClick={handleClick}
57
- variant="outlined"
58
- disabled={loading}
59
- endIcon={
60
- loading ? (
61
- <CircularProgress size="20px" thickness={1.7} />
62
- ) : (
63
- <KeyboardArrowDown />
64
- )
65
- }
66
- {...button?.buttonProps}
67
- >
68
- {button?.label}
69
- </StyledDropDownButton>
70
- )
71
-
72
- if (!button && !anchor) {
73
- return (
74
- <StyledIconButton
75
- outlined={icon?.outlined ?? false}
76
- onClick={handleClick}
77
- {...icon.iconProps}
78
- >
79
- {icon.icon}
80
- </StyledIconButton>
81
- )
82
- }
42
+ interface IModalState {
43
+ open: boolean
44
+ content: any
45
+ type: MenuItemType
83
46
  }
84
47
 
85
48
  const DropDownButton = ({
@@ -92,19 +55,41 @@ const DropDownButton = ({
92
55
  anchor,
93
56
  }: DropDownButtonProps) => {
94
57
  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)
95
- const open = Boolean(anchorEl)
58
+ const [open, setOpen] = useState(false)
59
+
60
+ const [modalState, setModalState] = useImmer<IModalState>({
61
+ open: false,
62
+ content: null,
63
+ type: 'drawer',
64
+ })
96
65
 
97
66
  const handleClick = (event: any) => {
98
67
  setAnchorEl(event.currentTarget)
68
+ setOpen(true)
99
69
  }
100
70
 
101
71
  const handleClose = () => {
102
72
  setAnchorEl(null)
73
+ setOpen(false)
74
+ }
75
+
76
+ const onModalClose = () => {
77
+ setModalState((s) => {
78
+ s.open = false
79
+ s.content = null
80
+ })
81
+ }
82
+ const onModalOpen = (item) => {
83
+ setModalState((s) => {
84
+ s.content = item.content
85
+ s.open = true
86
+ s.type = item.actionType
87
+ })
103
88
  }
104
89
 
105
90
  return (
106
91
  <>
107
- <RenderAnchor
92
+ <AnchorElement
108
93
  anchor={anchor}
109
94
  loading={loading}
110
95
  button={button}
@@ -115,6 +100,7 @@ const DropDownButton = ({
115
100
  elevation={0}
116
101
  id="basic-menu"
117
102
  anchorEl={anchorEl}
103
+ keepMounted
118
104
  open={open}
119
105
  onClose={handleClose}
120
106
  PaperProps={{
@@ -132,46 +118,58 @@ const DropDownButton = ({
132
118
  }}
133
119
  {...menuProps}
134
120
  >
135
- <RenderMenuItems menu={menu} handleClose={handleClose} />
121
+ {menu.map((item, index) => (
122
+ <RenderMenuItem
123
+ onModalOpen={() => onModalOpen(item)}
124
+ modalState={modalState}
125
+ key={index}
126
+ handleClose={handleClose}
127
+ label={item.label}
128
+ actionType={item?.actionType}
129
+ onClick={item?.onClick}
130
+ />
131
+ ))}
136
132
  </StyledMenu>
133
+ {modalState?.open && (
134
+ <RenderContent
135
+ onClose={onModalClose}
136
+ modalState={modalState}
137
+ contentType={modalState.type}
138
+ />
139
+ )}
137
140
  </>
138
141
  )
139
142
  }
140
143
 
141
- DropDownButton.MenuItem = ({ icon, label, ...props }) => {
142
- return (
143
- <StyledMenuItem
144
- sx={{ minWidth: '120px', width: '100%', ...props?.sx }}
145
- {...props}
146
- >
147
- {icon && <ListItemIcon>{icon}</ListItemIcon>}
148
- <ListItemText>{label}</ListItemText>
149
- </StyledMenuItem>
150
- )
151
- }
152
-
153
144
  export default DropDownButton
154
145
 
155
- const RenderMenuItems = ({ menu, handleClose }) => {
156
- return (
157
- <>
158
- {menu.map((item, index) => (
159
- <>
160
- {item?.customButton ? (
161
- item.customButton
162
- ) : (
163
- <DropDownButton.MenuItem
164
- icon={item?.icon}
165
- label={item?.label}
166
- key={index}
167
- onClick={() => {
168
- handleClose()
169
- item.onClick()
170
- }}
171
- />
172
- )}
173
- </>
174
- ))}
175
- </>
176
- )
146
+ const RenderContent = ({
147
+ contentType,
148
+ modalState,
149
+ onClose,
150
+ }: {
151
+ contentType: MenuItemType
152
+ modalState: any
153
+ onClose: () => void
154
+ }) => {
155
+ if (contentType === 'dialog')
156
+ return (
157
+ <CustomDialog
158
+ onClose={onClose}
159
+ open={modalState.open}
160
+ content={modalState.content}
161
+ title="Dialog Button"
162
+ />
163
+ )
164
+
165
+ if (contentType === 'drawer')
166
+ return (
167
+ <CustomDrawer
168
+ onClose={onClose}
169
+ open={modalState.open}
170
+ content={modalState.content}
171
+ title="Dialog Button"
172
+ />
173
+ )
174
+ return <></>
177
175
  }
@@ -0,0 +1,100 @@
1
+ import { ListItemIcon, ListItemText, styled } from '@mui/material'
2
+ import { ReactNode } from 'react'
3
+ import { Link } from 'react-router-dom'
4
+ import { DrawerButtonProps } from '../ModalButtons/DrawerButton'
5
+ import { StyledMenuItem } from './styles'
6
+
7
+ const StyledLink = styled(Link)(({ theme }) => ({
8
+ display: 'block',
9
+ textTransform: 'none',
10
+ textDecoration: 'none',
11
+ }))
12
+
13
+ export type MenuItemType = 'normal' | 'dialog' | 'drawer' | 'link'
14
+
15
+ export type MenuItemButtonProps = {
16
+ icon?: ReactNode
17
+ label: ReactNode
18
+ onClick: () => void
19
+ link?: {
20
+ to: string
21
+ target?: '_self' | '_blank'
22
+ }
23
+ }
24
+
25
+ const MenuItemButton = ({
26
+ icon,
27
+ label,
28
+ onClick,
29
+ ...props
30
+ }: MenuItemButtonProps) => {
31
+ return (
32
+ <StyledMenuItem
33
+ sx={{ minWidth: '180px', width: '100%' }}
34
+ onClick={onClick}
35
+ {...props}
36
+ >
37
+ {icon && <ListItemIcon>{icon}</ListItemIcon>}
38
+ <ListItemText>{label}</ListItemText>
39
+ </StyledMenuItem>
40
+ )
41
+ }
42
+
43
+ export type IMenuItemProps = Omit<MenuItemButtonProps, 'onClick'> & {
44
+ content?: DrawerButtonProps['content']
45
+ contentTitle?: ReactNode
46
+ actionType?: MenuItemType
47
+ onClick?: () => void
48
+ }
49
+
50
+ export interface IRenderMenuItemProps extends IMenuItemProps {
51
+ handleClose: () => void
52
+ modalState: any
53
+ onModalOpen: () => void
54
+ }
55
+
56
+ export const RenderMenuItem = ({
57
+ onClick,
58
+ actionType = 'normal',
59
+ handleClose,
60
+ modalState,
61
+ onModalOpen,
62
+ link = { target: '_blank', to: '' },
63
+ ...props
64
+ }: IRenderMenuItemProps) => {
65
+ const renderMenuItem: Record<MenuItemType, ReactNode> = {
66
+ normal: (
67
+ <MenuItemButton
68
+ {...props}
69
+ onClick={() => {
70
+ onClick()
71
+ handleClose()
72
+ }}
73
+ />
74
+ ),
75
+ dialog: (
76
+ <MenuItemButton
77
+ {...props}
78
+ onClick={() => {
79
+ onModalOpen()
80
+ handleClose()
81
+ }}
82
+ />
83
+ ),
84
+ drawer: (
85
+ <MenuItemButton
86
+ {...props}
87
+ onClick={() => {
88
+ onModalOpen()
89
+ handleClose()
90
+ }}
91
+ />
92
+ ),
93
+ link: (
94
+ <StyledLink to={link?.to} target={link.target}>
95
+ <MenuItemButton onClick={() => {}} {...props} />
96
+ </StyledLink>
97
+ ),
98
+ }
99
+ return <>{renderMenuItem[actionType]}</>
100
+ }
@@ -51,6 +51,9 @@ export const StyledMenu = styled(Menu)(({ theme }) => ({
51
51
  },
52
52
  '& > :last-child': {
53
53
  borderBottom: 'none',
54
+ '& li': {
55
+ borderBottom: 'none',
56
+ },
54
57
  },
55
58
  },
56
59
  }))
@@ -5,6 +5,7 @@ const StyledButtonWrapper = styled(Box)<{ size: 'regular' | 'large' }>(
5
5
  ({ theme, size }) => ({
6
6
  width: size === 'regular' ? '40px' : '50px',
7
7
  height: size === 'regular' ? '40px' : '50px',
8
+ flexShrink: 0,
8
9
  border: theme.borders.grayLight,
9
10
  display: 'flex',
10
11
  alignItems: 'center',
@@ -1,7 +1,8 @@
1
- import { Box, styled, SvgIcon } from '@mui/material'
2
- import { useEffect, useState } from 'react'
1
+ import { Box, BoxProps, FormHelperText, styled, SvgIcon } from '@mui/material'
2
+ import { ReactNode, useEffect, useState } from 'react'
3
3
  import { DateRangeIcon } from '../IconButtons'
4
4
  import DateTimePicker from './DateTimePicker'
5
+ import FormLabel from './FormLabel'
5
6
 
6
7
  const StyledDateRangePicker = styled(Box)<{ size: 'small' | 'medium' }>(
7
8
  ({ theme, size }) => ({
@@ -29,56 +30,76 @@ const StyledDateRangePicker = styled(Box)<{ size: 'small' | 'medium' }>(
29
30
  }),
30
31
  )
31
32
 
32
- interface Props {
33
- value: [Date, Date]
34
- onChange: (value: [Date, Date]) => void
33
+ interface IDateRangePickerProps {
34
+ value: {
35
+ start: Date
36
+ end: Date
37
+ }
38
+ onChange: (value: { start: Date; end: Date }) => void
35
39
  enableTime?: boolean
36
40
  size?: 'small' | 'medium'
41
+ containerProps?: BoxProps
42
+ label?: ReactNode
43
+ required?: boolean
44
+ name?: string
45
+ error?: boolean
46
+ helperText?: string
37
47
  }
38
48
  export default function DateRangePicker({
39
49
  value,
40
50
  onChange,
41
51
  enableTime = false,
42
52
  size = 'medium',
43
- }: Props) {
44
- const [state, setState] = useState([null, null])
53
+ containerProps,
54
+ required,
55
+ error,
56
+ helperText,
57
+ label,
58
+ name,
59
+ }: IDateRangePickerProps) {
60
+ const [state, setState] = useState({
61
+ start: null,
62
+ end: null,
63
+ })
45
64
 
46
65
  useEffect(() => {
47
66
  setState(value)
48
67
  }, [value])
49
68
 
50
69
  return (
51
- <StyledDateRangePicker size={size}>
52
- <DateTimePicker
53
- value={state[0]}
54
- placeholder="From Date"
55
- onChange={(value) => {
56
- setState((prev) => [value, prev[1]])
57
- onChange([value, state[1]])
58
- }}
59
- enableTime={enableTime}
60
- inputProps={{
61
- InputProps: null,
62
- size: size,
63
- }}
70
+ <Box width={'100%'} {...containerProps}>
71
+ <FormLabel
72
+ required={required}
73
+ name={name ?? 'date-range-picker'}
74
+ label={label}
64
75
  />
65
- <SvgIcon>
66
- <DateRangeIcon />
67
- </SvgIcon>
68
- <DateTimePicker
69
- value={state[1]}
70
- minDate={state[0]}
71
- placeholder="To Date"
72
- enableTime={enableTime}
73
- onChange={(value) => {
74
- setState((prev) => [prev[0], value])
75
- onChange([state[0], value])
76
- }}
77
- inputProps={{
78
- InputProps: null,
79
- size: size,
80
- }}
81
- />
82
- </StyledDateRangePicker>
76
+ <StyledDateRangePicker size={size}>
77
+ <DateTimePicker
78
+ placeholder="From Date"
79
+ value={state.start}
80
+ onChange={(value) => {
81
+ setState((prev) => ({ ...prev, start: value }))
82
+ onChange({ ...state, start: value })
83
+ }}
84
+ enableTime={enableTime}
85
+ inputProps={{ InputProps: null, size: size }}
86
+ />
87
+ <SvgIcon>
88
+ <DateRangeIcon />
89
+ </SvgIcon>
90
+ <DateTimePicker
91
+ minDate={state[0]}
92
+ placeholder="To Date"
93
+ enableTime={enableTime}
94
+ value={state.end}
95
+ onChange={(value) => {
96
+ setState((prev) => ({ ...prev, end: value }))
97
+ onChange({ ...state, end: value })
98
+ }}
99
+ inputProps={{ InputProps: null, size: size }}
100
+ />
101
+ </StyledDateRangePicker>
102
+ <>{error && <FormHelperText>{helperText}</FormHelperText>}</>
103
+ </Box>
83
104
  )
84
105
  }
@@ -33,39 +33,39 @@ export default function UserBox({
33
33
  )}
34
34
  menu={[
35
35
  ...actions,
36
- {
37
- customButton: (
38
- <DialogButton
39
- dialogProps={{
40
- maxWidth: 'xl',
41
- }}
42
- title="My Tickets"
43
- anchor={({ open }) => (
44
- <DropDownButton.MenuItem
45
- onClick={open}
46
- icon={<ConfirmationNumberOutlinedIcon />}
47
- label="My Tickets"
48
- />
49
- )}
50
- content={({ close }) => <MyTickets close={close} />}
51
- />
52
- ),
53
- },
54
- {
55
- customButton: (
56
- <DialogButton
57
- title="Change Password"
58
- anchor={({ open }) => (
59
- <DropDownButton.MenuItem
60
- onClick={open}
61
- icon={<HttpsOutlined />}
62
- label="Change Password"
63
- />
64
- )}
65
- content={({ close }) => <ChangePassword close={close} />}
66
- />
67
- ),
68
- },
36
+ // {
37
+ // customButton: (
38
+ // <DialogButton
39
+ // dialogProps={{
40
+ // maxWidth: 'xl',
41
+ // }}
42
+ // title="My Tickets"
43
+ // anchor={({ open }) => (
44
+ // <DropDownButton.MenuItem
45
+ // onClick={open}
46
+ // icon={<ConfirmationNumberOutlinedIcon />}
47
+ // label="My Tickets"
48
+ // />
49
+ // )}
50
+ // content={({ close }) => <MyTickets close={close} />}
51
+ // />
52
+ // ),
53
+ // },
54
+ // {
55
+ // customButton: (
56
+ // <DialogButton
57
+ // title="Change Password"
58
+ // anchor={({ open }) => (
59
+ // <DropDownButton.MenuItem
60
+ // onClick={open}
61
+ // icon={<HttpsOutlined />}
62
+ // label="Change Password"
63
+ // />
64
+ // )}
65
+ // content={({ close }) => <ChangePassword close={close} />}
66
+ // />
67
+ // ),
68
+ // },
69
69
  {
70
70
  label: 'Logout',
71
71
  icon: <ExitToAppOutlined />,
@@ -10,6 +10,7 @@ import {
10
10
  } from '@mui/material'
11
11
  import { TransitionProps } from '@mui/material/transitions'
12
12
  import { forwardRef, ReactNode, useState } from 'react'
13
+ import { SCROLLBAR_DARK } from '../../theme/muiTheme'
13
14
 
14
15
  const StyledDialogHeader = styled(Box)(() => ({
15
16
  height: '64px',
@@ -24,6 +25,9 @@ const StyledDialogHeader = styled(Box)(() => ({
24
25
  const StyledDialogContent = styled(Box)(() => ({
25
26
  width: '100%',
26
27
  padding: '1rem',
28
+ maxHeight: 'calc(100vh - 64px)',
29
+ overflow: 'auto',
30
+ ...SCROLLBAR_DARK,
27
31
  }))
28
32
 
29
33
  export const Transition = forwardRef(function Transition(
@@ -66,28 +70,52 @@ export default function DialogButton({
66
70
  {anchor({
67
71
  open: onOpen,
68
72
  })}
69
- <Dialog
70
- PaperProps={{ elevation: 2, sx: { borderRadius: '10px' } }}
71
- fullWidth
72
- onClose={onClose}
73
+ <CustomDialog
73
74
  open={open}
74
- transitionDuration={140}
75
- TransitionComponent={Transition}
76
- sx={{
77
- '& .MuiBackdrop-root': {
78
- backgroundColor: 'rgba(0, 0, 0, 0.4)',
79
- },
80
- }}
81
- {...dialogProps}
82
- >
83
- <StyledDialogHeader>
84
- <DialogTitle>{title}</DialogTitle>
85
- <IconButton onClick={onClose} sx={{ color: 'black' }}>
86
- <Close />
87
- </IconButton>
88
- </StyledDialogHeader>
89
- <StyledDialogContent>{content({ close: onClose })}</StyledDialogContent>
90
- </Dialog>
75
+ content={content}
76
+ dialogProps={dialogProps}
77
+ onClose={onClose}
78
+ title={title}
79
+ />
91
80
  </>
92
81
  )
93
82
  }
83
+
84
+ interface CustomDialogProps {
85
+ content: (props: { close: () => void }) => ReactNode
86
+ title: string | ReactNode
87
+ dialogProps?: Omit<DialogProps, 'open'>
88
+ onClose: () => void
89
+ open: boolean
90
+ }
91
+
92
+ export const CustomDialog = ({
93
+ onClose,
94
+ dialogProps,
95
+ title,
96
+ content,
97
+ open,
98
+ }: CustomDialogProps) => {
99
+ return (
100
+ <Dialog
101
+ PaperProps={{ elevation: 2, sx: { borderRadius: '10px' } }}
102
+ fullWidth
103
+ onClose={onClose}
104
+ open={open}
105
+ transitionDuration={140}
106
+ TransitionComponent={Transition}
107
+ sx={{
108
+ '& .MuiBackdrop-root': { backgroundColor: 'rgba(0, 0, 0, 0.4)' },
109
+ }}
110
+ {...dialogProps}
111
+ >
112
+ <StyledDialogHeader>
113
+ <DialogTitle>{title}</DialogTitle>
114
+ <IconButton onClick={onClose} sx={{ color: 'black' }}>
115
+ <Close />
116
+ </IconButton>
117
+ </StyledDialogHeader>
118
+ <StyledDialogContent>{content({ close: onClose })}</StyledDialogContent>
119
+ </Dialog>
120
+ )
121
+ }
@@ -4,10 +4,12 @@ import {
4
4
  ButtonProps,
5
5
  DialogTitle,
6
6
  Drawer,
7
+ DrawerProps,
7
8
  IconButton,
8
9
  styled,
9
10
  } from '@mui/material'
10
11
  import { ReactNode, useState } from 'react'
12
+ import { SCROLLBAR_DARK } from '../../theme/muiTheme'
11
13
 
12
14
  const StyledDrawerHeader = styled(Box)(({ theme }) => ({
13
15
  height: '64px',
@@ -24,9 +26,10 @@ const StyledDrawerContent = styled(Box)(({ theme }) => ({
24
26
  height: 'calc(100vh - 64px)',
25
27
  overflowY: 'auto',
26
28
  paddingBottom: '4rem',
29
+ ...SCROLLBAR_DARK,
27
30
  }))
28
31
 
29
- interface DrawerButtonProps {
32
+ export interface DrawerButtonProps {
30
33
  anchor: (props: { open: () => void }) => ReactNode
31
34
  content: (props: { close: () => void }) => ReactNode
32
35
  title: string | ReactNode
@@ -51,34 +54,60 @@ export default function DrawerButton({
51
54
  return (
52
55
  <>
53
56
  {anchor({ open: onOpen })}
54
- <Drawer
55
- anchor="right"
56
- elevation={2}
57
+ <CustomDrawer
58
+ content={content}
57
59
  onClose={onClose}
58
60
  open={open}
59
- PaperProps={{
60
- elevation: 2,
61
- }}
62
- sx={{
63
- zIndex: 500,
64
- '& .MuiDrawer-paper': {
65
- boxSizing: 'border-box',
66
- width: 600,
67
- },
68
- '& .MuiBackdrop-root': {
69
- backgroundColor: 'rgba(0, 0, 0, 0.4)',
70
- },
71
- }}
72
- transitionDuration={140}
73
- >
74
- <StyledDrawerHeader>
75
- <DialogTitle>{title}</DialogTitle>
76
- <IconButton onClick={onClose} sx={{ color: 'black' }}>
77
- <Close />
78
- </IconButton>
79
- </StyledDrawerHeader>
80
- <StyledDrawerContent>{content({ close: onClose })}</StyledDrawerContent>
81
- </Drawer>
61
+ title={title}
62
+ />
82
63
  </>
83
64
  )
84
65
  }
66
+
67
+ interface CustomDrawerProps {
68
+ content: (props: { close: () => void }) => ReactNode
69
+ title: string | ReactNode
70
+ drawerProps?: Omit<DrawerProps, 'open'>
71
+ onClose: () => void
72
+ open: boolean
73
+ }
74
+
75
+ export const CustomDrawer = ({
76
+ onClose,
77
+ drawerProps,
78
+ title,
79
+ content,
80
+ open,
81
+ }: CustomDrawerProps) => {
82
+ return (
83
+ <Drawer
84
+ anchor="right"
85
+ elevation={2}
86
+ onClose={onClose}
87
+ open={open}
88
+ PaperProps={{
89
+ elevation: 2,
90
+ }}
91
+ sx={{
92
+ zIndex: 500,
93
+ '& .MuiDrawer-paper': {
94
+ boxSizing: 'border-box',
95
+ width: 600,
96
+ },
97
+ '& .MuiBackdrop-root': {
98
+ backgroundColor: 'rgba(0, 0, 0, 0.4)',
99
+ },
100
+ }}
101
+ transitionDuration={140}
102
+ {...drawerProps}
103
+ >
104
+ <StyledDrawerHeader>
105
+ <DialogTitle>{title}</DialogTitle>
106
+ <IconButton onClick={onClose} sx={{ color: 'black' }}>
107
+ <Close />
108
+ </IconButton>
109
+ </StyledDrawerHeader>
110
+ <StyledDrawerContent>{content({ close: onClose })}</StyledDrawerContent>
111
+ </Drawer>
112
+ )
113
+ }
@@ -10,6 +10,38 @@ const borderRadius = {
10
10
  const PRIMARY_FONT = 'Avenir'
11
11
  const SECONDARY_FONT = 'Poppins'
12
12
 
13
+ export const SCROLLBAR_DARK = {
14
+ '&::-webkit-scrollbar': {
15
+ width: '0.5em',
16
+ height: '0.5em',
17
+ },
18
+
19
+ '&::-webkit-scrollbar-thumb': {
20
+ backgroundColor: 'rgba(0, 0, 0, 0.15)',
21
+ borderRadius: '3px',
22
+
23
+ '&:hover': {
24
+ background: 'rgba(0, 0, 0, 0.2)',
25
+ },
26
+ },
27
+ }
28
+
29
+ export const SCROLLBAR_LIGHT = {
30
+ '&::-webkit-scrollbar': {
31
+ width: '0.5em',
32
+ height: '0.5em',
33
+ },
34
+
35
+ '&::-webkit-scrollbar-thumb': {
36
+ backgroundColor: 'rgba(255, 255, 255, 0.15)',
37
+ borderRadius: '3px',
38
+
39
+ '&:hover': {
40
+ background: 'rgba(255, 255, 255, 0.2)',
41
+ },
42
+ },
43
+ }
44
+
13
45
  const themeColors = {
14
46
  primary: '#1E19F5',
15
47
  secondary: '#121212',