react-core-ts 2.0.3 → 2.0.5
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 +101 -99
- package/dist/ReactAutoComplete.js.map +1 -1
- package/dist/styles/styles/components/autocomplete.css +744 -0
- package/dist/styles/styles/components/selectedautocomplete.css +179 -0
- package/dist/styles/styles/components/tooltip.css +497 -0
- package/dist/styles/styles/components/treedropdown.css +97 -0
- package/dist/styles/styles/global.css +8 -0
- package/docs/App.tsx +158 -160
- package/package.json +1 -1
- package/src/ReactAutoComplete.tsx +138 -135
|
@@ -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
|
) {
|
|
@@ -282,8 +282,8 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
282
282
|
if (getData) {
|
|
283
283
|
try {
|
|
284
284
|
setIsLoading(true);
|
|
285
|
-
handlePickSuggestions(
|
|
286
|
-
const fetchedSuggestions = await getData?.(
|
|
285
|
+
handlePickSuggestions("*");
|
|
286
|
+
const fetchedSuggestions = await getData?.("*");
|
|
287
287
|
fetchedSuggestions?.forEach((element: any) => {
|
|
288
288
|
data?.push(element);
|
|
289
289
|
});
|
|
@@ -295,9 +295,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
295
295
|
}
|
|
296
296
|
};
|
|
297
297
|
useEffect(() => {
|
|
298
|
-
document.addEventListener(
|
|
298
|
+
document.addEventListener("click", handleClickOutside);
|
|
299
299
|
return () => {
|
|
300
|
-
document.removeEventListener(
|
|
300
|
+
document.removeEventListener("click", handleClickOutside);
|
|
301
301
|
};
|
|
302
302
|
}, []);
|
|
303
303
|
|
|
@@ -308,10 +308,10 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
308
308
|
}, [autoFocus]);
|
|
309
309
|
const onInputFocus = () => {
|
|
310
310
|
if (!isDisabled) {
|
|
311
|
-
if (autoFilter && inputValue ===
|
|
312
|
-
handleValChange(
|
|
311
|
+
if (autoFilter && inputValue === "") {
|
|
312
|
+
handleValChange("*");
|
|
313
313
|
} else if (
|
|
314
|
-
(type ===
|
|
314
|
+
(type === "custom_select" || type === "custom_search_select") &&
|
|
315
315
|
data &&
|
|
316
316
|
data?.length > 0
|
|
317
317
|
) {
|
|
@@ -330,15 +330,18 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
330
330
|
name: suggestion.name,
|
|
331
331
|
...(suggestion?.label ? { label: suggestion?.label } : {}),
|
|
332
332
|
});
|
|
333
|
-
if (type !==
|
|
333
|
+
if (type !== "custom_select") setInputValue(suggestion.name);
|
|
334
334
|
setDropOpen(false);
|
|
335
335
|
setSelectedIndex(index);
|
|
336
336
|
};
|
|
337
337
|
const handleOpen = (e: any) => {
|
|
338
|
-
if (!suggestions || suggestions?.length === 0)
|
|
338
|
+
if (!suggestions || suggestions?.length === 0) {
|
|
339
|
+
handleDropData();
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
339
342
|
if (!isLoading) {
|
|
340
343
|
setDropOpen(!dropOpen);
|
|
341
|
-
if (type !==
|
|
344
|
+
if (type !== "custom_select") setInputValue("");
|
|
342
345
|
}
|
|
343
346
|
};
|
|
344
347
|
|
|
@@ -349,28 +352,28 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
349
352
|
useEffect(() => {
|
|
350
353
|
if (!insideOpen) {
|
|
351
354
|
setSelectedIndex(0);
|
|
352
|
-
window.addEventListener(
|
|
355
|
+
window.addEventListener("scroll", handleScroll);
|
|
353
356
|
|
|
354
|
-
const mainElement = document.querySelector(
|
|
355
|
-
mainElement?.addEventListener(
|
|
357
|
+
const mainElement = document.querySelector("main");
|
|
358
|
+
mainElement?.addEventListener("scroll", handleScroll);
|
|
356
359
|
|
|
357
360
|
const gridElements = document.querySelectorAll(
|
|
358
|
-
|
|
361
|
+
".k-grid-content, .overflow-auto, .overflow-y-auto, .overflow-x-auto"
|
|
359
362
|
);
|
|
360
363
|
gridElements.forEach((gridElement: any) => {
|
|
361
|
-
gridElement.addEventListener(
|
|
364
|
+
gridElement.addEventListener("scroll", handleScroll);
|
|
362
365
|
});
|
|
363
366
|
|
|
364
|
-
window.addEventListener(
|
|
367
|
+
window.addEventListener("resize", getDropPosition);
|
|
365
368
|
getDropPosition();
|
|
366
369
|
return () => {
|
|
367
|
-
window.removeEventListener(
|
|
368
|
-
const mainElement = document.querySelector(
|
|
369
|
-
mainElement?.removeEventListener(
|
|
370
|
-
window.addEventListener(
|
|
371
|
-
const gridElements = document.querySelectorAll(
|
|
370
|
+
window.removeEventListener("scroll", handleScroll);
|
|
371
|
+
const mainElement = document.querySelector("main");
|
|
372
|
+
mainElement?.removeEventListener("scroll", handleScroll);
|
|
373
|
+
window.addEventListener("resize", getDropPosition);
|
|
374
|
+
const gridElements = document.querySelectorAll(".k-grid-content");
|
|
372
375
|
gridElements.forEach((gridElement: any) => {
|
|
373
|
-
gridElement.removeEventListener(
|
|
376
|
+
gridElement.removeEventListener("scroll", handleScroll);
|
|
374
377
|
});
|
|
375
378
|
};
|
|
376
379
|
}
|
|
@@ -378,13 +381,13 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
378
381
|
|
|
379
382
|
const handleClear = () => {
|
|
380
383
|
setDropOpen(false);
|
|
381
|
-
setInputValue(
|
|
382
|
-
onChange({ id: undefined, name:
|
|
384
|
+
setInputValue("");
|
|
385
|
+
onChange({ id: undefined, name: "", from: 3 });
|
|
383
386
|
onLabelClick();
|
|
384
387
|
};
|
|
385
388
|
|
|
386
389
|
useEffect(() => {
|
|
387
|
-
setInputValue(value?.name ??
|
|
390
|
+
setInputValue(value?.name ?? "");
|
|
388
391
|
}, [value?.name]);
|
|
389
392
|
|
|
390
393
|
useEffect(() => {
|
|
@@ -392,7 +395,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
392
395
|
}, [data]);
|
|
393
396
|
|
|
394
397
|
const getErrors = (err: any) => {
|
|
395
|
-
let errMsg =
|
|
398
|
+
let errMsg = "";
|
|
396
399
|
if (err.message) {
|
|
397
400
|
errMsg = err?.message;
|
|
398
401
|
} else if (err?.id?.message) {
|
|
@@ -403,61 +406,61 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
403
406
|
return errMsg;
|
|
404
407
|
};
|
|
405
408
|
const generateClassName = (
|
|
406
|
-
type:
|
|
409
|
+
type: "input" | "label" | "message" | "adorement"
|
|
407
410
|
): string => {
|
|
408
411
|
let className = propsClassName;
|
|
409
412
|
switch (type) {
|
|
410
|
-
case
|
|
413
|
+
case "input":
|
|
411
414
|
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 ${
|
|
412
415
|
label && isModern
|
|
413
|
-
?
|
|
414
|
-
:
|
|
416
|
+
? "placeholder-transparent"
|
|
417
|
+
: "focus:placeholder-grey-secondary placeholder-input-label"
|
|
415
418
|
} focus:placeholder-grey-secondary`;
|
|
416
419
|
|
|
417
420
|
if (errors && errors[name]) {
|
|
418
421
|
className +=
|
|
419
|
-
|
|
422
|
+
" border-[#FDA29B] focus:border-error-[#FDA29B] focus:ring-[#FDA29B] focus:ring-3 focus:outline-[#FDA29B] input-outline";
|
|
420
423
|
} else {
|
|
421
424
|
className +=
|
|
422
|
-
|
|
425
|
+
" text-grey-dark border-input-light focus:border-blue-navy focus:outline-none focus:ring-0";
|
|
423
426
|
}
|
|
424
427
|
|
|
425
|
-
className += getHeight()
|
|
428
|
+
className += getHeight();
|
|
426
429
|
|
|
427
430
|
break;
|
|
428
|
-
case
|
|
431
|
+
case "label":
|
|
429
432
|
className += ` flex modern-input-label-truncate peer-focus:modern-input-peer-focus-label-size
|
|
430
433
|
${
|
|
431
434
|
isDisabled
|
|
432
|
-
?
|
|
433
|
-
:
|
|
435
|
+
? "cursor-pointer"
|
|
436
|
+
: "cursor-text peer-focus:cursor-pointer"
|
|
434
437
|
} ${
|
|
435
438
|
isDisabled && !checkIsEmptyField()
|
|
436
|
-
?
|
|
439
|
+
? "disabled-input-label-bg"
|
|
437
440
|
: !isDisabled || !checkIsEmptyField()
|
|
438
|
-
?
|
|
439
|
-
:
|
|
441
|
+
? "active-input-label-bg"
|
|
442
|
+
: ""
|
|
440
443
|
} 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 ${
|
|
441
444
|
isDisabled
|
|
442
|
-
?
|
|
443
|
-
:
|
|
445
|
+
? "cursor-pointer"
|
|
446
|
+
: "cursor-text peer-focus:cursor-pointer"
|
|
444
447
|
}
|
|
445
448
|
${
|
|
446
449
|
checkIsEmptyField()
|
|
447
|
-
?
|
|
448
|
-
:
|
|
450
|
+
? "modern-input-label-size"
|
|
451
|
+
: "modern-input-peer-focus-label-size"
|
|
449
452
|
}`;
|
|
450
453
|
if (errors && errors[name]) {
|
|
451
|
-
className +=
|
|
454
|
+
className += " text-error-light ";
|
|
452
455
|
} else {
|
|
453
|
-
className +=
|
|
456
|
+
className += " text-grey-dark peer-focus:text-blue-navy";
|
|
454
457
|
}
|
|
455
458
|
break;
|
|
456
|
-
case
|
|
457
|
-
className =
|
|
459
|
+
case "message":
|
|
460
|
+
className = " text-error-icon ";
|
|
458
461
|
break;
|
|
459
|
-
case
|
|
460
|
-
className +=
|
|
462
|
+
case "adorement":
|
|
463
|
+
className += " absolute right-0 adorement gap-1 flex items-center ";
|
|
461
464
|
break;
|
|
462
465
|
default:
|
|
463
466
|
break;
|
|
@@ -482,30 +485,30 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
482
485
|
// return 'bottom'
|
|
483
486
|
// }
|
|
484
487
|
const filteredData =
|
|
485
|
-
inputValue !==
|
|
486
|
-
inputValue !==
|
|
487
|
-
type !==
|
|
488
|
+
inputValue !== "*" &&
|
|
489
|
+
inputValue !== "" &&
|
|
490
|
+
type !== "custom_select" &&
|
|
488
491
|
!noLocalFilter
|
|
489
492
|
? suggestions?.filter((item: valueProps) =>
|
|
490
493
|
checkIncludes(
|
|
491
494
|
item.name,
|
|
492
495
|
inputValue,
|
|
493
|
-
item.param1 ??
|
|
494
|
-
item.param2 ??
|
|
495
|
-
item.param3 ??
|
|
496
|
-
item.param4 ??
|
|
496
|
+
item.param1 ?? "",
|
|
497
|
+
item.param2 ?? "",
|
|
498
|
+
item.param3 ?? "",
|
|
499
|
+
item.param4 ?? ""
|
|
497
500
|
)
|
|
498
501
|
)
|
|
499
502
|
: suggestions;
|
|
500
503
|
|
|
501
504
|
const handleError = (data: any) => {
|
|
502
505
|
if (
|
|
503
|
-
getErrors(data[name]) ===
|
|
504
|
-
getErrors(data[name]) ===
|
|
506
|
+
getErrors(data[name]) === "required" ||
|
|
507
|
+
getErrors(data[name]) === "Required"
|
|
505
508
|
) {
|
|
506
509
|
return `${label ?? labelTitle} is ${getErrors(data[name])}`;
|
|
507
510
|
} else {
|
|
508
|
-
return getErrors(data[name]) ??
|
|
511
|
+
return getErrors(data[name]) ?? "";
|
|
509
512
|
}
|
|
510
513
|
};
|
|
511
514
|
|
|
@@ -556,34 +559,34 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
556
559
|
// Handle keyboard navigation
|
|
557
560
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
558
561
|
if (!dropOpen) return;
|
|
559
|
-
|
|
562
|
+
|
|
560
563
|
const nextIndex =
|
|
561
|
-
e.key ===
|
|
564
|
+
e.key === "ArrowDown"
|
|
562
565
|
? (selectedIndex + 1) % filteredData.length
|
|
563
|
-
: e.key ===
|
|
566
|
+
: e.key === "ArrowUp"
|
|
564
567
|
? (selectedIndex - 1 + filteredData.length) % filteredData.length
|
|
565
568
|
: selectedIndex;
|
|
566
|
-
|
|
569
|
+
|
|
567
570
|
switch (e.key) {
|
|
568
|
-
case
|
|
569
|
-
case
|
|
571
|
+
case "ArrowDown":
|
|
572
|
+
case "ArrowUp":
|
|
570
573
|
e.preventDefault();
|
|
571
|
-
|
|
574
|
+
|
|
572
575
|
// Update index first
|
|
573
576
|
setSelectedIndex(nextIndex);
|
|
574
|
-
|
|
577
|
+
|
|
575
578
|
// Wait for DOM update before scrolling
|
|
576
579
|
requestAnimationFrame(() => {
|
|
577
580
|
const el = itemRefs.current[nextIndex];
|
|
578
581
|
const container = scrollContainerRef.current;
|
|
579
|
-
|
|
582
|
+
|
|
580
583
|
if (el && container) {
|
|
581
584
|
const elTop = el.offsetTop;
|
|
582
585
|
const elBottom = elTop + el.offsetHeight;
|
|
583
|
-
|
|
586
|
+
|
|
584
587
|
const containerTop = container.scrollTop;
|
|
585
588
|
const containerBottom = containerTop + container.clientHeight;
|
|
586
|
-
|
|
589
|
+
|
|
587
590
|
if (elBottom > containerBottom) {
|
|
588
591
|
container.scrollTop = elBottom - container.clientHeight;
|
|
589
592
|
} else if (elTop < containerTop) {
|
|
@@ -592,26 +595,26 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
592
595
|
}
|
|
593
596
|
});
|
|
594
597
|
break;
|
|
595
|
-
|
|
596
|
-
case
|
|
598
|
+
|
|
599
|
+
case "Enter":
|
|
597
600
|
e.preventDefault();
|
|
598
601
|
handleSuggestionClick(filteredData[selectedIndex], selectedIndex);
|
|
599
602
|
break;
|
|
600
|
-
|
|
601
|
-
case
|
|
603
|
+
|
|
604
|
+
case "Escape":
|
|
602
605
|
e.preventDefault();
|
|
603
606
|
setDropOpen(false);
|
|
604
607
|
break;
|
|
605
|
-
|
|
608
|
+
|
|
606
609
|
default:
|
|
607
610
|
break;
|
|
608
611
|
}
|
|
609
612
|
};
|
|
610
613
|
|
|
611
614
|
if (filteredData?.length > 0 && !isLoading) {
|
|
612
|
-
window.addEventListener(
|
|
615
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
613
616
|
return () => {
|
|
614
|
-
window.removeEventListener(
|
|
617
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
615
618
|
};
|
|
616
619
|
}
|
|
617
620
|
}, [
|
|
@@ -640,9 +643,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
640
643
|
<li
|
|
641
644
|
className={`${
|
|
642
645
|
value?.id === suggestion?.id
|
|
643
|
-
?
|
|
646
|
+
? "bg-blue-navy text-white"
|
|
644
647
|
: `${
|
|
645
|
-
index === selectedIndex ?
|
|
648
|
+
index === selectedIndex ? "is-selected" : ""
|
|
646
649
|
} hover:bg-table-hover`
|
|
647
650
|
} cursor-pointer p-1 text-xxs ps-3.5 pl-[10px] qbs-autocomplete-suggections-items`}
|
|
648
651
|
key={suggestion?.id}
|
|
@@ -707,7 +710,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
707
710
|
useEffect(() => {
|
|
708
711
|
const shouldShowClose =
|
|
709
712
|
value?.name &&
|
|
710
|
-
(value?.id || String(value?.id) ===
|
|
713
|
+
(value?.id || String(value?.id) === "0") &&
|
|
711
714
|
!disabled &&
|
|
712
715
|
!readOnly &&
|
|
713
716
|
isClose;
|
|
@@ -721,7 +724,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
721
724
|
if (inputRef.current) {
|
|
722
725
|
const { scrollWidth, clientWidth, value } = inputRef.current;
|
|
723
726
|
// Check for overflow only when there's content
|
|
724
|
-
if (value.trim() !==
|
|
727
|
+
if (value.trim() !== "") {
|
|
725
728
|
setShowTooltip(scrollWidth > clientWidth + 2);
|
|
726
729
|
} else {
|
|
727
730
|
setShowTooltip(false); // No tooltip for empty input
|
|
@@ -730,13 +733,13 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
730
733
|
};
|
|
731
734
|
|
|
732
735
|
if (inputRef.current) {
|
|
733
|
-
inputRef.current.addEventListener(
|
|
736
|
+
inputRef.current.addEventListener("input", checkOverflow);
|
|
734
737
|
checkOverflow(); // Initial check
|
|
735
738
|
}
|
|
736
739
|
|
|
737
740
|
return () => {
|
|
738
741
|
if (inputRef.current) {
|
|
739
|
-
inputRef.current.removeEventListener(
|
|
742
|
+
inputRef.current.removeEventListener("input", checkOverflow);
|
|
740
743
|
}
|
|
741
744
|
};
|
|
742
745
|
}, [inputValue]);
|
|
@@ -754,7 +757,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
754
757
|
id={
|
|
755
758
|
id ? `autocomplete-container-${id}` : `autocomplete-container-${name}`
|
|
756
759
|
}
|
|
757
|
-
className={` flex-grow ${fullWidth ?
|
|
760
|
+
className={` flex-grow ${fullWidth ? "w-full" : "w-auto"}`}
|
|
758
761
|
ref={dropdownref}
|
|
759
762
|
>
|
|
760
763
|
{label && !isModern && (
|
|
@@ -774,7 +777,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
774
777
|
)}
|
|
775
778
|
|
|
776
779
|
<div
|
|
777
|
-
className={`flex relative ${fullWidth ?
|
|
780
|
+
className={`flex relative ${fullWidth ? "w-full" : "w-auto"}`}
|
|
778
781
|
style={{ width: width }}
|
|
779
782
|
>
|
|
780
783
|
<div
|
|
@@ -784,8 +787,8 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
784
787
|
>
|
|
785
788
|
<input
|
|
786
789
|
type="text"
|
|
787
|
-
readOnly={readOnly ?? type ===
|
|
788
|
-
value={inputValue ? inputValue :
|
|
790
|
+
readOnly={readOnly ?? type === "custom_select"}
|
|
791
|
+
value={inputValue ? inputValue : ""}
|
|
789
792
|
onBlur={handleClearInputValue}
|
|
790
793
|
autoComplete="off"
|
|
791
794
|
disabled={disabled}
|
|
@@ -808,18 +811,18 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
808
811
|
}
|
|
809
812
|
: {}),
|
|
810
813
|
}}
|
|
811
|
-
className={` ${generateClassName(
|
|
814
|
+
className={` ${generateClassName("input")}`}
|
|
812
815
|
onChange={handleChange}
|
|
813
816
|
placeholder={
|
|
814
|
-
type ===
|
|
817
|
+
type === "auto_complete"
|
|
815
818
|
? placeholder && isCustomPlaceholder
|
|
816
819
|
? placeholder
|
|
817
|
-
:
|
|
818
|
-
: placeholder ??
|
|
820
|
+
: "Type to search"
|
|
821
|
+
: placeholder ?? "--Select--"
|
|
819
822
|
}
|
|
820
823
|
onFocus={onInputFocus}
|
|
821
824
|
onClick={(e) => {
|
|
822
|
-
if (type ===
|
|
825
|
+
if (type === "custom_select") {
|
|
823
826
|
setDropOpen(!dropOpen);
|
|
824
827
|
handleOpen(e);
|
|
825
828
|
} else {
|
|
@@ -831,9 +834,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
831
834
|
<label
|
|
832
835
|
htmlFor={id}
|
|
833
836
|
onClick={() => onLabelClick()}
|
|
834
|
-
className={generateClassName(
|
|
837
|
+
className={generateClassName("label")}
|
|
835
838
|
>
|
|
836
|
-
{label ? <span className="truncate">{label}</span> :
|
|
839
|
+
{label ? <span className="truncate">{label}</span> : ""}
|
|
837
840
|
{required ? <span className="text-error"> *</span> : <></>}
|
|
838
841
|
</label>
|
|
839
842
|
)}
|
|
@@ -842,9 +845,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
842
845
|
<div
|
|
843
846
|
ref={adorementRef}
|
|
844
847
|
className={`${generateClassName(
|
|
845
|
-
|
|
848
|
+
"adorement"
|
|
846
849
|
)} qbs-autocomplete-adorement custom-dorpdown-adorement mr-[1px] ${
|
|
847
|
-
isLoading ?
|
|
850
|
+
isLoading ? "bg-white" : ""
|
|
848
851
|
}`}
|
|
849
852
|
>
|
|
850
853
|
{showClose && (
|
|
@@ -859,7 +862,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
859
862
|
</button>
|
|
860
863
|
)}
|
|
861
864
|
{isLoading && <Spinner />}
|
|
862
|
-
{type !==
|
|
865
|
+
{type !== "auto_complete" && !disabled && !readOnly && (
|
|
863
866
|
<button
|
|
864
867
|
disabled={disabled ?? readOnly}
|
|
865
868
|
onClick={(e) => handleOpen(e)}
|
|
@@ -883,7 +886,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
883
886
|
{errors && errors[name] && (
|
|
884
887
|
<div
|
|
885
888
|
className={` text-error-label relative cursor-pointer ${generateClassName(
|
|
886
|
-
|
|
889
|
+
"message"
|
|
887
890
|
)}`}
|
|
888
891
|
onMouseEnter={() => setIsHovered(true)}
|
|
889
892
|
onMouseLeave={() => setIsHovered(false)}
|