kelt-ui-kit-react 2.0.2 → 2.0.3

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 (127) hide show
  1. package/README.md +0 -26
  2. package/dist/_core/type/generiqueType.d.ts +4 -0
  3. package/dist/badge/Badge.d.ts +3 -1
  4. package/dist/button/Button.d.ts +1 -1
  5. package/dist/button/button.interface.d.ts +1 -2
  6. package/dist/dataTable/DataTable.d.ts +17 -14
  7. package/dist/dataTable/dataTable.interface.d.ts +24 -19
  8. package/dist/dataTable/dataTableActions/DataTableAction.d.ts +3 -5
  9. package/dist/dataTable/dataTableColumn/DataTableColumn.d.ts +13 -7
  10. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/DataTableColumnFilter.d.ts +10 -0
  11. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDate/DataTableColumnFilterDate.d.ts +9 -0
  12. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDateRange/dataTableColumnFilterDateRange.d.ts +9 -0
  13. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterEnum/DataTableColumnFilterEnum.d.ts +13 -0
  14. package/dist/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterString/DataTableColumnFilterString.d.ts +9 -0
  15. package/dist/dataTable/dataTableColumn/dataTableColumnSort/DataTableColumnSort.d.ts +11 -0
  16. package/dist/dataTable/dataTableFilters/DataTableFilters.d.ts +7 -0
  17. package/dist/dataTable/dataTableLoading/DataTableLoading.d.ts +1 -3
  18. package/dist/dataTable/dataTableRow/DataTableRow.d.ts +5 -6
  19. package/dist/dataTable/dataTableRow/dataTableRowOverlay/DataTableRowOverlay.d.ts +12 -0
  20. package/dist/dataTable/dataTableRow/dataTableRowValue/DataTableRowValue.d.ts +11 -0
  21. package/dist/expands/expand/expand.d.ts +1 -1
  22. package/dist/form/Form.d.ts +2 -4
  23. package/dist/form/form.enum.d.ts +2 -3
  24. package/dist/form/form.interface.d.ts +2 -19
  25. package/dist/form/input/Input.d.ts +3 -0
  26. package/dist/form/inputNumber/InputNumber.d.ts +0 -2
  27. package/dist/grid/col/Col.d.ts +6 -3
  28. package/dist/grid/col/colStyled/ColStyled.d.ts +5 -7
  29. package/dist/grid/grid.interface.d.ts +5 -9
  30. package/dist/header/Header.d.ts +1 -1
  31. package/dist/header/header.interface.d.ts +1 -2
  32. package/dist/icon/Icon.d.ts +1 -1
  33. package/dist/icon/icon.interface.d.ts +1 -0
  34. package/dist/index.d.ts +1 -5
  35. package/dist/index.js +3606 -3543
  36. package/dist/menus/menu/Menu.d.ts +0 -1
  37. package/dist/overlayPanel/OverlayPanel.d.ts +4 -2
  38. package/dist/overlayPanel/overlayPanelStyled/OverlayPanelStyled.d.ts +2 -0
  39. package/dist/select/Select.d.ts +6 -2
  40. package/dist/select/selectOption.interface.d.ts +1 -0
  41. package/dist/style.css +1 -1
  42. package/dist/tabs/Tabs.d.ts +2 -1
  43. package/dist/toaster/store/useToasterStore.d.ts +0 -1
  44. package/index.html +2 -1
  45. package/package/package.json +56 -0
  46. package/package/src/sidebar/Sidebar.tsx +208 -0
  47. package/package/src/sidebar/sidebar.css +104 -0
  48. package/package.json +1 -1
  49. package/src/App.menu.tsx +0 -8
  50. package/src/_core/type/generiqueType.tsx +4 -0
  51. package/src/badge/Badge.tsx +9 -1
  52. package/src/badge/badge.css +4 -0
  53. package/src/button/Button.tsx +1 -3
  54. package/src/button/button.css +2 -2
  55. package/src/button/button.interface.tsx +1 -2
  56. package/src/card/card.css +25 -5
  57. package/src/card/cardAction/CardAction.tsx +4 -4
  58. package/src/damier/Damier.tsx +7 -16
  59. package/src/damier/damier.css +4 -11
  60. package/src/dataTable/DataTable.tsx +685 -542
  61. package/src/dataTable/DataTable.view.tsx +48 -24
  62. package/src/dataTable/dataTable.css +134 -159
  63. package/src/dataTable/dataTable.interface.ts +25 -19
  64. package/src/dataTable/dataTableActions/DataTableAction.tsx +14 -25
  65. package/src/dataTable/dataTableColumn/DataTableColumn.tsx +64 -14
  66. package/src/dataTable/dataTableColumn/dataTableColumnFilter/DataTableColumnFilter.tsx +36 -0
  67. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilter.css +0 -0
  68. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDate/DataTableColumnFilterDate.tsx +39 -0
  69. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterDateRange/dataTableColumnFilterDateRange.tsx +80 -0
  70. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterEnum/DataTableColumnFilterEnum.tsx +89 -0
  71. package/src/dataTable/dataTableColumn/dataTableColumnFilter/dataTableColumnFilterString/DataTableColumnFilterString.tsx +37 -0
  72. package/src/dataTable/dataTableColumn/dataTableColumnSort/DataTableColumnSort.tsx +42 -0
  73. package/src/dataTable/dataTableFilters/DataTableFilters.tsx +91 -0
  74. package/src/dataTable/dataTableFilters/dataTableFilters.css +16 -0
  75. package/src/dataTable/dataTableLoading/DataTableLoading.tsx +4 -15
  76. package/src/dataTable/dataTableRow/DataTableRow.tsx +64 -180
  77. package/src/dataTable/dataTableRow/dataTableRowOverlay/DataTableRowOverlay.tsx +80 -0
  78. package/src/dataTable/dataTableRow/dataTableRowValue/DataTableRowValue.tsx +123 -0
  79. package/src/expands/Expands.tsx +2 -16
  80. package/src/expands/expand/expand.tsx +5 -122
  81. package/src/expands/expands.css +3 -8
  82. package/src/form/Form.tsx +93 -258
  83. package/src/form/Form.view.tsx +1 -9
  84. package/src/form/form.css +1 -51
  85. package/src/form/form.enum.ts +1 -2
  86. package/src/form/form.interface.tsx +2 -28
  87. package/src/form/input/Input.tsx +61 -7
  88. package/src/form/input/input.css +23 -1
  89. package/src/form/inputNumber/InputNumber.tsx +6 -11
  90. package/src/form/inputPrice/InputPrice.tsx +2 -4
  91. package/src/grid/col/Col.tsx +7 -5
  92. package/src/grid/col/colStyled/ColStyled.tsx +7 -21
  93. package/src/grid/grid.interface.tsx +5 -11
  94. package/src/grid/row/row.css +2 -2
  95. package/src/header/Header.tsx +2 -4
  96. package/src/header/header.css +0 -17
  97. package/src/header/header.interface.tsx +1 -2
  98. package/src/icon/Icon.tsx +6 -2
  99. package/src/icon/icon.interface.tsx +1 -0
  100. package/src/index.css +12 -58
  101. package/src/index.ts +2 -12
  102. package/src/menus/Menus.tsx +0 -1
  103. package/src/menus/menu/Menu.tsx +1 -2
  104. package/src/overlayPanel/OverlayPanel.tsx +71 -18
  105. package/src/overlayPanel/overlay.context.tsx +6 -4
  106. package/src/overlayPanel/overlayPanel.css +10 -1
  107. package/src/overlayPanel/overlayPanelStyled/OverlayPanelStyled.tsx +7 -2
  108. package/src/select/Select.tsx +178 -41
  109. package/src/select/select.css +94 -13
  110. package/src/select/selectOption.interface.ts +1 -0
  111. package/src/sidebar/Sidebar.tsx +5 -107
  112. package/src/sidebar/sidebar.css +1 -18
  113. package/src/tabs/Tabs.tsx +20 -1
  114. package/src/tabs/tabs.css +3 -9
  115. package/src/toaster/Toaster.tsx +2 -7
  116. package/src/toaster/Toaster.view.tsx +0 -1
  117. package/src/toaster/store/useToasterStore.tsx +0 -2
  118. package/src/toaster/toaster.css +2 -7
  119. package/dist/addressSearch/AddressSearch.d.ts +0 -20
  120. package/dist/addressSearch/AddressSearch.view.d.ts +0 -1
  121. package/dist/geocoding/GeocodingService.d.ts +0 -13
  122. package/dist/geocoding/geocoding.interface.d.ts +0 -20
  123. package/src/addressSearch/AddressSearch.tsx +0 -246
  124. package/src/addressSearch/AddressSearch.view.tsx +0 -52
  125. package/src/addressSearch/addressSearch.css +0 -133
  126. package/src/geocoding/GeocodingService.ts +0 -89
  127. package/src/geocoding/geocoding.interface.ts +0 -25
@@ -39,12 +39,10 @@
39
39
  height: 300px;
40
40
  flex: 1;
41
41
  min-height: 200px;
42
-
43
42
  .expand-header {
44
- background-color: color-mix(in srgb, var(--primary-color), white 5%);
43
+ background-color: #1d3758;
45
44
  color: #fff;
46
45
  }
47
-
48
46
  .expand-header-custom {
49
47
  .expand-header--children {
50
48
  display: flex;
@@ -67,7 +65,6 @@
67
65
  padding: 15px;
68
66
  color: #333;
69
67
  background-color: #fff;
70
-
71
68
  &.expand-header-custom {
72
69
  margin-bottom: 1rem;
73
70
  }
@@ -80,15 +77,13 @@
80
77
  .expand-header-title-left {
81
78
  margin-right: 0.5rem;
82
79
  text-transform: uppercase;
83
- font-size: 18px;
80
+ font-size: 14px;
84
81
  font-weight: 500;
85
82
  }
86
83
  }
87
-
88
84
  & .expand-footer {
89
85
  padding: 15px;
90
86
  }
91
-
92
87
  & .expand-body {
93
88
  display: none;
94
89
  flex: 1;
@@ -99,4 +94,4 @@
99
94
  flex-direction: column;
100
95
  }
101
96
  }
102
- }
97
+ }
package/src/form/Form.tsx CHANGED
@@ -9,40 +9,12 @@ import { Button } from "../button/Button";
9
9
  import { Icon } from "../icon/Icon";
10
10
  import { Select } from "../select/Select"; // <--- ton composant
11
11
  import "./form.css";
12
- import {
13
- FormInterface,
14
- FormMode,
15
- FormSection,
16
- FormValuesInterface,
17
- } from "./form.interface";
12
+ import { FormInterface, FormValuesInterface } from "./form.interface";
18
13
  import { Input } from "./input/Input";
19
- import { InputPrice } from "./inputPrice/InputPrice";
20
14
  import { TextArea } from "./textArea/TextArea";
21
- import { Col } from "../grid/col/Col";
22
- import { Row } from "../grid/row/Row";
23
- import { TypeInputEnum } from "./form.enum";
24
- import { AddressSearch } from "../addressSearch/AddressSearch";
25
-
26
- const euroFormatter = new Intl.NumberFormat("fr-FR", {
27
- style: "currency",
28
- currency: "EUR",
29
- });
30
-
31
- type FormFieldContainerProps = {
32
- field: FormInterface;
33
- gridEnabled: boolean;
34
- children: React.ReactNode;
35
- };
36
-
37
- const FormFieldContainer = ({
38
- field,
39
- gridEnabled,
40
- children,
41
- }: FormFieldContainerProps) =>
42
- gridEnabled ? <Col {...field.col}>{children}</Col> : <>{children}</>;
43
15
 
44
16
  export type FormProps<
45
- T extends { [key: string]: string | number | boolean | Date | string[] }
17
+ T extends { [key: string]: string | number | boolean | Date | string[] },
46
18
  > = {
47
19
  id?: string;
48
20
  className?: string;
@@ -50,10 +22,8 @@ export type FormProps<
50
22
  hideSubmit?: boolean;
51
23
  autoComplete?: string;
52
24
  children?: React.ReactNode;
53
- initialForm?: FormInterface[];
54
- sections?: FormSection[];
25
+ initialForm: FormInterface[];
55
26
  disabledSubmit?: boolean;
56
- mode?: FormMode;
57
27
  onSubmit?: (values: FormValuesInterface<T>) => void;
58
28
  onChange?: (values: FormValuesInterface<T>) => void;
59
29
  };
@@ -62,7 +32,6 @@ export const DynamicForm = forwardRef(
62
32
  <T extends { [key: string]: string | number | boolean | Date | string[] }>(
63
33
  {
64
34
  initialForm,
65
- sections,
66
35
  title,
67
36
  onSubmit,
68
37
  id,
@@ -71,7 +40,6 @@ export const DynamicForm = forwardRef(
71
40
  onChange,
72
41
  hideSubmit,
73
42
  disabledSubmit = false,
74
- mode = "edit",
75
43
  className,
76
44
  }: FormProps<T>,
77
45
  ref: React.Ref<{
@@ -81,19 +49,13 @@ export const DynamicForm = forwardRef(
81
49
  getValues?: () => FormValuesInterface<T>;
82
50
  updateFormValue?: (values: FormValuesInterface<T>) => void;
83
51
  setBtnDisabledSubmit?: (disabled: boolean) => void;
84
- }>
52
+ }>,
85
53
  ) => {
86
- const formFields = sections
87
- ? sections.reduce<FormInterface[]>(
88
- (fields, section) => fields.concat(section.fields),
89
- [],
90
- )
91
- : (initialForm ?? []);
92
54
  const [btnDisabledSubmit, setBtnDisabledSubmit] = useState(disabledSubmit);
93
55
  const [values, setValues] = useState<FormValuesInterface<T>>(() => {
94
56
  const initialValues: FormValuesInterface<T> =
95
57
  {} as FormValuesInterface<T>;
96
- formFields.forEach((field) => {
58
+ initialForm.forEach((field) => {
97
59
  (initialValues as any)[field.name] = field.value ?? "";
98
60
  });
99
61
  return initialValues;
@@ -105,7 +67,7 @@ export const DynamicForm = forwardRef(
105
67
  const handleChangeInput = useCallback(
106
68
  (
107
69
  event: React.ChangeEvent<HTMLInputElement>,
108
- forminterface: FormInterface
70
+ forminterface: FormInterface,
109
71
  ) => {
110
72
  const { name, type, checked, value } = event.target;
111
73
  const newValue = type === "checkbox" ? checked : value;
@@ -122,7 +84,7 @@ export const DynamicForm = forwardRef(
122
84
  return updatedValues;
123
85
  });
124
86
  },
125
- [onChange]
87
+ [onChange],
126
88
  );
127
89
  const handleChangeTextArea = useCallback(
128
90
  (name: string, value: string, forminterface: FormInterface) => {
@@ -138,14 +100,14 @@ export const DynamicForm = forwardRef(
138
100
  return updatedValues;
139
101
  });
140
102
  },
141
- [onChange]
103
+ [onChange],
142
104
  );
143
105
  /** Gestion des <select> */
144
106
  const handleChangeSelect = useCallback(
145
107
  (
146
108
  newValue: string | string[],
147
109
  name: string,
148
- forminterface: FormInterface
110
+ forminterface: FormInterface,
149
111
  ) => {
150
112
  if (forminterface.onChange) {
151
113
  forminterface.onChange(newValue, name);
@@ -157,7 +119,7 @@ export const DynamicForm = forwardRef(
157
119
  return updatedValues;
158
120
  });
159
121
  },
160
- [onChange]
122
+ [onChange],
161
123
  );
162
124
 
163
125
  const handleSubmit = useCallback(
@@ -167,14 +129,14 @@ export const DynamicForm = forwardRef(
167
129
  onSubmit(values);
168
130
  }
169
131
  },
170
- [onSubmit, values]
132
+ [onSubmit, values],
171
133
  );
172
134
 
173
135
  const resetForm = () => {
174
136
  setValues(() => {
175
137
  const resetValues: FormValuesInterface<T> =
176
138
  {} as FormValuesInterface<T>;
177
- formFields.forEach((field) => {
139
+ initialForm.forEach((field) => {
178
140
  (resetValues as any)[field.name] = field.value ?? "";
179
141
  });
180
142
  return resetValues;
@@ -189,7 +151,7 @@ export const DynamicForm = forwardRef(
189
151
  }, []);
190
152
 
191
153
  const focusInitialElement = () => {
192
- const focusedField = formFields.find((field) => field.focus);
154
+ const focusedField = initialForm.find((field) => field.focus);
193
155
  if (focusedField && inputRefs.current[focusedField.name]) {
194
156
  setTimeout(() => {
195
157
  inputRefs.current[focusedField.name]?.select();
@@ -200,7 +162,7 @@ export const DynamicForm = forwardRef(
200
162
  const getValues = () => values;
201
163
 
202
164
  const updateFormValue: (values: FormValuesInterface<T>) => void = (
203
- values
165
+ values,
204
166
  ) => {
205
167
  setValues((prevValues) => ({
206
168
  ...prevValues,
@@ -208,17 +170,6 @@ export const DynamicForm = forwardRef(
208
170
  }));
209
171
  };
210
172
 
211
- const updateValues = useCallback(
212
- (updatedValues: FormValuesInterface<T>) => {
213
- setValues((previousValues) => {
214
- const nextValues = { ...previousValues, ...updatedValues };
215
- onChange?.(nextValues);
216
- return nextValues;
217
- });
218
- },
219
- [onChange],
220
- );
221
-
222
173
  useImperativeHandle(ref, () => ({
223
174
  resetForm,
224
175
  clearInput,
@@ -228,188 +179,6 @@ export const DynamicForm = forwardRef(
228
179
  setBtnDisabledSubmit,
229
180
  }));
230
181
 
231
- const getReadValue = (field: FormInterface): React.ReactNode => {
232
- const value = values[field.name];
233
-
234
- if (field.formatReadValue) {
235
- return field.formatReadValue(value ?? "");
236
- }
237
-
238
- if (field.type === TypeInputEnum.SELECT) {
239
- const selectedValues = Array.isArray(value) ? value : [value];
240
- const labels = selectedValues
241
- .map(
242
- (selectedValue) =>
243
- field.options?.find((option) => option.value === selectedValue)
244
- ?.label ?? selectedValue,
245
- )
246
- .filter((selectedValue) => selectedValue !== undefined);
247
-
248
- return labels.join(", ") || "-";
249
- }
250
-
251
- if (field.type === TypeInputEnum.PRICE) {
252
- const amount = Number(value);
253
- return value === "" || value === undefined || Number.isNaN(amount)
254
- ? "-"
255
- : euroFormatter.format(amount);
256
- }
257
-
258
- if (typeof value === "boolean") {
259
- return value ? "Oui" : "Non";
260
- }
261
-
262
- if (value instanceof Date) {
263
- return value.toLocaleDateString();
264
- }
265
-
266
- if (Array.isArray(value)) {
267
- return value.join(", ") || "-";
268
- }
269
-
270
- return value === undefined || value === null || value === ""
271
- ? "-"
272
- : String(value);
273
- };
274
-
275
- const renderFields = (fields: FormInterface[]) => {
276
- const gridEnabled = fields.some((field) => field.col !== undefined);
277
- const FieldsContainer = gridEnabled ? Row : React.Fragment;
278
-
279
- return (
280
- <FieldsContainer>
281
- {fields.map((v, key) => {
282
- const required = v.onRequired
283
- ? v.onRequired(v.value)
284
- : v.required ?? false;
285
- const disabled = v.onDisabled
286
- ? v.onDisabled(v.value)
287
- : v.disabled ?? false;
288
-
289
- return (
290
- <FormFieldContainer
291
- key={v.name || key}
292
- field={v}
293
- gridEnabled={gridEnabled}
294
- >
295
- <div
296
- className={`d-flex flex-column ${v.className ?? ""
297
- } form-group form-group-${v.type}`}
298
- >
299
- {v.label && <label>{v.label}</label>}
300
- {v.icon && <Icon classIcon={v.icon} />}
301
-
302
- {mode === "read" ? (
303
- <div
304
- className={`form-read-value ${v.type === TypeInputEnum.TEXTAREA
305
- ? "form-read-value--textarea"
306
- : ""
307
- }`}
308
- >
309
- {getReadValue(v)}
310
- </div>
311
- ) : v.type === TypeInputEnum.ADDRESS ? (
312
- <AddressSearch
313
- id={v.id ?? v.name}
314
- label=""
315
- placeholder={v.placeholder}
316
- value={String(values[v.name] ?? "")}
317
- disabled={disabled}
318
- minimumQueryLength={v.addressSearch?.minimumQueryLength}
319
- debounceTime={v.addressSearch?.debounceTime}
320
- limit={v.addressSearch?.limit}
321
- provider={v.addressSearch?.provider}
322
- allowManualEntry
323
- manualEntryLabel={v.addressSearch?.manualEntryLabel}
324
- onChange={(value) =>
325
- updateValues({ [v.name]: value } as FormValuesInterface<T>)
326
- }
327
- onSelect={(address) => {
328
- const mappedValues =
329
- v.addressSearch?.mapAddress?.(address) ?? {};
330
- updateValues(mappedValues as FormValuesInterface<T>);
331
- v.addressSearch?.onSelect?.(address);
332
- }}
333
- />
334
- ) : v.type === "select" ? (
335
- <Select
336
- id={v.id ?? v.name}
337
- label={undefined}
338
- name={v.name}
339
- options={v.options ?? []}
340
- disabled={disabled}
341
- multiple={v.multiple}
342
- value={values[v.name] as any}
343
- required={required}
344
- defaultValue={v.value as string | string[]}
345
- placeholder={v.placeholder}
346
- onChangeMultiple={(newValue) =>
347
- handleChangeSelect(newValue, v.name, v)
348
- }
349
- onChange={(newValue) =>
350
- handleChangeSelect(newValue, v.name, v)
351
- }
352
- />
353
- ) : v.type === "textarea" ? (
354
- <TextArea
355
- id={v.id ?? v.name}
356
- name={v.name}
357
- className="textarea-input"
358
- placeholder={v.placeholder ?? ""}
359
- disabled={disabled}
360
- required={required}
361
- value={values[v.name] as string}
362
- onChange={(value, name) =>
363
- handleChangeTextArea(name, value, v)
364
- }
365
- />
366
- ) : v.type === TypeInputEnum.PRICE ? (
367
- <InputPrice
368
- id={v.id ?? v.name}
369
- ref={(el) => (inputRefs.current[v.name] = el)}
370
- name={v.name}
371
- placeholder={v.placeholder ?? ""}
372
- autoComplete={v.autoComplete}
373
- tabIndex={0}
374
- disabled={disabled}
375
- autoFocus={v.focus ?? false}
376
- required={required}
377
- value={String(values[v.name] ?? "")}
378
- onChange={(value) =>
379
- handleChangeTextArea(v.name, value, v)
380
- }
381
- />
382
- ) : (
383
- <Input
384
- id={v.id ?? v.name}
385
- ref={(el) => (inputRefs.current[v.name] = el)}
386
- name={v.name}
387
- type={v.type}
388
- placeholder={v.placeholder ?? ""}
389
- autoComplete={v.autoComplete}
390
- tabIndex={0}
391
- disabled={disabled}
392
- autoFocus={v.focus ?? false}
393
- required={required}
394
- step={v.step ?? "0.01"}
395
- value={values[v.name] as string | number}
396
- checked={
397
- v.type === "checkbox" ? !!values[v.name] : undefined
398
- }
399
- onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
400
- handleChangeInput(e, v)
401
- }
402
- onInvalid={v.onInvalid ? v.onInvalid : undefined}
403
- />
404
- )}
405
- </div>
406
- </FormFieldContainer>
407
- );
408
- })}
409
- </FieldsContainer>
410
- );
411
- };
412
-
413
182
  return (
414
183
  <form
415
184
  autoComplete={autoComplete ?? "off"}
@@ -417,23 +186,89 @@ export const DynamicForm = forwardRef(
417
186
  className={className ?? ""}
418
187
  >
419
188
  <div className="form-content">
420
- {sections
421
- ? sections.map((section, index) => (
422
- <section
423
- className={`form-section ${section.className ?? ""}`}
424
- key={index}
189
+ {initialForm.map((v, key) => {
190
+ const required = v.onRequired
191
+ ? v.onRequired(v.value)
192
+ : (v.required ?? false);
193
+ const disabled = v.onDisabled
194
+ ? v.onDisabled(v.value)
195
+ : (v.disabled ?? false);
196
+
197
+ return (
198
+ <div
199
+ key={key}
200
+ className={`d-flex flex-column ${
201
+ v.className ?? ""
202
+ } form-group form-group-${v.type}`}
425
203
  >
426
- {section.title && (
427
- <h3 className="form-section-title">{section.title}</h3>
204
+ {v.label && <label>{v.label}</label>}
205
+ {v.icon && <Icon classIcon={v.icon} />}
206
+
207
+ {v.type === "select" ? (
208
+ <Select
209
+ id={v.id ?? v.name}
210
+ label={undefined}
211
+ name={v.name}
212
+ options={v.options ?? []}
213
+ disabled={disabled}
214
+ multiple={v.multiple}
215
+ usePortal={v.usePortal}
216
+ searchable={v.searchable}
217
+ value={values[v.name] as any}
218
+ required={required}
219
+ defaultValue={v.value as string | string[]}
220
+ placeholder={v.placeholder}
221
+ onChangeMultiple={(newValue) =>
222
+ handleChangeSelect(newValue, v.name, v)
223
+ }
224
+ onChange={(newValue) =>
225
+ handleChangeSelect(newValue, v.name, v)
226
+ }
227
+ />
228
+ ) : v.type === "textarea" ? (
229
+ <TextArea
230
+ id={v.id ?? v.name}
231
+ name={v.name}
232
+ className="textarea-input"
233
+ placeholder={v.placeholder ?? ""}
234
+ disabled={disabled}
235
+ required={required}
236
+ value={values[v.name] as string}
237
+ onChange={(value, name) =>
238
+ handleChangeTextArea(name, value, v)
239
+ }
240
+ />
241
+ ) : (
242
+ <Input
243
+ id={v.id ?? v.name}
244
+ ref={(el) => (inputRefs.current[v.name] = el)}
245
+ name={v.name}
246
+ type={v.type}
247
+ placeholder={v.placeholder ?? ""}
248
+ autoComplete={v.autoComplete}
249
+ tabIndex={0}
250
+ disabled={disabled}
251
+ autoFocus={v.focus ?? false}
252
+ required={required}
253
+ step={v.step ?? "0.01"}
254
+ disabledDebounce={true}
255
+ value={values[v.name] as string | number}
256
+ checked={
257
+ v.type === "checkbox" ? !!values[v.name] : undefined
258
+ }
259
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
260
+ handleChangeInput(e, v)
261
+ }
262
+ onInvalid={v.onInvalid ? v.onInvalid : undefined}
263
+ />
428
264
  )}
429
- {renderFields(section.fields)}
430
- </section>
431
- ))
432
- : renderFields(initialForm ?? [])}
265
+ </div>
266
+ );
267
+ })}
433
268
  {children}
434
269
  </div>
435
270
  <div className="d-flex justify-content-end form-footer">
436
- {mode === "edit" && !hideSubmit && (
271
+ {!hideSubmit && (
437
272
  <Button
438
273
  id={`button-${id}`}
439
274
  disabled={btnDisabledSubmit}
@@ -443,5 +278,5 @@ export const DynamicForm = forwardRef(
443
278
  </div>
444
279
  </form>
445
280
  );
446
- }
281
+ },
447
282
  );
@@ -18,14 +18,12 @@ export const FormView = (): JSX.Element => {
18
18
  name: "nom",
19
19
  type: TypeInputEnum.PASSWORD,
20
20
  required: true,
21
- col: { xs: 12, md: 6 },
22
21
  },
23
22
  {
24
23
  value: 30,
25
24
  label: "Age",
26
25
  name: "age",
27
26
  type: TypeInputEnum.NUMBER,
28
- col: { xs: 12, md: 6 },
29
27
  },
30
28
  {
31
29
  value: false,
@@ -57,11 +55,5 @@ export const FormView = (): JSX.Element => {
57
55
  const handleSubmit = (values: FormValuesInterface<FormData>) => {
58
56
  console.log("Form Submitted: ", values);
59
57
  };
60
- return (
61
- <DynamicForm
62
- mode="edit"
63
- onSubmit={handleSubmit}
64
- initialForm={initialValues}
65
- />
66
- );
58
+ return <DynamicForm onSubmit={handleSubmit} initialForm={initialValues} />;
67
59
  };
package/src/form/form.css CHANGED
@@ -6,7 +6,7 @@ input {
6
6
  min-width: 250px;
7
7
 
8
8
  &:focus-visible {
9
- outline: 1px solid #9696a7;
9
+ outline: 0px;
10
10
  }
11
11
  }
12
12
 
@@ -20,19 +20,6 @@ input[type="radio"] {
20
20
  }
21
21
 
22
22
  form {
23
- .form-section+.form-section {
24
- margin-top: 1.25rem;
25
- }
26
-
27
- .form-section-title {
28
- margin: 0 15px 0.5rem;
29
- padding-bottom: 0.5rem;
30
- border-bottom: 1px solid #dedede;
31
- color: var(--primary-color);
32
- font-size: 1rem;
33
- font-weight: 600;
34
- }
35
-
36
23
  &.form-row {
37
24
  display: flex;
38
25
  flex-direction: row;
@@ -83,41 +70,4 @@ form {
83
70
  button {
84
71
  margin-top: 1rem;
85
72
  }
86
-
87
- .form-read-value {
88
- width: 100%;
89
- min-width: 250px;
90
- min-height: calc(1em + 1rem + 2px);
91
- box-sizing: border-box;
92
- border: 1px solid transparent;
93
- border-radius: 4px;
94
- margin: 0.25rem 0;
95
- padding: 0;
96
- font-size: 0.8rem;
97
- line-height: normal;
98
- overflow-wrap: anywhere;
99
- }
100
-
101
- .form-read-value--textarea {
102
- min-height: 3.25rem;
103
- white-space: pre-wrap;
104
- }
105
-
106
- .grid-row {
107
-
108
- .form-group,
109
- .input-container,
110
- .select-container,
111
- .form-read-value {
112
- min-width: 0;
113
- }
114
-
115
- input:not([type="checkbox"]):not([type="radio"]),
116
- .form-control-textarea,
117
- .form-read-value {
118
- box-sizing: border-box;
119
- min-width: 0;
120
- width: 100%;
121
- }
122
- }
123
73
  }
@@ -1,5 +1,4 @@
1
1
  export enum TypeInputEnum {
2
- ADDRESS = "address",
3
2
  TEXT = "text",
4
3
  BUTTON = "button",
5
4
  EMAIL = "email",
@@ -9,7 +8,7 @@ export enum TypeInputEnum {
9
8
  CHECKBOX = "checkbox",
10
9
  RADIO = "radio",
11
10
  DATE = "date",
11
+ DATERANGE = "daterange",
12
12
  SELECT = "select",
13
13
  TEXTAREA = "textarea",
14
- PRICE = "price",
15
14
  }
@@ -1,11 +1,4 @@
1
1
  import { TypeInputEnum } from "./form.enum";
2
- import { GridBreakpoints } from "../grid/grid.interface";
3
- import {
4
- GeocodedAddress,
5
- GeocodingProvider,
6
- } from "../geocoding/geocoding.interface";
7
-
8
- export type FormMode = "read" | "edit";
9
2
 
10
3
  export type FormValuesInterface<
11
4
  T extends { [key: string]: string | number | boolean | Date | string[] }
@@ -17,12 +10,6 @@ export interface FormCondition {
17
10
  regex: string;
18
11
  }
19
12
 
20
- export interface FormSection {
21
- title?: React.ReactNode;
22
- fields: FormInterface[];
23
- className?: string;
24
- }
25
-
26
13
  export interface FormInterface {
27
14
  value: string | number | boolean | Date;
28
15
  id?: string;
@@ -36,23 +23,10 @@ export interface FormInterface {
36
23
  condition?: FormCondition;
37
24
  icon?: string;
38
25
  multiple?: boolean;
26
+ usePortal?: boolean;
27
+ searchable?: boolean;
39
28
  options?: { value: string; label: string }[]; // <--- pour les <option>
40
29
  className?: string;
41
- col?: GridBreakpoints;
42
- addressSearch?: {
43
- minimumQueryLength?: number;
44
- debounceTime?: number;
45
- limit?: number;
46
- provider?: GeocodingProvider;
47
- manualEntryLabel?: string;
48
- mapAddress?: (
49
- address: GeocodedAddress,
50
- ) => Record<string, string | number | boolean | Date | string[]>;
51
- onSelect?: (address: GeocodedAddress) => void;
52
- };
53
- formatReadValue?: (
54
- value: string | number | boolean | Date | string[]
55
- ) => React.ReactNode;
56
30
  autoComplete?: string;
57
31
  step?: string;
58
32
  onChange?: (