odaptos_design_system 2.0.72 → 2.0.73
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/dist/Organisms/MultiSelect/MultiSelect.d.ts +2 -8
- package/dist/Organisms/SingleSelect/SingleSelect.d.ts +2 -8
- package/dist/odaptos_design_system.cjs.development.js +7 -91
- package/dist/odaptos_design_system.cjs.development.js.map +1 -1
- package/dist/odaptos_design_system.cjs.production.min.js +1 -1
- package/dist/odaptos_design_system.cjs.production.min.js.map +1 -1
- package/dist/odaptos_design_system.esm.js +9 -93
- package/dist/odaptos_design_system.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/Organisms/MultiSelect/MultiSelect.tsx +8 -73
- package/src/Organisms/SingleSelect/SingleSelect.tsx +4 -71
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import React, { useEffect, useState, useCallback, useRef } from 'react';
|
|
2
1
|
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
|
|
3
|
-
import { TextField
|
|
2
|
+
import { TextField } from '@mui/material';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
import React, { useEffect, useState } from 'react';
|
|
4
5
|
import {
|
|
5
6
|
Checkbox,
|
|
6
7
|
TextForButton,
|
|
@@ -11,7 +12,6 @@ import {
|
|
|
11
12
|
RemoveCircledIcon,
|
|
12
13
|
} from '../../';
|
|
13
14
|
import styles from './MultiSelect.modules.scss';
|
|
14
|
-
import { styled } from '@mui/material/styles';
|
|
15
15
|
|
|
16
16
|
interface OptionType {
|
|
17
17
|
label: string;
|
|
@@ -114,15 +114,6 @@ const CssTextField = styled(TextField)({
|
|
|
114
114
|
},
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
-
// Fonction utilitaire de debounce
|
|
118
|
-
const debounce = (func: Function, delay: number) => {
|
|
119
|
-
let timeoutId: NodeJS.Timeout;
|
|
120
|
-
return (...args: any[]) => {
|
|
121
|
-
clearTimeout(timeoutId);
|
|
122
|
-
timeoutId = setTimeout(() => func(...args), delay);
|
|
123
|
-
};
|
|
124
|
-
};
|
|
125
|
-
|
|
126
117
|
interface MultiSelectProps {
|
|
127
118
|
label: string;
|
|
128
119
|
placeholder?: string;
|
|
@@ -136,7 +127,7 @@ interface MultiSelectProps {
|
|
|
136
127
|
disabled?: boolean;
|
|
137
128
|
required?: boolean;
|
|
138
129
|
defaultValue: any[];
|
|
139
|
-
options:
|
|
130
|
+
options: any[];
|
|
140
131
|
error?: boolean;
|
|
141
132
|
helperText?: string;
|
|
142
133
|
errorText?: string;
|
|
@@ -146,17 +137,13 @@ interface MultiSelectProps {
|
|
|
146
137
|
deleteOption: (value: any) => void;
|
|
147
138
|
limitTags?: number;
|
|
148
139
|
onBlur?: () => void;
|
|
149
|
-
loadMoreOptions?: () => Promise<OptionType[]>;
|
|
150
|
-
initialLoadCount?: number;
|
|
151
140
|
}
|
|
152
141
|
|
|
153
142
|
/**
|
|
154
143
|
* Use this component for multiselection !!
|
|
155
144
|
*/
|
|
156
145
|
export const MultiSelect = ({
|
|
157
|
-
options
|
|
158
|
-
loadMoreOptions,
|
|
159
|
-
initialLoadCount = 50,
|
|
146
|
+
options,
|
|
160
147
|
label,
|
|
161
148
|
placeholder,
|
|
162
149
|
name,
|
|
@@ -180,47 +167,11 @@ export const MultiSelect = ({
|
|
|
180
167
|
onBlur,
|
|
181
168
|
...props
|
|
182
169
|
}: MultiSelectProps) => {
|
|
183
|
-
const [options, setOptions] = useState<OptionType[]>(
|
|
184
|
-
initialOptions.slice(0, initialLoadCount)
|
|
185
|
-
);
|
|
186
|
-
const [loading, setLoading] = useState(false);
|
|
187
|
-
const [hasMore, setHasMore] = useState(
|
|
188
|
-
initialOptions.length > initialLoadCount
|
|
189
|
-
);
|
|
190
170
|
const [value, setValue] = useState(
|
|
191
171
|
defaultValue === undefined ? [] : defaultValue
|
|
192
172
|
);
|
|
193
173
|
const [inputValue, setInputValue] = React.useState('');
|
|
194
174
|
|
|
195
|
-
const loadMore = useCallback(async () => {
|
|
196
|
-
if (loading || !hasMore) return;
|
|
197
|
-
setLoading(true);
|
|
198
|
-
if (loadMoreOptions) {
|
|
199
|
-
const newOptions = await loadMoreOptions();
|
|
200
|
-
setOptions((prevOptions) => [...prevOptions, ...newOptions]);
|
|
201
|
-
setHasMore(newOptions.length > 0);
|
|
202
|
-
} else {
|
|
203
|
-
const currentLength = options.length;
|
|
204
|
-
const nextOptions = initialOptions.slice(
|
|
205
|
-
currentLength,
|
|
206
|
-
currentLength + initialLoadCount
|
|
207
|
-
);
|
|
208
|
-
setOptions((prevOptions) => [...prevOptions, ...nextOptions]);
|
|
209
|
-
setHasMore(currentLength + nextOptions.length < initialOptions.length);
|
|
210
|
-
}
|
|
211
|
-
setLoading(false);
|
|
212
|
-
}, [
|
|
213
|
-
loading,
|
|
214
|
-
hasMore,
|
|
215
|
-
loadMoreOptions,
|
|
216
|
-
initialOptions,
|
|
217
|
-
options.length,
|
|
218
|
-
initialLoadCount,
|
|
219
|
-
]);
|
|
220
|
-
|
|
221
|
-
// Création d'une version debounced de loadMore
|
|
222
|
-
const debouncedLoadMore = useRef(debounce(loadMore, 300)).current;
|
|
223
|
-
|
|
224
175
|
useEffect(() => {
|
|
225
176
|
setValue(defaultValue === undefined ? [] : defaultValue);
|
|
226
177
|
}, [defaultValue]);
|
|
@@ -249,7 +200,9 @@ export const MultiSelect = ({
|
|
|
249
200
|
setValue(newValue);
|
|
250
201
|
onChange(newValue);
|
|
251
202
|
}}
|
|
252
|
-
options={
|
|
203
|
+
options={
|
|
204
|
+
options ? options : [{ label: 'Loading...', value: 0, year: 100 }]
|
|
205
|
+
}
|
|
253
206
|
multiple={true}
|
|
254
207
|
autoComplete={options.length > 10}
|
|
255
208
|
size="small"
|
|
@@ -300,13 +253,6 @@ export const MultiSelect = ({
|
|
|
300
253
|
);
|
|
301
254
|
}}
|
|
302
255
|
renderOption={(props, option, { selected }) => {
|
|
303
|
-
if (option.value === 'load-more') {
|
|
304
|
-
return (
|
|
305
|
-
<ListSubheader key="load-more" component="div">
|
|
306
|
-
{loading ? 'Chargement...' : 'Charger plus'}
|
|
307
|
-
</ListSubheader>
|
|
308
|
-
);
|
|
309
|
-
}
|
|
310
256
|
return (
|
|
311
257
|
<li
|
|
312
258
|
{...props}
|
|
@@ -343,17 +289,6 @@ export const MultiSelect = ({
|
|
|
343
289
|
}
|
|
344
290
|
return filtered;
|
|
345
291
|
}}
|
|
346
|
-
ListboxProps={{
|
|
347
|
-
onScroll: (event: React.UIEvent<HTMLUListElement>) => {
|
|
348
|
-
const listboxNode = event.currentTarget;
|
|
349
|
-
if (
|
|
350
|
-
listboxNode.scrollTop + listboxNode.clientHeight >=
|
|
351
|
-
listboxNode.scrollHeight - 50
|
|
352
|
-
) {
|
|
353
|
-
debouncedLoadMore();
|
|
354
|
-
}
|
|
355
|
-
},
|
|
356
|
-
}}
|
|
357
292
|
{...props}
|
|
358
293
|
/>
|
|
359
294
|
{errorText && (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
|
|
2
|
-
import { TextField
|
|
2
|
+
import { TextField } from '@mui/material';
|
|
3
3
|
import { styled } from '@mui/material/styles';
|
|
4
|
-
import React, { useEffect, useState
|
|
4
|
+
import React, { useEffect, useState } from 'react';
|
|
5
5
|
import {
|
|
6
6
|
Text,
|
|
7
7
|
TextForButton,
|
|
@@ -11,15 +11,6 @@ import {
|
|
|
11
11
|
} from '../../';
|
|
12
12
|
import styles from './SingleSelect.modules.scss';
|
|
13
13
|
|
|
14
|
-
// Fonction utilitaire de debounce
|
|
15
|
-
const debounce = (func: Function, delay: number) => {
|
|
16
|
-
let timeoutId: NodeJS.Timeout;
|
|
17
|
-
return (...args: any[]) => {
|
|
18
|
-
clearTimeout(timeoutId);
|
|
19
|
-
timeoutId = setTimeout(() => func(...args), delay);
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
|
|
23
14
|
interface OptionType {
|
|
24
15
|
label: string;
|
|
25
16
|
value: string;
|
|
@@ -131,20 +122,16 @@ interface SingleSelectProps {
|
|
|
131
122
|
errorText?: string;
|
|
132
123
|
canAddNewOption?: boolean;
|
|
133
124
|
defaultValue: any;
|
|
134
|
-
options:
|
|
125
|
+
options: any[];
|
|
135
126
|
onChange: (value: any) => void;
|
|
136
127
|
onBlur?: () => void;
|
|
137
|
-
loadMoreOptions?: () => Promise<OptionType[]>;
|
|
138
|
-
initialLoadCount?: number;
|
|
139
128
|
}
|
|
140
129
|
|
|
141
130
|
/**
|
|
142
131
|
* Use this component for single selection !!
|
|
143
132
|
*/
|
|
144
133
|
export const SingleSelect = ({
|
|
145
|
-
options
|
|
146
|
-
loadMoreOptions,
|
|
147
|
-
initialLoadCount = 50,
|
|
134
|
+
options,
|
|
148
135
|
label,
|
|
149
136
|
placeholder,
|
|
150
137
|
name,
|
|
@@ -169,47 +156,11 @@ export const SingleSelect = ({
|
|
|
169
156
|
defaultValue === undefined ? null : defaultValue
|
|
170
157
|
);
|
|
171
158
|
const [inputValue, setInputValue] = React.useState('');
|
|
172
|
-
const [options, setOptions] = useState<OptionType[]>(
|
|
173
|
-
initialOptions.slice(0, initialLoadCount)
|
|
174
|
-
);
|
|
175
|
-
const [loading, setLoading] = useState(false);
|
|
176
|
-
const [hasMore, setHasMore] = useState(
|
|
177
|
-
initialOptions.length > initialLoadCount
|
|
178
|
-
);
|
|
179
159
|
|
|
180
160
|
useEffect(() => {
|
|
181
161
|
setValue(defaultValue === undefined ? null : defaultValue);
|
|
182
162
|
}, [defaultValue]);
|
|
183
163
|
|
|
184
|
-
const loadMore = useCallback(async () => {
|
|
185
|
-
if (loading || !hasMore) return;
|
|
186
|
-
setLoading(true);
|
|
187
|
-
if (loadMoreOptions) {
|
|
188
|
-
const newOptions = await loadMoreOptions();
|
|
189
|
-
setOptions((prevOptions) => [...prevOptions, ...newOptions]);
|
|
190
|
-
setHasMore(newOptions.length > 0);
|
|
191
|
-
} else {
|
|
192
|
-
const currentLength = options.length;
|
|
193
|
-
const nextOptions = initialOptions.slice(
|
|
194
|
-
currentLength,
|
|
195
|
-
currentLength + initialLoadCount
|
|
196
|
-
);
|
|
197
|
-
setOptions((prevOptions) => [...prevOptions, ...nextOptions]);
|
|
198
|
-
setHasMore(currentLength + nextOptions.length < initialOptions.length);
|
|
199
|
-
}
|
|
200
|
-
setLoading(false);
|
|
201
|
-
}, [
|
|
202
|
-
loading,
|
|
203
|
-
hasMore,
|
|
204
|
-
loadMoreOptions,
|
|
205
|
-
initialOptions,
|
|
206
|
-
options.length,
|
|
207
|
-
initialLoadCount,
|
|
208
|
-
]);
|
|
209
|
-
|
|
210
|
-
// Création d'une version debounced de loadMore
|
|
211
|
-
const debouncedLoadMore = useRef(debounce(loadMore, 300)).current;
|
|
212
|
-
|
|
213
164
|
return (
|
|
214
165
|
<div
|
|
215
166
|
className={`${className && className}`}
|
|
@@ -275,30 +226,12 @@ export const SingleSelect = ({
|
|
|
275
226
|
}
|
|
276
227
|
className={`${styles.newAutocomplete}`}
|
|
277
228
|
renderOption={(props, option) => {
|
|
278
|
-
if (option.value === 'load-more') {
|
|
279
|
-
return (
|
|
280
|
-
<ListSubheader key="load-more" component="div">
|
|
281
|
-
{loading ? 'Chargement...' : 'Charger plus'}
|
|
282
|
-
</ListSubheader>
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
229
|
return (
|
|
286
230
|
<li {...props} key={option.value} id={option.value}>
|
|
287
231
|
<TextForButton text={option.label} size="sm" />
|
|
288
232
|
</li>
|
|
289
233
|
);
|
|
290
234
|
}}
|
|
291
|
-
ListboxProps={{
|
|
292
|
-
onScroll: (event: React.UIEvent<HTMLUListElement>) => {
|
|
293
|
-
const listboxNode = event.currentTarget;
|
|
294
|
-
if (
|
|
295
|
-
listboxNode.scrollTop + listboxNode.clientHeight >=
|
|
296
|
-
listboxNode.scrollHeight - 50
|
|
297
|
-
) {
|
|
298
|
-
debouncedLoadMore();
|
|
299
|
-
}
|
|
300
|
-
},
|
|
301
|
-
}}
|
|
302
235
|
filterOptions={(options, params) => {
|
|
303
236
|
const filtered = filter(options, params);
|
|
304
237
|
|