react-core-ts 1.0.41 → 1.0.43

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.
Files changed (46) hide show
  1. package/README.md +50 -0
  2. package/dist/AutoComplete.d.ts +2 -2
  3. package/dist/AutoComplete.js +44 -37
  4. package/dist/AutoComplete.js.map +1 -1
  5. package/dist/AutoCompleteWithSelectedList.d.ts +4 -0
  6. package/dist/AutoCompleteWithSelectedList.js +446 -0
  7. package/dist/AutoCompleteWithSelectedList.js.map +1 -0
  8. package/dist/ExpandableAutoComplete.js +12 -5
  9. package/dist/ExpandableAutoComplete.js.map +1 -1
  10. package/dist/commontypes.d.ts +11 -4
  11. package/dist/components/DropdownList.js +2 -2
  12. package/dist/components/DropdownList.js.map +1 -1
  13. package/dist/components/InputActions.d.ts +1 -0
  14. package/dist/components/InputActions.js +2 -2
  15. package/dist/components/InputActions.js.map +1 -1
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.js +3 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/styles/components/treedropdown.css +8 -0
  20. package/dist/styles/styles/components/autocomplete.css +602 -0
  21. package/dist/styles/styles/components/selectedautocomplete.css +121 -0
  22. package/dist/styles/styles/components/treedropdown.css +63 -0
  23. package/dist/styles/styles/global.css +7 -0
  24. package/dist/utilities/autosuggestions.d.ts +2 -2
  25. package/dist/utilities/autosuggestions.js +10 -7
  26. package/dist/utilities/autosuggestions.js.map +1 -1
  27. package/dist/utilities/filterSuggestions.d.ts +1 -1
  28. package/dist/utilities/filterSuggestions.js +10 -5
  29. package/dist/utilities/filterSuggestions.js.map +1 -1
  30. package/docs/App.tsx +96 -4
  31. package/docs/index.html +1 -1
  32. package/package.json +1 -1
  33. package/src/AutoComplete.tsx +66 -51
  34. package/src/AutoCompleteWithSelectedList.tsx +677 -0
  35. package/src/ExpandableAutoComplete.tsx +13 -5
  36. package/src/commontypes.ts +14 -6
  37. package/src/components/DropdownList.tsx +3 -3
  38. package/src/components/InputActions.tsx +3 -1
  39. package/src/index.html +1 -1
  40. package/src/index.tsx +1 -0
  41. package/src/styles/components/autocomplete.css +18 -1
  42. package/src/styles/components/selectedautocomplete.css +121 -0
  43. package/src/styles/components/treedropdown.css +8 -0
  44. package/src/styles/global.css +2 -1
  45. package/src/utilities/autosuggestions.ts +18 -12
  46. package/src/utilities/filterSuggestions.ts +10 -7
@@ -1,12 +1,19 @@
1
- import Tooltip from './utilities/tooltip';
2
- import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
1
+ import Tooltip from "./utilities/tooltip";
2
+ import React, {
3
+ forwardRef,
4
+ useCallback,
5
+ useEffect,
6
+ useImperativeHandle,
7
+ useRef,
8
+ useState,
9
+ } from "react";
3
10
 
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';
11
+ import { AutoSuggestionInputProps } from "./commontypes";
12
+ import { useSuggestions } from "./utilities/autosuggestions";
13
+ import { debounce } from "./utilities/debounce";
14
+ import { deepEqual } from "./utilities/deepEqual";
15
+ import { filterSuggestions } from "./utilities/filterSuggestions";
16
+ import { Close, DropArrow, Search, Spinner } from "./utilities/icons";
10
17
 
11
18
  type ValueProps = {
12
19
  [key: string]: string;
@@ -24,14 +31,14 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
24
31
  fullWidth = false,
25
32
  placeholder,
26
33
  id,
27
- type = 'custom_select',
34
+ type = "custom_select",
28
35
  selectedItems: propsSeelctedItems = [],
29
36
  readOnly = false,
30
37
  disabled = false,
31
38
  value,
32
39
  isMultiple = false,
33
- desc = 'name',
34
- descId = 'id',
40
+ desc = "name",
41
+ descId = "id",
35
42
  singleSelect,
36
43
  className,
37
44
  async = false,
@@ -50,12 +57,12 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
50
57
  const [isInitialRender, setIsInitialRender] = useState(true);
51
58
 
52
59
  const [inputValue, setInputValue] = useState<string>(value);
53
- const [searchValue, setSearchValue] = useState<string>('');
60
+ const [searchValue, setSearchValue] = useState<string>("");
54
61
  const [nextPage, setNextPage] = useState<number | undefined>(1);
55
62
  const [dropOpen, setDropOpen] = useState<boolean>(false);
56
63
  const [selectedItems, setSelectedItems] = useState<ValueProps[]>([]);
57
64
  // API call for suggestions through a custom hook
58
- const [dropdownPosition, setDropdownPosition] = useState('bottom');
65
+ const [dropdownPosition, setDropdownPosition] = useState("bottom");
59
66
  const inputRef = useRef(null);
60
67
  const dropRef = useRef(null);
61
68
  useImperativeHandle(ref, () => inputRef.current);
@@ -68,19 +75,19 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
68
75
  const spaceAbove = inputBoxRect.top;
69
76
  const spaceBelow = viewportHeight - inputBoxRect.bottom;
70
77
  if (spaceAbove > spaceBelow) {
71
- setDropdownPosition('top');
78
+ setDropdownPosition("top");
72
79
  } else {
73
- setDropdownPosition('bottom');
80
+ setDropdownPosition("bottom");
74
81
  }
75
82
  }
76
83
  };
77
84
 
78
85
  useEffect(() => {
79
- window.addEventListener('resize', adjustDropdownPosition);
86
+ window.addEventListener("resize", adjustDropdownPosition);
80
87
  adjustDropdownPosition();
81
88
 
82
89
  return () => {
83
- window.removeEventListener('resize', adjustDropdownPosition);
90
+ window.removeEventListener("resize", adjustDropdownPosition);
84
91
  };
85
92
  }, [dropOpen]);
86
93
 
@@ -101,19 +108,27 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
101
108
  // Handling the selection of a suggestion
102
109
  const handleSuggestionClick = useCallback((suggestion: ValueProps) => {
103
110
  if (isMultiple) {
104
- setSelectedItems((prev) => [...prev, suggestion]);
111
+ setSelectedItems((prev) => {
112
+ const isAdded = prev.some(
113
+ (item) => item[descId] === suggestion[descId]
114
+ );
115
+ if (isAdded) {
116
+ return prev.filter((item) => item[descId] !== suggestion[descId]);
117
+ } else {
118
+ return [...prev, suggestion];
119
+ }
120
+ });
105
121
  } else {
106
122
  setInputValue(suggestion[desc]);
123
+ setSearchValue("");
124
+ onChange(suggestion);
125
+ setDropOpen(false);
107
126
  }
108
- setSearchValue('');
109
- setInputValue(suggestion[desc]);
110
- onChange(suggestion);
111
- setDropOpen(false);
112
127
  }, []);
113
128
 
114
129
  // Adding debounce to avoid making API calls on every keystroke
115
130
  const handleChangeWithDebounce = debounce((value) => {
116
- if ((type === 'auto_complete' || type === 'auto_suggestion') && async) {
131
+ if ((type === "auto_complete" || type === "auto_suggestion") && async) {
117
132
  handlePickSuggestions(value, 1);
118
133
  }
119
134
  }, 1000);
@@ -135,7 +150,7 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
135
150
  setInputValue(suggestion[desc]);
136
151
  onChange(suggestion);
137
152
  } else {
138
- setInputValue('');
153
+ setInputValue("");
139
154
  }
140
155
  }
141
156
  };
@@ -145,7 +160,7 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
145
160
  }, [propsSeelctedItems]);
146
161
  // Effect to set the input value whenever `value` prop changes
147
162
  useEffect(() => {
148
- setInputValue(value ?? '');
163
+ setInputValue(value ?? "");
149
164
  }, [value]);
150
165
 
151
166
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -154,8 +169,8 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
154
169
  setSearchValue(value);
155
170
  handleChangeWithDebounce(value);
156
171
  if (!value) {
157
- setInputValue('');
158
- onChange({ [descId]: '', [desc]: '' });
172
+ setInputValue("");
173
+ onChange({ [descId]: "", [desc]: "" });
159
174
  }
160
175
  };
161
176
  const handleSuggestionChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -173,18 +188,18 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
173
188
 
174
189
  const handleClear = () => {
175
190
  if (searchValue) {
176
- setSearchValue('');
191
+ setSearchValue("");
177
192
  setDropOpen(false);
178
193
  } else {
179
- setInputValue('');
180
- onChange({ [descId]: '', [desc]: '' });
194
+ setInputValue("");
195
+ onChange({ [descId]: "", [desc]: "" });
181
196
  setDropOpen(false);
182
197
  }
183
198
  };
184
199
 
185
200
  const generateClassName = useCallback(() => {
186
201
  return `qbs-textfield-default ${className} ${
187
- errors && errors?.message ? 'textfield-error' : 'textfield'
202
+ errors && errors?.message ? "textfield-error" : "textfield"
188
203
  }`;
189
204
  }, [errors, name]);
190
205
  const handleRemoveSelectedItem = (index: number) => {
@@ -209,12 +224,12 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
209
224
  !dropdownRef.current.contains(event.target)
210
225
  ) {
211
226
  setDropOpen(false);
212
- setSearchValue('');
227
+ setSearchValue("");
213
228
  }
214
229
  };
215
- document.addEventListener('mousedown', handleClickOutside as any);
230
+ document.addEventListener("mousedown", handleClickOutside as any);
216
231
  return () => {
217
- document.removeEventListener('mousedown', handleClickOutside as any);
232
+ document.removeEventListener("mousedown", handleClickOutside as any);
218
233
  };
219
234
  }, []);
220
235
 
@@ -249,24 +264,24 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
249
264
  };
250
265
 
251
266
  const handleOnClick = () => {
252
- !disabled && !readOnly ? setDropOpen(true) : '';
267
+ !disabled && !readOnly ? setDropOpen(true) : "";
253
268
  };
254
269
  const tooltipContent =
255
270
  selectedItems?.length > 1
256
271
  ? selectedItems
257
272
  ?.slice(1)
258
273
  .map((item) => item[desc])
259
- .join(', ')
260
- : '';
274
+ .join(", ")
275
+ : "";
261
276
 
262
277
  return (
263
- <div className={fullWidth ? 'fullWidth' : 'autoWidth'} ref={dropdownRef}>
278
+ <div className={fullWidth ? "fullWidth" : "autoWidth"} ref={dropdownRef}>
264
279
  {label && (
265
280
  <div
266
281
  style={{
267
282
  marginBottom: 5,
268
- display: 'flex',
269
- justifyContent: 'space-between',
283
+ display: "flex",
284
+ justifyContent: "space-between",
270
285
  }}
271
286
  >
272
287
  <label className={`labels label-text`}>
@@ -280,7 +295,7 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
280
295
  )}
281
296
  {/* Displaying selected items for multi-select */}
282
297
 
283
- <div style={{ position: 'relative' }}>
298
+ <div style={{ position: "relative" }}>
284
299
  <div className="selected-items-container ">
285
300
  {selectedItems?.length > 0 && (
286
301
  <>
@@ -313,7 +328,7 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
313
328
  ref={inputRef}
314
329
  type="text"
315
330
  value={
316
- type === 'auto_suggestion'
331
+ type === "auto_suggestion"
317
332
  ? inputValue
318
333
  : searchValue || inputValue
319
334
  }
@@ -322,9 +337,9 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
322
337
  onFocus={onFocus}
323
338
  onClick={() => handleOnClick()}
324
339
  className={generateClassName()}
325
- placeholder={selectedItems?.length > 0 ? '' : placeholder ?? ''}
340
+ placeholder={selectedItems?.length > 0 ? "" : placeholder ?? ""}
326
341
  readOnly={
327
- readOnly || type === 'custom_select' || type == 'auto_suggestion'
342
+ readOnly || type === "custom_select" || type == "auto_suggestion"
328
343
  }
329
344
  disabled={disabled}
330
345
  data-testid="custom-autocomplete"
@@ -361,9 +376,9 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
361
376
  ref={dropRef}
362
377
  className={`qbs-autocomplete-suggestions ${dropdownPosition}`}
363
378
  >
364
- {type == 'auto_suggestion' && (
379
+ {type == "auto_suggestion" && (
365
380
  <div
366
- style={{ position: 'relative' }}
381
+ style={{ position: "relative" }}
367
382
  className="react-core-ts-search-container"
368
383
  >
369
384
  <span className="dropdown-search-icon">
@@ -395,9 +410,9 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
395
410
  key={idx.toString()}
396
411
  className={`qbs-autocomplete-listitem-container ${
397
412
  (isMultiple || singleSelect) &&
398
- 'qbs-autocomplete-checkbox-container'
413
+ "qbs-autocomplete-checkbox-container"
399
414
  } ${
400
- isSelected(suggestion, selected) ? 'is-selected' : ''
415
+ isSelected(suggestion, selected) ? "is-selected" : ""
401
416
  }`}
402
417
  >
403
418
  {(isMultiple || singleSelect) && (
@@ -427,7 +442,7 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
427
442
  <li
428
443
  key={idx}
429
444
  className={`qbs-autocomplete-suggestions-item ${
430
- isSelected(suggestion, selected) ? 'is-selected' : ''
445
+ isSelected(suggestion, selected) ? "is-selected" : ""
431
446
  }`}
432
447
  onClick={() => handleSuggestionClick(suggestion)}
433
448
  data-testid={suggestion[desc]}
@@ -440,7 +455,7 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
440
455
  <>
441
456
  {isLoading ? (
442
457
  <div
443
- style={{ display: 'flex', justifyContent: 'center' }}
458
+ style={{ display: "flex", justifyContent: "center" }}
444
459
  >
445
460
  <span>
446
461
  <Spinner />
@@ -451,7 +466,7 @@ const AutoComplete = forwardRef<HTMLInputElement, AutoSuggestionInputProps>(
451
466
  className="qbs-autocomplete-notfound"
452
467
  onClick={handleBlur}
453
468
  >
454
- {notDataMessage ?? 'No Results Found'}
469
+ {notDataMessage ?? "No Results Found"}
455
470
  </li>
456
471
  )}
457
472
  </>