@groupeactual/ui-kit 1.7.9 → 2.0.0-beta.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.
Files changed (144) hide show
  1. package/dist/cjs/index.js +15097 -66
  2. package/dist/es/{src/DesignSystemProvider.d.ts → DesignSystemProvider.d.ts} +6 -5
  3. package/dist/es/{src/components → components}/Accordion/Accordion.d.ts +1 -1
  4. package/dist/es/{src/components → components}/BannerNotification/BannerNotification.d.ts +1 -1
  5. package/dist/es/{src/components → components}/Breadcrumbs/Breadcrumbs.d.ts +2 -2
  6. package/dist/es/{src/components → components}/Button/Button.d.ts +2 -2
  7. package/dist/es/{src/components → components}/Chip/Chip.d.ts +1 -1
  8. package/dist/es/components/Datatable/Datatable.d.ts +4 -0
  9. package/dist/es/{src/components → components}/EmbbededNotification/EmbeddedNotification.d.ts +1 -1
  10. package/dist/es/{src/components/UploadDocument → components/FileUploader}/FileUploader.d.ts +1 -1
  11. package/dist/es/components/Form/AutoCompleteMulti/AutoCompleteMulti.d.ts +23 -0
  12. package/dist/es/{src/components → components}/Form/AutoCompleteSingle/AutoCompleteSingle.d.ts +8 -5
  13. package/dist/es/components/Form/Checkbox/Checkbox.d.ts +12 -0
  14. package/dist/es/components/Form/CheckboxGroup/CheckboxGroup.d.ts +12 -0
  15. package/dist/es/components/Form/CheckboxGroup/checkboxgroup.interface.d.ts +6 -0
  16. package/dist/es/{src/components → components}/Form/DatePicker/DatePicker.d.ts +6 -4
  17. package/dist/es/{src/components → components}/Form/MultiSelect/MultiSelect.d.ts +3 -3
  18. package/dist/es/components/Form/RadioGroup/RadioGroup.d.ts +16 -0
  19. package/dist/es/{src/components → components}/Form/Select/Select.d.ts +3 -3
  20. package/dist/es/components/Form/Switch/Switch.d.ts +11 -0
  21. package/dist/es/{src/components → components}/Form/TextField/TextField.d.ts +6 -5
  22. package/dist/es/{src/components → components}/Form/TimePicker/TimePicker.d.ts +3 -3
  23. package/dist/es/{src/components → components}/IconButton/IconButton.d.ts +3 -3
  24. package/dist/es/components/IconProvider/IconProvider.d.ts +24 -0
  25. package/dist/es/{src/components → components}/Link/Link.d.ts +1 -2
  26. package/dist/es/components/MenuItem/MenuItem.d.ts +9 -0
  27. package/dist/es/components/Modal/Dialog/Dialog.d.ts +4 -0
  28. package/dist/es/components/Modal/Drawer/Drawer.d.ts +4 -0
  29. package/dist/es/{src/components → components}/Modal/modal.interface.d.ts +4 -1
  30. package/dist/es/{src/components → components}/Navigation/Stepper/Stepper.d.ts +1 -1
  31. package/dist/es/{src/components → components}/Pagination/Pagination.d.ts +2 -1
  32. package/dist/es/{src/components → components}/Snackbar/Snackbar.d.ts +1 -1
  33. package/dist/es/components/TabsPanel/TabsPanel.d.ts +4 -0
  34. package/dist/es/components/TabsPanel/index.d.ts +1 -0
  35. package/dist/es/components/TabsPanel/tab.interface.d.ts +17 -0
  36. package/dist/es/components/Text/Text.d.ts +8 -0
  37. package/dist/es/{src/components → components}/Tooltip/Tooltip.d.ts +1 -1
  38. package/dist/es/{src/components → components}/index.d.ts +3 -2
  39. package/dist/es/index.d.ts +108 -153
  40. package/dist/es/index.js +37 -79
  41. package/package.json +20 -17
  42. package/src/DesignSystemProvider.tsx +21 -36
  43. package/src/components/Accordion/Accordion.tsx +41 -59
  44. package/src/components/BannerNotification/BannerNotification.tsx +19 -20
  45. package/src/components/Breadcrumbs/Breadcrumbs.tsx +32 -28
  46. package/src/components/Button/Button.tsx +70 -17
  47. package/src/components/Chip/Chip.tsx +88 -117
  48. package/src/components/Datatable/Datatable.tsx +49 -37
  49. package/src/components/Datatable/DatatableCellRender.tsx +1 -1
  50. package/src/components/EmbbededNotification/EmbeddedNotification.tsx +78 -69
  51. package/src/components/FileUploader/FileUploader.tsx +767 -0
  52. package/src/components/Form/AutoCompleteMulti/AutoCompleteMulti.tsx +289 -172
  53. package/src/components/Form/AutoCompleteSingle/AutoCompleteSingle.tsx +228 -126
  54. package/src/components/Form/Checkbox/Checkbox.tsx +38 -96
  55. package/src/components/Form/CheckboxGroup/CheckboxGroup.tsx +86 -60
  56. package/src/components/Form/CheckboxGroup/checkboxgroup.interface.ts +0 -15
  57. package/src/components/Form/DatePicker/DatePicker.tsx +88 -40
  58. package/src/components/Form/MultiSelect/MultiSelect.tsx +196 -171
  59. package/src/components/Form/RadioGroup/RadioGroup.tsx +76 -82
  60. package/src/components/Form/Select/Select.tsx +156 -136
  61. package/src/components/Form/Switch/Switch.tsx +87 -47
  62. package/src/components/Form/TextField/TextField.tsx +125 -76
  63. package/src/components/Form/TimePicker/TimePicker.tsx +26 -7
  64. package/src/components/IconButton/IconButton.tsx +64 -39
  65. package/src/components/IconProvider/IconProvider.tsx +90 -69
  66. package/src/components/Link/Link.tsx +6 -10
  67. package/src/components/MenuItem/MenuItem.tsx +35 -23
  68. package/src/components/Modal/Dialog/Dialog.tsx +17 -14
  69. package/src/components/Modal/Drawer/Drawer.tsx +97 -69
  70. package/src/components/Modal/modal.interface.ts +4 -1
  71. package/src/components/Navigation/Stepper/Step.tsx +7 -6
  72. package/src/components/Navigation/Stepper/Stepper.tsx +24 -23
  73. package/src/components/NotistackAdapter/NotistackAdapter.tsx +1 -1
  74. package/src/components/Pagination/Pagination.tsx +131 -118
  75. package/src/components/Snackbar/Snackbar.tsx +29 -29
  76. package/src/components/TabsPanel/TabsPanel.tsx +151 -0
  77. package/src/components/TabsPanel/index.ts +1 -0
  78. package/src/components/TabsPanel/tab.interface.ts +20 -0
  79. package/src/components/Text/Text.tsx +25 -12
  80. package/src/components/Tooltip/Tooltip.tsx +54 -51
  81. package/src/components/index.ts +3 -2
  82. package/src/index.ts +0 -1
  83. package/dist/es/src/components/Datatable/Datatable.d.ts +0 -4
  84. package/dist/es/src/components/Form/AutoCompleteMulti/AutoCompleteMulti.d.ts +0 -19
  85. package/dist/es/src/components/Form/Checkbox/Checkbox.d.ts +0 -14
  86. package/dist/es/src/components/Form/CheckboxGroup/CheckboxGroup.d.ts +0 -12
  87. package/dist/es/src/components/Form/CheckboxGroup/checkboxgroup.interface.d.ts +0 -8
  88. package/dist/es/src/components/Form/RadioGroup/RadioGroup.d.ts +0 -18
  89. package/dist/es/src/components/Form/Switch/Switch.d.ts +0 -10
  90. package/dist/es/src/components/IconProvider/IconProvider.d.ts +0 -19
  91. package/dist/es/src/components/MenuItem/MenuItem.d.ts +0 -10
  92. package/dist/es/src/components/Modal/Dialog/Dialog.d.ts +0 -4
  93. package/dist/es/src/components/Modal/Drawer/Drawer.d.ts +0 -4
  94. package/dist/es/src/components/Text/Text.d.ts +0 -8
  95. package/dist/es/src/index.d.ts +0 -5
  96. package/dist/es/src/interfaces/theme.d.ts +0 -51
  97. package/src/components/UploadDocument/FileUploader.tsx +0 -728
  98. package/src/interfaces/theme.ts +0 -51
  99. /package/dist/es/{src/components → components}/Accordion/index.d.ts +0 -0
  100. /package/dist/es/{src/components → components}/BannerNotification/index.d.ts +0 -0
  101. /package/dist/es/{src/components → components}/Breadcrumbs/index.d.ts +0 -0
  102. /package/dist/es/{src/components → components}/Button/index.d.ts +0 -0
  103. /package/dist/es/{src/components → components}/Chip/index.d.ts +0 -0
  104. /package/dist/es/{src/components → components}/Datatable/DatatableCellRender.d.ts +0 -0
  105. /package/dist/es/{src/components → components}/Datatable/datatable.interface.d.ts +0 -0
  106. /package/dist/es/{src/components → components}/Datatable/index.d.ts +0 -0
  107. /package/dist/es/{src/components → components}/Datatable/use-pagination-props.hook.d.ts +0 -0
  108. /package/dist/es/{src/components → components}/EmbbededNotification/index.d.ts +0 -0
  109. /package/dist/es/{src/components/UploadDocument → components/FileUploader}/fileuploader.interface.d.ts +0 -0
  110. /package/dist/es/{src/components/UploadDocument → components/FileUploader}/index.d.ts +0 -0
  111. /package/dist/es/{src/components → components}/Form/AutoCompleteMulti/index.d.ts +0 -0
  112. /package/dist/es/{src/components → components}/Form/AutoCompleteSingle/index.d.ts +0 -0
  113. /package/dist/es/{src/components → components}/Form/Checkbox/index.d.ts +0 -0
  114. /package/dist/es/{src/components → components}/Form/CheckboxGroup/index.d.ts +0 -0
  115. /package/dist/es/{src/components → components}/Form/DatePicker/index.d.ts +0 -0
  116. /package/dist/es/{src/components → components}/Form/MultiSelect/index.d.ts +0 -0
  117. /package/dist/es/{src/components → components}/Form/RadioGroup/index.d.ts +0 -0
  118. /package/dist/es/{src/components → components}/Form/Select/index.d.ts +0 -0
  119. /package/dist/es/{src/components → components}/Form/Switch/index.d.ts +0 -0
  120. /package/dist/es/{src/components → components}/Form/TextField/index.d.ts +0 -0
  121. /package/dist/es/{src/components → components}/Form/TimePicker/index.d.ts +0 -0
  122. /package/dist/es/{src/components → components}/IconButton/index.d.ts +0 -0
  123. /package/dist/es/{src/components → components}/IconProvider/index.d.ts +0 -0
  124. /package/dist/es/{src/components → components}/Link/index.d.ts +0 -0
  125. /package/dist/es/{src/components → components}/MenuItem/index.d.ts +0 -0
  126. /package/dist/es/{src/components → components}/Modal/Dialog/index.d.ts +0 -0
  127. /package/dist/es/{src/components → components}/Modal/Drawer/index.d.ts +0 -0
  128. /package/dist/es/{src/components → components}/Navigation/Stepper/Step.d.ts +0 -0
  129. /package/dist/es/{src/components → components}/Navigation/Stepper/index.d.ts +0 -0
  130. /package/dist/es/{src/components → components}/Navigation/Stepper/stepper.helper.d.ts +0 -0
  131. /package/dist/es/{src/components → components}/Navigation/Stepper/stepper.interface.d.ts +0 -0
  132. /package/dist/es/{src/components → components}/NotistackAdapter/NotistackAdapter.d.ts +0 -0
  133. /package/dist/es/{src/components → components}/NotistackAdapter/index.d.ts +0 -0
  134. /package/dist/es/{src/components → components}/Pagination/index.d.ts +0 -0
  135. /package/dist/es/{src/components → components}/Pagination/pagination.helper.d.ts +0 -0
  136. /package/dist/es/{src/components → components}/Snackbar/index.d.ts +0 -0
  137. /package/dist/es/{src/components → components}/Text/index.d.ts +0 -0
  138. /package/dist/es/{src/components → components}/Tooltip/index.d.ts +0 -0
  139. /package/dist/es/{src/components → components}/Tooltip/tooltip.interface.d.ts +0 -0
  140. /package/dist/es/{src/helpers → helpers}/GooglePickerWrapper.d.ts +0 -0
  141. /package/dist/es/{src/hooks → hooks}/useGooleDrivePicker.d.ts +0 -0
  142. /package/dist/es/{src/types → types}/googleDrive.d.ts +0 -0
  143. /package/src/components/{UploadDocument → FileUploader}/fileuploader.interface.ts +0 -0
  144. /package/src/components/{UploadDocument → FileUploader}/index.ts +0 -0
@@ -2,26 +2,27 @@ import React, {
2
2
  FocusEventHandler,
3
3
  ReactNode,
4
4
  useEffect,
5
+ useId,
5
6
  useMemo,
6
7
  useState,
7
8
  } from 'react';
8
9
 
9
10
  import { faEye, faEyeSlash } from '@fortawesome/pro-solid-svg-icons';
10
- import { TextFieldStyle } from '@groupeactual/design-tokens';
11
11
  import {
12
- TextField as MuiTextField,
13
- TextFieldProps,
14
- styled,
15
- useTheme,
12
+ Box,
13
+ FormHelperText,
14
+ InputLabel,
15
+ OutlinedInput,
16
+ OutlinedInputProps,
16
17
  } from '@mui/material';
17
18
 
18
- import Icon from '@/components/IconProvider';
19
+ import IconProvider from '@/components/IconProvider';
19
20
 
20
- interface Props extends Omit<TextFieldProps, 'error'> {
21
- error?: string;
22
- label?: string;
21
+ interface Props extends Omit<OutlinedInputProps, 'error'> {
22
+ label?: ReactNode;
23
23
  value?: string | unknown;
24
24
  name?: string;
25
+ error?: string;
25
26
  placeholder?: string;
26
27
  disabled?: boolean;
27
28
  endAdornment?: ReactNode;
@@ -29,6 +30,7 @@ interface Props extends Omit<TextFieldProps, 'error'> {
29
30
  width?: number | string;
30
31
  className?: string;
31
32
  focused?: boolean;
33
+ helperText?: string;
32
34
  onClick?: (_e: React.MouseEvent<HTMLInputElement>) => void;
33
35
  onBlur?: FocusEventHandler<unknown>;
34
36
  onChange?: (
@@ -36,7 +38,10 @@ interface Props extends Omit<TextFieldProps, 'error'> {
36
38
  ) => void;
37
39
  }
38
40
 
39
- const TextField = React.forwardRef<HTMLDivElement, Props>(
41
+ const TextField = React.forwardRef<
42
+ HTMLInputElement | HTMLTextAreaElement,
43
+ Props
44
+ >(
40
45
  (
41
46
  {
42
47
  name,
@@ -51,16 +56,13 @@ const TextField = React.forwardRef<HTMLDivElement, Props>(
51
56
  placeholder = '',
52
57
  maxLength,
53
58
  focused,
59
+ helperText,
54
60
  ...props
55
61
  },
56
62
  ref,
57
63
  ) => {
58
- const theme = useTheme();
59
- const StyledTextField = useMemo(
60
- () => styled(MuiTextField)(TextFieldStyle(theme)),
61
- [theme],
62
- );
63
-
64
+ const generatedId = useId();
65
+ const inputId = name || `textfield-${generatedId}`;
64
66
  const [showPassword, setShowPassword] = useState(false);
65
67
  const [currentType, setCurrentType] = useState<string>(
66
68
  props.type ?? 'text',
@@ -68,84 +70,131 @@ const TextField = React.forwardRef<HTMLDivElement, Props>(
68
70
 
69
71
  const passwordEndAdornment: React.ReactNode = useMemo(() => {
70
72
  return (
71
- <Icon
72
- className="DsTextField-passwordIcon"
73
- icon={showPassword ? faEyeSlash : faEye}
74
- color="blueClickable"
75
- onClick={() => setShowPassword(!showPassword)}
76
- />
73
+ <Box
74
+ sx={{
75
+ display: 'inline-flex',
76
+ alignItems: 'center',
77
+ marginRight: '13px',
78
+ cursor: 'pointer',
79
+ }}
80
+ >
81
+ <IconProvider
82
+ className="DsTextField-passwordIcon"
83
+ icon={showPassword ? faEyeSlash : faEye}
84
+ color="blueClickable"
85
+ onClick={() => setShowPassword(!showPassword)}
86
+ />
87
+ </Box>
77
88
  );
78
89
  }, [showPassword]);
79
90
 
80
- useEffect(() => {
81
- if (showPassword) {
82
- setCurrentType('text');
83
- } else {
84
- setCurrentType(props.type ?? 'text');
85
- }
86
- }, [showPassword]);
91
+ const hasError = useMemo(
92
+ () =>
93
+ Boolean(
94
+ (error && error?.length > 0) ||
95
+ (maxLength && String(value).length > maxLength),
96
+ ),
97
+ [error, maxLength, value],
98
+ );
87
99
 
88
100
  const getTextFieldClassName = useMemo(() => {
89
101
  const classNames = [
90
- (!placeholder && 'TextField-mui') || 'TextField-ds',
91
102
  props.color === 'success' && 'Mui-success',
92
103
  value && 'Mui-filled',
93
104
  props.className,
94
105
  ];
95
106
 
96
107
  return classNames.filter(Boolean).join(' ');
97
- }, [value, props.color]);
108
+ }, [value, props.color, props.className]);
98
109
 
99
- const hasError = useMemo(
100
- () =>
101
- Boolean(
102
- (error && error?.length > 0) ||
103
- (maxLength && String(value).length > maxLength),
104
- ),
105
- [error, maxLength, value],
106
- );
110
+ const getLabelAndPlaceholderClassName = useMemo(() => {
111
+ const classNames = [
112
+ props.color === 'success' && 'Mui-success',
113
+ (error || hasError) && 'Mui-error',
114
+ ];
115
+
116
+ return classNames.filter(Boolean).join(' ');
117
+ }, [props.color, hasError]);
118
+
119
+ useEffect(() => {
120
+ if (showPassword) {
121
+ setCurrentType('text');
122
+ } else {
123
+ setCurrentType(props.type ?? 'text');
124
+ }
125
+ }, [showPassword]);
107
126
 
108
127
  return (
109
- <StyledTextField
110
- variant="outlined"
111
- name={name}
112
- ref={ref}
113
- label={label}
114
- value={value}
115
- sx={{ width }}
116
- placeholder={placeholder}
117
- focused={focused}
118
- FormHelperTextProps={{ component: 'div' } as never}
119
- InputLabelProps={{
120
- shrink: (placeholder && true) || undefined,
121
- }}
122
- onClick={(e) => e.stopPropagation()}
123
- onChange={(e) => {
124
- onChange?.(e);
125
- }}
126
- onBlur={(e) => {
127
- onBlur?.(e);
128
- }}
129
- error={hasError}
130
- disabled={disabled}
131
- InputProps={
132
- props.type === 'password'
133
- ? { endAdornment: passwordEndAdornment }
134
- : { endAdornment }
135
- }
136
- {...props}
137
- className={getTextFieldClassName}
138
- type={currentType}
139
- helperText={
140
- <div style={{ display: 'table', width: '100%', marginRight: '4px' }}>
141
- {(error || props.helperText) && (
128
+ <Box data-testid="ds-text-field-container">
129
+ {label && (
130
+ <InputLabel
131
+ className={getLabelAndPlaceholderClassName}
132
+ disabled={disabled}
133
+ htmlFor={inputId}
134
+ data-testid="ds-text-field-label"
135
+ >
136
+ {label}
137
+ </InputLabel>
138
+ )}
139
+ <OutlinedInput
140
+ {...props}
141
+ name={name}
142
+ id={inputId}
143
+ ref={ref}
144
+ value={value}
145
+ sx={{ width }}
146
+ placeholder={placeholder}
147
+ autoFocus={focused}
148
+ onClick={(e) => e.stopPropagation()}
149
+ onChange={(e) => {
150
+ onChange?.(e);
151
+ }}
152
+ onBlur={(e) => {
153
+ onBlur?.(e);
154
+ }}
155
+ error={hasError}
156
+ disabled={disabled}
157
+ endAdornment={
158
+ props.type === 'password' ? (
159
+ passwordEndAdornment
160
+ ) : (
161
+ <Box
162
+ sx={{
163
+ display: 'inline-flex',
164
+ alignItems: 'center',
165
+ marginRight: '13px',
166
+ }}
167
+ data-testid="ds-end-adornment"
168
+ >
169
+ {endAdornment}
170
+ </Box>
171
+ )
172
+ }
173
+ margin="none"
174
+ className={getTextFieldClassName}
175
+ type={currentType}
176
+ data-testid="ds-outlined-input"
177
+ />
178
+ {(error || helperText || maxLength) && (
179
+ <FormHelperText
180
+ component="span"
181
+ className={getLabelAndPlaceholderClassName}
182
+ sx={{
183
+ display: 'table',
184
+ width: '100%',
185
+ marginRight: '4px',
186
+ marginTop: '4px',
187
+ }}
188
+ data-testid="ds-form-helper-text"
189
+ >
190
+ {(error || helperText) && (
142
191
  <div
143
192
  style={{
144
193
  display: maxLength ? 'table-cell' : '',
145
194
  float: 'left',
146
195
  }}
147
196
  >
148
- {error || props.helperText}
197
+ {error || helperText}
149
198
  </div>
150
199
  )}
151
200
  {maxLength && (
@@ -153,9 +202,9 @@ const TextField = React.forwardRef<HTMLDivElement, Props>(
153
202
  {String(value).length}/{maxLength} caract.
154
203
  </div>
155
204
  )}
156
- </div>
157
- }
158
- />
205
+ </FormHelperText>
206
+ )}
207
+ </Box>
159
208
  );
160
209
  },
161
210
  );
@@ -1,4 +1,10 @@
1
- import React, { MouseEventHandler, useEffect, useRef, useState } from 'react';
1
+ import React, {
2
+ MouseEventHandler,
3
+ ReactNode,
4
+ useEffect,
5
+ useRef,
6
+ useState,
7
+ } from 'react';
2
8
 
3
9
  import { faCheck, faClock } from '@fortawesome/pro-regular-svg-icons';
4
10
  import { Popover, PopoverProps, TextFieldProps } from '@mui/material';
@@ -10,11 +16,21 @@ import dayjs, { Dayjs } from 'dayjs';
10
16
  import TextField from '@/components/Form/TextField';
11
17
  import IconProvider from '@/components/IconProvider';
12
18
 
13
- interface Props extends Omit<TextFieldProps, 'error' | 'onChange'> {
19
+ interface Props
20
+ extends Omit<
21
+ TextFieldProps,
22
+ | 'error'
23
+ | 'onChange'
24
+ | 'margin'
25
+ | 'onInvalid'
26
+ | 'onKeyDown'
27
+ | 'onKeyUp'
28
+ | 'slotProps'
29
+ > {
14
30
  value: Dayjs | undefined;
15
31
  onChange?: (_time: string | Dayjs | undefined) => void;
16
32
  onTouched?: () => void;
17
- label?: string;
33
+ label?: ReactNode;
18
34
  helperText?: string;
19
35
  minTime?: Dayjs;
20
36
  maxTime?: Dayjs;
@@ -56,7 +72,7 @@ const TimePicker = ({
56
72
  const [textfieldWidth, setTextfieldWidth] = useState<number | undefined>(
57
73
  undefined,
58
74
  );
59
- const textFieldRef = useRef<HTMLDivElement>(null); // Reference for the TextField
75
+ const textFieldRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null); // Reference for the TextField
60
76
 
61
77
  const isOpen = Boolean(anchorEl);
62
78
 
@@ -132,7 +148,7 @@ const TimePicker = ({
132
148
  <TextField
133
149
  {...props}
134
150
  ref={textFieldRef}
135
- data-testid="select-hour"
151
+ data-testid="ds-select-hour"
136
152
  error={customError || error}
137
153
  label={label}
138
154
  helperText={customError ?? helperText}
@@ -153,22 +169,25 @@ const TimePicker = ({
153
169
  }}
154
170
  icon={faCheck}
155
171
  color="greenSuccess"
172
+ data-testid="ds-icon-success"
156
173
  />
157
174
  ) : (
158
175
  <IconProvider
159
176
  onClick={handleClick}
177
+ color={disabled ? 'text.disabled' : 'primary.main'}
160
178
  sx={{
161
179
  ':hover': {
162
180
  cursor: disabled ? 'auto' : 'pointer',
163
181
  },
164
182
  }}
165
183
  icon={faClock}
184
+ data-testid="ds-icon-clock"
166
185
  />
167
186
  )
168
187
  }
169
188
  />
170
189
  <Popover
171
- data-testid="select-hour_popover"
190
+ data-testid="ds-select-hour-popover"
172
191
  open={isOpen}
173
192
  anchorEl={anchorEl}
174
193
  onClose={handleClose}
@@ -201,7 +220,7 @@ const TimePicker = ({
201
220
  }
202
221
  >
203
222
  <DigitalClock
204
- data-testid="select-hour_digital_clock"
223
+ data-testid="ds-select-hour-digital-clock"
205
224
  timeStep={timeStep}
206
225
  value={value && typeof value === 'object' ? value : null}
207
226
  onChange={(time) => {
@@ -1,14 +1,12 @@
1
- import React, { MouseEventHandler, useMemo } from 'react';
1
+ import React, { MouseEventHandler } from 'react';
2
2
 
3
3
  import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
4
- import { IconButtonStyle } from '@groupeactual/design-tokens';
5
4
  import {
5
+ CircularProgress,
6
6
  IconButton as IconButtonMUI,
7
7
  IconButtonProps,
8
8
  SxProps,
9
9
  Theme,
10
- styled,
11
- useTheme,
12
10
  } from '@mui/material';
13
11
 
14
12
  import IconProvider from '@/components/IconProvider';
@@ -17,49 +15,76 @@ import { Placement } from '@/components/Tooltip/tooltip.interface';
17
15
 
18
16
  interface Props extends Omit<IconButtonProps, 'color'> {
19
17
  icon: IconDefinition;
20
- variant?: 'default' | 'table';
18
+ variant?: 'plain' | 'outlined';
21
19
  positionGroup?: 'left' | 'middle' | 'right';
22
20
  tooltipText?: string;
23
21
  tooltipPosition?: Placement;
24
22
  size?: 'small' | 'medium';
25
23
  sx?: SxProps<Theme>;
26
- color?: string;
24
+ color?: 'neutral' | 'success' | 'warning' | 'danger';
27
25
  onClick?: MouseEventHandler | undefined;
28
26
  }
29
27
 
30
- const IconButton = ({
31
- icon,
32
- variant = 'default',
33
- positionGroup,
34
- tooltipText = '',
35
- tooltipPosition = 'top',
36
- size = 'medium',
37
- color,
38
- onClick,
39
- ...iconButtonProps
40
- }: Props) => {
41
- const theme = useTheme();
42
- const StyledIconButton = useMemo(
43
- () => styled(IconButtonMUI)(IconButtonStyle(theme)),
44
- [theme],
45
- );
46
- return (
47
- <Tooltip title={tooltipText} placement={tooltipPosition}>
48
- <StyledIconButton
49
- className={`IconButtonVariant-${variant} IconButtonSize-${size} ${
50
- positionGroup ? `IconButtonPositionGroup-${positionGroup}` : ''
51
- } `}
52
- onClick={onClick}
53
- {...iconButtonProps}
54
- >
55
- <IconProvider
56
- color={color}
57
- icon={icon}
58
- size={size === 'small' ? 'sm' : 'md'}
59
- />
60
- </StyledIconButton>
61
- </Tooltip>
62
- );
28
+ const getColor = (
29
+ color: Props['color'],
30
+ ): 'primary' | 'success' | 'warning' | 'error' | undefined => {
31
+ switch (color) {
32
+ case 'danger':
33
+ return 'error';
34
+ case 'neutral':
35
+ return 'primary';
36
+ default:
37
+ return color;
38
+ }
63
39
  };
64
40
 
41
+ const IconButton = React.forwardRef<HTMLButtonElement, Props>(
42
+ (
43
+ {
44
+ icon,
45
+ variant = 'outlined',
46
+ positionGroup,
47
+ tooltipText = '',
48
+ tooltipPosition = 'top',
49
+ size = 'medium',
50
+ color = 'neutral',
51
+ onClick,
52
+ ...props
53
+ },
54
+ ref,
55
+ ) => {
56
+ return (
57
+ <Tooltip title={tooltipText} placement={tooltipPosition}>
58
+ <IconButtonMUI
59
+ onClick={onClick}
60
+ ref={ref}
61
+ {...props}
62
+ color={getColor(color)}
63
+ loadingIndicator={
64
+ <CircularProgress color={getColor(color)} size={14} thickness={4} />
65
+ }
66
+ className={`IconButtonVariant-${variant} IconButtonSize-${size} ${
67
+ positionGroup ? `IconButtonPositionGroup-${positionGroup}` : ''
68
+ } `}
69
+ data-testid="ds-icon-button"
70
+ >
71
+ {!props.loading && (
72
+ <>
73
+ <IconProvider
74
+ icon={icon}
75
+ size={size === 'small' ? 'sm' : 'md'}
76
+ color="inherit"
77
+ data-testid="ds-icon-provider"
78
+ />
79
+ {props.children}
80
+ </>
81
+ )}
82
+ </IconButtonMUI>
83
+ </Tooltip>
84
+ );
85
+ },
86
+ );
87
+
88
+ IconButton.displayName = 'IconButton';
89
+
65
90
  export default IconButton;
@@ -33,7 +33,6 @@ interface FontAwesomeSvgIconProps {
33
33
  fontSize: number | undefined;
34
34
  }
35
35
 
36
- // eslint-disable-next-line react/display-name
37
36
  const FontAwesomeSvgIcon = forwardRef<SVGSVGElement, FontAwesomeSvgIconProps>(
38
37
  ({ icon, fontSize }, ref) => {
39
38
  const {
@@ -67,80 +66,102 @@ const FontAwesomeSvgIcon = forwardRef<SVGSVGElement, FontAwesomeSvgIconProps>(
67
66
  },
68
67
  );
69
68
 
70
- const IconProvider = ({
71
- variant = 'none',
72
- icon,
73
- color = '#136cac', // blueClickable
74
- size = 16,
75
- sx,
76
- ...props
77
- }: Props & BoxProps): JSX.Element => {
78
- const theme = useTheme();
69
+ FontAwesomeSvgIcon.displayName = 'FontAwesomeSvgIcon';
79
70
 
80
- const usedColor = useMemo(() => {
81
- if (theme.palette[color]) {
82
- return theme.palette[color];
83
- } else {
84
- if (!color || color.length === 0) {
85
- return '#136cac';
71
+ const IconProvider = React.forwardRef<HTMLDivElement, Props & BoxProps>(
72
+ (
73
+ {
74
+ variant = 'none',
75
+ icon,
76
+ color = '#136cac', // blueClickable
77
+ size = 16,
78
+ sx,
79
+ ...props
80
+ },
81
+ ref,
82
+ ) => {
83
+ const theme = useTheme();
84
+
85
+ console.log('theme.palette', theme.palette);
86
+ const usedColor = useMemo(() => {
87
+ if (theme.palette[color]) {
88
+ return theme.palette[color];
86
89
  } else {
87
- return color;
90
+ if (!color || color.length === 0) {
91
+ return '#136cac';
92
+ } else {
93
+ return color;
94
+ }
88
95
  }
89
- }
90
- }, [theme.palette, color]);
96
+ }, [theme.palette, color]);
97
+ console.log('usedColor', usedColor);
91
98
 
92
- const getStyles = (): SxProps<Theme> => {
93
- switch (variant) {
94
- case 'square':
95
- return {
96
- ...sx,
97
- color: usedColor,
98
- backgroundColor: `${usedColor}14`,
99
- borderRadius: '4px',
100
- borderColor: '1px solid ' + usedColor,
101
- overflow: 'visible',
102
- padding: '10px',
103
- width: '36px',
104
- height: '36px',
105
- display: 'flex',
106
- justifyContent: 'center',
107
- alignItems: 'center',
108
- };
109
- default:
110
- return {
111
- ...sx,
112
- color: usedColor,
113
- width: usedFontSize,
114
- height: usedFontSize,
115
- lineHeight: usedFontSize + 'px',
116
- display: 'inline-flex',
117
- alignItems: 'center',
118
- justifyContent: 'center',
119
- };
120
- }
121
- };
99
+ const getStyles = (): SxProps<Theme> => {
100
+ switch (variant) {
101
+ case 'square':
102
+ return {
103
+ ...sx,
104
+ color: usedColor + ' !important',
105
+ backgroundColor: `${usedColor}14 !important`,
106
+ borderRadius: '4px',
107
+ borderColor: '1px solid ' + usedColor,
108
+ overflow: 'visible',
109
+ padding: '10px',
110
+ width: '36px',
111
+ height: '36px',
112
+ display: 'flex',
113
+ justifyContent: 'center',
114
+ alignItems: 'center',
115
+ };
116
+ default:
117
+ return {
118
+ ...sx,
119
+ color: usedColor + ' !important',
120
+ width: usedFontSize,
121
+ height: usedFontSize,
122
+ lineHeight: usedFontSize + 'px',
123
+ display: 'inline-flex',
124
+ alignItems: 'center',
125
+ justifyContent: 'center',
126
+ };
127
+ }
128
+ };
122
129
 
123
- const isKey = (key: PropertyKey): key is keyof typeof FontSizes => {
124
- return key in FontSizes;
125
- };
130
+ const isKey = (key: PropertyKey): key is keyof typeof FontSizes => {
131
+ return key in FontSizes;
132
+ };
126
133
 
127
- const usedFontSize = useMemo(() => {
128
- if (variant === 'square') {
129
- return 16;
130
- } else if (isKey(size)) {
131
- return FontSizes[size];
132
- } else if (size >= 0) {
133
- return size;
134
- } else {
135
- return 16;
136
- }
137
- }, [variant, size]);
134
+ const usedFontSize = useMemo(() => {
135
+ if (variant === 'square') {
136
+ return 16;
137
+ } else if (isKey(size)) {
138
+ return FontSizes[size];
139
+ } else if (size >= 0) {
140
+ return size;
141
+ } else {
142
+ return 16;
143
+ }
144
+ }, [variant, size]);
138
145
 
139
- return (
140
- <Box className="itemIcon" component="span" sx={getStyles()} {...props}>
141
- <FontAwesomeSvgIcon icon={icon} fontSize={usedFontSize} />
142
- </Box>
143
- );
144
- };
146
+ return (
147
+ <Box
148
+ {...props}
149
+ ref={ref}
150
+ className={`itemIcon ${props.className ?? ''}`}
151
+ component="span"
152
+ sx={getStyles()}
153
+ data-testid="ds-icon-provider"
154
+ >
155
+ <FontAwesomeSvgIcon
156
+ icon={icon}
157
+ fontSize={usedFontSize}
158
+ data-testid="ds-font-awesome-icon"
159
+ />
160
+ </Box>
161
+ );
162
+ },
163
+ );
164
+
165
+ IconProvider.displayName = 'IconProvider';
145
166
 
146
167
  export default IconProvider;