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.
@@ -5,18 +5,18 @@ import React, {
5
5
  useImperativeHandle,
6
6
  useRef,
7
7
  useState,
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';
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 = 'custom_select',
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 = 'name',
47
- descId = 'id',
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 = 'parentId',
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('resize', adjustDropdownPosition);
127
+ window.addEventListener("resize", adjustDropdownPosition);
128
128
  adjustDropdownPosition();
129
129
 
130
130
  return () => {
131
- window.removeEventListener('resize', adjustDropdownPosition);
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 === 'auto_complete' || type === 'auto_suggestion') && async) {
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]: '', [desc]: '' });
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 ? 'textfield-error' : 'tree-textfield'
213
- } ${expandable ? '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
- setDropOpen(false);
239
- setSearchValue('');
238
+ setTimeout(() => {
239
+ setDropOpen(false);
240
+ setSearchValue("");
241
+ }, 200);
240
242
  }
241
243
  };
242
- document.addEventListener('mousedown', handleClickOutside as any);
243
- window.addEventListener('scroll', handleClickOutside as any);
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('scroll', handleClickOutside as any)
251
+ div.addEventListener("scroll", handleClickOutside as any)
250
252
  );
251
253
  if (scrollRef && scrollRef.current && scrollRef.current !== null) {
252
- scrollRef.current.addEventListener('scroll', handleClickOutside as any);
254
+ scrollRef.current.addEventListener("scroll", handleClickOutside as any);
253
255
  }
256
+
254
257
  return () => {
255
- document.removeEventListener('mousedown', handleClickOutside as any);
256
- window.removeEventListener('scroll', handleClickOutside as any);
258
+ document.removeEventListener("mousedown", handleClickOutside as any);
259
+ window.removeEventListener("scroll", handleClickOutside as any);
257
260
  scrollableDivs.forEach((div) =>
258
- div.removeEventListener('scroll', handleClickOutside as any)
261
+ div.removeEventListener("scroll", handleClickOutside as any)
259
262
  );
260
263
  if (scrollRef && scrollRef.current && scrollRef.current !== null) {
261
264
  scrollRef.current.removeEventListener(
262
- 'scroll',
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: '', name: '' });
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 === 'required') ||
417
- errors.message === 'Required'
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 ? 'fullWidth' : 'autoWidth'} ref={dropdownRef}>
428
+ <div className={fullWidth ? "fullWidth" : "autoWidth"} ref={dropdownRef}>
426
429
  {label && (
427
430
  <div
428
431
  style={{
429
432
  marginBottom: 5,
430
- display: 'flex',
431
- justifyContent: 'space-between',
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 ? 'qbs-expandable-container' : 'qbs-container'
450
+ expandable ? "qbs-expandable-container" : "qbs-container"
448
451
  }`}
449
- style={{ position: 'relative' }}
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 ? 'qbs-normal' : ''
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 === 'auto_suggestion' && !expandable
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 ? '' : placeholder ?? ''}
522
+ placeholder={selectedItems?.length > 0 ? "" : placeholder ?? ""}
520
523
  readOnly={
521
524
  readOnly ||
522
- type === 'custom_select' ||
523
- (type == 'auto_suggestion' && !expandable)
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 == 'auto_suggestion' && !expandable && (
558
+ {type == "auto_suggestion" && !expandable && (
556
559
  <div
557
- style={{ position: 'relative' }}
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 ? '8px' : '0',
575
- minHeight: isTreeDropdown ? '184px' : '0',
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: 'flex', justifyContent: 'center' }}
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 ?? 'No Results Found'}
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
- setDropOpen(false);
256
- setSearchValue("");
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
- {label && isModern && (
637
+ {isModern && (
638
638
  <label
639
639
  htmlFor={id}
640
640
  onClick={() => onLabelClick()}
641
641
  className={generateClassName('label')}
642
642
  >
643
- {label}
644
- {required && label ? (
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>
@@ -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;