react-core-ts 1.9.4 → 1.9.6

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,97 @@
1
+ .qbs-tree-list-container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ }
5
+ .qbs-tree-list-container-sub {
6
+ display: flex;
7
+ flex-direction: row;
8
+ align-items: flex-start;
9
+ gap: 7px;
10
+ }
11
+
12
+ .qbs-tree-list-container-sub .no-children {
13
+ margin-left: 1.75rem; /* Corresponds to ml-7 in Tailwind */
14
+ }
15
+ .qbs-tree-list-container-sub-icon {
16
+ margin-top: 0.25rem; /* Corresponds to mt-1 in Tailwind */
17
+ cursor: pointer;
18
+ padding-top: 0.5rem; /* Corresponds to py-2 in Tailwind */
19
+ padding-bottom: 0.5rem;
20
+ transition: transform 0.3s ease; /* Smooth rotation transition */
21
+ color: #003c71;
22
+ }
23
+
24
+ .qbs-tree-list-container-sub-icon.expanded {
25
+ transform: rotate(90deg); /* Corresponds to rotate-90 in Tailwind */
26
+ }
27
+ .qbs-tree-list-container-sub-container {
28
+ display: flex;
29
+ gap: 15px; /* Corresponds to gap-2 in Tailwind */
30
+ padding: 0.5rem; /* Corresponds to p-2 in Tailwind */
31
+ flex-direction: row; /* Corresponds to flex-row in Tailwind */
32
+ width: 100%; /* Corresponds to w-full in Tailwind */
33
+ color: #3d414a;
34
+ }
35
+ .qbs-tree-list-container-sub-container-hideicon {
36
+ display: flex;
37
+ gap: 6px; /* Corresponds to gap-2 in Tailwind */
38
+ padding: 0.5rem; /* Corresponds to p-2 in Tailwind */
39
+ flex-direction: row; /* Corresponds to flex-row in Tailwind */
40
+ width: 100%; /* Corresponds to w-full in Tailwind */
41
+ color: #3d414a;
42
+ }
43
+ .qbs-tree-list-container-sub-container-hideicon:hover {
44
+ color: #003c71;
45
+ background-color: rgba(141, 194, 240, 0.15) !important;
46
+ }
47
+ .qbs-tree-list-container-sub-container:hover {
48
+ color: #003c71;
49
+ background-color: rgba(141, 194, 240, 0.15) !important;
50
+ }
51
+ .qbs-tree-list-container-sub-container.qbs-expanded-child {
52
+ color: #003c71;
53
+ }
54
+ .qbs-tree-list-container-sub-text.qbs-expanded-child {
55
+ color: #003c71;
56
+ }
57
+ .qbs-tree-list-container-sub-text:hover {
58
+ color: #003c71;
59
+ /* background-color: rgba(141, 194, 240, 0.15) !important; */
60
+ }
61
+
62
+ .qbs-tree-list-container-sub-container.checked,
63
+ .qbs-tree-list-container-sub-container-hideicon.checked {
64
+ color: #003c71;
65
+ background-color: rgba(
66
+ 141,
67
+ 194,
68
+ 240,
69
+ 0.15
70
+ ) !important; /* Corresponds to bg-green-200 in Tailwind */
71
+ }
72
+
73
+ .marginLeft {
74
+ margin-left: 28px; /* Corresponds to ml-2 in Tailwind */
75
+ }
76
+ .lightmarginLeft {
77
+ margin-left: 19px; /* Corresponds to ml-2 in Tailwind */
78
+ }
79
+ .qbs-tree-list-container-sub- {
80
+ line-height: 18px; /* Corresponds to leading-[18px] in Tailwind */
81
+ font-size: 0.875rem; /* Corresponds to text-sm in Tailwind (14px) */
82
+ }
83
+ .qbs-tree-list-container-child {
84
+ margin-left: 1rem; /* Corresponds to ml-4 in Tailwind */
85
+ margin-top: 0.5rem; /* Corresponds to mt-2 in Tailwind */
86
+ display: flex; /* Corresponds to flex in Tailwind */
87
+ flex-direction: column; /* Corresponds to flex-col in Tailwind */
88
+ gap: 0.5rem; /* Corresponds to gap-2 in Tailwind */
89
+ }
90
+ .qbs-tree-list-container-sub-text {
91
+ line-height: 18px; /* Corresponds to leading-[18px] in Tailwind */
92
+ font-size: 14px; /* Corresponds to text-sm in Tailwind (14px) */
93
+ font-weight: 500;
94
+ letter-spacing: 0.28px;
95
+ font-family: 'Noto Sans';
96
+ /* color: #3d414a; */
97
+ }
@@ -0,0 +1,8 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @import './components/autocomplete.css';
6
+ @import './components/treedropdown.css';
7
+ @import './components/selectedautocomplete.css';
8
+ @import './components/tooltip.css';
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "react-core-ts",
3
-
4
- "version": "1.9.4",
3
+ "version": "1.9.6",
5
4
  "description": "React Components",
6
5
  "main": "dist/index.js",
7
6
  "types": "dist/index.d.ts",
@@ -15,7 +15,7 @@ import { useSuggestions } from './utilities/autosuggestions';
15
15
  import { debounce } from './utilities/debounce';
16
16
  import { deepEqual } from './utilities/deepEqual';
17
17
  import { filterSuggestions } from './utilities/filterSuggestions';
18
- import { DropArrow, Search, Spinner } from './utilities/icons';
18
+ import { AllDropArrow, DropArrow, Search, Spinner } from './utilities/icons';
19
19
  import { default as Tooltip } from './utilities/NewTooltip';
20
20
 
21
21
  const AutoCompleteWithSelectedList = forwardRef<
@@ -70,7 +70,9 @@ const AutoCompleteWithSelectedList = forwardRef<
70
70
  shortCode = '',
71
71
  labelCode = '',
72
72
  tabInlineSearch = true,
73
- matchFromStart = false
73
+ matchFromStart = false,
74
+ autoDropdown = false,
75
+ enableSelectAll = false,
74
76
  },
75
77
  ref
76
78
  ) => {
@@ -101,6 +103,7 @@ const AutoCompleteWithSelectedList = forwardRef<
101
103
  const inputRef = useRef(null);
102
104
  const dropRef = useRef(null);
103
105
  const inputSearchRef = useRef(null);
106
+ const dropBtnRef = useRef<HTMLButtonElement>(null);
104
107
  useImperativeHandle(ref, () => inputRef.current);
105
108
  const [dropdownStyle, setDropdownStyle] = useState({
106
109
  top: 0,
@@ -108,6 +111,10 @@ const AutoCompleteWithSelectedList = forwardRef<
108
111
  width: 200,
109
112
  });
110
113
 
114
+ const [selectAll, setSelectAll] = useState(false);
115
+ const [refetchData, setRefetchData] = useState(false);
116
+ const [allDataLoaded, setAllDataLoaded] = useState(false);
117
+
111
118
  let originalOverflow = '';
112
119
  let hasScrollbar = false;
113
120
 
@@ -140,7 +147,12 @@ const AutoCompleteWithSelectedList = forwardRef<
140
147
 
141
148
  setSelHeight(defaultHeight);
142
149
  } else if (spaceAbove >= dropdownHeight) {
143
- const sHeight = tabInlineSearch ? 73 : 113;
150
+ let sHeight = tabInlineSearch ? 73 : 113;
151
+ sHeight =
152
+ sHeight -
153
+ (filteredData?.length > 0 && enableSelectAll && isMultiple
154
+ ? 32
155
+ : 0);
144
156
  dropLevelRef.current = 'top';
145
157
  dropdownPosition.top =
146
158
  inputRect.top +
@@ -291,6 +303,7 @@ const AutoCompleteWithSelectedList = forwardRef<
291
303
  const trimStart = value.trimStart();
292
304
  setSearchValue(trimStart);
293
305
  handleChangeWithDebounce(trimStart);
306
+ setAllDataLoaded(false);
294
307
  };
295
308
 
296
309
  const handleClear = () => {
@@ -310,6 +323,7 @@ const AutoCompleteWithSelectedList = forwardRef<
310
323
  setShowAllSelected(false);
311
324
  setSearchValue('');
312
325
  if (isMultiple) onChange([]);
326
+ if (async) resetSuggections?.();
313
327
  else onChange({ [descId]: '', [desc]: '' });
314
328
  };
315
329
 
@@ -324,18 +338,6 @@ const AutoCompleteWithSelectedList = forwardRef<
324
338
  });
325
339
  };
326
340
 
327
- useEffect(() => {
328
- if (isInitialRender) {
329
- setIsInitialRender(false);
330
- } else {
331
- onChange(selectedItems);
332
- }
333
-
334
- adjustDropdownPosition();
335
- setTimeout(() => {
336
- adjustDropdownPosition();
337
- }, 200);
338
- }, [selectedItems]);
339
341
  const uniqueDropArrowId = `${name}-drop-arrow-selected-list-icon`;
340
342
  useEffect(() => {
341
343
  const handleClickOutside = (event: any) => {
@@ -403,6 +405,19 @@ const AutoCompleteWithSelectedList = forwardRef<
403
405
  matchFromStart
404
406
  );
405
407
 
408
+ useEffect(() => {
409
+ if (isInitialRender) {
410
+ setIsInitialRender(false);
411
+ } else {
412
+ onChange(selectedItems);
413
+ }
414
+
415
+ adjustDropdownPosition();
416
+ setTimeout(() => {
417
+ adjustDropdownPosition();
418
+ }, 200);
419
+ }, [selectedItems, filteredData]);
420
+
406
421
  useEffect(() => {
407
422
  // Handle keyboard navigation
408
423
  const handleKeyDown = (e: any) => {
@@ -468,10 +483,12 @@ const AutoCompleteWithSelectedList = forwardRef<
468
483
  ): boolean => {
469
484
  if (Array.isArray(selectedItems)) {
470
485
  return selectedItems.some(
471
- (selectedItem) => selectedItem[desc] === item[desc]
486
+ (selectedItem) =>
487
+ selectedItem[desc] === item[desc] ||
488
+ selectedItem[descId] === item[descId]
472
489
  );
473
490
  } else {
474
- return item[desc] === selectedItems;
491
+ return item[desc] === selectedItems || item[descId] === selectedItems;
475
492
  }
476
493
  };
477
494
 
@@ -665,6 +682,56 @@ const AutoCompleteWithSelectedList = forwardRef<
665
682
  </ul>
666
683
  );
667
684
  };
685
+
686
+ const handleSelectAll = () => {
687
+ if (isMultiple) {
688
+ if (selectAll) {
689
+ setSelectedItems((prev) =>
690
+ prev.filter(
691
+ (item) => !filteredData.some((f) => f[descId] === item[descId])
692
+ )
693
+ );
694
+ } else {
695
+ filteredData.map((suggestion: ValueProps) =>
696
+ setSelectedItems((prev) => {
697
+ const isAdded = prev.some(
698
+ (item) => item[descId] === suggestion[descId]
699
+ );
700
+ if (isAdded) {
701
+ return prev;
702
+ } else {
703
+ return [...prev, suggestion];
704
+ }
705
+ })
706
+ );
707
+ }
708
+ }
709
+ };
710
+
711
+ const handleOpenDropdown = (e: any) => {
712
+ if (!suggestions || suggestions?.length === 0 || refetchData) {
713
+ if (autoDropdown && (inputValue === '' || inputValue.trim() === '')) {
714
+ handlePickSuggestions('*', 1);
715
+ setRefetchData(false);
716
+ setAllDataLoaded(true);
717
+ } else if (!refetchData && inputValue !== '') {
718
+ handlePickSuggestions(inputValue, 1);
719
+ setRefetchData(true);
720
+ setAllDataLoaded(false);
721
+ }
722
+ }
723
+ };
724
+
725
+ useEffect(() => {
726
+ const allSelected =
727
+ filteredData.length > 0 &&
728
+ filteredData.every((item) =>
729
+ selectedItems.some((s) => s[descId] === item[descId])
730
+ );
731
+
732
+ setSelectAll(allSelected);
733
+ }, [filteredData, selectedItems, descId]);
734
+
668
735
  useEffect(() => {
669
736
  handleUpdateParent?.(dropOpen, dropLevelRef.current);
670
737
  }, [dropOpen, dropLevelRef.current]);
@@ -818,7 +885,7 @@ const AutoCompleteWithSelectedList = forwardRef<
818
885
  tabInlineSearch && (
819
886
  <div
820
887
  style={{ position: 'relative' }}
821
- className="react-core-ts-search-container"
888
+ className="react-core-ts-search-container qbs-autocomplete-selected-suggestions-outer"
822
889
  >
823
890
  <span className="dropdown-search-icon">
824
891
  <Search />
@@ -831,13 +898,70 @@ const AutoCompleteWithSelectedList = forwardRef<
831
898
  autoComplete="off"
832
899
  ref={inputSearchRef}
833
900
  />
901
+
902
+ <>
903
+ {autoDropdown && !disabled && !readOnly && (
904
+ <button
905
+ disabled={disabled ?? readOnly}
906
+ onClick={(e) => handleOpenDropdown(e)}
907
+ className="text-[#667085] focus-visible:outline-slate-100 absolute right-2 qbs-all-dropdown-btn"
908
+ data-testid="drop-arrow"
909
+ type="button"
910
+ id="autocomplete-drop-icon"
911
+ ref={dropBtnRef}
912
+ >
913
+ <AllDropArrow
914
+ type={!allDataLoaded ? 'down' : 'up'}
915
+ uniqueId="all-dropdow-arrow-icon"
916
+ className="all-dropdow-arrow-icon"
917
+ />
918
+ </button>
919
+ )}
920
+ </>
834
921
  </div>
835
922
  )}
836
923
  </>
837
924
  )}
838
925
 
926
+ {filteredData?.length > 0 && enableSelectAll && isMultiple && (
927
+ <div
928
+ id="select-all"
929
+ className={`qbs-select-all-link qbs-cursor-pointer qbs-text-xs`}
930
+ onClick={handleSelectAll}
931
+ >
932
+ <div
933
+ className={`qbs-autocomplete-listitem-container qbs-autocomplete-checkbox-container`}
934
+ >
935
+ <div className="qbs-autocomplete-checkbox">
936
+ <input
937
+ type="checkbox"
938
+ checked={selectAll}
939
+ id={`qbs-checkbox-all`}
940
+ />
941
+ <label htmlFor={`qbs-checkbox-all`}>
942
+ <svg
943
+ width="8"
944
+ height="6"
945
+ viewBox="0 0 8 6"
946
+ fill="none"
947
+ xmlns="http://www.w3.org/2000/svg"
948
+ >
949
+ <path
950
+ d="M0 3.21739L2.89883 6L8 1.06994L6.89494 0L2.89883 3.86768L1.09728 2.14745L0 3.21739Z"
951
+ fill="white"
952
+ />
953
+ </svg>
954
+ </label>
955
+ </div>
956
+ <div className={`qbs-autocomplete-suggestions-item`}>
957
+ Select All
958
+ </div>
959
+ </div>
960
+ </div>
961
+ )}
962
+
839
963
  <div
840
- className={`qbs-autocomplete-suggestions-sub ${
964
+ className={`qbs-autocomplete-suggestions-sub qbs-autocomplete-selected-suggestions-outer ${
841
965
  viewMode ? 'hidden' : ''
842
966
  }`}
843
967
  ref={itemsRef}
@@ -14,7 +14,7 @@ import InputActions from './components/InputActions';
14
14
  import { useSuggestions } from './utilities/autosuggestions';
15
15
  import { debounce } from './utilities/debounce';
16
16
  import { deepEqual } from './utilities/deepEqual';
17
- import { default as Tooltip } from './utilities/expandableTootltip';
17
+ import { default as Tooltip } from './utilities/NewTooltip';
18
18
  import { filterSuggestions } from './utilities/filterSuggestions';
19
19
  import { AllDropArrow, Search, Spinner } from './utilities/icons';
20
20
 
@@ -65,6 +65,7 @@ const ExpandableAutoComplete = forwardRef<
65
65
  typeOnlyFetch = false,
66
66
  autoDropdown = false,
67
67
  enableSelectAll = false,
68
+ matchFromStart = false,
68
69
  },
69
70
  ref
70
71
  ) => {
@@ -107,11 +108,16 @@ const ExpandableAutoComplete = forwardRef<
107
108
  const spaceBelow = window.innerHeight - inputRect.bottom;
108
109
  const spaceAbove = inputRect.top + window.scrollY;
109
110
 
110
- const dropdownHeight = 275; // Assume a fixed height or calculate based on content
111
+ let dropdownHeight = 275; // Assume a fixed height or calculate based on content
111
112
  if (spaceBelow >= dropdownHeight) {
112
113
  dropdownPosition.top =
113
114
  inputRect.top + window.scrollY + inputRect.height;
114
115
  } else {
116
+ dropdownHeight =
117
+ dropdownHeight +
118
+ (filteredData?.length > 0 && enableSelectAll && isMultiple
119
+ ? 32
120
+ : 0);
115
121
  dropdownPosition.top =
116
122
  inputRect.top + window.scrollY - dropdownHeight + 73;
117
123
  }
@@ -122,15 +128,6 @@ const ExpandableAutoComplete = forwardRef<
122
128
  }
123
129
  };
124
130
 
125
- useEffect(() => {
126
- window.addEventListener('resize', adjustDropdownPosition);
127
- adjustDropdownPosition();
128
-
129
- return () => {
130
- window.removeEventListener('resize', adjustDropdownPosition);
131
- };
132
- }, [dropOpen, selectedItems]);
133
-
134
131
  const { suggestions, isLoading, handlePickSuggestions } = useSuggestions(
135
132
  getData,
136
133
  data,
@@ -321,9 +318,20 @@ const ExpandableAutoComplete = forwardRef<
321
318
  desc,
322
319
  selected,
323
320
  async,
324
- isTreeDropdown
321
+ isTreeDropdown,
322
+ true,
323
+ matchFromStart
325
324
  );
326
325
 
326
+ useEffect(() => {
327
+ window.addEventListener('resize', adjustDropdownPosition);
328
+ adjustDropdownPosition();
329
+
330
+ return () => {
331
+ window.removeEventListener('resize', adjustDropdownPosition);
332
+ };
333
+ }, [dropOpen, selectedItems, filteredData]);
334
+
327
335
  useEffect(() => {
328
336
  // Handle keyboard navigation
329
337
  const handleKeyDown = (e: any) => {
@@ -388,10 +396,12 @@ const ExpandableAutoComplete = forwardRef<
388
396
  ): boolean => {
389
397
  if (Array.isArray(selectedItems)) {
390
398
  return selectedItems.some(
391
- (selectedItem) => selectedItem[desc] === item[desc]
399
+ (selectedItem) =>
400
+ selectedItem[desc] === item[desc] ||
401
+ selectedItem[descId] === item[descId]
392
402
  );
393
403
  } else {
394
- return item[desc] === selectedItems;
404
+ return item[desc] === selectedItems || item[descId] === selectedItems;
395
405
  }
396
406
  };
397
407
 
@@ -117,9 +117,26 @@
117
117
  .qbs-hidden {
118
118
  display: none;
119
119
  }
120
+ .qbs-autocomplete-selected-suggestions {
121
+ padding: 8px 0px;
122
+ }
120
123
  .qbs-autocomplete-selected-suggestions .qbs-autocomplete-suggestions-sub {
121
124
  min-height: 184px;
122
125
  }
126
+ .qbs-autocomplete-selected-suggestions .qbs-autocomplete-selected-suggestions-outer {
127
+ padding: 0px 8px;
128
+ }
129
+ .qbs-autocomplete-selected-suggestions .qbs-autocomplete-listitem-container{
130
+ padding-top: 0px;
131
+ padding-left: 4px;
132
+ padding-right: 4px;
133
+ }
134
+ .qbs-autocomplete-selected-suggestions .qbs-autocomplete-selected-suggestions-outer span.dropdown-search-icon {
135
+ left: 16px;
136
+ }
137
+ .qbs-autocomplete-selected-suggestions .qbs-autocomplete-selected-suggestions-outer .qbs-all-dropdown-btn {
138
+ right: 16px;
139
+ }
123
140
  .selected-items-outer-container {
124
141
  display: flex;
125
142
  gap: 5px;