react-core-ts 2.1.19 → 2.1.21
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/AutoCompleteWithTabFilter.js +0 -1
- package/dist/AutoCompleteWithTabFilter.js.map +1 -1
- package/dist/ReactAutoComplete.js +35 -25
- package/dist/ReactAutoComplete.js.map +1 -1
- package/dist/ReactAutoCompleteDropdown.js +37 -25
- package/dist/ReactAutoCompleteDropdown.js.map +1 -1
- package/dist/ReactAutoCompleteSuggections.js +30 -20
- package/dist/ReactAutoCompleteSuggections.js.map +1 -1
- package/dist/ReactAutoCompleteTableView.js +37 -25
- package/dist/ReactAutoCompleteTableView.js.map +1 -1
- package/package.json +1 -1
- package/src/AutoCompleteWithTabFilter.tsx +0 -1
- package/src/ReactAutoComplete.tsx +48 -28
- package/src/ReactAutoCompleteDropdown.tsx +50 -28
- package/src/ReactAutoCompleteSuggections.tsx +46 -25
- package/src/ReactAutoCompleteTableView.tsx +48 -26
|
@@ -101,6 +101,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
101
101
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
102
102
|
const adorementRef = useRef<HTMLDivElement>(null);
|
|
103
103
|
const dropdownref = useRef<HTMLDivElement>(null);
|
|
104
|
+
const dropdownContentRef = useRef<HTMLDivElement | null>(null);
|
|
104
105
|
const dropBtnRef = useRef<HTMLButtonElement>(null);
|
|
105
106
|
const timerRef = useRef<number>(0); // To fix the no results found issue on second type
|
|
106
107
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
@@ -359,39 +360,57 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
359
360
|
}
|
|
360
361
|
};
|
|
361
362
|
|
|
362
|
-
const handleScroll = () => {
|
|
363
|
-
|
|
363
|
+
const handleScroll = (event: any) => {
|
|
364
|
+
const scrollTarget = event.target as Node | null;
|
|
365
|
+
|
|
366
|
+
// Ignore scrolls inside the main autocomplete container or dropdown content
|
|
367
|
+
if (
|
|
368
|
+
scrollTarget &&
|
|
369
|
+
((dropdownref.current && dropdownref.current.contains(scrollTarget)) ||
|
|
370
|
+
(dropdownContentRef.current &&
|
|
371
|
+
dropdownContentRef.current.contains(scrollTarget)))
|
|
372
|
+
) {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (dropOpen) {
|
|
377
|
+
setDropOpen(false);
|
|
378
|
+
}
|
|
364
379
|
};
|
|
365
380
|
|
|
366
381
|
useEffect(() => {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
382
|
+
// Only attach scroll listeners when dropdown is open and rendered in portal
|
|
383
|
+
if (insideOpen || !dropOpen) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
setSelectedIndex(0);
|
|
388
|
+
|
|
389
|
+
const scrollableDivs = document.querySelectorAll(
|
|
390
|
+
'div[style*="overflow"], .overflow-auto, .overflow-y-auto, .overflow-x-auto',
|
|
391
|
+
);
|
|
392
|
+
|
|
393
|
+
window.addEventListener('scroll', handleScroll);
|
|
394
|
+
document.addEventListener('scroll', handleScroll, true);
|
|
395
|
+
|
|
396
|
+
scrollableDivs.forEach((div) => {
|
|
397
|
+
div.addEventListener('scroll', handleScroll as any);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
window.addEventListener('resize', getDropPosition);
|
|
401
|
+
getDropPosition();
|
|
402
|
+
|
|
403
|
+
return () => {
|
|
404
|
+
window.removeEventListener('scroll', handleScroll);
|
|
405
|
+
document.removeEventListener('scroll', handleScroll, true);
|
|
406
|
+
|
|
407
|
+
scrollableDivs.forEach((div) => {
|
|
408
|
+
div.removeEventListener('scroll', handleScroll as any);
|
|
379
409
|
});
|
|
380
410
|
|
|
381
|
-
window.
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
window.removeEventListener('scroll', handleScroll);
|
|
385
|
-
const mainElement = document.querySelector('main');
|
|
386
|
-
mainElement?.removeEventListener('scroll', handleScroll);
|
|
387
|
-
window.addEventListener('resize', getDropPosition);
|
|
388
|
-
const gridElements = document.querySelectorAll('.k-grid-content');
|
|
389
|
-
gridElements.forEach((gridElement: any) => {
|
|
390
|
-
gridElement.removeEventListener('scroll', handleScroll);
|
|
391
|
-
});
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
}, [dropOpen]);
|
|
411
|
+
window.removeEventListener('resize', getDropPosition);
|
|
412
|
+
};
|
|
413
|
+
}, [dropOpen, insideOpen]);
|
|
395
414
|
|
|
396
415
|
const handleClear = () => {
|
|
397
416
|
setDropOpen(false);
|
|
@@ -732,6 +751,7 @@ const ModernAutoComplete: React.FC<AutoSuggestionInputProps> = ({
|
|
|
732
751
|
return (
|
|
733
752
|
(filteredData?.length > 0 || showNoResults) && (
|
|
734
753
|
<div
|
|
754
|
+
ref={dropdownContentRef}
|
|
735
755
|
className="autocomplete-suggections absolute bg-white shadow-gray-300 shadow-md border border-grey-light z-50 mt-9"
|
|
736
756
|
style={dropPosition}
|
|
737
757
|
>
|
|
@@ -103,6 +103,7 @@ const ModernAutoCompleteDropdown: React.FC<AutoSuggestionInputProps> = ({
|
|
|
103
103
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
104
104
|
const adorementRef = useRef<HTMLDivElement>(null);
|
|
105
105
|
const dropdownref = useRef<HTMLDivElement>(null);
|
|
106
|
+
const dropdownContentRef = useRef<HTMLDivElement | null>(null);
|
|
106
107
|
const dropBtnRef = useRef<HTMLButtonElement>(null);
|
|
107
108
|
const timerRef = useRef<number>(0); // To fix the no results found issue on second type
|
|
108
109
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
@@ -379,39 +380,59 @@ const ModernAutoCompleteDropdown: React.FC<AutoSuggestionInputProps> = ({
|
|
|
379
380
|
}
|
|
380
381
|
};
|
|
381
382
|
|
|
382
|
-
const handleScroll = () => {
|
|
383
|
-
|
|
383
|
+
const handleScroll = (event: any) => {
|
|
384
|
+
const scrollTarget = event.target as Node | null;
|
|
385
|
+
|
|
386
|
+
// Don't close if the user is scrolling inside the main autocomplete container
|
|
387
|
+
// or inside the dropdown content itself (portal list).
|
|
388
|
+
if (
|
|
389
|
+
scrollTarget &&
|
|
390
|
+
((dropdownref.current && dropdownref.current.contains(scrollTarget)) ||
|
|
391
|
+
(dropdownContentRef.current &&
|
|
392
|
+
dropdownContentRef.current.contains(scrollTarget)))
|
|
393
|
+
) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (dropOpen) {
|
|
398
|
+
setDropOpen(false);
|
|
399
|
+
}
|
|
384
400
|
};
|
|
385
401
|
|
|
386
402
|
useEffect(() => {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
403
|
+
// Only attach scroll listeners when dropdown is open and rendered in portal
|
|
404
|
+
if (insideOpen || !dropOpen) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
setSelectedIndex(0);
|
|
409
|
+
|
|
410
|
+
const scrollableDivs = document.querySelectorAll(
|
|
411
|
+
'div[style*="overflow"], .overflow-auto, .overflow-y-auto, .overflow-x-auto',
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
// Listen to window/document scrolls, plus any scrollable divs
|
|
415
|
+
window.addEventListener('scroll', handleScroll);
|
|
416
|
+
document.addEventListener('scroll', handleScroll, true);
|
|
417
|
+
|
|
418
|
+
scrollableDivs.forEach((div) => {
|
|
419
|
+
div.addEventListener('scroll', handleScroll as any);
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
window.addEventListener('resize', getDropPosition);
|
|
423
|
+
getDropPosition();
|
|
424
|
+
|
|
425
|
+
return () => {
|
|
426
|
+
window.removeEventListener('scroll', handleScroll);
|
|
427
|
+
document.removeEventListener('scroll', handleScroll, true);
|
|
428
|
+
|
|
429
|
+
scrollableDivs.forEach((div) => {
|
|
430
|
+
div.removeEventListener('scroll', handleScroll as any);
|
|
399
431
|
});
|
|
400
432
|
|
|
401
|
-
window.
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
window.removeEventListener('scroll', handleScroll);
|
|
405
|
-
const mainElement = document.querySelector('main');
|
|
406
|
-
mainElement?.removeEventListener('scroll', handleScroll);
|
|
407
|
-
window.addEventListener('resize', getDropPosition);
|
|
408
|
-
const gridElements = document.querySelectorAll('.k-grid-content');
|
|
409
|
-
gridElements.forEach((gridElement: any) => {
|
|
410
|
-
gridElement.removeEventListener('scroll', handleScroll);
|
|
411
|
-
});
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
}, [dropOpen]);
|
|
433
|
+
window.removeEventListener('resize', getDropPosition);
|
|
434
|
+
};
|
|
435
|
+
}, [dropOpen, insideOpen]);
|
|
415
436
|
|
|
416
437
|
const handleClear = () => {
|
|
417
438
|
setDropOpen(false);
|
|
@@ -749,6 +770,7 @@ const ModernAutoCompleteDropdown: React.FC<AutoSuggestionInputProps> = ({
|
|
|
749
770
|
return (
|
|
750
771
|
(filteredData?.length > 0 || showNoResults) && (
|
|
751
772
|
<div
|
|
773
|
+
ref={dropdownContentRef}
|
|
752
774
|
style={dropPosition}
|
|
753
775
|
className="autocomplete-suggections absolute bg-white shadow-gray-300 shadow-md border border-grey-light z-50 mt-9"
|
|
754
776
|
>
|
|
@@ -137,6 +137,7 @@ const ModernAutoCompleteSuggections: React.FC<
|
|
|
137
137
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
138
138
|
const adorementRef = useRef<HTMLDivElement>(null);
|
|
139
139
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
140
|
+
const dropdownContentRef = useRef<HTMLDivElement | null>(null);
|
|
140
141
|
const isExternalUpdateRef = useRef(false);
|
|
141
142
|
const previousDebouncedValueRef = useRef<string>('');
|
|
142
143
|
|
|
@@ -332,36 +333,52 @@ const ModernAutoCompleteSuggections: React.FC<
|
|
|
332
333
|
}
|
|
333
334
|
};
|
|
334
335
|
|
|
335
|
-
// Handle scroll to close dropdown
|
|
336
|
-
const handleScroll = () => {
|
|
336
|
+
// Handle scroll to close dropdown (only for scrolls outside the component/dropdown)
|
|
337
|
+
const handleScroll = (event: any) => {
|
|
338
|
+
const scrollTarget = event.target as Node | null;
|
|
339
|
+
|
|
340
|
+
if (
|
|
341
|
+
scrollTarget &&
|
|
342
|
+
((containerRef.current &&
|
|
343
|
+
containerRef.current.contains(scrollTarget)) ||
|
|
344
|
+
(dropdownContentRef.current &&
|
|
345
|
+
dropdownContentRef.current.contains(scrollTarget)))
|
|
346
|
+
) {
|
|
347
|
+
// Ignore scrolls inside the autocomplete container or the dropdown content
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
|
|
337
351
|
setShowDropdown(false);
|
|
338
352
|
};
|
|
339
353
|
|
|
340
354
|
// Attach event listeners for click outside and scroll
|
|
341
355
|
useEffect(() => {
|
|
342
|
-
if (showDropdown) {
|
|
343
|
-
|
|
344
|
-
window.addEventListener('scroll', handleScroll);
|
|
345
|
-
|
|
346
|
-
const mainElement = document.querySelector('main');
|
|
347
|
-
mainElement?.addEventListener('scroll', handleScroll);
|
|
348
|
-
|
|
349
|
-
const gridElements = document.querySelectorAll(
|
|
350
|
-
'.k-grid-content, .overflow-auto, .overflow-y-auto, .overflow-x-auto'
|
|
351
|
-
);
|
|
352
|
-
gridElements.forEach((gridElement: any) => {
|
|
353
|
-
gridElement.addEventListener('scroll', handleScroll);
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
return () => {
|
|
357
|
-
document.removeEventListener('click', handleClickOutside);
|
|
358
|
-
window.removeEventListener('scroll', handleScroll);
|
|
359
|
-
mainElement?.removeEventListener('scroll', handleScroll);
|
|
360
|
-
gridElements.forEach((gridElement: any) => {
|
|
361
|
-
gridElement.removeEventListener('scroll', handleScroll);
|
|
362
|
-
});
|
|
363
|
-
};
|
|
356
|
+
if (!showDropdown) {
|
|
357
|
+
return;
|
|
364
358
|
}
|
|
359
|
+
|
|
360
|
+
document.addEventListener('click', handleClickOutside);
|
|
361
|
+
|
|
362
|
+
const scrollableDivs = document.querySelectorAll(
|
|
363
|
+
'div[style*="overflow"], .overflow-auto, .overflow-y-auto, .overflow-x-auto'
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
window.addEventListener('scroll', handleScroll);
|
|
367
|
+
document.addEventListener('scroll', handleScroll, true);
|
|
368
|
+
|
|
369
|
+
scrollableDivs.forEach((div) => {
|
|
370
|
+
div.addEventListener('scroll', handleScroll as any);
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
return () => {
|
|
374
|
+
document.removeEventListener('click', handleClickOutside);
|
|
375
|
+
window.removeEventListener('scroll', handleScroll);
|
|
376
|
+
document.removeEventListener('scroll', handleScroll, true);
|
|
377
|
+
|
|
378
|
+
scrollableDivs.forEach((div) => {
|
|
379
|
+
div.removeEventListener('scroll', handleScroll as any);
|
|
380
|
+
});
|
|
381
|
+
};
|
|
365
382
|
}, [showDropdown]);
|
|
366
383
|
|
|
367
384
|
const checkIsEmptyField = (): boolean => {
|
|
@@ -643,7 +660,10 @@ const ModernAutoCompleteSuggections: React.FC<
|
|
|
643
660
|
<>
|
|
644
661
|
{insideOpen ? (
|
|
645
662
|
<div className="suggection-list">
|
|
646
|
-
<div
|
|
663
|
+
<div
|
|
664
|
+
ref={dropdownContentRef}
|
|
665
|
+
className="bg-white border border-grey-light shadow-gray-300 shadow-md rounded-sm max-h-40 overflow-auto text-[11px] text-gray-700 px-3.5 py-1.5"
|
|
666
|
+
>
|
|
647
667
|
{effectiveVisible.map((g) => (
|
|
648
668
|
<SuggestionItem
|
|
649
669
|
key={g.name}
|
|
@@ -657,6 +677,7 @@ const ModernAutoCompleteSuggections: React.FC<
|
|
|
657
677
|
) : (
|
|
658
678
|
<Portal>
|
|
659
679
|
<div
|
|
680
|
+
ref={dropdownContentRef}
|
|
660
681
|
className="autocomplete-suggections autosuggection-list suggection-list bg-white shadow-gray-300 shadow-md border border-grey-light z-50"
|
|
661
682
|
style={dropPosition}
|
|
662
683
|
>
|
|
@@ -114,6 +114,7 @@ const ReactAutoCompleteTableView: React.FC<AutoSuggestionInputProps> = ({
|
|
|
114
114
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
115
115
|
const adorementRef = useRef<HTMLDivElement>(null);
|
|
116
116
|
const dropdownref = useRef<HTMLDivElement>(null);
|
|
117
|
+
const dropdownContentRef = useRef<HTMLDivElement | null>(null);
|
|
117
118
|
const dropBtnRef = useRef<HTMLButtonElement>(null);
|
|
118
119
|
const timerRef = useRef<number>(0); // To fix the no results found issue on second type
|
|
119
120
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
@@ -381,39 +382,59 @@ const ReactAutoCompleteTableView: React.FC<AutoSuggestionInputProps> = ({
|
|
|
381
382
|
}
|
|
382
383
|
};
|
|
383
384
|
|
|
384
|
-
const handleScroll = () => {
|
|
385
|
-
|
|
385
|
+
const handleScroll = (event: any) => {
|
|
386
|
+
const scrollTarget = event.target as Node | null;
|
|
387
|
+
|
|
388
|
+
// Ignore scrolls that originate from inside the autocomplete container
|
|
389
|
+
// or inside the dropdown content itself.
|
|
390
|
+
if (
|
|
391
|
+
scrollTarget &&
|
|
392
|
+
((dropdownref.current && dropdownref.current.contains(scrollTarget)) ||
|
|
393
|
+
(dropdownContentRef.current &&
|
|
394
|
+
dropdownContentRef.current.contains(scrollTarget)))
|
|
395
|
+
) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (dropOpen) {
|
|
400
|
+
setDropOpen(false);
|
|
401
|
+
}
|
|
386
402
|
};
|
|
387
403
|
|
|
388
404
|
useEffect(() => {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
405
|
+
// Only attach scroll listeners when dropdown is open and rendered in portal
|
|
406
|
+
if (insideOpen || !dropOpen) {
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
392
409
|
|
|
393
|
-
|
|
394
|
-
|
|
410
|
+
setSelectedIndex(0);
|
|
411
|
+
|
|
412
|
+
const scrollableDivs = document.querySelectorAll(
|
|
413
|
+
'div[style*="overflow"], .overflow-auto, .overflow-y-auto, .overflow-x-auto'
|
|
414
|
+
);
|
|
395
415
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
416
|
+
// Listen to window/document scrolls, plus any scrollable divs
|
|
417
|
+
window.addEventListener('scroll', handleScroll);
|
|
418
|
+
document.addEventListener('scroll', handleScroll, true);
|
|
419
|
+
|
|
420
|
+
scrollableDivs.forEach((div) => {
|
|
421
|
+
div.addEventListener('scroll', handleScroll as any);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
window.addEventListener('resize', getDropPosition);
|
|
425
|
+
getDropPosition();
|
|
426
|
+
|
|
427
|
+
return () => {
|
|
428
|
+
window.removeEventListener('scroll', handleScroll);
|
|
429
|
+
document.removeEventListener('scroll', handleScroll, true);
|
|
430
|
+
|
|
431
|
+
scrollableDivs.forEach((div) => {
|
|
432
|
+
div.removeEventListener('scroll', handleScroll as any);
|
|
401
433
|
});
|
|
402
434
|
|
|
403
|
-
window.
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
window.removeEventListener('scroll', handleScroll);
|
|
407
|
-
const mainElement = document.querySelector('main');
|
|
408
|
-
mainElement?.removeEventListener('scroll', handleScroll);
|
|
409
|
-
window.addEventListener('resize', getDropPosition);
|
|
410
|
-
const gridElements = document.querySelectorAll('.k-grid-content');
|
|
411
|
-
gridElements.forEach((gridElement: any) => {
|
|
412
|
-
gridElement.removeEventListener('scroll', handleScroll);
|
|
413
|
-
});
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
}, [dropOpen]);
|
|
435
|
+
window.removeEventListener('resize', getDropPosition);
|
|
436
|
+
};
|
|
437
|
+
}, [dropOpen, insideOpen]);
|
|
417
438
|
|
|
418
439
|
const handleClear = () => {
|
|
419
440
|
setDropOpen(false);
|
|
@@ -731,6 +752,7 @@ const ReactAutoCompleteTableView: React.FC<AutoSuggestionInputProps> = ({
|
|
|
731
752
|
return (
|
|
732
753
|
(filteredData?.length > 0 || showNoResults) && (
|
|
733
754
|
<div
|
|
755
|
+
ref={dropdownContentRef}
|
|
734
756
|
style={{ ...dropPosition, overflow: 'hidden' }}
|
|
735
757
|
className="autocomplete-suggections autocomplete-suggections-tableview absolute bg-white shadow-gray-300 shadow-md border border-grey-light z-50 mt-9"
|
|
736
758
|
>
|