react-core-ts 1.2.31 → 1.2.32

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.
@@ -0,0 +1,778 @@
1
+ import React, {
2
+ forwardRef,
3
+ useCallback,
4
+ useEffect,
5
+ useImperativeHandle,
6
+ useRef,
7
+ useState,
8
+ } from 'react';
9
+ import ReactDOM from 'react-dom';
10
+
11
+ import { AutoSuggestionInputProps, TabPops, ValueProps } from './commontypes';
12
+ import DropdownList from './components/DropdownList';
13
+ import InputActions from './components/InputActions';
14
+ import { useSuggestions } from './utilities/autosuggestions';
15
+ import { debounce } from './utilities/debounce';
16
+ import { deepEqual } from './utilities/deepEqual';
17
+ import { default as Tooltip } from './utilities/expandableTootltip';
18
+ import { filterSuggestions } from './utilities/filterSuggestions';
19
+ import { DropArrow, Search, Spinner } from './utilities/icons';
20
+
21
+ const AutoCompleteWithSelectedList = forwardRef<
22
+ HTMLInputElement,
23
+ AutoSuggestionInputProps
24
+ >(
25
+ (
26
+ {
27
+ label,
28
+ onChange,
29
+ getData = async () => [],
30
+ data = [],
31
+ errors,
32
+ required = false,
33
+ name,
34
+ fullWidth = false,
35
+ placeholder,
36
+ id,
37
+ type = 'custom_select',
38
+ selectedItems: propsSeelctedItems = [],
39
+ readOnly = false,
40
+ disabled = false,
41
+ value,
42
+ isMultiple = false,
43
+ desc = 'name',
44
+ descId = 'id',
45
+ singleSelect,
46
+ className,
47
+ async = false,
48
+ paginationEnabled,
49
+ initialLoad = false,
50
+ actionLabel,
51
+ handleAction,
52
+ nextBlock,
53
+ notDataMessage,
54
+ initialDataMessage,
55
+ onFocus,
56
+ expandable = false,
57
+ textCount = 10,
58
+ itemCount = 1,
59
+ scrollRef,
60
+ countOnly = true,
61
+ typeOnlyFetch = false,
62
+ tab = [],
63
+ clearTabSwitch = false,
64
+ selectedRowLimit = 2,
65
+ topMargin = 0,
66
+ currentTab = 0,
67
+ selectedLabel = '',
68
+ viewMode = false,
69
+ },
70
+ ref
71
+ ) => {
72
+ const dropdownRef = useRef<HTMLDivElement>(null);
73
+ const dropdownSelectedRef = useRef<HTMLDivElement>(null);
74
+ const tabRef = useRef<HTMLUListElement>(null);
75
+ // State Hooks Section
76
+ const [isInitialRender, setIsInitialRender] = useState(true);
77
+
78
+ const [inputValue, setInputValue] = useState<string>(value);
79
+ const [searchValue, setSearchValue] = useState<string>('');
80
+ const [searchOldValue, setSearchOldValue] = useState<string>('');
81
+ const [nextPage, setNextPage] = useState<number | undefined>(1);
82
+ const [dropOpen, setDropOpen] = useState<boolean>(false);
83
+ const [selectedItems, setSelectedItems] = useState<ValueProps[]>([]);
84
+
85
+ const [showAllSelected, setShowAllSelected] = useState<boolean>(false);
86
+ const [expandArrowClick, setExpandArrowClick] = useState<
87
+ number | undefined
88
+ >(1);
89
+ const [activeTab, setActiveTab] = useState<number>(currentTab);
90
+ // API call for suggestions through a custom hook
91
+ const inputRef = useRef(null);
92
+ const dropRef = useRef(null);
93
+ const inputSearchRef = useRef(null);
94
+ useImperativeHandle(ref, () => inputRef.current);
95
+ const [dropdownStyle, setDropdownStyle] = useState<any>({
96
+ top: undefined,
97
+ left: 0,
98
+ width: 200,
99
+ });
100
+
101
+ const adjustDropdownPosition = () => {
102
+ if (dropdownRef.current) {
103
+ const inputRect = dropdownRef.current.getBoundingClientRect();
104
+ const dropdownPosition = {
105
+ left: inputRect.left + window.scrollX,
106
+ width: inputRect.width,
107
+ top: 0,
108
+ };
109
+ // Check if there's enough space below the input for the dropdown
110
+ const spaceBelow = window.innerHeight - inputRect.bottom;
111
+ let dropdownHeight = viewMode ? 160 : 380; // Assume a fixed height or calculate based on content
112
+
113
+ if (countOnly && !viewMode) {
114
+ // if (dropdownSelectedRef?.current) {
115
+ // dropdownHeight += dropdownSelectedRef?.current?.clientHeight;
116
+ // }
117
+ dropdownHeight += type === 'auto_suggestion' ? 220 : 192;
118
+ }
119
+
120
+ if (tab.length > 0) {
121
+ if (tabRef?.current) dropdownHeight += tabRef?.current?.clientHeight;
122
+ }
123
+ console.log(dropdownHeight);
124
+ if (spaceBelow >= dropdownHeight) {
125
+ dropdownPosition.top =
126
+ inputRect.top + window.scrollY + inputRect.height;
127
+ } else {
128
+ dropdownPosition.top = viewMode
129
+ ? inputRect.top + window.scrollY - dropdownHeight + 18 + topMargin
130
+ : inputRect.top + window.scrollY - dropdownHeight + 73 + topMargin;
131
+ }
132
+ setTimeout(() => {
133
+ setDropdownStyle({
134
+ ...dropdownPosition,
135
+ });
136
+ }, 100);
137
+ }
138
+ };
139
+
140
+ useEffect(() => {
141
+ window.addEventListener('resize', adjustDropdownPosition);
142
+ adjustDropdownPosition();
143
+
144
+ return () => {
145
+ window.removeEventListener('resize', adjustDropdownPosition);
146
+ };
147
+ }, [selectedItems, expandArrowClick, dropOpen]);
148
+
149
+ const { suggestions, isLoading, handlePickSuggestions } = useSuggestions(
150
+ getData,
151
+ data,
152
+ dropOpen,
153
+ async,
154
+ paginationEnabled,
155
+ initialLoad,
156
+ inputValue,
157
+ isMultiple,
158
+ setNextPage,
159
+ selectedItems,
160
+ typeOnlyFetch
161
+ // nextBlock
162
+ );
163
+
164
+ // Handling the selection of a suggestion
165
+ const handleSuggestionClick = useCallback((suggestion: ValueProps) => {
166
+ if (isMultiple) {
167
+ setSelectedItems((prev) => {
168
+ const isAdded =
169
+ prev && prev.length > 0
170
+ ? prev.some((item) => item[descId] === suggestion[descId])
171
+ : false;
172
+ if (isAdded) {
173
+ return prev.filter((item) => item[descId] !== suggestion[descId]);
174
+ } else {
175
+ return [...prev, suggestion];
176
+ }
177
+ });
178
+ } else {
179
+ setInputValue(suggestion[desc]);
180
+ setSearchValue('');
181
+ onChange(suggestion);
182
+ setDropOpen(false);
183
+ }
184
+ }, []);
185
+
186
+ // Adding debounce to avoid making API calls on every keystroke
187
+ const debouncedUpdate = useCallback(
188
+ debounce((value: string, tabVal?: number | string) => {
189
+ setSearchOldValue(value);
190
+ handlePickSuggestions(value, 1, false, tabVal);
191
+ }, 500),
192
+ []
193
+ );
194
+
195
+ const handleChangeWithDebounce = (value: string) => {
196
+ if ((type === 'auto_complete' || type === 'auto_suggestion') && async) {
197
+ const activeTabVal = tab.length > 0 ? tab?.[activeTab].id : undefined;
198
+ debouncedUpdate(value, activeTabVal);
199
+ }
200
+ };
201
+
202
+ const handleMultiSelect = (e: any, suggestion: ValueProps) => {
203
+ const { checked } = e.target;
204
+ if (isMultiple) {
205
+ if (checked) {
206
+ setSelectedItems((prev) => [...prev, suggestion]);
207
+ } else {
208
+ setSelectedItems((prev) => {
209
+ return prev.filter(
210
+ (item, i) => item[descId] !== suggestion[descId]
211
+ );
212
+ });
213
+ }
214
+ } else {
215
+ if (checked) {
216
+ setInputValue(suggestion[desc]);
217
+ onChange(suggestion);
218
+ } else {
219
+ setInputValue('');
220
+ }
221
+ }
222
+ };
223
+ useEffect(() => {
224
+ if (!deepEqual(selectedItems, propsSeelctedItems))
225
+ setSelectedItems(propsSeelctedItems);
226
+ }, [propsSeelctedItems]);
227
+ // Effect to set the input value whenever `value` prop changes
228
+ useEffect(() => {
229
+ setInputValue(value ?? '');
230
+ }, [value]);
231
+
232
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
233
+ const { value } = e.target;
234
+ // setDropOpen(true);
235
+ setSearchValue(value);
236
+ handleChangeWithDebounce(value);
237
+ if (!value) {
238
+ setInputValue('');
239
+ // onChange({ [descId]: '', [desc]: '' });
240
+ }
241
+ };
242
+ const handleSuggestionChange = (e: React.ChangeEvent<HTMLInputElement>) => {
243
+ const { value } = e.target;
244
+ setDropOpen(true);
245
+ setSearchValue(value);
246
+ handleChangeWithDebounce(value);
247
+ };
248
+
249
+ const handleClear = () => {
250
+ if (searchValue) {
251
+ setSearchValue('');
252
+ setDropOpen(false);
253
+ } else {
254
+ setInputValue('');
255
+ if (isMultiple) onChange([]);
256
+ else onChange({ [descId]: '', [desc]: '' });
257
+ setDropOpen(false);
258
+ }
259
+ };
260
+
261
+ const handleClearSelected = () => {
262
+ setSelectedItems([]);
263
+ if (isMultiple) onChange([]);
264
+ else onChange({ [descId]: '', [desc]: '' });
265
+ };
266
+
267
+ const generateClassName = useCallback(() => {
268
+ return `qbs-textfield-default ${className} ${
269
+ errors && errors?.message ? 'textfield-error' : 'textfield'
270
+ } ${expandable ? 'expandable' : ''}`;
271
+ }, [errors, name]);
272
+ const handleRemoveSelectedItem = (index: number) => {
273
+ setSelectedItems((prev) => {
274
+ return prev.filter((_, i) => i !== index);
275
+ });
276
+ };
277
+
278
+ useEffect(() => {
279
+ if (isInitialRender) {
280
+ setIsInitialRender(false);
281
+ } else {
282
+ onChange(selectedItems);
283
+ }
284
+ }, [selectedItems]);
285
+
286
+ useEffect(() => {
287
+ const handleClickOutside = (event: any) => {
288
+ if (
289
+ dropRef.current &&
290
+ event.target instanceof Node &&
291
+ !dropRef.current.contains(event.target) &&
292
+ event.target.nodeName !== 'svg'
293
+ ) {
294
+ setTimeout(() => {
295
+ setDropOpen(false);
296
+ }, 200);
297
+ //setSearchValue("");
298
+ }
299
+ };
300
+ document.addEventListener('mousedown', handleClickOutside as any);
301
+ window.addEventListener('scroll', handleClickOutside as any);
302
+
303
+ const scrollableDivs = document.querySelectorAll(
304
+ 'div[style*="overflow"], .overflow-auto '
305
+ );
306
+ scrollableDivs.forEach((div) =>
307
+ div.addEventListener('scroll', handleClickOutside as any)
308
+ );
309
+ if (scrollRef && scrollRef.current && scrollRef.current !== null) {
310
+ scrollRef.current.addEventListener('scroll', handleClickOutside as any);
311
+ }
312
+ return () => {
313
+ document.removeEventListener('mousedown', handleClickOutside as any);
314
+ window.removeEventListener('scroll', handleClickOutside as any);
315
+ scrollableDivs.forEach((div) =>
316
+ div.removeEventListener('scroll', handleClickOutside as any)
317
+ );
318
+ if (scrollRef && scrollRef.current && scrollRef.current !== null) {
319
+ scrollRef.current.removeEventListener(
320
+ 'scroll',
321
+ handleClickOutside as any
322
+ );
323
+ }
324
+ };
325
+ }, []);
326
+
327
+ // Filtering suggestions based on type and search value
328
+ const selected: any = isMultiple ? selectedItems : inputValue;
329
+ const filteredData: ValueProps[] = filterSuggestions(
330
+ suggestions,
331
+ searchValue,
332
+ type,
333
+ desc,
334
+ selected,
335
+ async,
336
+ false,
337
+ true
338
+ );
339
+ const isSelected = (
340
+ item: ValueProps,
341
+ selectedItems: ValueProps[] | string
342
+ ): boolean => {
343
+ if (Array.isArray(selectedItems)) {
344
+ return selectedItems.some(
345
+ (selectedItem) => selectedItem[desc] === item[desc]
346
+ );
347
+ } else {
348
+ return item[desc] === selectedItems;
349
+ }
350
+ };
351
+
352
+ const handleLoadMore = () => {
353
+ if (paginationEnabled) {
354
+ handlePickSuggestions(searchValue, nextPage + 1, true);
355
+ setNextPage(nextPage + 1);
356
+ }
357
+ };
358
+
359
+ const handleOnClick = () => {
360
+ (!disabled && !readOnly && !expandable && !dropOpen) || viewMode
361
+ ? setDropOpen(true)
362
+ : '';
363
+ };
364
+ const onInputFocus = () => {
365
+ if (!dropOpen) {
366
+ if (countOnly) {
367
+ setTimeout(() => {
368
+ if (inputSearchRef.current) inputSearchRef.current.focus();
369
+ }, 100);
370
+ } else {
371
+ if (inputRef.current) inputRef.current.focus();
372
+ }
373
+ handleOnClick();
374
+ }
375
+ };
376
+
377
+ const handleShowAllSelected = (enabled: boolean) => {
378
+ setExpandArrowClick(expandArrowClick + 1);
379
+ if (enabled) {
380
+ setShowAllSelected(true);
381
+ } else {
382
+ setShowAllSelected(false);
383
+ }
384
+ };
385
+
386
+ const handleCollapseArrowClick = () => {
387
+ setExpandArrowClick(expandArrowClick + 1);
388
+ setShowAllSelected(false);
389
+ };
390
+
391
+ const tooltipContent =
392
+ selectedItems?.length > itemCount
393
+ ? selectedItems
394
+ ?.slice(itemCount)
395
+ .map((item) => item[desc])
396
+ .join(', ')
397
+ : '';
398
+
399
+ const handleDropOpen = async (e: any) => {
400
+ e.stopPropagation();
401
+ if (!dropOpen) setDropOpen(true);
402
+ };
403
+
404
+ const handleDropClose = (e: any) => {
405
+ e.stopPropagation();
406
+ if (dropOpen) setDropOpen(false);
407
+ };
408
+
409
+ const handleTabClick = (index: number) => {
410
+ if (activeTab !== index) {
411
+ if (clearTabSwitch) {
412
+ handleClearSelected();
413
+ setSearchValue('');
414
+ setInputValue('');
415
+ handlePickSuggestions('', 1);
416
+ }
417
+ setActiveTab(index);
418
+ }
419
+ };
420
+
421
+ const getSelectedRowLimit = () => {
422
+ return selectedRowLimit * 33 + 5;
423
+ };
424
+
425
+ const getSelectedItems = (dropdown: boolean) => {
426
+ return (
427
+ <div
428
+ className="selected-items-outer-container"
429
+ style={{ maxHeight: `${getSelectedRowLimit()}px` }}
430
+ >
431
+ {selectedItems
432
+ .slice(
433
+ 0,
434
+ selectedItems?.length > itemCount
435
+ ? showAllSelected
436
+ ? selectedItems?.length
437
+ : itemCount
438
+ : selectedItems?.length
439
+ )
440
+ .map((item, index) => (
441
+ <div key={index} className="selected-items-container">
442
+ <Tooltip
443
+ title={item?.[desc]}
444
+ enabled={item?.[desc]?.length > textCount}
445
+ >
446
+ <div key={item.id} className="selected-item">
447
+ {item?.[desc]?.length > textCount
448
+ ? `${item?.[desc].substring(0, textCount)}...`
449
+ : item?.[desc]}
450
+ {!viewMode && (
451
+ <button
452
+ onClick={() => handleRemoveSelectedItem(index)}
453
+ className="remove-item-btn"
454
+ aria-label={`Remove ${item?.[desc]}`}
455
+ >
456
+ X
457
+ </button>
458
+ )}
459
+ </div>
460
+ </Tooltip>
461
+ </div>
462
+ ))}
463
+ {selectedItems?.length > itemCount && !showAllSelected && (
464
+ <div className="selected-items-container">
465
+ <Tooltip title={tooltipContent} enabled={true}>
466
+ <div
467
+ className={`selected-item-more qbs-rounded-full qbs-min-h-6 qbs-min-w-6 qbs-p-1 ${
468
+ dropdown ? 'qbs-cursor-pointer' : ''
469
+ }`}
470
+ onClick={() => {
471
+ handleShowAllSelected(dropdown);
472
+ }}
473
+ >
474
+ +{selectedItems?.length - itemCount}{' '}
475
+ <span className="qbs-hidden">more</span>
476
+ </div>
477
+ </Tooltip>
478
+ </div>
479
+ )}
480
+ </div>
481
+ );
482
+ };
483
+
484
+ const getTabItems = () => {
485
+ return (
486
+ <ul
487
+ className="qbs-flex qbs-flex-wrap qbs-w-full qbs-tab qbs-mb-2 -qbs-mt-2"
488
+ ref={tabRef}
489
+ >
490
+ {tab.map((item: TabPops, idx: number) => (
491
+ <li className="qbs-flex-1 qbs-tab-items" key={`tab-${idx}`}>
492
+ <span
493
+ className={`qbs-inline-block qbs-tab-item qbs-text-sm qbs-cursor-pointer qbs-w-full qbs-text-center qbs-p-1 qbs-border-b-2 ${
494
+ activeTab === idx ? 'qbs-tab-active-item' : ''
495
+ }`}
496
+ onClick={() => {
497
+ handleTabClick(idx);
498
+ }}
499
+ >
500
+ {item.label}
501
+ </span>
502
+ </li>
503
+ ))}
504
+ </ul>
505
+ );
506
+ };
507
+
508
+ return (
509
+ <div className={fullWidth ? 'fullWidth' : 'autoWidth'} ref={dropdownRef}>
510
+ {label && (
511
+ <div
512
+ style={{
513
+ marginBottom: 5,
514
+ display: 'flex',
515
+ justifyContent: 'space-between',
516
+ }}
517
+ >
518
+ <label className={`labels label-text`}>
519
+ {label}
520
+ {required && <span className="text-error"> *</span>}
521
+ </label>
522
+ <span onClick={() => handleAction?.()} className={`action_label`}>
523
+ {actionLabel}
524
+ </span>
525
+ </div>
526
+ )}
527
+ {/* Displaying selected items for multi-select */}
528
+
529
+ <div
530
+ className={`qbs-relative qbs-autocomplete-selected-comp ${
531
+ expandable ? 'qbs-expandable-container' : 'qbs-container'
532
+ }`}
533
+ >
534
+ {selectedItems?.length > 0 && (
535
+ <>
536
+ {!countOnly ? (
537
+ getSelectedItems(false)
538
+ ) : (
539
+ <div
540
+ className="selected-items-container qbs-text-sm qbs-gap-1"
541
+ onClick={() => onInputFocus()}
542
+ >
543
+ <span className="badge qbs-rounded-full qbs-text-xs qbs-inline-flex qbs-items-center qbs-justify-center qbs-px-2 qbs-py-1 qbs-leading-none qbs-min-w-6 qbs-min-h-6">
544
+ {selectedItems?.length}
545
+ </span>
546
+ <span className="selected-label-text">
547
+ {selectedLabel && selectedLabel !== '' ? (
548
+ selectedLabel
549
+ ) : (
550
+ <>Item{selectedItems?.length > 1 && 's'} Selected</>
551
+ )}
552
+ </span>
553
+ </div>
554
+ )}
555
+ </>
556
+ )}
557
+
558
+ <div
559
+ className={`qbs-textfield-expandable ${
560
+ !expandable ? 'qbs-normal' : ''
561
+ }`}
562
+ data-value={
563
+ selectedItems?.length > 0 || searchValue
564
+ ? searchValue
565
+ : placeholder ?? ''
566
+ }
567
+ onClick={() => onInputFocus()}
568
+ >
569
+ <input
570
+ id={id}
571
+ ref={inputRef}
572
+ type="text"
573
+ value={
574
+ type === 'auto_suggestion' && !expandable
575
+ ? inputValue
576
+ : searchValue || inputValue
577
+ }
578
+ onChange={handleChange}
579
+ // onBlur={handleBlur}
580
+ onFocus={onFocus}
581
+ onClick={() => handleOnClick()}
582
+ className={generateClassName()}
583
+ placeholder={selectedItems?.length > 0 ? '' : placeholder ?? ''}
584
+ readOnly={
585
+ readOnly ||
586
+ type === 'custom_select' ||
587
+ (type == 'auto_suggestion' && !expandable)
588
+ }
589
+ disabled={disabled}
590
+ data-testid="custom-autocomplete"
591
+ />
592
+ </div>
593
+
594
+ {/* Icons for Clearing Input or Toggling Dropdown */}
595
+
596
+ <InputActions
597
+ inputValue={inputValue}
598
+ searchValue={searchValue}
599
+ dropOpen={dropOpen}
600
+ handleDropOpen={handleDropOpen}
601
+ handleDropClose={handleDropClose}
602
+ disabled={disabled}
603
+ readOnly={readOnly}
604
+ expandable={expandable}
605
+ handleClear={handleClear}
606
+ countOnly={countOnly}
607
+ viewMode={viewMode}
608
+ />
609
+ {/* Displaying Loading Spinner */}
610
+
611
+ {/* Suggestions Dropdown */}
612
+
613
+ {dropOpen &&
614
+ ReactDOM.createPortal(
615
+ <div
616
+ ref={dropRef}
617
+ style={{
618
+ ...dropdownStyle,
619
+ minHeight: viewMode
620
+ ? 160
621
+ : type === 'auto_suggestion'
622
+ ? 164
623
+ : 192,
624
+ }}
625
+ className={`qbs-autocomplete-suggestions qbs-autocomplete-selected-suggestions ${
626
+ viewMode ? 'qbs-dropdown-selected-preview' : ''
627
+ } ${viewMode && selectedItems?.length === 0 ? 'hidden' : ''}`}
628
+ >
629
+ {!viewMode && (
630
+ <>
631
+ <>{tab.length > 0 && getTabItems()}</>
632
+ {type == 'auto_suggestion' && !expandable && (
633
+ <div
634
+ style={{ position: 'relative' }}
635
+ className="react-core-ts-search-container"
636
+ >
637
+ <span className="dropdown-search-icon">
638
+ <Search />
639
+ </span>
640
+ <input
641
+ className="dropdown-search-input"
642
+ onChange={handleSuggestionChange}
643
+ value={searchValue}
644
+ placeholder="Search"
645
+ ref={inputSearchRef}
646
+ />
647
+ </div>
648
+ )}
649
+ </>
650
+ )}
651
+
652
+ <div
653
+ className={`qbs-autocomplete-suggestions-sub ${
654
+ viewMode ? 'hidden' : ''
655
+ }`}
656
+ >
657
+ {filteredData?.length > 0 ? (
658
+ filteredData.map((suggestion: ValueProps, idx: number) => (
659
+ <DropdownList
660
+ idx={idx}
661
+ suggestion={suggestion}
662
+ isSelected={isSelected}
663
+ handleSuggestionClick={handleSuggestionClick}
664
+ handleMultiSelect={handleMultiSelect}
665
+ selected={selected}
666
+ isMultiple={isMultiple}
667
+ singleSelect={singleSelect}
668
+ desc={desc}
669
+ key={suggestion[descId]}
670
+ />
671
+ ))
672
+ ) : (
673
+ <>
674
+ {isLoading ||
675
+ (searchValue !== searchOldValue &&
676
+ searchValue !== '' &&
677
+ async) ? (
678
+ <div className="qbs-flex qbs-align-middle qbs-justify-center qbs-min-emp-h">
679
+ <div className="qbs-pt-16">
680
+ <Spinner />
681
+ </div>
682
+ </div>
683
+ ) : (
684
+ <div className="qbs-autocomplete-notfound qbs-text-center qbs-justify-center qbs-align-middle qbs-min-emp-h">
685
+ {searchValue !== ''
686
+ ? notDataMessage ?? 'No Results Found'
687
+ : initialDataMessage ?? 'Type to search'}
688
+ </div>
689
+ )}
690
+ </>
691
+ )}
692
+ {paginationEnabled &&
693
+ nextBlock !== 0 &&
694
+ nextBlock !== undefined &&
695
+ filteredData?.length > 0 && (
696
+ <div
697
+ className="loadMoreSection"
698
+ onClick={() => handleLoadMore()}
699
+ >
700
+ <p style={{ margin: 2 }}>Load More</p>
701
+ </div>
702
+ )}
703
+ </div>
704
+ <>
705
+ {/* {countOnly && selectedItems?.length > 0 && ( */}
706
+ <>
707
+ <div
708
+ style={{
709
+ minHeight: viewMode ? 160 : 192,
710
+ maxHeight: viewMode ? 160 : 192,
711
+ }}
712
+ className={`qbs-expandable-container qbs-dropdown-selected-container`}
713
+ ref={dropdownSelectedRef}
714
+ >
715
+ {selectedItems?.length > 0 ? (
716
+ <div
717
+ className={`qbs-flex qbs-w-full qbs-text-xs items-center`}
718
+ >
719
+ <div className="qbs-selected-lbs qbs-flex-grow">
720
+ Selected Items
721
+ </div>
722
+ <div
723
+ className={`qbs-clear-link qbs-text-right qbs-cursor-pointer ${
724
+ viewMode ? 'hidden' : ''
725
+ }`}
726
+ onClick={handleClearSelected}
727
+ >
728
+ Clear all
729
+ </div>
730
+ </div>
731
+ ) : (
732
+ <div className="w-full flex items-center justify-center">
733
+ {' '}
734
+ No Items Selected
735
+ </div>
736
+ )}
737
+
738
+ {getSelectedItems(true)}
739
+
740
+ <>
741
+ {selectedItems?.length > itemCount &&
742
+ showAllSelected && (
743
+ <div className="qbs-readmore-collapse">
744
+ <div
745
+ className="qbs-more-collapse"
746
+ onClick={() => {
747
+ handleCollapseArrowClick();
748
+ }}
749
+ >
750
+ <DropArrow className={`icon-button-rotate`} />
751
+ </div>
752
+ </div>
753
+ )}
754
+ </>
755
+ </div>
756
+ </>
757
+ {/* )} */}
758
+ </>
759
+ </div>,
760
+ document.body
761
+ )}
762
+ </div>
763
+
764
+ {/* Displaying Validation Error */}
765
+ {errors && (
766
+ <div
767
+ className="text-error text-error-label mt-[1px]"
768
+ data-testid="autocomplete-error"
769
+ >
770
+ {errors.message}
771
+ </div>
772
+ )}
773
+ </div>
774
+ );
775
+ }
776
+ );
777
+
778
+ export default React.memo(AutoCompleteWithSelectedList);