kelt-ui-kit-react 1.2.8 → 1.3.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.
@@ -13,7 +13,7 @@ interface SearchProps {
13
13
  }
14
14
  interface FormData {
15
15
  recherche: string;
16
- [key: string]: string | number | boolean | Date;
16
+ [key: string]: string | number | boolean | Date | string[];
17
17
  }
18
18
  export declare const Search: import('react').ForwardRefExoticComponent<SearchProps & import('react').RefAttributes<{
19
19
  clearInput: (name: string) => void;
@@ -5,11 +5,13 @@ export interface SelectProps {
5
5
  label?: string;
6
6
  title?: string;
7
7
  disabled?: boolean;
8
- defaultValue?: string;
9
- value?: string;
8
+ defaultValue?: string | string[];
9
+ multiple?: boolean;
10
+ value?: string | string[];
10
11
  className?: string;
11
12
  options: SelectOptionInterface[];
13
+ onChangeMultiple?: (value: string[]) => void;
12
14
  onChange?: (value: string) => void;
13
15
  placeholder?: string;
14
16
  }
15
- export declare const Select: ({ id, label, options, className, disabled, defaultValue, onChange, value, placeholder, }: SelectProps) => JSX.Element;
17
+ export declare const Select: ({ id, label, options, className, disabled, multiple, defaultValue, onChange, onChangeMultiple, value, placeholder, }: SelectProps) => JSX.Element;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kelt-ui-kit-react",
3
3
  "type": "module",
4
- "version": "1.2.8",
4
+ "version": "1.3.0",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
package/src/form/Form.tsx CHANGED
@@ -7,11 +7,12 @@ import React, {
7
7
  } from "react";
8
8
  import { Button } from "../button/Button";
9
9
  import { Icon } from "../icon/Icon";
10
+ import { Select } from "../select/Select"; // <--- ton composant
10
11
  import "./form.css";
11
12
  import { FormInterface, FormValuesInterface } from "./form.interface";
12
13
 
13
14
  export type FormProps<
14
- T extends { [key: string]: string | number | boolean | Date }
15
+ T extends { [key: string]: string | number | boolean | Date | string[] }
15
16
  > = {
16
17
  className?: string;
17
18
  title?: string;
@@ -22,7 +23,7 @@ export type FormProps<
22
23
  };
23
24
 
24
25
  export const DynamicForm = forwardRef(
25
- <T extends { [key: string]: string | number | boolean | Date }>(
26
+ <T extends { [key: string]: string | number | boolean | Date | string[] }>(
26
27
  {
27
28
  initialForm,
28
29
  title,
@@ -48,27 +49,44 @@ export const DynamicForm = forwardRef(
48
49
  return initialValues;
49
50
  });
50
51
 
51
- // Stocker les références des inputs
52
52
  const inputRefs = useRef<{ [key: string]: HTMLInputElement | null }>({});
53
53
 
54
- const handleChange = useCallback(
54
+ /** Gestion des <input> */
55
+ const handleChangeInput = useCallback(
55
56
  (
56
57
  event: React.ChangeEvent<HTMLInputElement>,
57
58
  forminterface: FormInterface
58
59
  ) => {
59
- const { name, value, type, checked } = event.target;
60
+ const { name, type, checked, value } = event.target;
61
+ const newValue = type === "checkbox" ? checked : value;
62
+
60
63
  if (forminterface.onChange) {
61
- forminterface.onChange(value, name);
64
+ forminterface.onChange(newValue, name);
62
65
  }
66
+
63
67
  setValues((prevValues) => {
64
- const currentValues = prevValues || {};
65
- const updatedValues = {
66
- ...currentValues,
67
- [name]: type === "checkbox" ? checked : value,
68
- };
69
- if (onChange) {
70
- onChange(updatedValues);
71
- }
68
+ const updatedValues = { ...prevValues, [name]: newValue };
69
+ if (onChange) onChange(updatedValues);
70
+ return updatedValues;
71
+ });
72
+ },
73
+ [onChange]
74
+ );
75
+
76
+ /** Gestion des <select> */
77
+ const handleChangeSelect = useCallback(
78
+ (
79
+ newValue: string | string[],
80
+ name: string,
81
+ forminterface: FormInterface
82
+ ) => {
83
+ if (forminterface.onChange) {
84
+ forminterface.onChange(newValue, name);
85
+ }
86
+
87
+ setValues((prevValues) => {
88
+ const updatedValues = { ...prevValues, [name]: newValue };
89
+ if (onChange) onChange(updatedValues);
72
90
  return updatedValues;
73
91
  });
74
92
  },
@@ -103,7 +121,6 @@ export const DynamicForm = forwardRef(
103
121
  }));
104
122
  }, []);
105
123
 
106
- // Fonction pour donner le focus à l'élément qui devait initialement l'avoir
107
124
  const focusInitialElement = () => {
108
125
  const focusedField = initialForm.find((field) => field.focus);
109
126
  if (focusedField && inputRefs.current[focusedField.name]) {
@@ -112,7 +129,9 @@ export const DynamicForm = forwardRef(
112
129
  }, 500);
113
130
  }
114
131
  };
132
+
115
133
  const getValues = () => values;
134
+
116
135
  const updateFormValue: (values: FormValuesInterface<T>) => void = (
117
136
  values
118
137
  ) => {
@@ -121,6 +140,7 @@ export const DynamicForm = forwardRef(
121
140
  ...values,
122
141
  }));
123
142
  };
143
+
124
144
  useImperativeHandle(ref, () => ({
125
145
  resetForm,
126
146
  clearInput,
@@ -138,6 +158,7 @@ export const DynamicForm = forwardRef(
138
158
  const disabled = v.onDisabled
139
159
  ? v.onDisabled(v.value)
140
160
  : v.disabled ?? false;
161
+
141
162
  return (
142
163
  <div
143
164
  key={key}
@@ -146,24 +167,43 @@ export const DynamicForm = forwardRef(
146
167
  {v.label && <label>{v.label}</label>}
147
168
  {v.icon && <Icon classIcon={v.icon} />}
148
169
 
149
- <input
150
- ref={(el) => (inputRefs.current[v.name] = el)}
151
- name={v.name}
152
- type={v.type}
153
- placeholder={v.placeholder ?? ""}
154
- autoComplete={v.autoComplete ?? "on"}
155
- tabIndex={0}
156
- disabled={disabled}
157
- autoFocus={v.focus ?? false}
158
- required={required}
159
- step={v.step ?? "0.01"}
160
- value={values && (values[v.name] as string | number)}
161
- checked={v.type === "checkbox" ? !!values[v.name] : undefined}
162
- onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
163
- handleChange(e, v)
164
- }
165
- onInvalid={v.onInvalid ? v.onInvalid : undefined}
166
- />
170
+ {v.type === "select" ? (
171
+ <Select
172
+ id={v.name}
173
+ label={undefined}
174
+ options={v.options ?? []}
175
+ disabled={disabled}
176
+ multiple={v.multiple}
177
+ value={values[v.name] as any}
178
+ defaultValue={v.value as string | string[]}
179
+ placeholder={v.placeholder}
180
+ onChangeMultiple={(newValue) =>
181
+ handleChangeSelect(newValue, v.name, v)
182
+ }
183
+ onChange={(newValue) =>
184
+ handleChangeSelect(newValue, v.name, v)
185
+ }
186
+ />
187
+ ) : (
188
+ <input
189
+ ref={(el) => (inputRefs.current[v.name] = el)}
190
+ name={v.name}
191
+ type={v.type}
192
+ placeholder={v.placeholder ?? ""}
193
+ autoComplete={v.autoComplete ?? "on"}
194
+ tabIndex={0}
195
+ disabled={disabled}
196
+ autoFocus={v.focus ?? false}
197
+ required={required}
198
+ step={v.step ?? "0.01"}
199
+ value={values[v.name] as string | number}
200
+ checked={v.type === "checkbox" ? !!values[v.name] : undefined}
201
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
202
+ handleChangeInput(e, v)
203
+ }
204
+ onInvalid={v.onInvalid ? v.onInvalid : undefined}
205
+ />
206
+ )}
167
207
  </div>
168
208
  );
169
209
  })}
@@ -7,7 +7,7 @@ interface FormData {
7
7
  age: number;
8
8
  validate: boolean;
9
9
  password: string;
10
- [key: string]: string | number | boolean | Date; // Signature d'index ajoutée
10
+ [key: string]: string | number | boolean | Date | string[]; // Signature d'index ajoutée
11
11
  }
12
12
  export const FormView = (): JSX.Element => {
13
13
  const initialValues: FormInterface[] = [
@@ -8,4 +8,5 @@ export enum TypeInputEnum {
8
8
  CHECKBOX = "checkbox",
9
9
  RADIO = "radio",
10
10
  DATE = "date",
11
+ SELECT = "select",
11
12
  }
@@ -1,7 +1,7 @@
1
1
  import { TypeInputEnum } from "./form.enum";
2
2
 
3
3
  export type FormValuesInterface<
4
- T extends { [key: string]: string | number | boolean | Date }
4
+ T extends { [key: string]: string | number | boolean | Date | string[] }
5
5
  > = Partial<{
6
6
  [K in keyof T]: T[K];
7
7
  }>;
@@ -22,10 +22,15 @@ export interface FormInterface {
22
22
  required?: boolean;
23
23
  condition?: FormCondition;
24
24
  icon?: string;
25
+ multiple?: boolean;
26
+ options?: { value: string; label: string }[]; // <--- pour les <option>
25
27
  className?: string;
26
28
  autoComplete?: autoCompleteType;
27
29
  step?: string;
28
- onChange?: (value: string | number | boolean | Date, name?: string) => void;
30
+ onChange?: (
31
+ value: string | number | boolean | Date | string[],
32
+ name?: string
33
+ ) => void;
29
34
  onRequired?: (value: string | number | boolean | Date) => boolean;
30
35
  onDisabled?: (value: string | number | boolean | Date) => boolean;
31
36
  onInvalid?: (e: React.ChangeEvent<HTMLInputElement>) => void;
@@ -27,7 +27,7 @@ interface SearchProps {
27
27
 
28
28
  interface FormData {
29
29
  recherche: string;
30
- [key: string]: string | number | boolean | Date;
30
+ [key: string]: string | number | boolean | Date | string[]; // Signature d'index ajoutée
31
31
  }
32
32
 
33
33
  export const Search = forwardRef<
@@ -2,7 +2,7 @@ import { FormValuesInterface } from "../form/form.interface";
2
2
  import { Search } from "./Search";
3
3
  interface FormData {
4
4
  recherche: string;
5
- [key: string]: string | number | boolean | Date; // Signature d'index ajoutée
5
+ [key: string]: string | number | boolean | Date | string[]; // Signature d'index ajoutée
6
6
  }
7
7
  export const SearchView = (): JSX.Element => {
8
8
  const onChange = (values: FormValuesInterface<FormData>) => {
@@ -1,14 +1,18 @@
1
+ import { useRef } from "react";
1
2
  import "./select.css";
2
3
  import { SelectOptionInterface } from "./selectOption.interface";
4
+
3
5
  export interface SelectProps {
4
6
  id?: string;
5
7
  label?: string;
6
8
  title?: string;
7
9
  disabled?: boolean;
8
- defaultValue?: string;
9
- value?: string;
10
+ defaultValue?: string | string[];
11
+ multiple?: boolean;
12
+ value?: string | string[];
10
13
  className?: string;
11
14
  options: SelectOptionInterface[];
15
+ onChangeMultiple?: (value: string[]) => void;
12
16
  onChange?: (value: string) => void;
13
17
  placeholder?: string;
14
18
  }
@@ -19,27 +23,45 @@ export const Select = ({
19
23
  options,
20
24
  className,
21
25
  disabled,
26
+ multiple = false,
22
27
  defaultValue,
23
28
  onChange,
29
+ onChangeMultiple,
24
30
  value,
25
31
  placeholder,
26
32
  }: SelectProps): JSX.Element => {
33
+ const inputRefs = useRef<{ [key: string]: HTMLSelectElement | null }>({});
34
+
27
35
  const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
28
- const selectedValue = event.target.value;
29
- if (onChange) {
30
- onChange(selectedValue);
36
+ let selectedValue: string | string[];
37
+ if (multiple) {
38
+ selectedValue = Array.from(
39
+ event.target.selectedOptions,
40
+ (opt) => opt.value
41
+ );
42
+ if (onChangeMultiple) {
43
+ onChangeMultiple(selectedValue as string[]);
44
+ }
45
+ } else {
46
+ selectedValue = event.target.value;
47
+ if (onChange) {
48
+ onChange(selectedValue);
49
+ }
31
50
  }
32
51
  };
52
+
33
53
  return (
34
54
  <div id={id} className={`select-container ${className ? className : ""}`}>
35
55
  {label && <label className="select-container-label">{label}</label>}
36
56
  <select
37
57
  disabled={disabled}
38
58
  className="select-container-select"
39
- value={value ?? defaultValue ?? ""}
59
+ value={value ?? defaultValue ?? (multiple ? [] : "")}
40
60
  onChange={handleChange}
61
+ multiple={multiple}
62
+ ref={(el) => (inputRefs.current[id ?? "select"] = el)}
41
63
  >
42
- {placeholder && !defaultValue && (
64
+ {placeholder && !defaultValue && !multiple && (
43
65
  <option value="">{placeholder}</option>
44
66
  )}
45
67
  {options.map((option, index) => (