@campxdev/shared 1.3.2 → 1.4.0

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.3.2",
3
+ "version": "1.4.0",
4
4
  "main": "./exports.ts",
5
5
  "scripts": {
6
6
  "start": "react-scripts start",
@@ -8,6 +8,8 @@ interface ActionButtonProps extends ButtonProps {
8
8
  export default function ActionButton({ loading, ...props }: ActionButtonProps) {
9
9
  return (
10
10
  <Button
11
+ fullWidth
12
+ sx={{ height: '50px', flexShrink: 'unset' }}
11
13
  variant={!props?.variant ? 'contained' : props?.variant}
12
14
  endIcon={loading ? <CircularProgress size={20} /> : null}
13
15
  disabled={loading}
@@ -14,6 +14,7 @@ import { ReactNode, useState } from 'react'
14
14
  import {
15
15
  StyledDropDownButton,
16
16
  StyledIconButton,
17
+ StyledMenu,
17
18
  StyledMenuItem,
18
19
  } from './styles'
19
20
 
@@ -53,6 +54,7 @@ const RenderAnchor = ({ button, icon, handleClick, loading, anchor }) => {
53
54
  return (
54
55
  <StyledDropDownButton
55
56
  onClick={handleClick}
57
+ variant="outlined"
56
58
  disabled={loading}
57
59
  endIcon={
58
60
  loading ? (
@@ -109,20 +111,21 @@ const DropDownButton = ({
109
111
  icon={icon}
110
112
  handleClick={handleClick}
111
113
  />
112
- <Menu
113
- elevation={2}
114
+ <StyledMenu
115
+ elevation={0}
114
116
  id="basic-menu"
115
117
  anchorEl={anchorEl}
116
118
  open={open}
117
119
  onClose={handleClose}
118
120
  PaperProps={{
119
- elevation: 2,
121
+ elevation: 0,
120
122
  }}
121
- MenuListProps={{ sx: { padding: 0 }, ...menuListProps }}
123
+ MenuListProps={{ ...menuListProps }}
122
124
  anchorOrigin={{
123
125
  vertical: 'bottom',
124
126
  horizontal: 'right',
125
127
  }}
128
+ transitionDuration={150}
126
129
  transformOrigin={{
127
130
  vertical: 'top',
128
131
  horizontal: 'right',
@@ -130,7 +133,7 @@ const DropDownButton = ({
130
133
  {...menuProps}
131
134
  >
132
135
  <RenderMenuItems menu={menu} handleClose={handleClose} />
133
- </Menu>
136
+ </StyledMenu>
134
137
  </>
135
138
  )
136
139
  }
@@ -1,4 +1,4 @@
1
- import { Button, IconButton, MenuItem, styled } from '@mui/material'
1
+ import { Button, IconButton, Menu, MenuItem, styled } from '@mui/material'
2
2
 
3
3
  export const StyledIconButton = styled(IconButton, {
4
4
  shouldForwardProp: (prop) => prop !== 'outlined',
@@ -7,10 +7,9 @@ export const StyledIconButton = styled(IconButton, {
7
7
  ...(outlined && {
8
8
  border: `1px solid ${theme.palette.primary.main}`,
9
9
  borderRadius: '5px',
10
- ...(size === 'small' && {
11
- height: '50px',
12
- width: '50px',
13
- }),
10
+ height: '40px',
11
+ width: '40px',
12
+ ...(size === 'small' && {}),
14
13
  }),
15
14
  }),
16
15
  )
@@ -18,6 +17,7 @@ export const StyledIconButton = styled(IconButton, {
18
17
  export const StyledMenuItem = styled(MenuItem)(({}) => ({
19
18
  display: 'flex',
20
19
  alignItems: 'center',
20
+ height: '60px',
21
21
  '& .MuiListItemIcon-root': {
22
22
  minWidth: '24px',
23
23
  },
@@ -25,11 +25,32 @@ export const StyledMenuItem = styled(MenuItem)(({}) => ({
25
25
  height: '18px',
26
26
  width: '18px',
27
27
  },
28
- '& .MuiTypography-root': {
29
- fontWeight: 600,
30
- },
31
28
  }))
32
29
 
33
30
  export const StyledDropDownButton = styled(Button)(({}) => ({
34
- padding: '0 14px',
31
+ padding: '0 15px',
32
+ minWidth: '180px',
33
+ justifyContent: 'space-between',
34
+ }))
35
+
36
+ export const StyledMenu = styled(Menu)(({ theme }) => ({
37
+ '& .MuiPaper-root': {
38
+ borderRadius: '10px',
39
+ border: '1px solid #1212121A',
40
+ marginTop: '10px',
41
+ boxShadow: '0px 4px 16px #0000000F',
42
+ },
43
+ '& .MuiList-root': {
44
+ minWidth: '240px',
45
+ padding: 0,
46
+ '& li': {
47
+ borderBottom: theme.borders.grayLight,
48
+ ':hover': {
49
+ backgroundColor: 'rgba(0, 0, 0, 0.025)',
50
+ },
51
+ },
52
+ '& > :last-child': {
53
+ borderBottom: 'none',
54
+ },
55
+ },
35
56
  }))
@@ -1,19 +1,13 @@
1
- import {
2
- Checkbox,
3
- FormControl,
4
- FormControlLabel,
5
- FormGroup,
6
- Typography,
7
- } from '@mui/material'
1
+ import { Box, FormGroup, FormGroupProps, FormHelperText } from '@mui/material'
2
+ import { ReactNode } from 'react'
8
3
  import { Controller } from 'react-hook-form'
9
- import FormLabel from './FormLabel'
4
+ import { FormLabel, SingleCheckbox } from '../Input'
10
5
 
11
- interface Props {
12
- label?: string
6
+ interface Props extends FormGroupProps {
7
+ label?: ReactNode
13
8
  name: string
14
- size?: 'small' | 'medium'
15
9
  control: any
16
- options: Array<{ label: string; value: string }>
10
+ options: Array<{ label: ReactNode; value: any }>
17
11
  required?: boolean
18
12
  row?: boolean
19
13
  }
@@ -21,12 +15,12 @@ interface Props {
21
15
  export default function FormMultiCheckbox(props: Props) {
22
16
  const {
23
17
  name,
24
- size = 'small',
25
18
  control,
26
19
  label = '',
27
20
  options = [],
28
21
  required = false,
29
22
  row = true,
23
+ ...rest
30
24
  } = props
31
25
 
32
26
  return (
@@ -34,48 +28,34 @@ export default function FormMultiCheckbox(props: Props) {
34
28
  name={name}
35
29
  control={control}
36
30
  render={({ field, fieldState: { error } }) => (
37
- <>
38
- <Typography variant="subtitle1">
39
- {label}
40
- {required && <span style={{ color: 'red' }}>{' *'}</span>}
41
- </Typography>
42
- <FormControl size={size} fullWidth>
43
- <FormGroup row={row} sx={{ flexWrap: 'wrap' }}>
44
- {options?.map((item, index) => (
45
- <FormControlLabel
46
- name={name}
47
- key={index}
48
- control={
49
- <Checkbox
50
- size="small"
51
- checked={field?.value
52
- ?.map((item: any) => item?.value)
53
- ?.includes(item?.value)}
54
- onChange={(e) => {
55
- let value = field.value || []
56
- if (e.target.checked) {
57
- let newValue = [...value, item]
58
- field.onChange(newValue)
59
- } else {
60
- let filteredValue = value.filter(
61
- (opt: any) => opt?.value !== item.value,
62
- )
63
- field.onChange(filteredValue)
64
- }
65
- }}
66
- />
31
+ <Box width="100%">
32
+ <FormLabel label={label} name={name} required={required} />
33
+ <FormGroup row={row} sx={{ flexWrap: 'wrap' }} {...rest}>
34
+ {options?.map((item, index) => (
35
+ <SingleCheckbox
36
+ key={index}
37
+ name={name}
38
+ checked={field?.value
39
+ ?.map((item: any) => item?.value)
40
+ ?.includes(item?.value)}
41
+ label={item.label}
42
+ onChange={(e) => {
43
+ let value = field.value || []
44
+ if (e.target.checked) {
45
+ let newValue = [...value, item]
46
+ field.onChange(newValue)
47
+ } else {
48
+ let filteredValue = value.filter(
49
+ (opt: any) => opt?.value !== item.value,
50
+ )
51
+ field.onChange(filteredValue)
67
52
  }
68
- label={item.label}
69
- />
70
- ))}
71
- </FormGroup>
72
- </FormControl>
73
- {error && (
74
- <Typography variant="caption" color="error" sx={{ pl: '2px' }}>
75
- {error.message}
76
- </Typography>
77
- )}
78
- </>
53
+ }}
54
+ />
55
+ ))}
56
+ </FormGroup>
57
+ {error && <FormHelperText>{error.message}</FormHelperText>}
58
+ </Box>
79
59
  )}
80
60
  />
81
61
  )
@@ -1,15 +1,7 @@
1
- import {
2
- Box,
3
- FormControlLabel,
4
- Radio,
5
- RadioGroup as MuiRadioGroup,
6
- RadioGroupProps,
7
- Stack,
8
- Typography,
9
- } from '@mui/material'
1
+ import { Box, FormHelperText, RadioGroupProps } from '@mui/material'
10
2
  import { ReactNode } from 'react'
11
3
  import { Controller } from 'react-hook-form'
12
- import FormLabel from './FormLabel'
4
+ import { RadioGroup } from '../Input'
13
5
 
14
6
  interface Props extends RadioGroupProps {
15
7
  label?: ReactNode
@@ -23,84 +15,26 @@ interface Props extends RadioGroupProps {
23
15
  }
24
16
 
25
17
  export default function FormRadioGroup(props: Props) {
26
- const {
27
- name,
28
- control,
29
- label,
30
- sx,
31
- options = [],
32
- row = false,
33
- required = false,
34
- Container,
35
- } = props
18
+ const { name, control, label, options = [], row = false, ...rest } = props
36
19
 
37
20
  return (
38
- <>
39
- <Controller
40
- name={name}
41
- control={control}
42
- render={({ field, fieldState: { error } }) => (
43
- <Stack direction={row ? 'row' : 'column'}>
44
- {Container ? (
45
- <Container style={{ borderColor: error ? 'red' : '' }}>
46
- {
47
- <RadioComponent
48
- field={field}
49
- name={name}
50
- label={label}
51
- row={row}
52
- options={options}
53
- required={required}
54
- />
55
- }
56
- </Container>
57
- ) : (
58
- <RadioComponent
59
- field={field}
60
- name={name}
61
- label={label}
62
- row={row}
63
- options={options}
64
- required={required}
65
- />
66
- )}
67
- {error && (
68
- <Typography
69
- variant="subtitle1"
70
- sx={{ pl: '2px' }}
71
- color="rgb(211, 47, 47)"
72
- >
73
- {error.message}
74
- </Typography>
75
- )}
76
- </Stack>
77
- )}
78
- />
79
- </>
80
- )
81
- }
82
-
83
- const RadioComponent = ({ label, required, row, options, name, field }) => {
84
- return (
85
- <>
86
- <Box>
87
- {label && <FormLabel label={label} required={required} />}
88
- <MuiRadioGroup
89
- value={field.value}
90
- onChange={field.onChange}
91
- row={row}
92
- name={name}
93
- >
94
- {options.map((item, index) => (
95
- <FormControlLabel
96
- key={index}
97
- value={item.value}
98
- control={<Radio />}
99
- label={item.label}
100
- />
101
- ))}
102
- </MuiRadioGroup>
103
- </Box>
104
- </>
21
+ <Controller
22
+ name={name}
23
+ control={control}
24
+ render={({ field, fieldState: { error } }) => (
25
+ <Box width="100%">
26
+ <RadioGroup
27
+ row={row}
28
+ name={name}
29
+ label={label}
30
+ options={options}
31
+ value={field.value}
32
+ onChange={field.onChange}
33
+ {...rest}
34
+ />
35
+ {error?.message && <FormHelperText>{error.message}</FormHelperText>}
36
+ </Box>
37
+ )}
38
+ />
105
39
  )
106
40
  }
@@ -1,46 +1,28 @@
1
- import { Checkbox, FormControlLabel, Typography } from '@mui/material'
1
+ import { CheckboxProps } from '@mui/material'
2
+ import { ReactNode } from 'react'
2
3
  import { Controller } from 'react-hook-form'
4
+ import { SingleCheckbox } from '../Input'
3
5
 
4
- interface Props {
5
- label?: string
6
+ interface Props extends CheckboxProps {
7
+ label?: ReactNode
6
8
  name: string
7
- size?: 'small' | 'medium'
8
9
  control: any
9
- sx?: any
10
10
  }
11
11
 
12
12
  export default function FormSingleCheckbox(props: Props) {
13
- const { name, size = 'medium', control, label = '', sx } = props
13
+ const { name, control, label = '', ...rest } = props
14
14
  return (
15
- <>
16
- <Controller
17
- name={name}
18
- control={control}
19
- render={({ field, fieldState: { error } }) => (
20
- <>
21
- <FormControlLabel
22
- sx={{ width: '100%', ...sx }}
23
- control={
24
- <Checkbox
25
- size={size}
26
- checked={field.value}
27
- onChange={field.onChange}
28
- />
29
- }
30
- label={label}
31
- />
32
- {error && (
33
- <Typography
34
- variant="caption"
35
- sx={{ pl: '2px' }}
36
- color="rgb(211, 47, 47)"
37
- >
38
- {error.message}
39
- </Typography>
40
- )}
41
- </>
42
- )}
43
- />
44
- </>
15
+ <Controller
16
+ name={name}
17
+ control={control}
18
+ render={({ field, fieldState: { error } }) => (
19
+ <SingleCheckbox
20
+ checked={field.value}
21
+ onChange={field.onChange}
22
+ label={label}
23
+ {...rest}
24
+ />
25
+ )}
26
+ />
45
27
  )
46
28
  }
@@ -1,37 +1,21 @@
1
- import {
2
- FormControl,
3
- InputLabel,
4
- MenuItem,
5
- Select,
6
- SelectProps,
7
- styled,
8
- Typography,
9
- } from '@mui/material'
1
+ import { SelectProps } from '@mui/material'
10
2
  import { ReactNode } from 'react'
11
3
  import { Controller } from 'react-hook-form'
12
- import FormLabel from './FormLabel'
4
+ import { SingleSelect } from '../Input'
5
+
13
6
  type Props = {
14
- name?: string
15
- control?: any
7
+ name: string
8
+ control: any
16
9
  options: Array<{ label: ReactNode; value: any }>
17
- label?: string
18
- textColor?: string
19
- onChange?: (value: any) => void
20
- required?: boolean
21
10
  firstItemEmpty?: boolean
22
11
  } & SelectProps
23
12
 
24
- const StyledFormControl = styled(FormControl)(({ theme }) => ({}))
25
-
26
13
  export default function FormSingleSelect(props: Props) {
27
14
  const {
28
15
  name = 'select',
29
16
  options = [],
30
17
  control,
31
18
  label,
32
- textColor,
33
- onChange,
34
- required,
35
19
  firstItemEmpty = false,
36
20
  size = 'medium',
37
21
  } = props
@@ -45,49 +29,17 @@ export default function FormSingleSelect(props: Props) {
45
29
  name={name}
46
30
  control={control}
47
31
  render={({ field, fieldState: { error } }) => (
48
- <StyledFormControl size={size} fullWidth>
49
- <InputLabel id={name}>
50
- <FormLabel required={required} label={label} />
51
- </InputLabel>
52
- <Select
53
- multiple={false}
54
- size={size}
55
- error={Boolean(error)}
56
- variant="outlined"
57
- sx={{ color: textColor }}
58
- fullWidth
59
- label={label}
60
- displayEmpty={firstItemEmpty}
61
- MenuProps={{
62
- PaperProps: {
63
- sx: { maxHeight: 300 },
64
- },
65
- }}
66
- value={field.value}
67
- onChange={(e) => {
68
- if (onChange) onChange(e.target.value)
69
- field.onChange(e.target.value)
70
- }}
71
- >
72
- {inputOptions?.map((item, index) => (
73
- <MenuItem key={index} value={item.value}>
74
- {item.label}
75
- </MenuItem>
76
- ))}
77
- </Select>
78
- {error && (
79
- <Typography
80
- fontSize={12}
81
- sx={{
82
- paddingLeft: '2px',
83
- marginTop: '2px',
84
- }}
85
- color="error"
86
- >
87
- {error.message}
88
- </Typography>
89
- )}
90
- </StyledFormControl>
32
+ <SingleSelect
33
+ size={size}
34
+ label={label}
35
+ name={name}
36
+ value={field.value}
37
+ onChange={field.onChange}
38
+ options={inputOptions}
39
+ error={!!error}
40
+ helperText={error?.message}
41
+ {...props}
42
+ />
91
43
  )}
92
44
  />
93
45
  )
@@ -1,11 +1,7 @@
1
- import {
2
- TextField as MuiTextField,
3
- TextFieldProps as MuiTextFieldProps,
4
- Typography,
5
- } from '@mui/material'
1
+ import { TextFieldProps as MuiTextFieldProps } from '@mui/material'
6
2
  import React from 'react'
7
3
  import { Controller } from 'react-hook-form'
8
- import FormLabel from './FormLabel'
4
+ import { TextField } from '../Input'
9
5
 
10
6
  type MyTextFieldProps = MuiTextFieldProps & {
11
7
  control?: any
@@ -24,49 +20,21 @@ export default function FormTextField({
24
20
  control,
25
21
  label,
26
22
  value,
27
- handleChange,
28
- required = false,
29
- hookForm = true,
30
23
  ...rest
31
24
  }: MyTextFieldProps) {
32
- if (!hookForm)
33
- return (
34
- <MuiTextField
35
- label={
36
- <>
37
- {label}
38
- {required && (
39
- <Typography fontSize={14} component={'span'} color="error">
40
- {' *'}
41
- </Typography>
42
- )}
43
- </>
44
- }
45
- value={value}
46
- name={name}
47
- onChange={handleChange}
48
- {...rest}
49
- />
50
- )
51
25
  return (
52
26
  <Controller
53
27
  control={control}
54
28
  name={name}
55
- defaultValue=""
56
29
  render={({ field: { onChange, value }, fieldState: { error } }) => (
57
- <MuiTextField
58
- {...rest}
30
+ <TextField
59
31
  name={name}
60
- label={<FormLabel required={required} label={label} />}
61
- onChange={(e) => {
62
- onChange(e)
63
- if (handleChange) {
64
- handleChange(e)
65
- }
66
- }}
32
+ label={label}
33
+ onChange={onChange}
67
34
  value={value}
68
35
  error={error ? true : false}
69
36
  helperText={error ? error.message : null}
37
+ {...rest}
70
38
  />
71
39
  )}
72
40
  />
@@ -49,7 +49,9 @@ export default function AutoCompleteSearch({
49
49
  renderInput={(params) => (
50
50
  <TextField
51
51
  variant="outlined"
52
- label={<FormLabel label={label} required={props.required} />}
52
+ label={
53
+ <FormLabel label={label} required={props.required} name={name} />
54
+ }
53
55
  {...params}
54
56
  />
55
57
  )}
@@ -78,7 +80,13 @@ export default function AutoCompleteSearch({
78
80
  <TextField
79
81
  error={Boolean(error)}
80
82
  variant="outlined"
81
- label={<FormLabel label={label} required={props.required} />}
83
+ label={
84
+ <FormLabel
85
+ label={label}
86
+ required={props.required}
87
+ name={name}
88
+ />
89
+ }
82
90
  InputProps={{
83
91
  ...params.InputProps,
84
92
  endAdornment: (
@@ -28,7 +28,7 @@ export default function FormDatePicker(props: Props) {
28
28
  <LocalizationProvider dateAdapter={AdapterMoment}>
29
29
  <Box>
30
30
  <DatePicker
31
- label={<FormLabel label={label} required={required} />}
31
+ label={<FormLabel label={label} required={required} name={name} />}
32
32
  mask="__/__/____"
33
33
  inputFormat="DD/MM/yyyy"
34
34
  value={value}
@@ -1,14 +1,21 @@
1
- import { Typography } from '@mui/material'
1
+ import { alpha, styled, Typography, TypographyProps } from '@mui/material'
2
+
3
+ export default function FormLabel({ label, required, name }) {
4
+ if (typeof label !== 'string') return label
2
5
 
3
- export default function FormLabel({ label, required }) {
4
6
  return (
5
- <>
6
- {label}
7
- {required && (
8
- <Typography fontSize={14} component={'span'} color="error">
9
- {' *'}
10
- </Typography>
11
- )}
12
- </>
7
+ <Typography
8
+ htmlFor={name}
9
+ component="label"
10
+ sx={{
11
+ color: alpha('#121212', 0.5),
12
+ marginBottom: '2px',
13
+ '& span': {
14
+ color: (theme) => theme.palette.error.main,
15
+ },
16
+ }}
17
+ >
18
+ {label} {required && <span>{' *'}</span>}
19
+ </Typography>
13
20
  )
14
21
  }