@groupeactual/ui-kit 0.4.37 → 0.4.38

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.
@@ -7,6 +7,11 @@ import React, {
7
7
  import AccordionMui, { AccordionProps } from '@mui/material/Accordion';
8
8
  import AccordionSummary from '@mui/material/AccordionSummary';
9
9
  import AccordionDetails from '@mui/material/AccordionDetails';
10
+ import {
11
+ faChevronDown
12
+ } from '@fortawesome/pro-regular-svg-icons';
13
+
14
+ import IconProvider from '../Icon/Icon';
10
15
 
11
16
  interface Props extends AccordionProps {
12
17
  icon: ReactNode;
@@ -35,18 +40,20 @@ const Accordion = ({
35
40
 
36
41
  return (
37
42
  <AccordionMui
38
- sx={{ border: `1px solid`, borderColor: 'greyLightDefaultBorder' }}
43
+ className="DsAccordion"
39
44
  expanded={internalExpanded}
40
45
  onClick={(e) => {
41
46
  if (!props.disabled) {
42
47
  setInternalExpanded(!internalExpanded);
43
- onClick && onClick(e);
48
+ if (onClick) {
49
+ onClick(e);
50
+ }
44
51
  }
45
52
  }}
46
53
  {...props}
47
54
  >
48
55
  <AccordionSummary
49
- expandIcon={icon}
56
+ expandIcon={<IconProvider icon={faChevronDown} size="md" />}
50
57
  sx={{
51
58
  fontWeight: 500,
52
59
  fontSize: 18,
@@ -93,11 +93,11 @@ const Chip = ({
93
93
  backgroundColor: backgroundColor,
94
94
  '&.MuiChip-colorSecondary:hover': suffixIcon &&
95
95
  suffixAction && {
96
- backgroundColor: '#004f88 !important'
96
+ backgroundColor: 'blueHoverClickable !important'
97
97
  },
98
98
  '&.MuiChip-deleteIconColorPrimary:hover': suffixIcon &&
99
99
  suffixAction && {
100
- backgroundColor: '#004f88 !important'
100
+ backgroundColor: 'blueHoverClickable !important'
101
101
  }
102
102
  }}
103
103
  avatar={
@@ -119,6 +119,9 @@ const Chip = ({
119
119
  setIsTooltipOpen(true);
120
120
  }
121
121
  }}
122
+ sx={{
123
+ cursor: suffixAction ? 'pointer !important' : 'default'
124
+ }}
122
125
  size="sm"
123
126
  />
124
127
  ) : (
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
2
 
3
3
  import CheckboxMUI, { CheckboxProps } from '@mui/material/Checkbox';
4
4
  import FormControl from '@mui/material/FormControl';
@@ -15,6 +15,7 @@ interface Props {
15
15
  value: any,
16
16
  shouldValidate?: boolean | undefined
17
17
  ) => void;
18
+ description?: string;
18
19
  error?: string;
19
20
  }
20
21
 
@@ -22,12 +23,27 @@ const Checkbox = ({
22
23
  name,
23
24
  value,
24
25
  error,
26
+ description,
25
27
  label,
26
28
  onChange,
27
29
  ...props
28
30
  }: CheckboxProps & Props): JSX.Element => {
29
31
  const [internalValue, setInternalValue] = useState(value);
30
32
 
33
+ const getComponentClassName = useMemo(() => {
34
+ const classNames: string[] = ['DsCheckbox'];
35
+ if (props.disabled) classNames.push('Mui-disabled');
36
+
37
+ return classNames.join(' ');
38
+ }, [props.disabled]);
39
+
40
+ const getLabelClassName = useMemo(() => {
41
+ const classNames: string[] = ['DsCheckbox-label'];
42
+ if (props.disabled) classNames.push('Mui-disabled');
43
+
44
+ return classNames.join(' ');
45
+ }, [props.disabled]);
46
+
31
47
  useEffect(() => {
32
48
  if (value !== internalValue) {
33
49
  setInternalValue(value);
@@ -35,7 +51,7 @@ const Checkbox = ({
35
51
  }, [value]);
36
52
 
37
53
  return (
38
- <FormControl fullWidth>
54
+ <FormControl fullWidth className={getComponentClassName}>
39
55
  <FormControlLabel
40
56
  control={
41
57
  <Box>
@@ -46,7 +62,7 @@ const Checkbox = ({
46
62
  color="primary"
47
63
  onChange={(e) => {
48
64
  setInternalValue(e.target.checked);
49
- onChange && onChange(name, e.target.checked, true);
65
+ if (onChange) onChange(name, e.target.checked, true);
50
66
  }}
51
67
  {...props}
52
68
  />
@@ -55,28 +71,20 @@ const Checkbox = ({
55
71
  label={
56
72
  <Typography
57
73
  component="span"
58
- sx={{
59
- fontSize: '14px',
60
- marginLeft: '-3px',
61
- marginTop: '2px',
62
- fontWeight: 400,
63
- color: error ? '#B80025' : '#000'
64
- }}
74
+ className={getLabelClassName}
65
75
  >
66
76
  {label}
67
77
  </Typography>
68
78
  }
69
79
  />
70
- {error && (
80
+ {(error || description) && (
71
81
  <Typography
82
+ className="DsCheckbox-info"
72
83
  sx={{
73
- marginTop: -0.5,
74
- color: '#B80025',
75
- fontWeight: 400,
76
- fontSize: '10px'
84
+ color: error ? '#B80025' : '#545352'
77
85
  }}
78
86
  >
79
- {error}
87
+ {error || description}
80
88
  </Typography>
81
89
  )}
82
90
  </FormControl>
@@ -18,16 +18,17 @@ import Chip from '../../Chip/Chip';
18
18
  interface Props<T>
19
19
  extends Omit<
20
20
  SelectProps<T[]>,
21
- 'value' | 'onChange' | 'defaultValue' | 'color'
21
+ 'value' | 'onChange' | 'defaultValue' | 'color' | 'error'
22
22
  > {
23
23
  label: string;
24
24
  options: T[];
25
25
  helperText?: string;
26
26
  color?: 'success';
27
- getOptionLabel: (option: T) => string;
27
+ getRenderValue: (option: T) => string;
28
28
  onChange: (value: T[]) => void;
29
29
  defaultValue?: T[];
30
30
  width?: number;
31
+ error?: string;
31
32
  }
32
33
 
33
34
  const MultiSelect = <T extends {}>({
@@ -38,7 +39,7 @@ const MultiSelect = <T extends {}>({
38
39
  placeholder,
39
40
  width = 200,
40
41
  defaultValue = [],
41
- getOptionLabel,
42
+ getRenderValue,
42
43
  helperText,
43
44
  onChange,
44
45
  onBlur,
@@ -48,7 +49,7 @@ const MultiSelect = <T extends {}>({
48
49
 
49
50
  const handleChange = (event: SelectChangeEvent<typeof options>) => {
50
51
  const newValue = event.target.value as T[];
51
- onChange(newValue);
52
+ if (onChange) onChange(newValue);
52
53
  setValues(newValue);
53
54
  };
54
55
 
@@ -58,7 +59,7 @@ const MultiSelect = <T extends {}>({
58
59
  };
59
60
 
60
61
  const handleClearValues = () => {
61
- onChange([]);
62
+ if (onChange) onChange([]);
62
63
  setValues([]);
63
64
  };
64
65
 
@@ -71,7 +72,7 @@ const MultiSelect = <T extends {}>({
71
72
  if (props.disabled) classNames.push('Mui-disabled');
72
73
  if (values?.length > 0) classNames.push('Mui-filled');
73
74
 
74
- return classNames;
75
+ return classNames.join(' ');
75
76
  }, [values, props.disabled]);
76
77
 
77
78
  const getInputLabelClassName = useMemo(() => {
@@ -79,7 +80,7 @@ const MultiSelect = <T extends {}>({
79
80
  if (error) classNames.push('Mui-error');
80
81
  if (props.disabled) classNames.push('Mui-disabled');
81
82
 
82
- return classNames;
83
+ return classNames.join(' ');
83
84
  }, [error, props.disabled]);
84
85
 
85
86
  return (
@@ -88,16 +89,14 @@ const MultiSelect = <T extends {}>({
88
89
  id={label === placeholder ? 'select-mui' : 'select-ds'}
89
90
  fullWidth
90
91
  color={color}
91
- className={getFormControlClassName.join(' ')}
92
+ className={getFormControlClassName}
92
93
  sx={{
93
94
  '.MuiOutlinedInput-input': {
94
95
  marginTop: values?.length > 0 ? '0px' : '2px'
95
96
  }
96
97
  }}
97
98
  >
98
- <InputLabel className={getInputLabelClassName.join(' ')}>
99
- {label}
100
- </InputLabel>
99
+ <InputLabel className={getInputLabelClassName}>{label}</InputLabel>
101
100
  <MuiSelect
102
101
  sx={{
103
102
  color: color + '! important',
@@ -129,7 +128,7 @@ const MultiSelect = <T extends {}>({
129
128
  disabled={props.disabled}
130
129
  variant="filled"
131
130
  color="default"
132
- label={getOptionLabel(selectedOption)}
131
+ label={getRenderValue(selectedOption)}
133
132
  suffixIcon={faTimesCircle}
134
133
  suffixAction={() =>
135
134
  !props.disabled && handleDeleteChip(selectedOption)
@@ -180,12 +179,15 @@ const MultiSelect = <T extends {}>({
180
179
  key={i}
181
180
  value={option as any}
182
181
  sx={{
182
+ fontSize: 14,
183
183
  fontWeight: values.indexOf(option) === -1 ? 400 : 500,
184
184
  backgroundColor:
185
- values.indexOf(option) === -1 ? '#ffffff' : '#D3E4F0'
185
+ values.indexOf(option) === -1
186
+ ? 'white'
187
+ : 'blueHoverEquivalence'
186
188
  }}
187
189
  >
188
- {getOptionLabel(option)}
190
+ {getRenderValue(option)}
189
191
  </MenuItem>
190
192
  ))}
191
193
  </MuiSelect>
@@ -1,4 +1,10 @@
1
- import React, { BaseSyntheticEvent, useMemo, useState } from 'react';
1
+ import React, {
2
+ BaseSyntheticEvent,
3
+ useContext,
4
+ useMemo,
5
+ useState
6
+ } from 'react';
7
+ import { useTheme } from '@mui/system';
2
8
  import { FormHelperText, InputLabel, MenuItem } from '@mui/material';
3
9
  import Box from '@mui/material/Box';
4
10
  import FormControl from '@mui/material/FormControl';
@@ -12,16 +18,17 @@ import Icon from '../../Icon';
12
18
  interface Props<T>
13
19
  extends Omit<
14
20
  SelectProps<T>,
15
- 'value' | 'onChange' | 'defaultValue' | 'color'
21
+ 'value' | 'onChange' | 'defaultValue' | 'color' | 'error'
16
22
  > {
17
23
  label?: string;
18
24
  helperText?: string;
19
25
  options: T[];
20
- getOptionLabel?: (option: T) => string;
26
+ getRenderValue?: (option: T) => string;
21
27
  color?: 'success';
22
28
  onChange: (value: T) => void;
23
29
  defaultValue?: T | undefined;
24
30
  width?: number;
31
+ error?: string;
25
32
  }
26
33
 
27
34
  const Select = <T extends {}>({
@@ -32,17 +39,18 @@ const Select = <T extends {}>({
32
39
  error,
33
40
  placeholder,
34
41
  onChange,
35
- getOptionLabel,
42
+ getRenderValue,
36
43
  helperText,
37
44
  onBlur,
38
45
  width = 200,
39
46
  ...props
40
47
  }: Props<T>) => {
48
+ const theme = useTheme();
41
49
  const [value, setValue] = useState(defaultValue);
42
50
 
43
51
  const handleChange = (event: SelectChangeEvent<T>) => {
44
52
  const newValue = event.target.value as T;
45
- onChange(newValue);
53
+ if (onChange) onChange(newValue);
46
54
  setValue(newValue);
47
55
  };
48
56
 
@@ -51,7 +59,7 @@ const Select = <T extends {}>({
51
59
  if (props.disabled) classNames.push('Mui-disabled');
52
60
  if (value) classNames.push('Mui-filled');
53
61
 
54
- return classNames;
62
+ return classNames.join(' ');
55
63
  }, [value, props.disabled]);
56
64
 
57
65
  const getInputLabelClassName = useMemo(() => {
@@ -59,7 +67,7 @@ const Select = <T extends {}>({
59
67
  if (error) classNames.push('Mui-error');
60
68
  if (props.disabled) classNames.push('Mui-disabled');
61
69
 
62
- return classNames;
70
+ return classNames.join(' ');
63
71
  }, [error, props.disabled]);
64
72
 
65
73
  return (
@@ -68,16 +76,14 @@ const Select = <T extends {}>({
68
76
  id={label === placeholder ? 'select-mui' : 'select-ds'}
69
77
  fullWidth
70
78
  color={color}
71
- className={getFormControlClassName.join(' ')}
79
+ className={getFormControlClassName}
72
80
  sx={{
73
81
  '.MuiOutlinedInput-input': {
74
82
  marginTop: value ? '0px' : '2px'
75
83
  }
76
84
  }}
77
85
  >
78
- <InputLabel className={getInputLabelClassName.join(' ')}>
79
- {label}
80
- </InputLabel>
86
+ <InputLabel className={getInputLabelClassName}>{label}</InputLabel>
81
87
  <MuiSelect
82
88
  sx={{
83
89
  color: color + '! important',
@@ -91,7 +97,7 @@ const Select = <T extends {}>({
91
97
  }}
92
98
  label={label}
93
99
  placeholder={label === placeholder ? '' : placeholder}
94
- value={value}
100
+ value={value ?? ''}
95
101
  error={!!error}
96
102
  notched={
97
103
  /* eslint-disable-next-line no-undefined */
@@ -123,20 +129,32 @@ const Select = <T extends {}>({
123
129
  }
124
130
  }
125
131
  }}
132
+ renderValue={(value) =>
133
+ getRenderValue ? getRenderValue(value) : value['label']
134
+ }
126
135
  {...props}
127
136
  >
128
137
  {options?.map((option, i) => (
129
138
  <MenuItem
139
+ sx={{
140
+ fontSize: 14,
141
+ fontWeight: value === option ? 500 : 400,
142
+ backgroundColor:
143
+ value === option ? 'blueHoverEquivalence' : 'white'
144
+ }}
130
145
  key={i}
131
146
  value={option as any}
132
147
  onMouseEnter={(e: BaseSyntheticEvent) =>
133
- (e.target.style.backgroundColor = '#D3E4F0')
134
- }
135
- onMouseLeave={(e: BaseSyntheticEvent) =>
136
- (e.target.style.backgroundColor = '#ffffff')
148
+ (e.target.style.backgroundColor =
149
+ theme.palette['blueHoverEquivalence'])
137
150
  }
151
+ onMouseLeave={(e: BaseSyntheticEvent) => {
152
+ if (value !== option) {
153
+ e.target.style.backgroundColor = theme.palette['white'];
154
+ }
155
+ }}
138
156
  >
139
- {getOptionLabel ? getOptionLabel(option) : option['label']}
157
+ {getRenderValue ? getRenderValue(option) : option['label']}
140
158
  </MenuItem>
141
159
  ))}
142
160
  </MuiSelect>
@@ -2,12 +2,15 @@ import React, {
2
2
  FocusEventHandler,
3
3
  ReactNode,
4
4
  useEffect,
5
+ useMemo,
5
6
  useState
6
7
  } from 'react';
7
-
8
+ import { faEye, faEyeSlash } from '@fortawesome/pro-solid-svg-icons';
8
9
  import MuiTextField, { TextFieldProps } from '@mui/material/TextField';
9
10
  import { InputProps as StandardInputProps } from '@mui/material/Input/Input';
10
11
 
12
+ import Icon from '../../Icon';
13
+
11
14
  interface Props extends Omit<TextFieldProps, 'error'> {
12
15
  error?: string;
13
16
  onBlur?: FocusEventHandler<unknown>;
@@ -34,12 +37,34 @@ const TextField = ({
34
37
  ...props
35
38
  }: Props) => {
36
39
  const [internalValue, setInternalValue] = useState(value);
40
+ const [showPassword, setShowPassword] = useState(false);
41
+ const [currentType, setCurrentType] = useState<string>(props.type ?? 'text');
42
+
43
+ const passwordEndAdornment: React.ReactNode = useMemo(() => {
44
+ return (
45
+ <Icon
46
+ className="DsTextField-passwordIcon"
47
+ icon={showPassword ? faEyeSlash : faEye}
48
+ color="blueClickable"
49
+ onClick={() => setShowPassword(!showPassword)}
50
+ />
51
+ );
52
+ }, [showPassword]);
53
+
37
54
  useEffect(() => {
38
55
  if (value !== internalValue) {
39
56
  setInternalValue(value);
40
57
  }
41
58
  }, [value]);
42
59
 
60
+ useEffect(() => {
61
+ if (showPassword) {
62
+ setCurrentType('text');
63
+ } else {
64
+ setCurrentType(props.type ?? 'text');
65
+ }
66
+ }, [showPassword]);
67
+
43
68
  return (
44
69
  <MuiTextField
45
70
  id={label === placeholder ? 'text-field-mui' : 'text-field-ds'}
@@ -69,11 +94,16 @@ const TextField = ({
69
94
  }}
70
95
  error={!!error}
71
96
  disabled={disabled}
72
- InputProps={{ endAdornment }}
97
+ InputProps={
98
+ props.type === 'password'
99
+ ? { endAdornment: passwordEndAdornment }
100
+ : { endAdornment }
101
+ }
73
102
  inputProps={{ maxLength }}
74
103
  {...props}
104
+ type={currentType}
75
105
  helperText={
76
- <div style={{ display: 'table', width: '100%' }}>
106
+ <div style={{ display: 'table', width: '100%', marginRight: '4px' }}>
77
107
  {(error || props.helperText) && (
78
108
  <div
79
109
  style={{
@@ -66,6 +66,7 @@ const IconProvider = ({
66
66
  icon,
67
67
  color = '#136cac', // blueClickable
68
68
  size = 16,
69
+ sx,
69
70
  ...props
70
71
  }: Props & BoxProps): ReactElement => {
71
72
  const getStyles = (): SxProps<Theme> => {
@@ -79,20 +80,22 @@ const IconProvider = ({
79
80
  switch (variant) {
80
81
  case 'square':
81
82
  return {
83
+ ...sx,
82
84
  color: usedColor,
83
85
  backgroundColor: `${usedColor}14`,
84
86
  borderRadius: '4px',
85
87
  borderColor: '1px solid ' + usedColor,
86
88
  overflow: 'visible',
87
89
  padding: '10px',
88
- width: '35px',
89
- height: '35px',
90
+ width: '36px',
91
+ height: '36px',
90
92
  display: 'flex',
91
93
  justifyContent: 'center',
92
94
  alignItems: 'center'
93
95
  };
94
96
  default:
95
97
  return {
98
+ ...sx,
96
99
  color: usedColor,
97
100
  width: usedFontSize,
98
101
  height: size,