@xqmsg/ui-core 0.24.2 → 0.24.3

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 (42) hide show
  1. package/README.md +8 -13
  2. package/dist/components/input/components/dropdown/index.d.ts +1 -0
  3. package/dist/ui-core.cjs.development.js +156 -100
  4. package/dist/ui-core.cjs.development.js.map +1 -1
  5. package/dist/ui-core.cjs.production.min.js +1 -1
  6. package/dist/ui-core.cjs.production.min.js.map +1 -1
  7. package/dist/ui-core.esm.js +157 -101
  8. package/dist/ui-core.esm.js.map +1 -1
  9. package/package.json +6 -2
  10. package/src/components/icons/checkmark/index.tsx +1 -1
  11. package/src/components/icons/chevron/down/index.tsx +7 -1
  12. package/src/components/icons/chevron/right/index.tsx +1 -1
  13. package/src/components/icons/clock/index.tsx +1 -1
  14. package/src/components/icons/dropdown/index.tsx +5 -1
  15. package/src/components/icons/error/index.tsx +1 -1
  16. package/src/components/icons/file/fill/index.tsx +1 -1
  17. package/src/components/icons/file/outline/index.tsx +1 -1
  18. package/src/components/icons/folder/add/fill/index.tsx +1 -1
  19. package/src/components/icons/folder/add/outline/index.tsx +1 -1
  20. package/src/components/icons/folder/outline/index.tsx +1 -1
  21. package/src/components/icons/group/index.tsx +1 -1
  22. package/src/components/icons/home/index.tsx +1 -1
  23. package/src/components/icons/image/index.tsx +1 -1
  24. package/src/components/icons/link/index.tsx +1 -1
  25. package/src/components/icons/menu/index.tsx +1 -1
  26. package/src/components/icons/microsoft/index.tsx +1 -1
  27. package/src/components/icons/neutral/index.tsx +3 -1
  28. package/src/components/icons/page/index.tsx +1 -1
  29. package/src/components/icons/positive/index.tsx +1 -1
  30. package/src/components/icons/question/index.tsx +1 -1
  31. package/src/components/icons/search/index.tsx +1 -1
  32. package/src/components/icons/services/index.tsx +1 -1
  33. package/src/components/icons/settings/index.tsx +3 -1
  34. package/src/components/icons/table/fill/index.tsx +1 -1
  35. package/src/components/icons/table/outline/index.tsx +1 -1
  36. package/src/components/icons/task/index.tsx +1 -1
  37. package/src/components/icons/trash/index.tsx +1 -1
  38. package/src/components/icons/video/index.tsx +1 -1
  39. package/src/components/icons/warning/index.tsx +1 -1
  40. package/src/components/input/StackedMultiSelect/index.tsx +34 -27
  41. package/src/components/input/StackedSelect/index.tsx +30 -25
  42. package/src/components/input/components/dropdown/index.tsx +39 -11
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.24.2",
2
+ "version": "0.24.3",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -37,7 +37,11 @@
37
37
  "trailingComma": "es5"
38
38
  },
39
39
  "name": "@xqmsg/ui-core",
40
- "author": "josh@xqmsg.com",
40
+ "author": {
41
+ "name": "XQ",
42
+ "email": "ike@xqmsg.com",
43
+ "url": "https://xqmsg.co"
44
+ },
41
45
  "module": "dist/ui-core.esm.js",
42
46
  "size-limit": [
43
47
  {
@@ -9,5 +9,5 @@ export interface CheckmarkProps {
9
9
  * A functional React component utilized to render the `Checkmark` icon component
10
10
  */
11
11
  export const Checkmark: React.FC<CheckmarkProps> = ({ boxSize }) => {
12
- return <CheckmarkIcon boxSize={boxSize} />;
12
+ return <CheckmarkIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -10,5 +10,11 @@ export interface ChevronDownProps {
10
10
  * A functional React component utilized to render the `ChevronDown` icon component
11
11
  */
12
12
  export const ChevronDown: React.FC<ChevronDownProps> = ({ boxSize }) => {
13
- return <ChevronDownIcon boxSize={boxSize} fill={colors.fill.action} />;
13
+ return (
14
+ <ChevronDownIcon
15
+ width={boxSize}
16
+ height={boxSize}
17
+ fill={colors.fill.action}
18
+ />
19
+ );
14
20
  };
@@ -9,5 +9,5 @@ export interface ChevronRightProps {
9
9
  * A functional React component utilized to render the `ChevronRight` icon component
10
10
  */
11
11
  export const ChevronRight: React.FC<ChevronRightProps> = ({ boxSize }) => {
12
- return <ChevronRightIcon boxSize={boxSize} />;
12
+ return <ChevronRightIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface ClockProps {
9
9
  * A functional React component utilized to render the `Clock` icon component
10
10
  */
11
11
  export const Clock: React.FC<ClockProps> = ({ boxSize }) => {
12
- return <ClockIcon boxSize={boxSize} />;
12
+ return <ClockIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -11,6 +11,10 @@ export interface DropdownProps {
11
11
  */
12
12
  export const Dropdown: React.FC<DropdownProps> = ({ boxSize, disabled }) => {
13
13
  return (
14
- <DropdownIcon boxSize={boxSize} fill={disabled ? '#3C3C4399' : '#0082FF'} />
14
+ <DropdownIcon
15
+ width={boxSize}
16
+ height={boxSize}
17
+ fill={disabled ? '#3C3C4399' : '#0082FF'}
18
+ />
15
19
  );
16
20
  };
@@ -9,5 +9,5 @@ export interface ErrorProps {
9
9
  * A functional React component utilized to render the `Error` icon component
10
10
  */
11
11
  export const Error: React.FC<ErrorProps> = ({ boxSize }) => {
12
- return <ErrorIcon boxSize={boxSize} />;
12
+ return <ErrorIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface FileFillProps {
9
9
  * A functional React component utilized to render the `FileFill` icon component
10
10
  */
11
11
  export const FileFill: React.FC<FileFillProps> = ({ boxSize }) => {
12
- return <FileFillIcon boxSize={boxSize} />;
12
+ return <FileFillIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface FileOutlineProps {
9
9
  * A functional React component utilized to render the `FileOutline` icon component
10
10
  */
11
11
  export const FileOutline: React.FC<FileOutlineProps> = ({ boxSize }) => {
12
- return <FileOutlineIcon boxSize={boxSize} />;
12
+ return <FileOutlineIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface FolderAddFillProps {
9
9
  * A functional React component utilized to render the `FolderAddFill` icon component
10
10
  */
11
11
  export const FolderAddFill: React.FC<FolderAddFillProps> = ({ boxSize }) => {
12
- return <FolderAddFillIcon boxSize={boxSize} />;
12
+ return <FolderAddFillIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -11,5 +11,5 @@ export interface FolderAddOutlineProps {
11
11
  export const FolderAddOutline: React.FC<FolderAddOutlineProps> = ({
12
12
  boxSize,
13
13
  }) => {
14
- return <FolderAddOutlineIcon boxSize={boxSize} />;
14
+ return <FolderAddOutlineIcon width={boxSize} height={boxSize} />;
15
15
  };
@@ -9,5 +9,5 @@ export interface FolderOutlineProps {
9
9
  * A functional React component utilized to render the `FolderOutline` icon component
10
10
  */
11
11
  export const FolderOutline: React.FC<FolderOutlineProps> = ({ boxSize }) => {
12
- return <FolderOutlineIcon boxSize={boxSize} />;
12
+ return <FolderOutlineIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface GroupProps {
9
9
  * A functional React component utilized to render the `Group` icon component
10
10
  */
11
11
  export const Group: React.FC<GroupProps> = ({ boxSize }) => {
12
- return <GroupIcon boxSize={boxSize} />;
12
+ return <GroupIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface HomeProps {
9
9
  * A functional React component utilized to render the `Home` icon component
10
10
  */
11
11
  export const Home: React.FC<HomeProps> = ({ boxSize }) => {
12
- return <HomeIcon boxSize={boxSize} />;
12
+ return <HomeIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface ImageProps {
9
9
  * A functional React component utilized to render the `Image` icon component
10
10
  */
11
11
  export const Image: React.FC<ImageProps> = ({ boxSize }) => {
12
- return <ImageIcon boxSize={boxSize} />;
12
+ return <ImageIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface LinkProps {
9
9
  * A functional React component utilized to render the `Link` icon component
10
10
  */
11
11
  export const Link: React.FC<LinkProps> = ({ boxSize }) => {
12
- return <LinkIcon boxSize={boxSize} />;
12
+ return <LinkIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface MenuProps {
9
9
  * A functional React component utilized to render the `Menu` icon component
10
10
  */
11
11
  export const Menu: React.FC<MenuProps> = ({ boxSize }) => {
12
- return <MenuIcon boxSize={boxSize} />;
12
+ return <MenuIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface MicrosoftProps {
9
9
  * A functional React component utilized to render the `Microsoft` icon component
10
10
  */
11
11
  export const Microsoft: React.FC<MicrosoftProps> = ({ boxSize }) => {
12
- return <MicrosoftLogo boxSize={boxSize} />;
12
+ return <MicrosoftLogo width={boxSize} height={boxSize} />;
13
13
  };
@@ -10,5 +10,7 @@ export interface NeutralProps {
10
10
  * A functional React component utilized to render the `Neutral` icon component
11
11
  */
12
12
  export const Neutral: React.FC<NeutralProps> = ({ color, boxSize }) => {
13
- return <NeutralIcon boxSize={boxSize} fill={color || '#3C3C43'} />;
13
+ return (
14
+ <NeutralIcon width={boxSize} height={boxSize} fill={color || '#3C3C43'} />
15
+ );
14
16
  };
@@ -9,5 +9,5 @@ export interface PageProps {
9
9
  * A functional React component utilized to render the `Page` icon component
10
10
  */
11
11
  export const Page: React.FC<PageProps> = ({ boxSize }) => {
12
- return <PageIcon boxSize={boxSize} />;
12
+ return <PageIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface PositiveProps {
9
9
  * A functional React component utilized to render the `Positive` icon component
10
10
  */
11
11
  export const Positive: React.FC<PositiveProps> = ({ boxSize }) => {
12
- return <PositiveIcon boxSize={boxSize} />;
12
+ return <PositiveIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface QuestionProps {
9
9
  * A functional React component utilized to render the `Question` icon component
10
10
  */
11
11
  export const Question: React.FC<QuestionProps> = ({ boxSize }) => {
12
- return <QuestionIcon boxSize={boxSize} />;
12
+ return <QuestionIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface SearchProps {
9
9
  * A functional React component utilized to render the `Search` icon component
10
10
  */
11
11
  export const Search: React.FC<SearchProps> = ({ boxSize }) => {
12
- return <SearchIcon boxSize={boxSize} />;
12
+ return <SearchIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface ServicesProps {
9
9
  * A functional React component utilized to render the `Services` icon component
10
10
  */
11
11
  export const Services: React.FC<ServicesProps> = ({ boxSize }) => {
12
- return <ServicesIcon boxSize={boxSize} />;
12
+ return <ServicesIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -10,5 +10,7 @@ export interface SettingsProps {
10
10
  * A functional React component utilized to render the `Settings` icon component
11
11
  */
12
12
  export const Settings: React.FC<SettingsProps> = ({ boxSize }) => {
13
- return <SettingsIcon boxSize={boxSize} fill={colors.fill.action} />;
13
+ return (
14
+ <SettingsIcon width={boxSize} height={boxSize} fill={colors.fill.action} />
15
+ );
14
16
  };
@@ -9,5 +9,5 @@ export interface TableFillProps {
9
9
  * A functional React component utilized to render the `TableFill` icon component
10
10
  */
11
11
  export const TableFill: React.FC<TableFillProps> = ({ boxSize }) => {
12
- return <TableFillIcon boxSize={boxSize} />;
12
+ return <TableFillIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface TableOutlineProps {
9
9
  * A functional React component utilized to render the `TableOutline` icon component
10
10
  */
11
11
  export const TableOutline: React.FC<TableOutlineProps> = ({ boxSize }) => {
12
- return <TableOutlineIcon boxSize={boxSize} />;
12
+ return <TableOutlineIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -6,5 +6,5 @@ import { IconProps } from '..';
6
6
  * A functional React component utilized to render the `Task` icon component
7
7
  */
8
8
  export const Task: React.FC<IconProps> = ({ boxSize }) => {
9
- return <TaskIcon boxSize={boxSize} />;
9
+ return <TaskIcon width={boxSize} height={boxSize} />;
10
10
  };
@@ -9,5 +9,5 @@ export interface TrashProps {
9
9
  * A functional React component utilized to render the `Trash` icon component
10
10
  */
11
11
  export const Trash: React.FC<TrashProps> = ({ boxSize }) => {
12
- return <TrashIcon boxSize={boxSize} />;
12
+ return <TrashIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface VideoProps {
9
9
  * A functional React component utilized to render the `Video` icon component
10
10
  */
11
11
  export const Video: React.FC<VideoProps> = ({ boxSize }) => {
12
- return <VideoIcon boxSize={boxSize} />;
12
+ return <VideoIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -9,5 +9,5 @@ export interface WarningProps {
9
9
  * A functional React component utilized to render the `Warning` icon component
10
10
  */
11
11
  export const Warning: React.FC<WarningProps> = ({ boxSize }) => {
12
- return <WarningIcon boxSize={boxSize} />;
12
+ return <WarningIcon width={boxSize} height={boxSize} />;
13
13
  };
@@ -1,12 +1,10 @@
1
1
  import React, {
2
2
  KeyboardEventHandler,
3
3
  useEffect,
4
- useMemo,
5
4
  useRef,
6
5
  useState,
7
6
  } from 'react';
8
7
  import { Box, Flex, Text, Input } from '@chakra-ui/react';
9
- import { debounce } from 'lodash';
10
8
  import {
11
9
  FieldOption,
12
10
  FieldOptions,
@@ -50,13 +48,16 @@ const StackedMultiSelect = React.forwardRef<
50
48
  const [isInit, setIsInit] = useState(false);
51
49
  const [localValues, setLocalValues] = useState<FieldOptions>([]);
52
50
  const [localOptions, setLocalOptions] = useState<FieldOptions>(options);
51
+ const [filteredOptions, setFilteredOptions] = useState<FieldOptions>(
52
+ localOptions
53
+ );
53
54
  const [isFocussed, setIsFocussed] = useState(false);
54
55
  const [shouldSideScroll, setShouldSideScroll] = useState(false);
55
56
  const [optionIndex, setOptionIndex] = useState<number | null>(null);
56
57
 
57
58
  const [position, setPosition] = useState<'top' | 'bottom'>('top');
58
59
  const [searchValue, setSearchValue] = useState('');
59
- const [debouncedSearchValue, setDebouncedSearchValue] = useState('');
60
+ // const [debouncedSearchValue, setDebouncedSearchValue] = useState('');
60
61
 
61
62
  const boundingClientRect = dropdownRef.current?.getBoundingClientRect() as DOMRect;
62
63
 
@@ -137,6 +138,9 @@ const StackedMultiSelect = React.forwardRef<
137
138
  );
138
139
 
139
140
  setLocalValues(prevLocalValues => [...prevLocalValues, option]);
141
+
142
+ // reset search on value select
143
+ setSearchValue('');
140
144
  };
141
145
 
142
146
  const handleDelete = (option: FieldOption) => {
@@ -180,8 +184,8 @@ const StackedMultiSelect = React.forwardRef<
180
184
 
181
185
  if (e.key === 'ArrowUp' && optionIndex !== null && optionIndex > 0) {
182
186
  const incrementValue =
183
- localOptions[optionIndex - 1] &&
184
- localOptions[optionIndex - 1].value === 'section_header'
187
+ filteredOptions[optionIndex - 1] &&
188
+ filteredOptions[optionIndex - 1].value === 'section_header'
185
189
  ? 2
186
190
  : 1;
187
191
  setOptionIndex(optionIndex - incrementValue);
@@ -195,11 +199,11 @@ const StackedMultiSelect = React.forwardRef<
195
199
  if (
196
200
  e.key === 'ArrowDown' &&
197
201
  optionIndex !== null &&
198
- optionIndex < localOptions.length
202
+ optionIndex < filteredOptions.length
199
203
  ) {
200
204
  const incrementValue =
201
- localOptions[optionIndex + 1] &&
202
- localOptions[optionIndex + 1].value === 'section_header'
205
+ filteredOptions[optionIndex + 1] &&
206
+ filteredOptions[optionIndex + 1].value === 'section_header'
203
207
  ? 2
204
208
  : 1;
205
209
  setOptionIndex(optionIndex + incrementValue);
@@ -211,7 +215,7 @@ const StackedMultiSelect = React.forwardRef<
211
215
  }
212
216
 
213
217
  if (e.key === 'Enter' && optionIndex !== null) {
214
- const option = localOptions.find((_, idx) => optionIndex === idx);
218
+ const option = filteredOptions.find((_, idx) => optionIndex === idx);
215
219
  if (!option) return;
216
220
 
217
221
  handleChange(option);
@@ -222,8 +226,6 @@ const StackedMultiSelect = React.forwardRef<
222
226
  if (e.key === 'Tab') {
223
227
  return setIsFocussed(false);
224
228
  }
225
-
226
- return update(debouncedSearchValue.concat(e.key));
227
229
  }
228
230
  };
229
231
 
@@ -236,24 +238,27 @@ const StackedMultiSelect = React.forwardRef<
236
238
  );
237
239
 
238
240
  dropdownMenuRef.current?.scrollTo({
239
- top: idx * 24,
241
+ top: idx * 27,
240
242
  behavior: 'smooth',
241
243
  });
242
-
243
- setSearchValue('');
244
- setDebouncedSearchValue('');
245
244
  }
246
245
  }, [options, searchValue]);
247
246
 
248
- const updateSearchValue = useMemo(() => {
249
- return debounce(val => {
250
- setSearchValue(val);
251
- }, 1000);
252
- }, []);
253
-
254
- const update = (value: string) => {
255
- updateSearchValue(value);
256
- setDebouncedSearchValue(value);
247
+ useEffect(() => {
248
+ setFilteredOptions(
249
+ localOptions.filter(element => {
250
+ return element.label.toLowerCase().includes(searchValue.toLowerCase());
251
+ })
252
+ );
253
+ }, [localOptions, searchValue]);
254
+
255
+ const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
256
+ console.log(e);
257
+ const initialOptionIndex =
258
+ filteredOptions[0]?.value === 'section_header' ? 1 : 0;
259
+ setOptionIndex(initialOptionIndex);
260
+ const { value } = e.target;
261
+ setSearchValue(value);
257
262
  };
258
263
 
259
264
  return (
@@ -330,17 +335,19 @@ const StackedMultiSelect = React.forwardRef<
330
335
  _focus={{ boxShadow: 'none !important' }}
331
336
  />
332
337
  <Flex mr="4px" justifyContent="center" alignItems="center">
333
- <DropdownIcon boxSize="16px" disabled={disabled} />
338
+ <DropdownIcon boxSize="12px" disabled={disabled} />
334
339
  </Flex>
335
340
  </Flex>
336
341
  {isFocussed && (
337
342
  <Dropdown
338
343
  dropdownRef={dropdownMenuRef}
339
344
  onSelectItem={option => handleChange(option)}
340
- options={localOptions}
345
+ options={filteredOptions}
341
346
  position={position}
342
347
  optionIndex={optionIndex}
343
- />
348
+ >
349
+ <Input value={searchValue} onChange={handleInput} />
350
+ </Dropdown>
344
351
  )}
345
352
  </Box>
346
353
  );
@@ -2,18 +2,15 @@ import React, {
2
2
  KeyboardEventHandler,
3
3
  useEffect,
4
4
  useRef,
5
- useMemo,
6
5
  useState,
7
6
  } from 'react';
8
7
  import { Box, Input, InputGroup, InputRightElement } from '@chakra-ui/react';
9
8
  import { FieldOptions } from '../InputTypes';
10
9
  import { StackedInputProps } from '../StackedInput/StackedInput';
11
- import colors from '../../../theme/foundations/colors';
12
10
  import { UseFormSetValue, FieldValues, Control } from 'react-hook-form';
13
11
  import { Dropdown } from '../components/dropdown';
14
12
  import { useOnClickOutside } from '../../../hooks/useOnOutsideClick';
15
13
  import { Dropdown as DropdownIcon } from '../../icons/dropdown';
16
- import { debounce } from 'lodash';
17
14
 
18
15
  export interface StackedSelectProps extends StackedInputProps {
19
16
  options: FieldOptions;
@@ -51,7 +48,9 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
51
48
  const [optionIndex, setOptionIndex] = useState<number | null>(null);
52
49
  const [position, setPosition] = useState<'top' | 'bottom'>('top');
53
50
  const [searchValue, setSearchValue] = useState('');
54
- const [debouncedSearchValue, setDebouncedSearchValue] = useState('');
51
+ const [filteredOptions, setFilteredOptions] = useState<FieldOptions>(
52
+ options
53
+ );
55
54
 
56
55
  const boundingClientRect = dropdownRef.current?.getBoundingClientRect() as DOMRect;
57
56
 
@@ -70,9 +69,12 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
70
69
  (fullOptions || options).find(option => option.value === value)
71
70
  ?.label ?? ''
72
71
  );
73
- }, [fullOptions, value]);
72
+ }, [fullOptions, options, value]);
74
73
 
75
- useOnClickOutside(dropdownRef, () => setIsFocussed(false));
74
+ useOnClickOutside(dropdownRef, () => {
75
+ setIsFocussed(false);
76
+ setSearchValue('');
77
+ });
76
78
 
77
79
  const handleOnSelectItem = (option: {
78
80
  label: string;
@@ -85,6 +87,7 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
85
87
  setValue(name as string, option.value);
86
88
  setSelectedOption(option.label);
87
89
  setIsFocussed(false);
90
+ setSearchValue('');
88
91
  };
89
92
 
90
93
  const handleOnKeyDown: KeyboardEventHandler<HTMLInputElement> = e => {
@@ -173,22 +176,27 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
173
176
  top: idx * 24,
174
177
  behavior: 'smooth',
175
178
  });
176
-
177
- setSearchValue('');
178
- setDebouncedSearchValue('');
179
179
  }
180
180
  }, [options, searchValue]);
181
181
 
182
- const updateSearchValue = useMemo(() => {
183
- return debounce(val => {
184
- setSearchValue(val);
185
- }, 1000);
186
- }, []);
182
+ useEffect(() => {
183
+ setFilteredOptions(
184
+ options.filter(element => {
185
+ return element.label
186
+ .toLowerCase()
187
+ .includes(searchValue.toLowerCase());
188
+ })
189
+ );
190
+ }, [options, searchValue]);
187
191
 
188
- const update = (value: string) => {
189
- updateSearchValue(value);
190
- setDebouncedSearchValue(value);
192
+ const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
193
+ const initialOptionIndex =
194
+ filteredOptions[0]?.value === 'section_header' ? 1 : 0;
195
+ setOptionIndex(initialOptionIndex);
196
+ const { value } = e.target;
197
+ setSearchValue(value);
191
198
  };
199
+ console.log(searchValue);
192
200
 
193
201
  return (
194
202
  <Box ref={dropdownRef} position="relative">
@@ -198,21 +206,18 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
198
206
  {...props}
199
207
  ref={_ref}
200
208
  onClick={() => setIsFocussed(!isFocussed)}
201
- cursor="pointer"
202
- color="transparent"
209
+ cursor={isFocussed ? 'select' : 'pointer'}
203
210
  fontSize="13px"
204
- textShadow={`0 0 0 ${colors.label.primary.light}`}
205
- value={selectedOption}
206
- disabled={disabled}
211
+ value={isFocussed ? searchValue : selectedOption}
207
212
  autoComplete="off"
208
- onChange={e => update(debouncedSearchValue.concat(e.target.value))}
213
+ onChange={handleInput}
209
214
  onKeyDown={handleOnKeyDown}
210
215
  />
211
216
  <InputRightElement
212
217
  cursor={disabled ? 'not-allowed' : 'pointer'}
213
218
  onClick={() => !disabled && setIsFocussed(!isFocussed)}
214
219
  >
215
- <DropdownIcon boxSize="16px" disabled={disabled} />
220
+ <DropdownIcon boxSize="12px" disabled={disabled} />
216
221
  </InputRightElement>
217
222
  </InputGroup>
218
223
  {isFocussed && (
@@ -220,7 +225,7 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
220
225
  position={position}
221
226
  dropdownRef={dropdownMenuRef}
222
227
  onSelectItem={handleOnSelectItem}
223
- options={options}
228
+ options={filteredOptions}
224
229
  optionIndex={optionIndex}
225
230
  />
226
231
  )}
@@ -9,6 +9,7 @@ export interface DropdownProps {
9
9
  dropdownRef: RefObject<HTMLDivElement>;
10
10
  position: 'top' | 'bottom';
11
11
  optionIndex?: number | null;
12
+ children?: React.ReactNode;
12
13
  }
13
14
 
14
15
  /**
@@ -20,8 +21,25 @@ export const Dropdown: React.FC<DropdownProps> = ({
20
21
  dropdownRef,
21
22
  position,
22
23
  optionIndex,
24
+ children,
23
25
  }) => {
24
26
  const DropdownContent = useMemo(() => {
27
+ if (!options || options.length === 0) {
28
+ return (
29
+ <Box
30
+ borderRadius="inherit"
31
+ fontSize="13px"
32
+ px="8px"
33
+ py="4px"
34
+ width="100%"
35
+ color={colors.label.primary.light}
36
+ bg="inherit"
37
+ whiteSpace="nowrap"
38
+ >
39
+ No options
40
+ </Box>
41
+ );
42
+ }
25
43
  return options.map((option, idx) => (
26
44
  <Box key={idx} width="100%" role="combobox">
27
45
  {option.value === 'section_header' &&
@@ -79,13 +97,8 @@ export const Dropdown: React.FC<DropdownProps> = ({
79
97
  ));
80
98
  }, [onSelectItem, optionIndex, options]);
81
99
 
82
- if (!options) return null;
83
-
84
100
  return (
85
101
  <Flex
86
- flexDirection="column"
87
- ref={dropdownRef}
88
- scrollMargin="15px"
89
102
  bg={colors.fill.light.quaternary}
90
103
  backdropFilter="auto"
91
104
  backdropBlur="64px"
@@ -94,18 +107,33 @@ export const Dropdown: React.FC<DropdownProps> = ({
94
107
  borderColor={colors.fill.light.tertiary}
95
108
  mt="3px"
96
109
  maxH="240px"
97
- overflowY="auto"
110
+ position="absolute"
98
111
  px="8px"
99
112
  py="4px"
100
- position="absolute"
101
- top={position === 'top' ? 26 : undefined}
102
- bottom={position === 'bottom' ? 30 : undefined}
103
- width="fit-content"
113
+ overflow="hidden"
104
114
  minWidth="100%"
105
115
  zIndex={100}
106
116
  tabIndex={-2000}
117
+ alignItems="flex-start"
118
+ flexDirection="column"
119
+ top={position === 'top' ? 26 : undefined}
120
+ bottom={position === 'bottom' ? 30 : undefined}
107
121
  >
108
- {DropdownContent}
122
+ {children && (
123
+ <Box width="100%" mb={2} mt={1}>
124
+ {children}
125
+ </Box>
126
+ )}
127
+ <Flex
128
+ width="fit-content"
129
+ overflowY="auto"
130
+ flexDirection="column"
131
+ ref={dropdownRef}
132
+ minWidth="100%"
133
+ scrollMargin="15px"
134
+ >
135
+ {DropdownContent}
136
+ </Flex>
109
137
  </Flex>
110
138
  );
111
139
  };