react-core-ts 1.0.26 → 1.0.28

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.
@@ -21,7 +21,7 @@ var TreeNode = function (_a) {
21
21
  react_1.default.createElement("div", { style: { display: 'flex' }, className: "qbs-items-start qbs-gap-4 qbs-flex-row ".concat(((_b = node === null || node === void 0 ? void 0 : node.children) === null || _b === void 0 ? void 0 : _b.length) > 0 ? '' : 'ml-5') },
22
22
  (node === null || node === void 0 ? void 0 : node.children) && ((_c = node === null || node === void 0 ? void 0 : node.children) === null || _c === void 0 ? void 0 : _c.length) > 0 && (react_1.default.createElement("span", { onClick: function () { return handleToggle(node); }, className: "qbs-mt-1 qbs-cursor-pointer qbs-py-2 ".concat(node.expanded ? ' qbs-rotate-90' : '') },
23
23
  react_1.default.createElement(Icons_1.DropSideIcon, null))),
24
- react_1.default.createElement("div", { className: "qbs-flex qbs-gap-2 qbs-p-2 qbs-flex-row" },
24
+ react_1.default.createElement("div", { className: "qbs-flex qbs-gap-2 qbs-p-2 qbs-flex-row ".concat((node === null || node === void 0 ? void 0 : node.checked) ? 'qbs-bg-slected_node/20' : '') },
25
25
  (isMultiple || singleSelect) && (react_1.default.createElement("div", { className: "qbs-autocomplete-checkbox" },
26
26
  react_1.default.createElement("input", { onChange: function (e) { return handleCheckbox(e, node); }, type: "checkbox", checked: node.checked, id: "qbs-checkbox-".concat(idx.toString()) }),
27
27
  react_1.default.createElement("label", { htmlFor: "qbs-checkbox-".concat(idx.toString()) },
@@ -1 +1 @@
1
- {"version":3,"file":"TreeNode.js","sourceRoot":"","sources":["../../src/components/TreeNode.tsx"],"names":[],"mappings":";;;;;AAAA,gDAA0B;AAE1B,iCAAuC;AAEvC,IAAM,QAAQ,GAAkB,UAAC,EAUhC;;QATC,IAAI,UAAA,EACJ,UAAU,gBAAA,EACV,YAAY,kBAAA,EACZ,GAAG,SAAA,EACH,IAAI,UAAA,EACJ,YAAY,kBAAA,EACZ,UAAU,gBAAA,EACV,QAAQ,cAAA,EACR,MAAM,YAAA;IAEN,sDAAsD;IACtD,IAAM,YAAY,GAAG,UAAC,IAAU;QAC9B,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC;IAEF,IAAM,cAAc,GAAG,UAAC,CAAM,EAAE,QAAa;QACnC,IAAA,OAAO,GAAK,CAAC,CAAC,MAAM,QAAb,CAAc;QAC7B,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC;IACF,OAAO,CACL;QACE,sCAAI,SAAS,EAAC,wBAAwB;YACpC,uCACE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAC1B,SAAS,EAAE,iDACT,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,0CAAE,MAAM,IAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CACxC;gBAID,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,KAAI,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,0CAAE,MAAM,IAAG,CAAC,IAAI,CAC/C,wCACE,OAAO,EAAE,cAAM,OAAA,YAAY,CAAC,IAAI,CAAC,EAAlB,CAAkB,EACjC,SAAS,EAAE,+CACT,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CACrC;oBAEF,8BAAC,oBAAY,OAAG,CACX,CACR;gBACD,uCAAK,SAAS,EAAC,yCAAyC;oBACrD,CAAC,UAAU,IAAI,YAAY,CAAC,IAAI,CAC/B,uCAAK,SAAS,EAAC,2BAA2B;wBACxC,yCACE,QAAQ,EAAE,UAAC,CAAC,IAAK,OAAA,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,EAAvB,CAAuB,EACxC,IAAI,EAAC,UAAU,EACf,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,EAAE,EAAE,uBAAgB,GAAG,CAAC,QAAQ,EAAE,CAAE,GACpC;wBACF,yCAAO,OAAO,EAAE,uBAAgB,GAAG,CAAC,QAAQ,EAAE,CAAE;4BAC9C,uCACE,KAAK,EAAC,GAAG,EACT,MAAM,EAAC,GAAG,EACV,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,MAAM,EACX,KAAK,EAAC,4BAA4B;gCAElC,wCACE,CAAC,EAAC,qFAAqF,EACvF,IAAI,EAAC,OAAO,GACZ,CACE,CACA,CACJ,CACP;oBACD,wCAAM,SAAS,EAAC,iCAAiC,IAAE,IAAI,CAAC,IAAI,CAAC,CAAQ,CACjE,CACF,CACH;QAEJ,QAAQ,CACL,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"TreeNode.js","sourceRoot":"","sources":["../../src/components/TreeNode.tsx"],"names":[],"mappings":";;;;;AAAA,gDAA0B;AAE1B,iCAAuC;AAEvC,IAAM,QAAQ,GAAkB,UAAC,EAUhC;;QATC,IAAI,UAAA,EACJ,UAAU,gBAAA,EACV,YAAY,kBAAA,EACZ,GAAG,SAAA,EACH,IAAI,UAAA,EACJ,YAAY,kBAAA,EACZ,UAAU,gBAAA,EACV,QAAQ,cAAA,EACR,MAAM,YAAA;IAEN,sDAAsD;IACtD,IAAM,YAAY,GAAG,UAAC,IAAU;QAC9B,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC;IAEF,IAAM,cAAc,GAAG,UAAC,CAAM,EAAE,QAAa;QACnC,IAAA,OAAO,GAAK,CAAC,CAAC,MAAM,QAAb,CAAc;QAC7B,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC;IACF,OAAO,CACL;QACE,sCAAI,SAAS,EAAC,wBAAwB;YACpC,uCACE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAC1B,SAAS,EAAE,iDACT,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,0CAAE,MAAM,IAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CACxC;gBAID,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,KAAI,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,0CAAE,MAAM,IAAG,CAAC,IAAI,CAC/C,wCACE,OAAO,EAAE,cAAM,OAAA,YAAY,CAAC,IAAI,CAAC,EAAlB,CAAkB,EACjC,SAAS,EAAE,+CACT,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CACrC;oBAEF,8BAAC,oBAAY,OAAG,CACX,CACR;gBACD,uCACE,SAAS,EAAE,kDACT,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,EAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,CAC7C;oBAED,CAAC,UAAU,IAAI,YAAY,CAAC,IAAI,CAC/B,uCAAK,SAAS,EAAC,2BAA2B;wBACxC,yCACE,QAAQ,EAAE,UAAC,CAAC,IAAK,OAAA,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,EAAvB,CAAuB,EACxC,IAAI,EAAC,UAAU,EACf,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,EAAE,EAAE,uBAAgB,GAAG,CAAC,QAAQ,EAAE,CAAE,GACpC;wBACF,yCAAO,OAAO,EAAE,uBAAgB,GAAG,CAAC,QAAQ,EAAE,CAAE;4BAC9C,uCACE,KAAK,EAAC,GAAG,EACT,MAAM,EAAC,GAAG,EACV,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,MAAM,EACX,KAAK,EAAC,4BAA4B;gCAElC,wCACE,CAAC,EAAC,qFAAqF,EACvF,IAAI,EAAC,OAAO,GACZ,CACE,CACA,CACJ,CACP;oBACD,wCAAM,SAAS,EAAC,iCAAiC,IAC9C,IAAI,CAAC,IAAI,CAAC,CACN,CACH,CACF,CACH;QAEJ,QAAQ,CACL,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,QAAQ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-core-ts",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "React Components",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -8,7 +8,7 @@
8
8
  "start": "webpack serve --open --mode development",
9
9
  "build": "tsc && cp -R src/styles dist/styles",
10
10
  "test": "jest",
11
- "prepublishOnly": "npm run build && rm -rf src"
11
+ "prepublishOnly": "npm run build"
12
12
  },
13
13
  "repository": {
14
14
  "type": "git",
@@ -0,0 +1,489 @@
1
+ import Tooltip from './utilities/tooltip';
2
+ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
3
+
4
+ import { AutoSuggestionInputProps } from './commontypes';
5
+ import { useSuggestions } from './utilities/autosuggestions';
6
+ import { debounce } from './utilities/debounce';
7
+ import { deepEqual } from './utilities/deepEqual';
8
+ import { filterSuggestions } from './utilities/filterSuggestions';
9
+ import { Close, DropArrow, Search, Spinner } from './utilities/icons';
10
+
11
+ type ValueProps = {
12
+ [key: string]: string;
13
+ };
14
+ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
15
+ (
16
+ {
17
+ label,
18
+ onChange,
19
+ getData = async () => [],
20
+ data = [],
21
+ errors,
22
+ required = false,
23
+ name,
24
+ fullWidth = false,
25
+ placeholder,
26
+ id,
27
+ type = 'custom_select',
28
+ selectedItems: propsSeelctedItems = [],
29
+ readOnly = false,
30
+ disabled = false,
31
+ value,
32
+ isMultiple = false,
33
+ desc = 'name',
34
+ descId = 'id',
35
+ singleSelect,
36
+ className,
37
+ async = false,
38
+ paginationEnabled,
39
+ initialLoad,
40
+ actionLabel,
41
+ handleAction,
42
+ nextBlock,
43
+ notDataMessage,
44
+ onFocus,
45
+ },
46
+ ref
47
+ ) => {
48
+ const dropdownRef = useRef<HTMLDivElement>(null);
49
+ // State Hooks Section
50
+ const [isInitialRender, setIsInitialRender] = useState(true);
51
+
52
+ const [inputValue, setInputValue] = useState<string>(value);
53
+ const [searchValue, setSearchValue] = useState<string>('');
54
+ const [nextPage, setNextPage] = useState<number | undefined>(1);
55
+ const [dropOpen, setDropOpen] = useState<boolean>(false);
56
+ const [selectedItems, setSelectedItems] = useState<ValueProps[]>([]);
57
+ // API call for suggestions through a custom hook
58
+ const [dropdownPosition, setDropdownPosition] = useState('bottom');
59
+ const inputRef = useRef(null);
60
+ const dropRef = useRef(null);
61
+ useImperativeHandle(ref, () => inputRef.current);
62
+
63
+ const adjustDropdownPosition = () => {
64
+ if (inputRef.current && dropRef.current) {
65
+ const inputBoxRect = inputRef.current.getBoundingClientRect();
66
+ const viewportHeight = window.innerHeight;
67
+
68
+ const spaceAbove = inputBoxRect.top;
69
+ const spaceBelow = viewportHeight - inputBoxRect.bottom;
70
+ if (spaceAbove > spaceBelow) {
71
+ setDropdownPosition('top');
72
+ } else {
73
+ setDropdownPosition('bottom');
74
+ }
75
+ }
76
+ };
77
+
78
+ useEffect(() => {
79
+ window.addEventListener('resize', adjustDropdownPosition);
80
+ adjustDropdownPosition();
81
+
82
+ return () => {
83
+ window.removeEventListener('resize', adjustDropdownPosition);
84
+ };
85
+ }, [dropOpen]);
86
+
87
+ const { suggestions, isLoading, handlePickSuggestions } = useSuggestions(
88
+ getData,
89
+ data,
90
+ dropOpen,
91
+ async,
92
+ paginationEnabled,
93
+ initialLoad,
94
+ inputValue,
95
+ isMultiple,
96
+ setNextPage,
97
+ selectedItems
98
+ // nextBlock
99
+ );
100
+
101
+ // Handling the selection of a suggestion
102
+ const handleSuggestionClick = useCallback((suggestion: ValueProps) => {
103
+ if (isMultiple) {
104
+ setSelectedItems((prev) => [...prev, suggestion]);
105
+ } else {
106
+ setInputValue(suggestion[desc]);
107
+ }
108
+ setSearchValue('');
109
+ setInputValue(suggestion[desc]);
110
+ onChange(suggestion);
111
+ setDropOpen(false);
112
+ }, []);
113
+
114
+ // Adding debounce to avoid making API calls on every keystroke
115
+ const handleChangeWithDebounce = debounce((value) => {
116
+ if ((type === 'auto_complete' || type === 'auto_suggestion') && async) {
117
+ handlePickSuggestions(value, 1);
118
+ }
119
+ }, 1000);
120
+
121
+ const handleMultiSelect = (e: any, suggestion: ValueProps) => {
122
+ const { checked } = e.target;
123
+ if (isMultiple) {
124
+ if (checked) {
125
+ setSelectedItems((prev) => [...prev, suggestion]);
126
+ } else {
127
+ setSelectedItems((prev) => {
128
+ return prev.filter(
129
+ (item, i) => item[descId] !== suggestion[descId]
130
+ );
131
+ });
132
+ }
133
+ } else {
134
+ if (checked) {
135
+ setInputValue(suggestion[desc]);
136
+ onChange(suggestion);
137
+ } else {
138
+ setInputValue('');
139
+ }
140
+ }
141
+ };
142
+ useEffect(() => {
143
+ if (!deepEqual(selectedItems, propsSeelctedItems))
144
+ setSelectedItems(propsSeelctedItems);
145
+ }, [propsSeelctedItems]);
146
+ // Effect to set the input value whenever `value` prop changes
147
+ useEffect(() => {
148
+ setInputValue(value ?? '');
149
+ }, [value]);
150
+
151
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
152
+ const { value } = e.target;
153
+ setDropOpen(true);
154
+ setSearchValue(value);
155
+ handleChangeWithDebounce(value);
156
+ if (!value) {
157
+ setInputValue('');
158
+ onChange({ [descId]: '', [desc]: '' });
159
+ }
160
+ };
161
+ const handleSuggestionChange = (e: React.ChangeEvent<HTMLInputElement>) => {
162
+ const { value } = e.target;
163
+ setDropOpen(true);
164
+ setSearchValue(value);
165
+ handleChangeWithDebounce(value);
166
+ };
167
+
168
+ const handleBlur = () => {
169
+ setTimeout(() => {
170
+ setDropOpen(false);
171
+ }, 200);
172
+ };
173
+
174
+ const handleClear = () => {
175
+ if (searchValue) {
176
+ setSearchValue('');
177
+ setDropOpen(false);
178
+ } else {
179
+ setInputValue('');
180
+ onChange({ [descId]: '', [desc]: '' });
181
+ setDropOpen(false);
182
+ }
183
+ };
184
+
185
+ const generateClassName = useCallback(() => {
186
+ return `qbs-textfield-default ${className} ${
187
+ errors && errors?.message ? 'textfield-error' : 'textfield'
188
+ }`;
189
+ }, [errors, name]);
190
+ const handleRemoveSelectedItem = (index: number) => {
191
+ setSelectedItems((prev) => {
192
+ return prev.filter((_, i) => i !== index);
193
+ });
194
+ };
195
+
196
+ useEffect(() => {
197
+ if (isInitialRender) {
198
+ setIsInitialRender(false);
199
+ } else {
200
+ onChange(selectedItems);
201
+ }
202
+ }, [selectedItems]);
203
+
204
+ useEffect(() => {
205
+ const handleClickOutside = (event: React.MouseEvent) => {
206
+ if (
207
+ dropdownRef.current &&
208
+ event.target instanceof Node &&
209
+ !dropdownRef.current.contains(event.target)
210
+ ) {
211
+ setDropOpen(false);
212
+ setSearchValue('');
213
+ }
214
+ };
215
+ document.addEventListener('mousedown', handleClickOutside as any);
216
+ return () => {
217
+ document.removeEventListener('mousedown', handleClickOutside as any);
218
+ };
219
+ }, []);
220
+
221
+ // Filtering suggestions based on type and search value
222
+ const selected: any = isMultiple ? selectedItems : inputValue;
223
+ const filteredData: ValueProps[] = filterSuggestions(
224
+ suggestions,
225
+ searchValue,
226
+ type,
227
+ desc,
228
+ selected,
229
+ async
230
+ );
231
+ const isSelected = (
232
+ item: ValueProps,
233
+ selectedItems: ValueProps[] | string
234
+ ): boolean => {
235
+ if (Array.isArray(selectedItems)) {
236
+ return selectedItems.some(
237
+ (selectedItem) => selectedItem[desc] === item[desc]
238
+ );
239
+ } else {
240
+ return item[desc] === selectedItems;
241
+ }
242
+ };
243
+
244
+ const handleLoadMore = () => {
245
+ if (paginationEnabled) {
246
+ handlePickSuggestions(searchValue, nextPage + 1, true);
247
+ setNextPage(nextPage + 1);
248
+ }
249
+ };
250
+
251
+ const handleOnClick = () => {
252
+ !disabled && !readOnly ? setDropOpen(true) : '';
253
+ };
254
+ const tooltipContent =
255
+ selectedItems?.length > 1
256
+ ? selectedItems
257
+ ?.slice(1)
258
+ .map((item) => item[desc])
259
+ .join(', ')
260
+ : '';
261
+
262
+ return (
263
+ <div className={fullWidth ? 'fullWidth' : 'autoWidth'} ref={dropdownRef}>
264
+ {label && (
265
+ <div
266
+ style={{
267
+ marginBottom: 5,
268
+ display: 'flex',
269
+ justifyContent: 'space-between',
270
+ }}
271
+ >
272
+ <label className={`labels label-text`}>
273
+ {label}
274
+ {required && <span className="text-error"> *</span>}
275
+ </label>
276
+ <span onClick={() => handleAction?.()} className={`action_label`}>
277
+ {actionLabel}
278
+ </span>
279
+ </div>
280
+ )}
281
+ {/* Displaying selected items for multi-select */}
282
+
283
+ <div style={{ position: 'relative' }}>
284
+ <div className="selected-items-container ">
285
+ {selectedItems?.length > 0 && (
286
+ <>
287
+ <div key={selectedItems[0].id} className="selected-item">
288
+ <Tooltip title={selectedItems[0]?.[desc]}>
289
+ {selectedItems[0]?.[desc]?.length > 8
290
+ ? `${selectedItems[0]?.[desc].substring(0, 8)}...`
291
+ : selectedItems[0]?.[desc]}
292
+ </Tooltip>
293
+ <button
294
+ onClick={() => handleRemoveSelectedItem(0)}
295
+ className="remove-item-btn"
296
+ aria-label={`Remove ${selectedItems[0]?.[desc]}`}
297
+ >
298
+ X
299
+ </button>
300
+ </div>
301
+ <Tooltip title={tooltipContent}>
302
+ {selectedItems?.length > 1 && (
303
+ <div className="selected-item-more">
304
+ +{selectedItems?.length - 1} more
305
+ </div>
306
+ )}
307
+ </Tooltip>
308
+ </>
309
+ )}
310
+ </div>
311
+ <input
312
+ id={id}
313
+ ref={inputRef}
314
+ type="text"
315
+ value={
316
+ type === 'auto_suggestion'
317
+ ? inputValue
318
+ : searchValue || inputValue
319
+ }
320
+ onChange={handleChange}
321
+ // onBlur={handleBlur}
322
+ onFocus={onFocus}
323
+ onClick={() => handleOnClick()}
324
+ className={generateClassName()}
325
+ placeholder={selectedItems?.length > 0 ? '' : placeholder ?? ''}
326
+ readOnly={
327
+ readOnly || type === 'custom_select' || type == 'auto_suggestion'
328
+ }
329
+ disabled={disabled}
330
+ data-testid="custom-autocomplete"
331
+ />
332
+
333
+ {/* Icons for Clearing Input or Toggling Dropdown */}
334
+ <div className="qbs-autocomplete-close-icon">
335
+ {(inputValue || searchValue) && !disabled && !readOnly && (
336
+ <button
337
+ onClick={handleClear}
338
+ className="icon-button"
339
+ aria-label="clear"
340
+ >
341
+ <Close />
342
+ </button>
343
+ )}
344
+
345
+ <button
346
+ disabled={disabled || readOnly}
347
+ type="button"
348
+ onClick={() => setDropOpen(!dropOpen)}
349
+ className="icon-button"
350
+ aria-label="toggle"
351
+ >
352
+ <DropArrow />
353
+ </button>
354
+ </div>
355
+
356
+ {/* Displaying Loading Spinner */}
357
+
358
+ {/* Suggestions Dropdown */}
359
+ {dropOpen && (
360
+ <ul
361
+ ref={dropRef}
362
+ className={`qbs-autocomplete-suggestions ${dropdownPosition}`}
363
+ >
364
+ {type == 'auto_suggestion' && (
365
+ <div
366
+ style={{ position: 'relative' }}
367
+ className="react-core-ts-search-container"
368
+ >
369
+ <span className="dropdown-search-icon">
370
+ <Search />
371
+ </span>
372
+ <input
373
+ className="dropdown-search-input"
374
+ onChange={handleSuggestionChange}
375
+ value={searchValue}
376
+ placeholder="Search"
377
+ />
378
+ </div>
379
+ )}
380
+
381
+ <div className="qbs-autocomplete-suggestions-sub">
382
+ {/* Displaying Suggestions or Not Found Message */}
383
+ {/* {isLoading && (
384
+ <div style={{ display: 'flex', justifyContent: 'center' }}>
385
+ <span>
386
+ <Spinner />
387
+ </span>
388
+ </div>
389
+
390
+ {/* )} */}
391
+
392
+ {filteredData?.length > 0 ? (
393
+ filteredData.map((suggestion: ValueProps, idx: number) => (
394
+ <div
395
+ key={idx.toString()}
396
+ className={`qbs-autocomplete-listitem-container ${
397
+ (isMultiple || singleSelect) &&
398
+ 'qbs-autocomplete-checkbox-container'
399
+ } ${
400
+ isSelected(suggestion, selected) ? 'is-selected' : ''
401
+ }`}
402
+ >
403
+ {(isMultiple || singleSelect) && (
404
+ <div className="qbs-autocomplete-checkbox">
405
+ <input
406
+ onChange={(e) => handleMultiSelect(e, suggestion)}
407
+ type="checkbox"
408
+ checked={isSelected(suggestion, selected)}
409
+ id={`qbs-checkbox-${idx.toString()}`}
410
+ />
411
+ <label htmlFor={`qbs-checkbox-${idx.toString()}`}>
412
+ <svg
413
+ width="8"
414
+ height="6"
415
+ viewBox="0 0 8 6"
416
+ fill="none"
417
+ xmlns="http://www.w3.org/2000/svg"
418
+ >
419
+ <path
420
+ d="M0 3.21739L2.89883 6L8 1.06994L6.89494 0L2.89883 3.86768L1.09728 2.14745L0 3.21739Z"
421
+ fill="white"
422
+ />
423
+ </svg>
424
+ </label>
425
+ </div>
426
+ )}
427
+ <li
428
+ key={idx}
429
+ className={`qbs-autocomplete-suggestions-item ${
430
+ isSelected(suggestion, selected) ? 'is-selected' : ''
431
+ }`}
432
+ onClick={() => handleSuggestionClick(suggestion)}
433
+ data-testid={suggestion[desc]}
434
+ >
435
+ {suggestion[desc]}
436
+ </li>
437
+ </div>
438
+ ))
439
+ ) : (
440
+ <>
441
+ {isLoading ? (
442
+ <div
443
+ style={{ display: 'flex', justifyContent: 'center' }}
444
+ >
445
+ <span>
446
+ <Spinner />
447
+ </span>
448
+ </div>
449
+ ) : (
450
+ <li
451
+ className="qbs-autocomplete-notfound"
452
+ onClick={handleBlur}
453
+ >
454
+ {notDataMessage ?? 'No Results Found'}
455
+ </li>
456
+ )}
457
+ </>
458
+ )}
459
+ {paginationEnabled &&
460
+ nextBlock !== 0 &&
461
+ nextBlock !== undefined &&
462
+ filteredData?.length > 0 && (
463
+ <div
464
+ className="loadMoreSection"
465
+ onClick={() => handleLoadMore()}
466
+ >
467
+ <p style={{ margin: 2 }}>Load More</p>
468
+ </div>
469
+ )}
470
+ </div>
471
+ </ul>
472
+ )}
473
+ </div>
474
+
475
+ {/* Displaying Validation Error */}
476
+ {errors && (
477
+ <div
478
+ className="text-error text-error-label mt-[1px]"
479
+ data-testid="autocomplete-error"
480
+ >
481
+ {errors.message}
482
+ </div>
483
+ )}
484
+ </div>
485
+ );
486
+ }
487
+ );
488
+
489
+ export default React.memo(AutoComplete);