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