react-core-ts 1.2.2 → 1.2.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/README.md +2 -0
- package/dist/AutoCompleteWithSelectedList.js +38 -32
- package/dist/AutoCompleteWithSelectedList.js.map +1 -1
- package/dist/AutoCompleteWithTreeStructure.d.ts +2 -2
- package/dist/AutoCompleteWithTreeStructure.js +44 -42
- package/dist/AutoCompleteWithTreeStructure.js.map +1 -1
- package/dist/ExpandableAutoComplete.js +5 -3
- package/dist/ExpandableAutoComplete.js.map +1 -1
- package/dist/ReactAutoComplete.js +2 -2
- package/dist/ReactAutoComplete.js.map +1 -1
- package/dist/commontypes.d.ts +2 -0
- package/dist/styles/components/autocomplete.css +5 -0
- package/package.json +1 -1
- package/src/AutoCompleteWithSelectedList.tsx +62 -35
- package/src/AutoCompleteWithTreeStructure.tsx +65 -62
- package/src/ExpandableAutoComplete.tsx +5 -3
- package/src/ReactAutoComplete.tsx +4 -8
- package/src/commontypes.ts +2 -0
- package/src/styles/components/autocomplete.css +5 -0
|
@@ -5,18 +5,18 @@ import React, {
|
|
|
5
5
|
useImperativeHandle,
|
|
6
6
|
useRef,
|
|
7
7
|
useState,
|
|
8
|
-
} from
|
|
9
|
-
import ReactDOM from
|
|
10
|
-
|
|
11
|
-
import { AutoSuggestionInputProps } from
|
|
12
|
-
import InputActions from
|
|
13
|
-
import TreeNode from
|
|
14
|
-
import { useSuggestions } from
|
|
15
|
-
import { buildTree } from
|
|
16
|
-
import { debounce } from
|
|
17
|
-
import { deepEqual } from
|
|
18
|
-
import { default as Tooltip } from
|
|
19
|
-
import { Search, Spinner } from
|
|
8
|
+
} from "react";
|
|
9
|
+
import ReactDOM from "react-dom";
|
|
10
|
+
|
|
11
|
+
import { AutoSuggestionInputProps } from "./commontypes";
|
|
12
|
+
import InputActions from "./components/InputActions";
|
|
13
|
+
import TreeNode from "./components/TreeNode";
|
|
14
|
+
import { useSuggestions } from "./utilities/autosuggestions";
|
|
15
|
+
import { buildTree } from "./utilities/convertFlatArraytoTreeStructure";
|
|
16
|
+
import { debounce } from "./utilities/debounce";
|
|
17
|
+
import { deepEqual } from "./utilities/deepEqual";
|
|
18
|
+
import { default as Tooltip } from "./utilities/expandableTootltip";
|
|
19
|
+
import { Search, Spinner } from "./utilities/icons";
|
|
20
20
|
|
|
21
21
|
type ValueProps = {
|
|
22
22
|
[key: string]: string;
|
|
@@ -37,14 +37,14 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
37
37
|
fullWidth = false,
|
|
38
38
|
placeholder,
|
|
39
39
|
id,
|
|
40
|
-
type =
|
|
40
|
+
type = "custom_select",
|
|
41
41
|
selectedItems: propsSeelctedItems = [],
|
|
42
42
|
readOnly = false,
|
|
43
43
|
disabled = false,
|
|
44
44
|
value,
|
|
45
45
|
isMultiple = false,
|
|
46
|
-
desc =
|
|
47
|
-
descId =
|
|
46
|
+
desc = "name",
|
|
47
|
+
descId = "id",
|
|
48
48
|
singleSelect,
|
|
49
49
|
className,
|
|
50
50
|
async = false,
|
|
@@ -61,7 +61,7 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
61
61
|
scrollRef,
|
|
62
62
|
isTreeDropdown = true,
|
|
63
63
|
flatArray = false,
|
|
64
|
-
parentField =
|
|
64
|
+
parentField = "parentId",
|
|
65
65
|
errorFlag,
|
|
66
66
|
},
|
|
67
67
|
ref
|
|
@@ -71,7 +71,7 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
71
71
|
const [isInitialRender, setIsInitialRender] = useState(true);
|
|
72
72
|
|
|
73
73
|
const [inputValue, setInputValue] = useState<string>(value);
|
|
74
|
-
const [searchValue, setSearchValue] = useState<string>(
|
|
74
|
+
const [searchValue, setSearchValue] = useState<string>("");
|
|
75
75
|
const [nextPage, setNextPage] = useState<number | undefined>(1);
|
|
76
76
|
const [dropOpen, setDropOpen] = useState<boolean>(false);
|
|
77
77
|
const [selectedItems, setSelectedItems] = useState<ValueProps[]>([]);
|
|
@@ -124,11 +124,11 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
124
124
|
};
|
|
125
125
|
|
|
126
126
|
useEffect(() => {
|
|
127
|
-
window.addEventListener(
|
|
127
|
+
window.addEventListener("resize", adjustDropdownPosition);
|
|
128
128
|
adjustDropdownPosition();
|
|
129
129
|
|
|
130
130
|
return () => {
|
|
131
|
-
window.removeEventListener(
|
|
131
|
+
window.removeEventListener("resize", adjustDropdownPosition);
|
|
132
132
|
};
|
|
133
133
|
}, [dropOpen, selectedItems]);
|
|
134
134
|
|
|
@@ -148,7 +148,7 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
148
148
|
|
|
149
149
|
// Adding debounce to avoid making API calls on every keystroke
|
|
150
150
|
const handleChangeWithDebounce = debounce((value) => {
|
|
151
|
-
if ((type ===
|
|
151
|
+
if ((type === "auto_complete" || type === "auto_suggestion") && async) {
|
|
152
152
|
handlePickSuggestions(value, 1);
|
|
153
153
|
}
|
|
154
154
|
}, 1000);
|
|
@@ -170,7 +170,7 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
170
170
|
}, [propsSeelctedItems]);
|
|
171
171
|
// Effect to set the input value whenever `value` prop changes
|
|
172
172
|
useEffect(() => {
|
|
173
|
-
setInputValue(value ??
|
|
173
|
+
setInputValue(value ?? "");
|
|
174
174
|
}, [value]);
|
|
175
175
|
|
|
176
176
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
@@ -179,7 +179,7 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
179
179
|
setSearchValue(value);
|
|
180
180
|
handleChangeWithDebounce(value);
|
|
181
181
|
if (!value) {
|
|
182
|
-
setInputValue(
|
|
182
|
+
setInputValue("");
|
|
183
183
|
// onChange({ [descId]: '', [desc]: '' });
|
|
184
184
|
}
|
|
185
185
|
};
|
|
@@ -198,19 +198,19 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
198
198
|
|
|
199
199
|
const handleClear = () => {
|
|
200
200
|
if (searchValue) {
|
|
201
|
-
setSearchValue(
|
|
201
|
+
setSearchValue("");
|
|
202
202
|
setDropOpen(false);
|
|
203
203
|
} else {
|
|
204
|
-
setInputValue(
|
|
205
|
-
onChange({ [descId]:
|
|
204
|
+
setInputValue("");
|
|
205
|
+
onChange({ [descId]: "", [desc]: "" });
|
|
206
206
|
setDropOpen(false);
|
|
207
207
|
}
|
|
208
208
|
};
|
|
209
209
|
|
|
210
210
|
const generateClassName = useCallback(() => {
|
|
211
211
|
return `qbs-textfield-default ${className} ${
|
|
212
|
-
errors && errors?.message ?
|
|
213
|
-
} ${expandable ?
|
|
212
|
+
errors && errors?.message ? "textfield-error" : "tree-textfield"
|
|
213
|
+
} ${expandable ? "expandable" : ""}`;
|
|
214
214
|
}, [errors, name]);
|
|
215
215
|
const handleRemoveSelectedItem = (index: number) => {
|
|
216
216
|
setSelectedItems((prev) => {
|
|
@@ -235,31 +235,34 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
235
235
|
// &&
|
|
236
236
|
// event.target.nodeName !== 'svg'
|
|
237
237
|
) {
|
|
238
|
-
|
|
239
|
-
|
|
238
|
+
setTimeout(() => {
|
|
239
|
+
setDropOpen(false);
|
|
240
|
+
setSearchValue("");
|
|
241
|
+
}, 200);
|
|
240
242
|
}
|
|
241
243
|
};
|
|
242
|
-
document.addEventListener(
|
|
243
|
-
window.addEventListener(
|
|
244
|
+
document.addEventListener("mousedown", handleClickOutside as any);
|
|
245
|
+
window.addEventListener("scroll", handleClickOutside as any);
|
|
244
246
|
|
|
245
247
|
const scrollableDivs = document.querySelectorAll(
|
|
246
|
-
'div[style*="overflow"]'
|
|
248
|
+
'div[style*="overflow"], .overflow-auto'
|
|
247
249
|
);
|
|
248
250
|
scrollableDivs.forEach((div) =>
|
|
249
|
-
div.addEventListener(
|
|
251
|
+
div.addEventListener("scroll", handleClickOutside as any)
|
|
250
252
|
);
|
|
251
253
|
if (scrollRef && scrollRef.current && scrollRef.current !== null) {
|
|
252
|
-
scrollRef.current.addEventListener(
|
|
254
|
+
scrollRef.current.addEventListener("scroll", handleClickOutside as any);
|
|
253
255
|
}
|
|
256
|
+
|
|
254
257
|
return () => {
|
|
255
|
-
document.removeEventListener(
|
|
256
|
-
window.removeEventListener(
|
|
258
|
+
document.removeEventListener("mousedown", handleClickOutside as any);
|
|
259
|
+
window.removeEventListener("scroll", handleClickOutside as any);
|
|
257
260
|
scrollableDivs.forEach((div) =>
|
|
258
|
-
div.removeEventListener(
|
|
261
|
+
div.removeEventListener("scroll", handleClickOutside as any)
|
|
259
262
|
);
|
|
260
263
|
if (scrollRef && scrollRef.current && scrollRef.current !== null) {
|
|
261
264
|
scrollRef.current.removeEventListener(
|
|
262
|
-
|
|
265
|
+
"scroll",
|
|
263
266
|
handleClickOutside as any
|
|
264
267
|
);
|
|
265
268
|
}
|
|
@@ -270,7 +273,7 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
270
273
|
const selected: any = isMultiple ? selectedItems : inputValue;
|
|
271
274
|
|
|
272
275
|
const handleOnClick = () => {
|
|
273
|
-
!disabled && !readOnly ? setDropOpen(true) :
|
|
276
|
+
!disabled && !readOnly ? setDropOpen(true) : "";
|
|
274
277
|
};
|
|
275
278
|
const onInputFocus = () => {
|
|
276
279
|
if (inputRef.current) inputRef.current.focus();
|
|
@@ -282,8 +285,8 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
282
285
|
? selectedItems
|
|
283
286
|
?.slice(itemCount)
|
|
284
287
|
.map((item) => item[desc])
|
|
285
|
-
.join(
|
|
286
|
-
:
|
|
288
|
+
.join(", ")
|
|
289
|
+
: "";
|
|
287
290
|
|
|
288
291
|
const handleDropOpen = (e: any) => {
|
|
289
292
|
if (!dropOpen) setDropOpen(true);
|
|
@@ -329,8 +332,8 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
329
332
|
onChange(checkedNodes);
|
|
330
333
|
} else {
|
|
331
334
|
if (!checked) {
|
|
332
|
-
setInputValue(
|
|
333
|
-
onChange({ id:
|
|
335
|
+
setInputValue("");
|
|
336
|
+
onChange({ id: "", name: "" });
|
|
334
337
|
}
|
|
335
338
|
// Single-select logic: uncheck all other nodes and check only the clicked one
|
|
336
339
|
newTreeData = dropDownData.map((node) =>
|
|
@@ -413,8 +416,8 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
413
416
|
|
|
414
417
|
const handleerror = (error: any) => {
|
|
415
418
|
if (
|
|
416
|
-
(errors && errors.message ===
|
|
417
|
-
errors.message ===
|
|
419
|
+
(errors && errors.message === "required") ||
|
|
420
|
+
errors.message === "Required"
|
|
418
421
|
) {
|
|
419
422
|
return `${label} is required`;
|
|
420
423
|
} else {
|
|
@@ -422,13 +425,13 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
422
425
|
}
|
|
423
426
|
};
|
|
424
427
|
return (
|
|
425
|
-
<div className={fullWidth ?
|
|
428
|
+
<div className={fullWidth ? "fullWidth" : "autoWidth"} ref={dropdownRef}>
|
|
426
429
|
{label && (
|
|
427
430
|
<div
|
|
428
431
|
style={{
|
|
429
432
|
marginBottom: 5,
|
|
430
|
-
display:
|
|
431
|
-
justifyContent:
|
|
433
|
+
display: "flex",
|
|
434
|
+
justifyContent: "space-between",
|
|
432
435
|
}}
|
|
433
436
|
>
|
|
434
437
|
<label className={`labels label-text`}>
|
|
@@ -444,9 +447,9 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
444
447
|
|
|
445
448
|
<div
|
|
446
449
|
className={`${
|
|
447
|
-
expandable ?
|
|
450
|
+
expandable ? "qbs-expandable-container" : "qbs-container"
|
|
448
451
|
}`}
|
|
449
|
-
style={{ position:
|
|
452
|
+
style={{ position: "relative" }}
|
|
450
453
|
>
|
|
451
454
|
{selectedItems?.length > 0 && (
|
|
452
455
|
<>
|
|
@@ -493,12 +496,12 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
493
496
|
|
|
494
497
|
<div
|
|
495
498
|
className={`qbs-textfield-expandable ${
|
|
496
|
-
!expandable ?
|
|
499
|
+
!expandable ? "qbs-normal" : ""
|
|
497
500
|
}`}
|
|
498
501
|
data-value={
|
|
499
502
|
selectedItems?.length > 0 || searchValue
|
|
500
503
|
? searchValue
|
|
501
|
-
: placeholder ??
|
|
504
|
+
: placeholder ?? ""
|
|
502
505
|
}
|
|
503
506
|
onClick={() => onInputFocus()}
|
|
504
507
|
>
|
|
@@ -507,7 +510,7 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
507
510
|
ref={inputRef}
|
|
508
511
|
type="text"
|
|
509
512
|
value={
|
|
510
|
-
type ===
|
|
513
|
+
type === "auto_suggestion" && !expandable
|
|
511
514
|
? inputValue
|
|
512
515
|
: searchValue || inputValue
|
|
513
516
|
}
|
|
@@ -516,11 +519,11 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
516
519
|
onFocus={onFocus}
|
|
517
520
|
onClick={() => handleOnClick()}
|
|
518
521
|
className={generateClassName()}
|
|
519
|
-
placeholder={selectedItems?.length > 0 ?
|
|
522
|
+
placeholder={selectedItems?.length > 0 ? "" : placeholder ?? ""}
|
|
520
523
|
readOnly={
|
|
521
524
|
readOnly ||
|
|
522
|
-
type ===
|
|
523
|
-
(type ==
|
|
525
|
+
type === "custom_select" ||
|
|
526
|
+
(type == "auto_suggestion" && !expandable)
|
|
524
527
|
}
|
|
525
528
|
disabled={disabled}
|
|
526
529
|
data-testid="custom-autocomplete"
|
|
@@ -552,9 +555,9 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
552
555
|
style={{ ...dropdownStyle, minHeight: 192 }}
|
|
553
556
|
className={`qbs-autocomplete-suggestions`}
|
|
554
557
|
>
|
|
555
|
-
{type ==
|
|
558
|
+
{type == "auto_suggestion" && !expandable && (
|
|
556
559
|
<div
|
|
557
|
-
style={{ position:
|
|
560
|
+
style={{ position: "relative" }}
|
|
558
561
|
className="react-core-ts-search-container"
|
|
559
562
|
>
|
|
560
563
|
<span className="dropdown-search-icon">
|
|
@@ -571,8 +574,8 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
571
574
|
|
|
572
575
|
<div
|
|
573
576
|
style={{
|
|
574
|
-
gap: isTreeDropdown ?
|
|
575
|
-
minHeight: isTreeDropdown ?
|
|
577
|
+
gap: isTreeDropdown ? "8px" : "0",
|
|
578
|
+
minHeight: isTreeDropdown ? "184px" : "0",
|
|
576
579
|
}}
|
|
577
580
|
className={`qbs-autocomplete-suggestions-sub `}
|
|
578
581
|
>
|
|
@@ -603,7 +606,7 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
603
606
|
<>
|
|
604
607
|
{isLoading ? (
|
|
605
608
|
<div
|
|
606
|
-
style={{ display:
|
|
609
|
+
style={{ display: "flex", justifyContent: "center" }}
|
|
607
610
|
>
|
|
608
611
|
<span>
|
|
609
612
|
<Spinner />
|
|
@@ -614,7 +617,7 @@ const AutoCompleteWithTreeStructure = forwardRef<
|
|
|
614
617
|
className="qbs-autocomplete-notfound"
|
|
615
618
|
onClick={handleBlur}
|
|
616
619
|
>
|
|
617
|
-
{notDataMessage ??
|
|
620
|
+
{notDataMessage ?? "No Results Found"}
|
|
618
621
|
</li>
|
|
619
622
|
)}
|
|
620
623
|
</>
|
|
@@ -252,15 +252,17 @@ const ExpandableAutoComplete = forwardRef<
|
|
|
252
252
|
// &&
|
|
253
253
|
// event.target.nodeName !== "svg"
|
|
254
254
|
) {
|
|
255
|
-
|
|
256
|
-
|
|
255
|
+
setTimeout(() => {
|
|
256
|
+
setDropOpen(false);
|
|
257
|
+
setSearchValue("");
|
|
258
|
+
}, 200);
|
|
257
259
|
}
|
|
258
260
|
};
|
|
259
261
|
document.addEventListener("mousedown", handleClickOutside as any);
|
|
260
262
|
window.addEventListener("scroll", handleClickOutside as any);
|
|
261
263
|
|
|
262
264
|
const scrollableDivs = document.querySelectorAll(
|
|
263
|
-
'div[style*="overflow"]'
|
|
265
|
+
'div[style*="overflow"], .overflow-auto'
|
|
264
266
|
);
|
|
265
267
|
scrollableDivs.forEach((div) =>
|
|
266
268
|
div.addEventListener("scroll", handleClickOutside as any)
|
|
@@ -327,7 +327,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
327
327
|
const mainElement = document.querySelector('main');
|
|
328
328
|
mainElement?.addEventListener('scroll', handleScroll);
|
|
329
329
|
|
|
330
|
-
const gridElements = document.querySelectorAll('.k-grid-content');
|
|
330
|
+
const gridElements = document.querySelectorAll('.k-grid-content, .overflow-auto');
|
|
331
331
|
gridElements.forEach((gridElement: any) => {
|
|
332
332
|
gridElement.addEventListener('scroll', handleScroll);
|
|
333
333
|
});
|
|
@@ -634,18 +634,14 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
634
634
|
}
|
|
635
635
|
}}
|
|
636
636
|
/>
|
|
637
|
-
{
|
|
637
|
+
{isModern && (
|
|
638
638
|
<label
|
|
639
639
|
htmlFor={id}
|
|
640
640
|
onClick={() => onLabelClick()}
|
|
641
641
|
className={generateClassName('label')}
|
|
642
642
|
>
|
|
643
|
-
{label}
|
|
644
|
-
{required
|
|
645
|
-
<span className="text-error"> *</span>
|
|
646
|
-
) : (
|
|
647
|
-
<></>
|
|
648
|
-
)}
|
|
643
|
+
{label ? label : ''}
|
|
644
|
+
{required ? <span className="text-error"> *</span> : <></>}
|
|
649
645
|
</label>
|
|
650
646
|
)}
|
|
651
647
|
</div>
|
package/src/commontypes.ts
CHANGED
|
@@ -61,6 +61,8 @@ export interface AutoSuggestionInputProps {
|
|
|
61
61
|
selectedRowLimit?: number // used for showing selected items rows limit, will show scroll if more items added
|
|
62
62
|
topMargin?: number // adjust dropdown postion manually if any overlap issue
|
|
63
63
|
currentTab?: number // current active tab
|
|
64
|
+
selectedLabel?: string // Able to change the "Item selected" label
|
|
65
|
+
viewMode?: boolean // show only selected items
|
|
64
66
|
}
|
|
65
67
|
export interface IconsProps {
|
|
66
68
|
name: any;
|
|
@@ -209,6 +209,11 @@ body * {
|
|
|
209
209
|
margin-top: 2px;
|
|
210
210
|
padding-top: 10px;
|
|
211
211
|
}
|
|
212
|
+
.qbs-dropdown-selected-preview {
|
|
213
|
+
.qbs-dropdown-selected-container {
|
|
214
|
+
border-top: 0px;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
212
217
|
|
|
213
218
|
.qbs-dropdown-selected-container .qbs-clear-link {
|
|
214
219
|
color: #e76458;
|