react-core-ts 2.0.5 → 2.0.6
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/ReactAutoComplete.d.ts +4 -4
- package/dist/ReactAutoComplete.js +118 -101
- package/dist/ReactAutoComplete.js.map +1 -1
- package/package.json +1 -1
- package/src/ReactAutoComplete.tsx +144 -127
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useRef, useState } from
|
|
2
|
-
import { FieldErrors } from
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { FieldErrors } from 'react-hook-form';
|
|
3
3
|
|
|
4
|
-
import CustomIcons from
|
|
5
|
-
import Spinner from
|
|
6
|
-
import Portal from
|
|
7
|
-
import { debounce } from
|
|
8
|
-
import { applyPositionClass } from
|
|
9
|
-
import { DropArrow } from
|
|
4
|
+
import CustomIcons from './components/customIcons';
|
|
5
|
+
import Spinner from './components/loader/Spinner';
|
|
6
|
+
import Portal from './components/portal';
|
|
7
|
+
import { debounce } from './utilities/debounce';
|
|
8
|
+
import { applyPositionClass } from './utilities/getPosition';
|
|
9
|
+
import { DropArrow } from './utilities/icons';
|
|
10
10
|
|
|
11
11
|
type valueProps = {
|
|
12
12
|
id?: string | number;
|
|
@@ -31,7 +31,7 @@ interface AutoSuggestionInputProps {
|
|
|
31
31
|
value?: valueProps;
|
|
32
32
|
onChange: (value?: valueProps) => void;
|
|
33
33
|
data?: any[];
|
|
34
|
-
type?:
|
|
34
|
+
type?: 'custom_select' | 'auto_complete' | 'custom_search_select';
|
|
35
35
|
placeholder?: string;
|
|
36
36
|
getData?: ((key?: string) => Promise<any>) | ((key?: string) => any);
|
|
37
37
|
errors?: FieldErrors;
|
|
@@ -51,7 +51,7 @@ interface AutoSuggestionInputProps {
|
|
|
51
51
|
width?: number;
|
|
52
52
|
labelTitle?: string;
|
|
53
53
|
isModern?: boolean;
|
|
54
|
-
size?:
|
|
54
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xxs';
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
@@ -64,13 +64,13 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
64
64
|
required = false,
|
|
65
65
|
autoFocus,
|
|
66
66
|
name,
|
|
67
|
-
shortCode =
|
|
68
|
-
labelCode =
|
|
67
|
+
shortCode = '',
|
|
68
|
+
labelCode = '',
|
|
69
69
|
fullWidth,
|
|
70
70
|
placeholder,
|
|
71
71
|
id,
|
|
72
72
|
className: propsClassName,
|
|
73
|
-
type =
|
|
73
|
+
type = 'custom_select',
|
|
74
74
|
readOnly,
|
|
75
75
|
disabled = false,
|
|
76
76
|
value,
|
|
@@ -86,9 +86,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
86
86
|
fromPrefix,
|
|
87
87
|
labelTitle,
|
|
88
88
|
isModern = true,
|
|
89
|
-
size =
|
|
89
|
+
size = 'md',
|
|
90
90
|
}) => {
|
|
91
|
-
const [inputValue, setInputValue] = useState<any>(value?.name ??
|
|
91
|
+
const [inputValue, setInputValue] = useState<any>(value?.name ?? '');
|
|
92
92
|
const [isHovered, setIsHovered] = useState<boolean>(false);
|
|
93
93
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
94
94
|
const [dropOpen, setDropOpen] = useState<boolean>(false);
|
|
@@ -126,8 +126,8 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
126
126
|
) => {
|
|
127
127
|
return substring &&
|
|
128
128
|
mainString &&
|
|
129
|
-
typeof mainString ===
|
|
130
|
-
typeof subString ===
|
|
129
|
+
typeof mainString === 'string' &&
|
|
130
|
+
typeof subString === 'string'
|
|
131
131
|
? mainString
|
|
132
132
|
.toString()
|
|
133
133
|
.toLowerCase()
|
|
@@ -142,23 +142,23 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
142
142
|
return (
|
|
143
143
|
checkIncludesIfExists(mainString, subString) ||
|
|
144
144
|
(!!checkParams &&
|
|
145
|
-
((checkArrayContains(checkParams,
|
|
145
|
+
((checkArrayContains(checkParams, 'param1') &&
|
|
146
146
|
checkIncludesIfExists(param1, subString)) ||
|
|
147
|
-
(checkArrayContains(checkParams,
|
|
147
|
+
(checkArrayContains(checkParams, 'param2') &&
|
|
148
148
|
checkIncludesIfExists(param2, subString)) ||
|
|
149
|
-
(checkArrayContains(checkParams,
|
|
149
|
+
(checkArrayContains(checkParams, 'param3') &&
|
|
150
150
|
checkIncludesIfExists(param3, subString)) ||
|
|
151
|
-
(checkArrayContains(checkParams,
|
|
151
|
+
(checkArrayContains(checkParams, 'param4') &&
|
|
152
152
|
checkIncludesIfExists(param4, subString))))
|
|
153
153
|
);
|
|
154
154
|
};
|
|
155
155
|
|
|
156
156
|
const getHeight = () => {
|
|
157
157
|
switch (size) {
|
|
158
|
-
case
|
|
159
|
-
return
|
|
158
|
+
case 'sm':
|
|
159
|
+
return ' h-[34px] ';
|
|
160
160
|
default:
|
|
161
|
-
return
|
|
161
|
+
return ' ';
|
|
162
162
|
}
|
|
163
163
|
};
|
|
164
164
|
|
|
@@ -169,8 +169,8 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
169
169
|
setInputValue(value);
|
|
170
170
|
handleValChange(value);
|
|
171
171
|
if (!value) {
|
|
172
|
-
setInputValue(
|
|
173
|
-
onChange({ id: undefined, name:
|
|
172
|
+
setInputValue('');
|
|
173
|
+
onChange({ id: undefined, name: '', from: 2 });
|
|
174
174
|
}
|
|
175
175
|
};
|
|
176
176
|
|
|
@@ -178,11 +178,11 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
178
178
|
debounce(
|
|
179
179
|
(value: string) => {
|
|
180
180
|
setDropOpen(true);
|
|
181
|
-
onChange({ id: undefined, name:
|
|
182
|
-
if (value.trim() ===
|
|
181
|
+
onChange({ id: undefined, name: '', from: 1 });
|
|
182
|
+
if (value.trim() === '' && type === 'auto_complete') {
|
|
183
183
|
setSuggestions([]);
|
|
184
184
|
if (autoFilter) {
|
|
185
|
-
handleDropData(
|
|
185
|
+
handleDropData('*');
|
|
186
186
|
} else {
|
|
187
187
|
setDropOpen(false);
|
|
188
188
|
}
|
|
@@ -198,11 +198,11 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
198
198
|
[]
|
|
199
199
|
);
|
|
200
200
|
const handleDropData = (value?: string) => {
|
|
201
|
-
if (type ===
|
|
201
|
+
if (type === 'auto_complete') {
|
|
202
202
|
if (isStaticList) {
|
|
203
203
|
loadStaticData();
|
|
204
204
|
const filteredData =
|
|
205
|
-
value && value !==
|
|
205
|
+
value && value !== '*'
|
|
206
206
|
? data?.filter((item) =>
|
|
207
207
|
checkIncludes(
|
|
208
208
|
item.name,
|
|
@@ -216,13 +216,13 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
216
216
|
setSuggestions(filteredData);
|
|
217
217
|
} else handlePickSuggestions(value);
|
|
218
218
|
} else if (
|
|
219
|
-
(type ===
|
|
219
|
+
(type === 'custom_select' || type === 'custom_search_select') &&
|
|
220
220
|
(!data || data?.length === 0)
|
|
221
221
|
) {
|
|
222
222
|
handlePickSuggestions();
|
|
223
|
-
} else if (type ===
|
|
223
|
+
} else if (type === 'custom_search_select' && data && data?.length > 0) {
|
|
224
224
|
const filteredData =
|
|
225
|
-
value && value !==
|
|
225
|
+
value && value !== '*'
|
|
226
226
|
? data.filter((item) =>
|
|
227
227
|
checkIncludes(
|
|
228
228
|
item.name,
|
|
@@ -252,10 +252,10 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
252
252
|
const onLabelClick = () => {
|
|
253
253
|
if (!isDisabled) {
|
|
254
254
|
inputRef?.current?.focus();
|
|
255
|
-
if (autoFilter && inputValue ===
|
|
256
|
-
handleValChange(
|
|
255
|
+
if (autoFilter && inputValue === '') {
|
|
256
|
+
handleValChange('*');
|
|
257
257
|
} else if (
|
|
258
|
-
(type ===
|
|
258
|
+
(type === 'custom_select' || type === 'custom_search_select') &&
|
|
259
259
|
data &&
|
|
260
260
|
data?.length > 0
|
|
261
261
|
) {
|
|
@@ -265,9 +265,17 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
265
265
|
}
|
|
266
266
|
};
|
|
267
267
|
const handleClickOutside = (event: MouseEvent) => {
|
|
268
|
+
const target = event.target as Node;
|
|
269
|
+
const dropButton = document.getElementById('autocomplete-drop-icon');
|
|
270
|
+
const closeButton = document.getElementById('autocomplete-close-icon');
|
|
271
|
+
|
|
268
272
|
if (
|
|
269
273
|
dropdownref.current &&
|
|
270
|
-
!dropdownref.current.contains(
|
|
274
|
+
!dropdownref.current.contains(target) &&
|
|
275
|
+
target !== dropButton &&
|
|
276
|
+
!dropButton?.contains(target) &&
|
|
277
|
+
target !== closeButton &&
|
|
278
|
+
!closeButton?.contains(target)
|
|
271
279
|
) {
|
|
272
280
|
setDropOpen(false);
|
|
273
281
|
}
|
|
@@ -282,8 +290,8 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
282
290
|
if (getData) {
|
|
283
291
|
try {
|
|
284
292
|
setIsLoading(true);
|
|
285
|
-
handlePickSuggestions(
|
|
286
|
-
const fetchedSuggestions = await getData?.(
|
|
293
|
+
handlePickSuggestions('*');
|
|
294
|
+
const fetchedSuggestions = await getData?.('*');
|
|
287
295
|
fetchedSuggestions?.forEach((element: any) => {
|
|
288
296
|
data?.push(element);
|
|
289
297
|
});
|
|
@@ -295,9 +303,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
295
303
|
}
|
|
296
304
|
};
|
|
297
305
|
useEffect(() => {
|
|
298
|
-
document.addEventListener(
|
|
306
|
+
document.addEventListener('click', handleClickOutside);
|
|
299
307
|
return () => {
|
|
300
|
-
document.removeEventListener(
|
|
308
|
+
document.removeEventListener('click', handleClickOutside);
|
|
301
309
|
};
|
|
302
310
|
}, []);
|
|
303
311
|
|
|
@@ -308,10 +316,10 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
308
316
|
}, [autoFocus]);
|
|
309
317
|
const onInputFocus = () => {
|
|
310
318
|
if (!isDisabled) {
|
|
311
|
-
if (autoFilter && inputValue ===
|
|
312
|
-
handleValChange(
|
|
319
|
+
if (autoFilter && inputValue === '') {
|
|
320
|
+
handleValChange('*');
|
|
313
321
|
} else if (
|
|
314
|
-
(type ===
|
|
322
|
+
(type === 'custom_select' || type === 'custom_search_select') &&
|
|
315
323
|
data &&
|
|
316
324
|
data?.length > 0
|
|
317
325
|
) {
|
|
@@ -330,18 +338,22 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
330
338
|
name: suggestion.name,
|
|
331
339
|
...(suggestion?.label ? { label: suggestion?.label } : {}),
|
|
332
340
|
});
|
|
333
|
-
if (type !==
|
|
341
|
+
if (type !== 'custom_select') setInputValue(suggestion.name);
|
|
334
342
|
setDropOpen(false);
|
|
335
343
|
setSelectedIndex(index);
|
|
336
344
|
};
|
|
337
345
|
const handleOpen = (e: any) => {
|
|
346
|
+
if (e) {
|
|
347
|
+
e.preventDefault();
|
|
348
|
+
e.stopPropagation();
|
|
349
|
+
}
|
|
338
350
|
if (!suggestions || suggestions?.length === 0) {
|
|
339
351
|
handleDropData();
|
|
340
352
|
return;
|
|
341
353
|
}
|
|
342
354
|
if (!isLoading) {
|
|
343
355
|
setDropOpen(!dropOpen);
|
|
344
|
-
if (type !==
|
|
356
|
+
if (type !== 'custom_select') setInputValue('');
|
|
345
357
|
}
|
|
346
358
|
};
|
|
347
359
|
|
|
@@ -352,28 +364,28 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
352
364
|
useEffect(() => {
|
|
353
365
|
if (!insideOpen) {
|
|
354
366
|
setSelectedIndex(0);
|
|
355
|
-
window.addEventListener(
|
|
367
|
+
window.addEventListener('scroll', handleScroll);
|
|
356
368
|
|
|
357
|
-
const mainElement = document.querySelector(
|
|
358
|
-
mainElement?.addEventListener(
|
|
369
|
+
const mainElement = document.querySelector('main');
|
|
370
|
+
mainElement?.addEventListener('scroll', handleScroll);
|
|
359
371
|
|
|
360
372
|
const gridElements = document.querySelectorAll(
|
|
361
|
-
|
|
373
|
+
'.k-grid-content, .overflow-auto, .overflow-y-auto, .overflow-x-auto'
|
|
362
374
|
);
|
|
363
375
|
gridElements.forEach((gridElement: any) => {
|
|
364
|
-
gridElement.addEventListener(
|
|
376
|
+
gridElement.addEventListener('scroll', handleScroll);
|
|
365
377
|
});
|
|
366
378
|
|
|
367
|
-
window.addEventListener(
|
|
379
|
+
window.addEventListener('resize', getDropPosition);
|
|
368
380
|
getDropPosition();
|
|
369
381
|
return () => {
|
|
370
|
-
window.removeEventListener(
|
|
371
|
-
const mainElement = document.querySelector(
|
|
372
|
-
mainElement?.removeEventListener(
|
|
373
|
-
window.addEventListener(
|
|
374
|
-
const gridElements = document.querySelectorAll(
|
|
382
|
+
window.removeEventListener('scroll', handleScroll);
|
|
383
|
+
const mainElement = document.querySelector('main');
|
|
384
|
+
mainElement?.removeEventListener('scroll', handleScroll);
|
|
385
|
+
window.addEventListener('resize', getDropPosition);
|
|
386
|
+
const gridElements = document.querySelectorAll('.k-grid-content');
|
|
375
387
|
gridElements.forEach((gridElement: any) => {
|
|
376
|
-
gridElement.removeEventListener(
|
|
388
|
+
gridElement.removeEventListener('scroll', handleScroll);
|
|
377
389
|
});
|
|
378
390
|
};
|
|
379
391
|
}
|
|
@@ -381,13 +393,13 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
381
393
|
|
|
382
394
|
const handleClear = () => {
|
|
383
395
|
setDropOpen(false);
|
|
384
|
-
setInputValue(
|
|
385
|
-
onChange({ id: undefined, name:
|
|
396
|
+
setInputValue('');
|
|
397
|
+
onChange({ id: undefined, name: '', from: 3 });
|
|
386
398
|
onLabelClick();
|
|
387
399
|
};
|
|
388
400
|
|
|
389
401
|
useEffect(() => {
|
|
390
|
-
setInputValue(value?.name ??
|
|
402
|
+
setInputValue(value?.name ?? '');
|
|
391
403
|
}, [value?.name]);
|
|
392
404
|
|
|
393
405
|
useEffect(() => {
|
|
@@ -395,7 +407,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
395
407
|
}, [data]);
|
|
396
408
|
|
|
397
409
|
const getErrors = (err: any) => {
|
|
398
|
-
let errMsg =
|
|
410
|
+
let errMsg = '';
|
|
399
411
|
if (err.message) {
|
|
400
412
|
errMsg = err?.message;
|
|
401
413
|
} else if (err?.id?.message) {
|
|
@@ -406,61 +418,61 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
406
418
|
return errMsg;
|
|
407
419
|
};
|
|
408
420
|
const generateClassName = (
|
|
409
|
-
type:
|
|
421
|
+
type: 'input' | 'label' | 'message' | 'adorement'
|
|
410
422
|
): string => {
|
|
411
423
|
let className = propsClassName;
|
|
412
424
|
switch (type) {
|
|
413
|
-
case
|
|
425
|
+
case 'input':
|
|
414
426
|
className += ` block text-common text-input-text font-normal px-3.5 w-full text-sm text-gray-900 bg-transparent border appearance-none peer h-10 rounded-[4px] disabled:text-input-disabled bg-white disabled:bg-disabled ${
|
|
415
427
|
label && isModern
|
|
416
|
-
?
|
|
417
|
-
:
|
|
428
|
+
? 'placeholder-transparent'
|
|
429
|
+
: 'focus:placeholder-grey-secondary placeholder-input-label'
|
|
418
430
|
} focus:placeholder-grey-secondary`;
|
|
419
431
|
|
|
420
432
|
if (errors && errors[name]) {
|
|
421
433
|
className +=
|
|
422
|
-
|
|
434
|
+
' border-[#FDA29B] focus:border-error-[#FDA29B] focus:ring-[#FDA29B] focus:ring-3 focus:outline-[#FDA29B] input-outline';
|
|
423
435
|
} else {
|
|
424
436
|
className +=
|
|
425
|
-
|
|
437
|
+
' text-grey-dark border-input-light focus:border-blue-navy focus:outline-none focus:ring-0';
|
|
426
438
|
}
|
|
427
439
|
|
|
428
440
|
className += getHeight();
|
|
429
441
|
|
|
430
442
|
break;
|
|
431
|
-
case
|
|
443
|
+
case 'label':
|
|
432
444
|
className += ` flex modern-input-label-truncate peer-focus:modern-input-peer-focus-label-size
|
|
433
445
|
${
|
|
434
446
|
isDisabled
|
|
435
|
-
?
|
|
436
|
-
:
|
|
447
|
+
? 'cursor-pointer'
|
|
448
|
+
: 'cursor-text peer-focus:cursor-pointer'
|
|
437
449
|
} ${
|
|
438
450
|
isDisabled && !checkIsEmptyField()
|
|
439
|
-
?
|
|
451
|
+
? 'disabled-input-label-bg'
|
|
440
452
|
: !isDisabled || !checkIsEmptyField()
|
|
441
|
-
?
|
|
442
|
-
:
|
|
453
|
+
? 'active-input-label-bg'
|
|
454
|
+
: ''
|
|
443
455
|
} absolute duration-300 transform -translate-y-4 top-2 z-1 origin-[0] px-0 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:top-1/2 peer-focus:top-2 peer-focus:-translate-y-4 start-[14px] rtl:peer-focus:translate-x-1/4 rtl:peer-focus:left-auto ${
|
|
444
456
|
isDisabled
|
|
445
|
-
?
|
|
446
|
-
:
|
|
457
|
+
? 'cursor-pointer'
|
|
458
|
+
: 'cursor-text peer-focus:cursor-pointer'
|
|
447
459
|
}
|
|
448
460
|
${
|
|
449
461
|
checkIsEmptyField()
|
|
450
|
-
?
|
|
451
|
-
:
|
|
462
|
+
? 'modern-input-label-size'
|
|
463
|
+
: 'modern-input-peer-focus-label-size'
|
|
452
464
|
}`;
|
|
453
465
|
if (errors && errors[name]) {
|
|
454
|
-
className +=
|
|
466
|
+
className += ' text-error-light ';
|
|
455
467
|
} else {
|
|
456
|
-
className +=
|
|
468
|
+
className += ' text-grey-dark peer-focus:text-blue-navy';
|
|
457
469
|
}
|
|
458
470
|
break;
|
|
459
|
-
case
|
|
460
|
-
className =
|
|
471
|
+
case 'message':
|
|
472
|
+
className = ' text-error-icon ';
|
|
461
473
|
break;
|
|
462
|
-
case
|
|
463
|
-
className +=
|
|
474
|
+
case 'adorement':
|
|
475
|
+
className += ' absolute right-0 adorement gap-1 flex items-center ';
|
|
464
476
|
break;
|
|
465
477
|
default:
|
|
466
478
|
break;
|
|
@@ -485,30 +497,30 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
485
497
|
// return 'bottom'
|
|
486
498
|
// }
|
|
487
499
|
const filteredData =
|
|
488
|
-
inputValue !==
|
|
489
|
-
inputValue !==
|
|
490
|
-
type !==
|
|
500
|
+
inputValue !== '*' &&
|
|
501
|
+
inputValue !== '' &&
|
|
502
|
+
type !== 'custom_select' &&
|
|
491
503
|
!noLocalFilter
|
|
492
504
|
? suggestions?.filter((item: valueProps) =>
|
|
493
505
|
checkIncludes(
|
|
494
506
|
item.name,
|
|
495
507
|
inputValue,
|
|
496
|
-
item.param1 ??
|
|
497
|
-
item.param2 ??
|
|
498
|
-
item.param3 ??
|
|
499
|
-
item.param4 ??
|
|
508
|
+
item.param1 ?? '',
|
|
509
|
+
item.param2 ?? '',
|
|
510
|
+
item.param3 ?? '',
|
|
511
|
+
item.param4 ?? ''
|
|
500
512
|
)
|
|
501
513
|
)
|
|
502
514
|
: suggestions;
|
|
503
515
|
|
|
504
516
|
const handleError = (data: any) => {
|
|
505
517
|
if (
|
|
506
|
-
getErrors(data[name]) ===
|
|
507
|
-
getErrors(data[name]) ===
|
|
518
|
+
getErrors(data[name]) === 'required' ||
|
|
519
|
+
getErrors(data[name]) === 'Required'
|
|
508
520
|
) {
|
|
509
521
|
return `${label ?? labelTitle} is ${getErrors(data[name])}`;
|
|
510
522
|
} else {
|
|
511
|
-
return getErrors(data[name]) ??
|
|
523
|
+
return getErrors(data[name]) ?? '';
|
|
512
524
|
}
|
|
513
525
|
};
|
|
514
526
|
|
|
@@ -561,15 +573,15 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
561
573
|
if (!dropOpen) return;
|
|
562
574
|
|
|
563
575
|
const nextIndex =
|
|
564
|
-
e.key ===
|
|
576
|
+
e.key === 'ArrowDown'
|
|
565
577
|
? (selectedIndex + 1) % filteredData.length
|
|
566
|
-
: e.key ===
|
|
578
|
+
: e.key === 'ArrowUp'
|
|
567
579
|
? (selectedIndex - 1 + filteredData.length) % filteredData.length
|
|
568
580
|
: selectedIndex;
|
|
569
581
|
|
|
570
582
|
switch (e.key) {
|
|
571
|
-
case
|
|
572
|
-
case
|
|
583
|
+
case 'ArrowDown':
|
|
584
|
+
case 'ArrowUp':
|
|
573
585
|
e.preventDefault();
|
|
574
586
|
|
|
575
587
|
// Update index first
|
|
@@ -596,12 +608,12 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
596
608
|
});
|
|
597
609
|
break;
|
|
598
610
|
|
|
599
|
-
case
|
|
611
|
+
case 'Enter':
|
|
600
612
|
e.preventDefault();
|
|
601
613
|
handleSuggestionClick(filteredData[selectedIndex], selectedIndex);
|
|
602
614
|
break;
|
|
603
615
|
|
|
604
|
-
case
|
|
616
|
+
case 'Escape':
|
|
605
617
|
e.preventDefault();
|
|
606
618
|
setDropOpen(false);
|
|
607
619
|
break;
|
|
@@ -612,9 +624,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
612
624
|
};
|
|
613
625
|
|
|
614
626
|
if (filteredData?.length > 0 && !isLoading) {
|
|
615
|
-
window.addEventListener(
|
|
627
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
616
628
|
return () => {
|
|
617
|
-
window.removeEventListener(
|
|
629
|
+
window.removeEventListener('keydown', handleKeyDown);
|
|
618
630
|
};
|
|
619
631
|
}
|
|
620
632
|
}, [
|
|
@@ -643,9 +655,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
643
655
|
<li
|
|
644
656
|
className={`${
|
|
645
657
|
value?.id === suggestion?.id
|
|
646
|
-
?
|
|
658
|
+
? 'bg-blue-navy text-white'
|
|
647
659
|
: `${
|
|
648
|
-
index === selectedIndex ?
|
|
660
|
+
index === selectedIndex ? 'is-selected' : ''
|
|
649
661
|
} hover:bg-table-hover`
|
|
650
662
|
} cursor-pointer p-1 text-xxs ps-3.5 pl-[10px] qbs-autocomplete-suggections-items`}
|
|
651
663
|
key={suggestion?.id}
|
|
@@ -710,7 +722,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
710
722
|
useEffect(() => {
|
|
711
723
|
const shouldShowClose =
|
|
712
724
|
value?.name &&
|
|
713
|
-
(value?.id || String(value?.id) ===
|
|
725
|
+
(value?.id || String(value?.id) === '0') &&
|
|
714
726
|
!disabled &&
|
|
715
727
|
!readOnly &&
|
|
716
728
|
isClose;
|
|
@@ -724,7 +736,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
724
736
|
if (inputRef.current) {
|
|
725
737
|
const { scrollWidth, clientWidth, value } = inputRef.current;
|
|
726
738
|
// Check for overflow only when there's content
|
|
727
|
-
if (value.trim() !==
|
|
739
|
+
if (value.trim() !== '') {
|
|
728
740
|
setShowTooltip(scrollWidth > clientWidth + 2);
|
|
729
741
|
} else {
|
|
730
742
|
setShowTooltip(false); // No tooltip for empty input
|
|
@@ -733,13 +745,13 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
733
745
|
};
|
|
734
746
|
|
|
735
747
|
if (inputRef.current) {
|
|
736
|
-
inputRef.current.addEventListener(
|
|
748
|
+
inputRef.current.addEventListener('input', checkOverflow);
|
|
737
749
|
checkOverflow(); // Initial check
|
|
738
750
|
}
|
|
739
751
|
|
|
740
752
|
return () => {
|
|
741
753
|
if (inputRef.current) {
|
|
742
|
-
inputRef.current.removeEventListener(
|
|
754
|
+
inputRef.current.removeEventListener('input', checkOverflow);
|
|
743
755
|
}
|
|
744
756
|
};
|
|
745
757
|
}, [inputValue]);
|
|
@@ -757,7 +769,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
757
769
|
id={
|
|
758
770
|
id ? `autocomplete-container-${id}` : `autocomplete-container-${name}`
|
|
759
771
|
}
|
|
760
|
-
className={` flex-grow ${fullWidth ?
|
|
772
|
+
className={` flex-grow ${fullWidth ? 'w-full' : 'w-auto'}`}
|
|
761
773
|
ref={dropdownref}
|
|
762
774
|
>
|
|
763
775
|
{label && !isModern && (
|
|
@@ -777,7 +789,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
777
789
|
)}
|
|
778
790
|
|
|
779
791
|
<div
|
|
780
|
-
className={`flex relative ${fullWidth ?
|
|
792
|
+
className={`flex relative ${fullWidth ? 'w-full' : 'w-auto'}`}
|
|
781
793
|
style={{ width: width }}
|
|
782
794
|
>
|
|
783
795
|
<div
|
|
@@ -787,8 +799,8 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
787
799
|
>
|
|
788
800
|
<input
|
|
789
801
|
type="text"
|
|
790
|
-
readOnly={readOnly ?? type ===
|
|
791
|
-
value={inputValue ? inputValue :
|
|
802
|
+
readOnly={readOnly ?? type === 'custom_select'}
|
|
803
|
+
value={inputValue ? inputValue : ''}
|
|
792
804
|
onBlur={handleClearInputValue}
|
|
793
805
|
autoComplete="off"
|
|
794
806
|
disabled={disabled}
|
|
@@ -811,21 +823,27 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
811
823
|
}
|
|
812
824
|
: {}),
|
|
813
825
|
}}
|
|
814
|
-
className={` ${generateClassName(
|
|
826
|
+
className={` ${generateClassName('input')}`}
|
|
815
827
|
onChange={handleChange}
|
|
816
828
|
placeholder={
|
|
817
|
-
type ===
|
|
829
|
+
type === 'auto_complete'
|
|
818
830
|
? placeholder && isCustomPlaceholder
|
|
819
831
|
? placeholder
|
|
820
|
-
:
|
|
821
|
-
: placeholder ??
|
|
832
|
+
: 'Type to search'
|
|
833
|
+
: placeholder ?? '--Select--'
|
|
822
834
|
}
|
|
823
835
|
onFocus={onInputFocus}
|
|
824
836
|
onClick={(e) => {
|
|
825
|
-
if (type ===
|
|
826
|
-
|
|
827
|
-
|
|
837
|
+
if (type === 'custom_select') {
|
|
838
|
+
e.stopPropagation();
|
|
839
|
+
if (!suggestions || suggestions?.length === 0) {
|
|
840
|
+
handleDropData();
|
|
841
|
+
}
|
|
842
|
+
if (!isLoading) {
|
|
843
|
+
setDropOpen(!dropOpen);
|
|
844
|
+
}
|
|
828
845
|
} else {
|
|
846
|
+
e.stopPropagation();
|
|
829
847
|
setDropOpen(!dropOpen);
|
|
830
848
|
}
|
|
831
849
|
}}
|
|
@@ -834,9 +852,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
834
852
|
<label
|
|
835
853
|
htmlFor={id}
|
|
836
854
|
onClick={() => onLabelClick()}
|
|
837
|
-
className={generateClassName(
|
|
855
|
+
className={generateClassName('label')}
|
|
838
856
|
>
|
|
839
|
-
{label ? <span className="truncate">{label}</span> :
|
|
857
|
+
{label ? <span className="truncate">{label}</span> : ''}
|
|
840
858
|
{required ? <span className="text-error"> *</span> : <></>}
|
|
841
859
|
</label>
|
|
842
860
|
)}
|
|
@@ -845,9 +863,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
845
863
|
<div
|
|
846
864
|
ref={adorementRef}
|
|
847
865
|
className={`${generateClassName(
|
|
848
|
-
|
|
866
|
+
'adorement'
|
|
849
867
|
)} qbs-autocomplete-adorement custom-dorpdown-adorement mr-[1px] ${
|
|
850
|
-
isLoading ?
|
|
868
|
+
isLoading ? 'bg-white' : ''
|
|
851
869
|
}`}
|
|
852
870
|
>
|
|
853
871
|
{showClose && (
|
|
@@ -862,11 +880,10 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
862
880
|
</button>
|
|
863
881
|
)}
|
|
864
882
|
{isLoading && <Spinner />}
|
|
865
|
-
{type !==
|
|
883
|
+
{type !== 'auto_complete' && !disabled && !readOnly && (
|
|
866
884
|
<button
|
|
867
885
|
disabled={disabled ?? readOnly}
|
|
868
886
|
onClick={(e) => handleOpen(e)}
|
|
869
|
-
onBlur={handleClose}
|
|
870
887
|
className=" text-[#667085] focus-visible:outline-slate-100"
|
|
871
888
|
data-testid="drop-arrow"
|
|
872
889
|
type="button"
|
|
@@ -886,7 +903,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
886
903
|
{errors && errors[name] && (
|
|
887
904
|
<div
|
|
888
905
|
className={` text-error-label relative cursor-pointer ${generateClassName(
|
|
889
|
-
|
|
906
|
+
'message'
|
|
890
907
|
)}`}
|
|
891
908
|
onMouseEnter={() => setIsHovered(true)}
|
|
892
909
|
onMouseLeave={() => setIsHovered(false)}
|