react-core-ts 2.0.2 → 2.0.4
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/AutoCompleteWithSelectedList.js +20 -2
- package/dist/AutoCompleteWithSelectedList.js.map +1 -1
- package/dist/AutoCompleteWithTabFilter.js +199 -41
- package/dist/AutoCompleteWithTabFilter.js.map +1 -1
- package/dist/ReactAutoComplete.d.ts +4 -4
- package/dist/ReactAutoComplete.js +98 -99
- package/dist/ReactAutoComplete.js.map +1 -1
- package/dist/commontypes.d.ts +1 -0
- package/dist/dropdownFilterTabs.d.ts +2 -0
- package/dist/dropdownFilterTabs.js +94 -22
- package/dist/dropdownFilterTabs.js.map +1 -1
- package/dist/dummyAutoCompleteWithSelectedList.js +0 -1
- package/dist/dummyAutoCompleteWithSelectedList.js.map +1 -1
- package/dist/styles/components/autocomplete.css +27 -0
- package/dist/styles/styles/components/autocomplete.css +27 -0
- package/dist/utilities/tooltip.js +0 -1
- package/dist/utilities/tooltip.js.map +1 -1
- package/docs/App.tsx +183 -123
- package/package.json +1 -1
- package/src/AutoCompleteWithSelectedList.tsx +42 -1
- package/src/AutoCompleteWithTabFilter.tsx +222 -24
- package/src/ReactAutoComplete.tsx +135 -135
- package/src/commontypes.ts +1 -0
- package/src/dropdownFilterTabs.tsx +106 -19
- package/src/dummyAutoCompleteWithSelectedList.tsx +0 -1
- package/src/styles/components/autocomplete.css +27 -0
- package/src/utilities/tooltip.tsx +0 -1
|
@@ -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,15 @@ 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
338
|
if (!suggestions || suggestions?.length === 0) handleDropData();
|
|
339
|
-
if (!isLoading) {
|
|
339
|
+
if (!isLoading && type !== "custom_select") {
|
|
340
340
|
setDropOpen(!dropOpen);
|
|
341
|
-
|
|
341
|
+
setInputValue("");
|
|
342
342
|
}
|
|
343
343
|
};
|
|
344
344
|
|
|
@@ -349,28 +349,28 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
349
349
|
useEffect(() => {
|
|
350
350
|
if (!insideOpen) {
|
|
351
351
|
setSelectedIndex(0);
|
|
352
|
-
window.addEventListener(
|
|
352
|
+
window.addEventListener("scroll", handleScroll);
|
|
353
353
|
|
|
354
|
-
const mainElement = document.querySelector(
|
|
355
|
-
mainElement?.addEventListener(
|
|
354
|
+
const mainElement = document.querySelector("main");
|
|
355
|
+
mainElement?.addEventListener("scroll", handleScroll);
|
|
356
356
|
|
|
357
357
|
const gridElements = document.querySelectorAll(
|
|
358
|
-
|
|
358
|
+
".k-grid-content, .overflow-auto, .overflow-y-auto, .overflow-x-auto"
|
|
359
359
|
);
|
|
360
360
|
gridElements.forEach((gridElement: any) => {
|
|
361
|
-
gridElement.addEventListener(
|
|
361
|
+
gridElement.addEventListener("scroll", handleScroll);
|
|
362
362
|
});
|
|
363
363
|
|
|
364
|
-
window.addEventListener(
|
|
364
|
+
window.addEventListener("resize", getDropPosition);
|
|
365
365
|
getDropPosition();
|
|
366
366
|
return () => {
|
|
367
|
-
window.removeEventListener(
|
|
368
|
-
const mainElement = document.querySelector(
|
|
369
|
-
mainElement?.removeEventListener(
|
|
370
|
-
window.addEventListener(
|
|
371
|
-
const gridElements = document.querySelectorAll(
|
|
367
|
+
window.removeEventListener("scroll", handleScroll);
|
|
368
|
+
const mainElement = document.querySelector("main");
|
|
369
|
+
mainElement?.removeEventListener("scroll", handleScroll);
|
|
370
|
+
window.addEventListener("resize", getDropPosition);
|
|
371
|
+
const gridElements = document.querySelectorAll(".k-grid-content");
|
|
372
372
|
gridElements.forEach((gridElement: any) => {
|
|
373
|
-
gridElement.removeEventListener(
|
|
373
|
+
gridElement.removeEventListener("scroll", handleScroll);
|
|
374
374
|
});
|
|
375
375
|
};
|
|
376
376
|
}
|
|
@@ -378,13 +378,13 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
378
378
|
|
|
379
379
|
const handleClear = () => {
|
|
380
380
|
setDropOpen(false);
|
|
381
|
-
setInputValue(
|
|
382
|
-
onChange({ id: undefined, name:
|
|
381
|
+
setInputValue("");
|
|
382
|
+
onChange({ id: undefined, name: "", from: 3 });
|
|
383
383
|
onLabelClick();
|
|
384
384
|
};
|
|
385
385
|
|
|
386
386
|
useEffect(() => {
|
|
387
|
-
setInputValue(value?.name ??
|
|
387
|
+
setInputValue(value?.name ?? "");
|
|
388
388
|
}, [value?.name]);
|
|
389
389
|
|
|
390
390
|
useEffect(() => {
|
|
@@ -392,7 +392,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
392
392
|
}, [data]);
|
|
393
393
|
|
|
394
394
|
const getErrors = (err: any) => {
|
|
395
|
-
let errMsg =
|
|
395
|
+
let errMsg = "";
|
|
396
396
|
if (err.message) {
|
|
397
397
|
errMsg = err?.message;
|
|
398
398
|
} else if (err?.id?.message) {
|
|
@@ -403,61 +403,61 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
403
403
|
return errMsg;
|
|
404
404
|
};
|
|
405
405
|
const generateClassName = (
|
|
406
|
-
type:
|
|
406
|
+
type: "input" | "label" | "message" | "adorement"
|
|
407
407
|
): string => {
|
|
408
408
|
let className = propsClassName;
|
|
409
409
|
switch (type) {
|
|
410
|
-
case
|
|
410
|
+
case "input":
|
|
411
411
|
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
412
|
label && isModern
|
|
413
|
-
?
|
|
414
|
-
:
|
|
413
|
+
? "placeholder-transparent"
|
|
414
|
+
: "focus:placeholder-grey-secondary placeholder-input-label"
|
|
415
415
|
} focus:placeholder-grey-secondary`;
|
|
416
416
|
|
|
417
417
|
if (errors && errors[name]) {
|
|
418
418
|
className +=
|
|
419
|
-
|
|
419
|
+
" border-[#FDA29B] focus:border-error-[#FDA29B] focus:ring-[#FDA29B] focus:ring-3 focus:outline-[#FDA29B] input-outline";
|
|
420
420
|
} else {
|
|
421
421
|
className +=
|
|
422
|
-
|
|
422
|
+
" text-grey-dark border-input-light focus:border-blue-navy focus:outline-none focus:ring-0";
|
|
423
423
|
}
|
|
424
424
|
|
|
425
|
-
className += getHeight()
|
|
425
|
+
className += getHeight();
|
|
426
426
|
|
|
427
427
|
break;
|
|
428
|
-
case
|
|
428
|
+
case "label":
|
|
429
429
|
className += ` flex modern-input-label-truncate peer-focus:modern-input-peer-focus-label-size
|
|
430
430
|
${
|
|
431
431
|
isDisabled
|
|
432
|
-
?
|
|
433
|
-
:
|
|
432
|
+
? "cursor-pointer"
|
|
433
|
+
: "cursor-text peer-focus:cursor-pointer"
|
|
434
434
|
} ${
|
|
435
435
|
isDisabled && !checkIsEmptyField()
|
|
436
|
-
?
|
|
436
|
+
? "disabled-input-label-bg"
|
|
437
437
|
: !isDisabled || !checkIsEmptyField()
|
|
438
|
-
?
|
|
439
|
-
:
|
|
438
|
+
? "active-input-label-bg"
|
|
439
|
+
: ""
|
|
440
440
|
} 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
441
|
isDisabled
|
|
442
|
-
?
|
|
443
|
-
:
|
|
442
|
+
? "cursor-pointer"
|
|
443
|
+
: "cursor-text peer-focus:cursor-pointer"
|
|
444
444
|
}
|
|
445
445
|
${
|
|
446
446
|
checkIsEmptyField()
|
|
447
|
-
?
|
|
448
|
-
:
|
|
447
|
+
? "modern-input-label-size"
|
|
448
|
+
: "modern-input-peer-focus-label-size"
|
|
449
449
|
}`;
|
|
450
450
|
if (errors && errors[name]) {
|
|
451
|
-
className +=
|
|
451
|
+
className += " text-error-light ";
|
|
452
452
|
} else {
|
|
453
|
-
className +=
|
|
453
|
+
className += " text-grey-dark peer-focus:text-blue-navy";
|
|
454
454
|
}
|
|
455
455
|
break;
|
|
456
|
-
case
|
|
457
|
-
className =
|
|
456
|
+
case "message":
|
|
457
|
+
className = " text-error-icon ";
|
|
458
458
|
break;
|
|
459
|
-
case
|
|
460
|
-
className +=
|
|
459
|
+
case "adorement":
|
|
460
|
+
className += " absolute right-0 adorement gap-1 flex items-center ";
|
|
461
461
|
break;
|
|
462
462
|
default:
|
|
463
463
|
break;
|
|
@@ -482,30 +482,30 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
482
482
|
// return 'bottom'
|
|
483
483
|
// }
|
|
484
484
|
const filteredData =
|
|
485
|
-
inputValue !==
|
|
486
|
-
inputValue !==
|
|
487
|
-
type !==
|
|
485
|
+
inputValue !== "*" &&
|
|
486
|
+
inputValue !== "" &&
|
|
487
|
+
type !== "custom_select" &&
|
|
488
488
|
!noLocalFilter
|
|
489
489
|
? suggestions?.filter((item: valueProps) =>
|
|
490
490
|
checkIncludes(
|
|
491
491
|
item.name,
|
|
492
492
|
inputValue,
|
|
493
|
-
item.param1 ??
|
|
494
|
-
item.param2 ??
|
|
495
|
-
item.param3 ??
|
|
496
|
-
item.param4 ??
|
|
493
|
+
item.param1 ?? "",
|
|
494
|
+
item.param2 ?? "",
|
|
495
|
+
item.param3 ?? "",
|
|
496
|
+
item.param4 ?? ""
|
|
497
497
|
)
|
|
498
498
|
)
|
|
499
499
|
: suggestions;
|
|
500
500
|
|
|
501
501
|
const handleError = (data: any) => {
|
|
502
502
|
if (
|
|
503
|
-
getErrors(data[name]) ===
|
|
504
|
-
getErrors(data[name]) ===
|
|
503
|
+
getErrors(data[name]) === "required" ||
|
|
504
|
+
getErrors(data[name]) === "Required"
|
|
505
505
|
) {
|
|
506
506
|
return `${label ?? labelTitle} is ${getErrors(data[name])}`;
|
|
507
507
|
} else {
|
|
508
|
-
return getErrors(data[name]) ??
|
|
508
|
+
return getErrors(data[name]) ?? "";
|
|
509
509
|
}
|
|
510
510
|
};
|
|
511
511
|
|
|
@@ -556,34 +556,34 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
556
556
|
// Handle keyboard navigation
|
|
557
557
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
558
558
|
if (!dropOpen) return;
|
|
559
|
-
|
|
559
|
+
|
|
560
560
|
const nextIndex =
|
|
561
|
-
e.key ===
|
|
561
|
+
e.key === "ArrowDown"
|
|
562
562
|
? (selectedIndex + 1) % filteredData.length
|
|
563
|
-
: e.key ===
|
|
563
|
+
: e.key === "ArrowUp"
|
|
564
564
|
? (selectedIndex - 1 + filteredData.length) % filteredData.length
|
|
565
565
|
: selectedIndex;
|
|
566
|
-
|
|
566
|
+
|
|
567
567
|
switch (e.key) {
|
|
568
|
-
case
|
|
569
|
-
case
|
|
568
|
+
case "ArrowDown":
|
|
569
|
+
case "ArrowUp":
|
|
570
570
|
e.preventDefault();
|
|
571
|
-
|
|
571
|
+
|
|
572
572
|
// Update index first
|
|
573
573
|
setSelectedIndex(nextIndex);
|
|
574
|
-
|
|
574
|
+
|
|
575
575
|
// Wait for DOM update before scrolling
|
|
576
576
|
requestAnimationFrame(() => {
|
|
577
577
|
const el = itemRefs.current[nextIndex];
|
|
578
578
|
const container = scrollContainerRef.current;
|
|
579
|
-
|
|
579
|
+
|
|
580
580
|
if (el && container) {
|
|
581
581
|
const elTop = el.offsetTop;
|
|
582
582
|
const elBottom = elTop + el.offsetHeight;
|
|
583
|
-
|
|
583
|
+
|
|
584
584
|
const containerTop = container.scrollTop;
|
|
585
585
|
const containerBottom = containerTop + container.clientHeight;
|
|
586
|
-
|
|
586
|
+
|
|
587
587
|
if (elBottom > containerBottom) {
|
|
588
588
|
container.scrollTop = elBottom - container.clientHeight;
|
|
589
589
|
} else if (elTop < containerTop) {
|
|
@@ -592,26 +592,26 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
592
592
|
}
|
|
593
593
|
});
|
|
594
594
|
break;
|
|
595
|
-
|
|
596
|
-
case
|
|
595
|
+
|
|
596
|
+
case "Enter":
|
|
597
597
|
e.preventDefault();
|
|
598
598
|
handleSuggestionClick(filteredData[selectedIndex], selectedIndex);
|
|
599
599
|
break;
|
|
600
|
-
|
|
601
|
-
case
|
|
600
|
+
|
|
601
|
+
case "Escape":
|
|
602
602
|
e.preventDefault();
|
|
603
603
|
setDropOpen(false);
|
|
604
604
|
break;
|
|
605
|
-
|
|
605
|
+
|
|
606
606
|
default:
|
|
607
607
|
break;
|
|
608
608
|
}
|
|
609
609
|
};
|
|
610
610
|
|
|
611
611
|
if (filteredData?.length > 0 && !isLoading) {
|
|
612
|
-
window.addEventListener(
|
|
612
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
613
613
|
return () => {
|
|
614
|
-
window.removeEventListener(
|
|
614
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
615
615
|
};
|
|
616
616
|
}
|
|
617
617
|
}, [
|
|
@@ -640,9 +640,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
640
640
|
<li
|
|
641
641
|
className={`${
|
|
642
642
|
value?.id === suggestion?.id
|
|
643
|
-
?
|
|
643
|
+
? "bg-blue-navy text-white"
|
|
644
644
|
: `${
|
|
645
|
-
index === selectedIndex ?
|
|
645
|
+
index === selectedIndex ? "is-selected" : ""
|
|
646
646
|
} hover:bg-table-hover`
|
|
647
647
|
} cursor-pointer p-1 text-xxs ps-3.5 pl-[10px] qbs-autocomplete-suggections-items`}
|
|
648
648
|
key={suggestion?.id}
|
|
@@ -707,7 +707,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
707
707
|
useEffect(() => {
|
|
708
708
|
const shouldShowClose =
|
|
709
709
|
value?.name &&
|
|
710
|
-
(value?.id || String(value?.id) ===
|
|
710
|
+
(value?.id || String(value?.id) === "0") &&
|
|
711
711
|
!disabled &&
|
|
712
712
|
!readOnly &&
|
|
713
713
|
isClose;
|
|
@@ -721,7 +721,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
721
721
|
if (inputRef.current) {
|
|
722
722
|
const { scrollWidth, clientWidth, value } = inputRef.current;
|
|
723
723
|
// Check for overflow only when there's content
|
|
724
|
-
if (value.trim() !==
|
|
724
|
+
if (value.trim() !== "") {
|
|
725
725
|
setShowTooltip(scrollWidth > clientWidth + 2);
|
|
726
726
|
} else {
|
|
727
727
|
setShowTooltip(false); // No tooltip for empty input
|
|
@@ -730,13 +730,13 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
730
730
|
};
|
|
731
731
|
|
|
732
732
|
if (inputRef.current) {
|
|
733
|
-
inputRef.current.addEventListener(
|
|
733
|
+
inputRef.current.addEventListener("input", checkOverflow);
|
|
734
734
|
checkOverflow(); // Initial check
|
|
735
735
|
}
|
|
736
736
|
|
|
737
737
|
return () => {
|
|
738
738
|
if (inputRef.current) {
|
|
739
|
-
inputRef.current.removeEventListener(
|
|
739
|
+
inputRef.current.removeEventListener("input", checkOverflow);
|
|
740
740
|
}
|
|
741
741
|
};
|
|
742
742
|
}, [inputValue]);
|
|
@@ -754,7 +754,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
754
754
|
id={
|
|
755
755
|
id ? `autocomplete-container-${id}` : `autocomplete-container-${name}`
|
|
756
756
|
}
|
|
757
|
-
className={` flex-grow ${fullWidth ?
|
|
757
|
+
className={` flex-grow ${fullWidth ? "w-full" : "w-auto"}`}
|
|
758
758
|
ref={dropdownref}
|
|
759
759
|
>
|
|
760
760
|
{label && !isModern && (
|
|
@@ -774,7 +774,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
774
774
|
)}
|
|
775
775
|
|
|
776
776
|
<div
|
|
777
|
-
className={`flex relative ${fullWidth ?
|
|
777
|
+
className={`flex relative ${fullWidth ? "w-full" : "w-auto"}`}
|
|
778
778
|
style={{ width: width }}
|
|
779
779
|
>
|
|
780
780
|
<div
|
|
@@ -784,8 +784,8 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
784
784
|
>
|
|
785
785
|
<input
|
|
786
786
|
type="text"
|
|
787
|
-
readOnly={readOnly ?? type ===
|
|
788
|
-
value={inputValue ? inputValue :
|
|
787
|
+
readOnly={readOnly ?? type === "custom_select"}
|
|
788
|
+
value={inputValue ? inputValue : ""}
|
|
789
789
|
onBlur={handleClearInputValue}
|
|
790
790
|
autoComplete="off"
|
|
791
791
|
disabled={disabled}
|
|
@@ -808,18 +808,18 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
808
808
|
}
|
|
809
809
|
: {}),
|
|
810
810
|
}}
|
|
811
|
-
className={` ${generateClassName(
|
|
811
|
+
className={` ${generateClassName("input")}`}
|
|
812
812
|
onChange={handleChange}
|
|
813
813
|
placeholder={
|
|
814
|
-
type ===
|
|
814
|
+
type === "auto_complete"
|
|
815
815
|
? placeholder && isCustomPlaceholder
|
|
816
816
|
? placeholder
|
|
817
|
-
:
|
|
818
|
-
: placeholder ??
|
|
817
|
+
: "Type to search"
|
|
818
|
+
: placeholder ?? "--Select--"
|
|
819
819
|
}
|
|
820
820
|
onFocus={onInputFocus}
|
|
821
821
|
onClick={(e) => {
|
|
822
|
-
if (type ===
|
|
822
|
+
if (type === "custom_select") {
|
|
823
823
|
setDropOpen(!dropOpen);
|
|
824
824
|
handleOpen(e);
|
|
825
825
|
} else {
|
|
@@ -831,9 +831,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
831
831
|
<label
|
|
832
832
|
htmlFor={id}
|
|
833
833
|
onClick={() => onLabelClick()}
|
|
834
|
-
className={generateClassName(
|
|
834
|
+
className={generateClassName("label")}
|
|
835
835
|
>
|
|
836
|
-
{label ? <span className="truncate">{label}</span> :
|
|
836
|
+
{label ? <span className="truncate">{label}</span> : ""}
|
|
837
837
|
{required ? <span className="text-error"> *</span> : <></>}
|
|
838
838
|
</label>
|
|
839
839
|
)}
|
|
@@ -842,9 +842,9 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
842
842
|
<div
|
|
843
843
|
ref={adorementRef}
|
|
844
844
|
className={`${generateClassName(
|
|
845
|
-
|
|
845
|
+
"adorement"
|
|
846
846
|
)} qbs-autocomplete-adorement custom-dorpdown-adorement mr-[1px] ${
|
|
847
|
-
isLoading ?
|
|
847
|
+
isLoading ? "bg-white" : ""
|
|
848
848
|
}`}
|
|
849
849
|
>
|
|
850
850
|
{showClose && (
|
|
@@ -859,7 +859,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
859
859
|
</button>
|
|
860
860
|
)}
|
|
861
861
|
{isLoading && <Spinner />}
|
|
862
|
-
{type !==
|
|
862
|
+
{type !== "auto_complete" && !disabled && !readOnly && (
|
|
863
863
|
<button
|
|
864
864
|
disabled={disabled ?? readOnly}
|
|
865
865
|
onClick={(e) => handleOpen(e)}
|
|
@@ -883,7 +883,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
883
883
|
{errors && errors[name] && (
|
|
884
884
|
<div
|
|
885
885
|
className={` text-error-label relative cursor-pointer ${generateClassName(
|
|
886
|
-
|
|
886
|
+
"message"
|
|
887
887
|
)}`}
|
|
888
888
|
onMouseEnter={() => setIsHovered(true)}
|
|
889
889
|
onMouseLeave={() => setIsHovered(false)}
|
package/src/commontypes.ts
CHANGED
|
@@ -98,6 +98,7 @@ export interface AutoSuggestionInputProps {
|
|
|
98
98
|
onToolTabChange?: (value?: ValueProps | ValueProps[]) => void;
|
|
99
99
|
autoRefreshMainDropdown?: boolean;
|
|
100
100
|
singleSelectIcon?: any;
|
|
101
|
+
autoTabSelectAll?: boolean; // auto select all when tab is selected
|
|
101
102
|
}
|
|
102
103
|
export interface IconsProps {
|
|
103
104
|
name: any;
|