@xqmsg/ui-core 0.14.4 → 0.15.0

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 (38) hide show
  1. package/dist/components/input/StackedCheckbox/StackedCheckbox.d.ts +10 -0
  2. package/dist/components/input/StackedMultiSelect/index.d.ts +0 -1
  3. package/dist/components/input/StackedPilledInput/index.d.ts +0 -1
  4. package/dist/components/input/components/dropdown/index.d.ts +3 -1
  5. package/dist/theme/components/button.d.ts +10 -8
  6. package/dist/theme/components/input.d.ts +2 -0
  7. package/dist/theme/components/select.d.ts +2 -0
  8. package/dist/theme/components/table.d.ts +1 -0
  9. package/dist/theme/components/textarea.d.ts +3 -1
  10. package/dist/ui-core.cjs.development.js +336 -186
  11. package/dist/ui-core.cjs.development.js.map +1 -1
  12. package/dist/ui-core.cjs.production.min.js +1 -1
  13. package/dist/ui-core.cjs.production.min.js.map +1 -1
  14. package/dist/ui-core.esm.js +337 -187
  15. package/dist/ui-core.esm.js.map +1 -1
  16. package/package.json +1 -1
  17. package/src/components/banner/index.tsx +7 -15
  18. package/src/components/button/Button.stories.tsx +15 -5
  19. package/src/components/button/index.tsx +2 -2
  20. package/src/components/input/Input.stories.tsx +95 -47
  21. package/src/components/input/StackedCheckbox/StackedCheckbox.tsx +27 -0
  22. package/src/components/input/StackedMultiSelect/index.tsx +187 -144
  23. package/src/components/input/StackedPilledInput/index.tsx +217 -225
  24. package/src/components/input/StackedSelect/StackedSelect.tsx +34 -2
  25. package/src/components/input/StackedSwitch/index.tsx +9 -1
  26. package/src/components/input/StackedTextarea/StackedTextarea.tsx +1 -1
  27. package/src/components/input/components/dropdown/index.tsx +23 -6
  28. package/src/components/input/components/token/index.tsx +11 -6
  29. package/src/components/input/index.tsx +5 -4
  30. package/src/components/table/index.tsx +2 -7
  31. package/src/theme/components/button.ts +10 -10
  32. package/src/theme/components/input.ts +1 -0
  33. package/src/theme/components/table.ts +1 -0
  34. package/src/theme/components/textarea.ts +4 -1
  35. package/dist/components/input/StackedCheckbox/StackedCheckboxGroup.d.ts +0 -10
  36. package/dist/components/input/StackedMultiSelect/components/MultiValue/index.d.ts +0 -10
  37. package/src/components/input/StackedCheckbox/StackedCheckboxGroup.tsx +0 -29
  38. package/src/components/input/StackedMultiSelect/components/MultiValue/index.tsx +0 -21
@@ -17,8 +17,6 @@ export interface StackedPilledInputProps extends InputFieldProps {
17
17
  setError: UseFormSetError<FieldValues>;
18
18
  clearErrors: UseFormClearErrors<FieldValues>;
19
19
  control: Control<FieldValues, any>;
20
- // Number of allowed options
21
- maxLength?: number;
22
20
  }
23
21
 
24
22
  /**
@@ -27,87 +25,65 @@ export interface StackedPilledInputProps extends InputFieldProps {
27
25
  const StackedPilledInput = React.forwardRef<
28
26
  HTMLInputElement,
29
27
  StackedPilledInputProps
30
- >(
31
- (
32
- {
33
- name,
34
- setValue,
35
- control,
36
- placeholder,
37
- disabled,
38
- maxLength,
39
- setError,
40
- clearErrors,
41
- },
42
- _ref
43
- ) => {
44
- const watchedValue = useWatch({ control, name: name as string });
45
- const [lastestFormValueToArray, setLatestFormValueToArray] = useState<
46
- string[]
47
- >([]);
48
-
49
- const inputRef = useRef<HTMLInputElement>(null);
50
- const inputWrapperRef = useRef(null);
51
-
52
- const [tokenIndex, setTokenIndex] = useState<number | null>(null);
53
- const [isFocussed, setIsFocussed] = useState(false);
54
-
55
- const [localValue, setLocalValue] = useState('');
56
-
57
- // gets latest watched form value (common delimited) from RHF state and creates a list
58
- useEffect(() => {
59
- if (watchedValue !== undefined && !watchedValue.length) {
60
- setLatestFormValueToArray([]);
28
+ >(({ name, setValue, control, placeholder, disabled, clearErrors }, _ref) => {
29
+ const watchedValue = useWatch({ control, name: name as string });
30
+ const [lastestFormValueToArray, setLatestFormValueToArray] = useState<
31
+ string[]
32
+ >([]);
33
+
34
+ const inputRef = useRef<HTMLInputElement>(null);
35
+ const inputWrapperRef = useRef(null);
36
+ const scrollRef = useRef<HTMLDivElement>(null);
37
+
38
+ const [tokenIndex, setTokenIndex] = useState<number | null>(null);
39
+ const [isFocussed, setIsFocussed] = useState(false);
40
+ const [shouldSideScroll, setShouldSideScroll] = useState(false);
41
+ const [localValue, setLocalValue] = useState('');
42
+
43
+ // gets latest watched form value (common delimited) from RHF state and creates a list
44
+ useEffect(() => {
45
+ if (watchedValue !== undefined && !watchedValue.length) {
46
+ setLatestFormValueToArray([]);
47
+ }
48
+
49
+ if (watchedValue !== undefined && watchedValue?.length) {
50
+ if (shouldSideScroll) {
51
+ (scrollRef.current as HTMLDivElement).scrollTo({
52
+ left: scrollRef.current?.scrollWidth,
53
+ behavior: 'smooth',
54
+ });
55
+ setShouldSideScroll(false);
61
56
  }
62
57
 
63
- if (watchedValue !== undefined && watchedValue?.length) {
64
- setLatestFormValueToArray(watchedValue.split(',').filter(Boolean));
65
- }
66
- }, [watchedValue]);
67
-
68
- const onHandleKeyDown = (e: React.KeyboardEvent) => {
69
- if (e.key === ' ' || e.key === 'Enter' || e.key === ',') {
70
- if (maxLength && lastestFormValueToArray.length >= maxLength) {
71
- return setError(name as string, {
72
- type: 'maxLength',
73
- message: `Exceeded maximum of ${maxLength} options`,
74
- });
75
- }
76
-
77
- if (
78
- e.key === 'Enter' &&
79
- !localValue.trim().length &&
80
- tokenIndex !== null
81
- ) {
82
- setLocalValue(lastestFormValueToArray[tokenIndex]);
83
-
84
- const filteredUniqueValues = Array.from(
85
- new Set(
86
- lastestFormValueToArray.filter(
87
- value => value !== lastestFormValueToArray[tokenIndex]
88
- )
89
- )
90
- );
91
-
92
- setValue(
93
- name as string,
94
- filteredUniqueValues.toString().replace(/\s/g, ''),
95
- {
96
- shouldValidate: true,
97
- shouldDirty: true,
98
- }
99
- );
100
-
101
- return setTokenIndex(null);
102
- }
58
+ setLatestFormValueToArray(watchedValue.split(',').filter(Boolean));
59
+ }
60
+ }, [watchedValue, shouldSideScroll]);
61
+
62
+ const onHandleKeyDown = (e: React.KeyboardEvent) => {
63
+ setShouldSideScroll(true);
64
+
65
+ if (
66
+ e.key === ' ' ||
67
+ e.key === 'Enter' ||
68
+ e.key === ',' ||
69
+ e.key === 'Tab'
70
+ ) {
71
+ if (
72
+ e.key === 'Enter' &&
73
+ !localValue.trim().length &&
74
+ tokenIndex !== null
75
+ ) {
76
+ setLocalValue(lastestFormValueToArray[tokenIndex]);
103
77
 
104
78
  const filteredUniqueValues = Array.from(
105
- new Set([...lastestFormValueToArray, ...localValue.trim().split(',')])
79
+ new Set(
80
+ lastestFormValueToArray.filter(
81
+ value => value !== lastestFormValueToArray[tokenIndex]
82
+ )
83
+ )
106
84
  );
107
85
 
108
- setLocalValue('');
109
-
110
- return setValue(
86
+ setValue(
111
87
  name as string,
112
88
  filteredUniqueValues.toString().replace(/\s/g, ''),
113
89
  {
@@ -115,68 +91,15 @@ const StackedPilledInput = React.forwardRef<
115
91
  shouldDirty: true,
116
92
  }
117
93
  );
118
- }
119
-
120
- if (!localValue.trim().length && lastestFormValueToArray.length) {
121
- if (e.key === 'Backspace' && tokenIndex !== null) {
122
- setLocalValue(
123
- lastestFormValueToArray[tokenIndex].substring(
124
- 0,
125
- lastestFormValueToArray[tokenIndex].length
126
- )
127
- );
128
-
129
- const filteredUniqueValues = Array.from(
130
- new Set(
131
- [...lastestFormValueToArray].filter(
132
- value => value !== lastestFormValueToArray[tokenIndex]
133
- )
134
- )
135
- );
136
94
 
137
- setValue(
138
- name as string,
139
- filteredUniqueValues.toString().replace(/\s/g, ''),
140
- {
141
- shouldValidate: true,
142
- shouldDirty: true,
143
- }
144
- );
145
-
146
- return setTokenIndex(null);
147
- }
148
-
149
- if (e.key === 'ArrowLeft') {
150
- if (tokenIndex === 0) return;
151
-
152
- if (!tokenIndex) {
153
- return setTokenIndex(lastestFormValueToArray.length - 1);
154
- }
155
-
156
- return setTokenIndex(
157
- prevTokenIndex => (prevTokenIndex as number) - 1
158
- );
159
- }
160
-
161
- if (e.key === 'ArrowRight') {
162
- if (tokenIndex === null) return;
163
-
164
- if (tokenIndex === lastestFormValueToArray.length - 1) {
165
- return setTokenIndex(null);
166
- }
167
- return setTokenIndex(
168
- prevTokenIndex => (prevTokenIndex as number) + 1
169
- );
170
- }
95
+ return setTokenIndex(null);
171
96
  }
172
- };
173
97
 
174
- const onRemoveTag = (index: number) => {
175
- const filteredUniqueValues = lastestFormValueToArray.filter(
176
- (_, i) => i !== index
98
+ const filteredUniqueValues = Array.from(
99
+ new Set([...lastestFormValueToArray, ...localValue.trim().split(',')])
177
100
  );
178
101
 
179
- setLatestFormValueToArray(filteredUniqueValues);
102
+ setLocalValue('');
180
103
 
181
104
  setValue(
182
105
  name as string,
@@ -186,20 +109,25 @@ const StackedPilledInput = React.forwardRef<
186
109
  shouldDirty: true,
187
110
  }
188
111
  );
189
- };
190
112
 
191
- const onBlur = () => {
192
- clearErrors(name);
113
+ return setIsFocussed(false);
114
+ }
193
115
 
194
- if (localValue.trim()) {
195
- if (
196
- maxLength &&
197
- watchedValue.length + localValue.trim().length > maxLength
198
- )
199
- return setLocalValue('');
116
+ if (!localValue.trim().length && lastestFormValueToArray.length) {
117
+ if (e.key === 'Backspace' && tokenIndex !== null) {
118
+ setLocalValue(
119
+ lastestFormValueToArray[tokenIndex].substring(
120
+ 0,
121
+ lastestFormValueToArray[tokenIndex].length
122
+ )
123
+ );
200
124
 
201
125
  const filteredUniqueValues = Array.from(
202
- new Set([...lastestFormValueToArray, ...localValue.trim().split(',')])
126
+ new Set(
127
+ [...lastestFormValueToArray].filter(
128
+ value => value !== lastestFormValueToArray[tokenIndex]
129
+ )
130
+ )
203
131
  );
204
132
 
205
133
  setValue(
@@ -210,94 +138,158 @@ const StackedPilledInput = React.forwardRef<
210
138
  shouldDirty: true,
211
139
  }
212
140
  );
213
- setLocalValue('');
141
+
142
+ return setTokenIndex(null);
214
143
  }
215
- setIsFocussed(false);
216
- };
217
144
 
218
- useOutsideClick({ ref: inputWrapperRef, handler: onBlur });
145
+ if (e.key === 'ArrowLeft') {
146
+ if (tokenIndex === 0) return;
219
147
 
220
- return (
221
- <Box position="relative">
148
+ if (!tokenIndex) {
149
+ return setTokenIndex(lastestFormValueToArray.length - 1);
150
+ }
151
+
152
+ return setTokenIndex(prevTokenIndex => (prevTokenIndex as number) - 1);
153
+ }
154
+
155
+ if (e.key === 'ArrowRight') {
156
+ if (tokenIndex === null) return;
157
+
158
+ if (tokenIndex === lastestFormValueToArray.length - 1) {
159
+ return setTokenIndex(null);
160
+ }
161
+ return setTokenIndex(prevTokenIndex => (prevTokenIndex as number) + 1);
162
+ }
163
+ }
164
+ };
165
+
166
+ const onRemoveTag = (index: number) => {
167
+ const filteredUniqueValues = lastestFormValueToArray.filter(
168
+ (_, i) => i !== index
169
+ );
170
+
171
+ setLatestFormValueToArray(filteredUniqueValues);
172
+
173
+ setValue(
174
+ name as string,
175
+ filteredUniqueValues.toString().replace(/\s/g, ''),
176
+ {
177
+ shouldValidate: true,
178
+ shouldDirty: true,
179
+ }
180
+ );
181
+ };
182
+
183
+ const onBlur = () => {
184
+ clearErrors(name);
185
+
186
+ if (localValue.trim()) {
187
+ const filteredUniqueValues = Array.from(
188
+ new Set([...lastestFormValueToArray, ...localValue.trim().split(',')])
189
+ );
190
+
191
+ setValue(
192
+ name as string,
193
+ filteredUniqueValues.toString().replace(/\s/g, ''),
194
+ {
195
+ shouldValidate: true,
196
+ shouldDirty: true,
197
+ }
198
+ );
199
+ setLocalValue('');
200
+ }
201
+ setIsFocussed(false);
202
+ };
203
+
204
+ useOutsideClick({ ref: inputWrapperRef, handler: onBlur });
205
+
206
+ return (
207
+ <Box position="relative">
208
+ <Flex
209
+ fontSize="13px"
210
+ border={isFocussed ? '2px solid' : '1px solid'}
211
+ borderColor={isFocussed ? colors.border.focus : colors.border.default}
212
+ py="5px"
213
+ pl="8px"
214
+ borderRadius="4px"
215
+ alignItems="center"
216
+ justifyContent="space-between"
217
+ onClick={() => {
218
+ if (!disabled) {
219
+ inputRef.current?.focus();
220
+ }
221
+ }}
222
+ bg={disabled ? colors.fill.light.quaternary : '#ffffff'}
223
+ cursor={disabled ? 'not-allowed' : 'pointer'}
224
+ ref={inputWrapperRef}
225
+ h="26px"
226
+ >
222
227
  <Flex
223
- fontSize="13px"
224
- border={isFocussed ? '2px solid' : '1px solid'}
225
- borderColor={isFocussed ? colors.border.focus : colors.border.default}
226
- py="5px"
227
- pl="8px"
228
- borderRadius="4px"
228
+ h="18px"
229
229
  alignItems="center"
230
- justifyContent="space-between"
231
- onClick={() => {
232
- if (!disabled) {
233
- inputRef.current?.focus();
234
- }
230
+ // width="fit-content"
231
+ // maxW="80%"
232
+ overflowX="scroll"
233
+ style={{
234
+ scrollbarWidth: 'none' /* Firefox */,
235
+ msOverflowStyle: 'none',
235
236
  }}
236
- bg={disabled ? colors.fill.light.quaternary : '#ffffff'}
237
- cursor={disabled ? 'not-allowed' : 'pointer'}
238
- ref={inputWrapperRef}
237
+ sx={{
238
+ '::-webkit-scrollbar': {
239
+ display: 'none',
240
+ },
241
+ }}
242
+ ref={scrollRef}
239
243
  >
240
- <Flex
241
- height="28px"
242
- alignItems="center"
243
- width="fit-content"
244
- maxW="80%"
245
- overflowX="auto"
246
- style={{
247
- scrollbarWidth: 'none' /* Firefox */,
248
- }}
249
- >
250
- {lastestFormValueToArray.length ? (
251
- lastestFormValueToArray.map((label, index) => (
252
- <Box
253
- mr="4px"
254
- border={
255
- tokenIndex === index
256
- ? `2px solid ${colors.border.focus}`
257
- : 'none'
258
- }
259
- borderRadius="full"
260
- onClick={() => setTokenIndex(index)}
261
- width="100%"
262
- >
263
- <Token
264
- label={label}
265
- onDelete={(e: any) => {
266
- e.stopPropagation();
267
- e.preventDefault();
268
- onRemoveTag(index);
269
- }}
270
- />
271
- </Box>
272
- ))
273
- ) : (
274
- <Text color={colors.label.secondary.light} fontSize="13px">
275
- {placeholder}
276
- </Text>
277
- )}
278
- </Flex>
279
- <Flex flex={1}>
280
- <Input
281
- onKeyDown={onHandleKeyDown}
282
- type="text"
283
- padding={0}
284
- width="100%"
285
- border="none"
286
- height="26px"
287
- color={tokenIndex !== null ? 'transparent' : colors.label.primary}
288
- _focus={{ boxShadow: 'none !important' }}
289
- value={localValue}
290
- onChange={e =>
291
- tokenIndex === null && setLocalValue(e.target.value)
292
- }
293
- ref={inputRef}
294
- onFocus={() => setIsFocussed(true)}
295
- />
296
- </Flex>
244
+ {lastestFormValueToArray.length ? (
245
+ lastestFormValueToArray.map((label, index) => (
246
+ <Box
247
+ mr="4px"
248
+ border={
249
+ tokenIndex === index
250
+ ? `1px solid ${colors.border.focus}`
251
+ : 'none'
252
+ }
253
+ borderRadius="full"
254
+ onClick={() => setTokenIndex(index)}
255
+ width="100%"
256
+ >
257
+ <Token
258
+ label={label}
259
+ onDelete={(e: any) => {
260
+ e.stopPropagation();
261
+ e.preventDefault();
262
+ onRemoveTag(index);
263
+ }}
264
+ />
265
+ </Box>
266
+ ))
267
+ ) : (
268
+ <Text color={colors.label.secondary.light} fontSize="13px">
269
+ {placeholder}
270
+ </Text>
271
+ )}
297
272
  </Flex>
298
- </Box>
299
- );
300
- }
301
- );
273
+ <Flex flex={1}>
274
+ <Input
275
+ onKeyDown={onHandleKeyDown}
276
+ type="text"
277
+ padding={0}
278
+ width="100%"
279
+ border="none"
280
+ height="auto"
281
+ color={tokenIndex !== null ? 'transparent' : colors.label.primary}
282
+ _focus={{ boxShadow: 'none !important' }}
283
+ value={localValue}
284
+ onChange={e => tokenIndex === null && setLocalValue(e.target.value)}
285
+ ref={inputRef}
286
+ onFocus={() => setIsFocussed(true)}
287
+ onBlur={() => setIsFocussed(false)}
288
+ />
289
+ </Flex>
290
+ </Flex>
291
+ </Box>
292
+ );
293
+ });
302
294
 
303
295
  export default StackedPilledInput;
@@ -1,4 +1,4 @@
1
- import React, { useRef, useState } from 'react';
1
+ import React, { useEffect, useRef, useState } from 'react';
2
2
  import {
3
3
  Box,
4
4
  Image,
@@ -30,11 +30,24 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
30
30
  { isRequired, options, name, setValue, handleOnChange, value, ...props },
31
31
  _ref
32
32
  ) => {
33
- const dropdownRef = useRef(null);
33
+ const dropdownRef = useRef<HTMLDivElement>(null);
34
+ const dropdownMenuRef = useRef<HTMLDivElement>(null);
35
+
34
36
  const [isFocussed, setIsFocussed] = useState(false);
35
37
  const [selectedOption, setSelectedOption] = useState(
36
38
  options.find(option => option.value === value)?.label ?? ''
37
39
  );
40
+ const [position, setPosition] = useState<'top' | 'bottom'>('top');
41
+
42
+ useEffect(() => {
43
+ const boundingClientRect = dropdownRef.current?.getBoundingClientRect() as DOMRect;
44
+
45
+ if (document.body.clientHeight - (boundingClientRect?.y + 240) >= 0) {
46
+ setPosition('top');
47
+ } else {
48
+ setPosition('bottom');
49
+ }
50
+ }, [dropdownRef]);
38
51
 
39
52
  useDidMountEffect(() => {
40
53
  setSelectedOption(
@@ -71,6 +84,23 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
71
84
  textShadow={`0 0 0 ${colors.label.primary.light}`}
72
85
  value={selectedOption}
73
86
  autoComplete="off"
87
+ onKeyDown={e => {
88
+ if (isFocussed) {
89
+ if (e.key === 'Tab') {
90
+ return setIsFocussed(false);
91
+ }
92
+
93
+ const idx = options.findIndex(
94
+ option => option.label[0].toLocaleLowerCase() === e.key
95
+ );
96
+ console.log(idx);
97
+
98
+ dropdownMenuRef.current?.scrollTo({
99
+ top: idx * 27,
100
+ behavior: 'smooth',
101
+ });
102
+ }
103
+ }}
74
104
  />
75
105
  <InputRightElement
76
106
  cursor="pointer"
@@ -81,6 +111,8 @@ const StackedSelect = React.forwardRef<HTMLInputElement, StackedSelectProps>(
81
111
  </InputGroup>
82
112
  {isFocussed && (
83
113
  <Dropdown
114
+ position={position}
115
+ dropdownRef={dropdownMenuRef}
84
116
  onSelectItem={option => handleOnSelectItem(option)}
85
117
  options={options}
86
118
  />
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Switch, SwitchProps } from '@chakra-ui/react';
3
+ import colors from '../../../theme/foundations/colors';
3
4
 
4
5
  export interface StackedSwitchProps extends SwitchProps {}
5
6
 
@@ -8,9 +9,16 @@ export interface StackedSwitchProps extends SwitchProps {}
8
9
  */
9
10
  const StackedSwitch = React.forwardRef<HTMLInputElement, StackedSwitchProps>(
10
11
  ({ isRequired, onChange, value }, _ref) => {
12
+ if (value === null) return null;
13
+
11
14
  return (
12
15
  <Switch
13
- size="lg"
16
+ h="26px"
17
+ mx="4px"
18
+ _focus={{
19
+ border: '2px solid',
20
+ borderColor: colors.border.focus,
21
+ }}
14
22
  ref={_ref}
15
23
  isRequired={isRequired}
16
24
  value={String(value)}
@@ -11,7 +11,7 @@ const StackedTextarea = React.forwardRef<
11
11
  HTMLTextAreaElement,
12
12
  StackedTextareaProps
13
13
  >(({ ...props }, _ref) => {
14
- return <Textarea ref={_ref} {...props} />;
14
+ return <Textarea ref={_ref} {...props} fontSize="13px" />;
15
15
  });
16
16
 
17
17
  export default StackedTextarea;
@@ -1,11 +1,13 @@
1
- import React, { useMemo } from 'react';
2
- import { Box } from '@chakra-ui/react';
1
+ import React, { RefObject, useMemo } from 'react';
2
+ import { Box, Flex } from '@chakra-ui/react';
3
3
  import colors from '../../../../../src/theme/foundations/colors';
4
4
  import { FieldOption, FieldOptions } from '../../InputTypes';
5
5
 
6
6
  export interface DropdownProps {
7
7
  onSelectItem: (option: FieldOption) => void;
8
8
  options: FieldOptions;
9
+ dropdownRef: RefObject<HTMLDivElement>;
10
+ position: 'top' | 'bottom';
9
11
  }
10
12
 
11
13
  /**
@@ -14,6 +16,8 @@ export interface DropdownProps {
14
16
  export const Dropdown: React.FC<DropdownProps> = ({
15
17
  onSelectItem,
16
18
  options,
19
+ dropdownRef,
20
+ position,
17
21
  }) => {
18
22
  const DropdownContent = useMemo(() => {
19
23
  return options.map((option, idx) => (
@@ -24,12 +28,15 @@ export const Dropdown: React.FC<DropdownProps> = ({
24
28
  <Box
25
29
  color={colors.label.secondary.light}
26
30
  fontSize="13px"
31
+ width="fit-content"
27
32
  fontWeight="bold"
28
33
  px="8px"
29
34
  bg="inherit"
35
+ whiteSpace="nowrap"
30
36
  >
31
37
  {idx > 0 && (
32
38
  <Box
39
+ width="100%"
33
40
  my="3px"
34
41
  borderTop="2px solid"
35
42
  borderColor={colors.border.default}
@@ -47,13 +54,16 @@ export const Dropdown: React.FC<DropdownProps> = ({
47
54
  fontSize="13px"
48
55
  px="8px"
49
56
  py="4px"
57
+ width="fit-content"
50
58
  color={colors.label.primary.light}
51
59
  _hover={{
52
60
  color: colors.label.primary.dark,
53
61
  bg: colors.fill.action,
54
62
  borderRadius: '4px',
63
+ width: '100%',
55
64
  }}
56
65
  bg="inherit"
66
+ whiteSpace="nowrap"
57
67
  >
58
68
  {option.label}
59
69
  </Box>
@@ -63,7 +73,10 @@ export const Dropdown: React.FC<DropdownProps> = ({
63
73
  }, [onSelectItem, options]);
64
74
 
65
75
  return (
66
- <Box
76
+ <Flex
77
+ flexDirection="column"
78
+ ref={dropdownRef}
79
+ scrollMargin="15px"
67
80
  bg={colors.fill.light.quaternary}
68
81
  backdropFilter="auto"
69
82
  backdropBlur="64px"
@@ -71,15 +84,19 @@ export const Dropdown: React.FC<DropdownProps> = ({
71
84
  border="0.25px solid"
72
85
  borderColor={colors.fill.light.tertiary}
73
86
  mt="3px"
74
- maxH="320px"
87
+ maxH="240px"
75
88
  overflowY="auto"
76
89
  px="8px"
77
90
  py="4px"
78
91
  position="absolute"
79
- width="100%"
92
+ top={position === 'top' ? 26 : undefined}
93
+ bottom={position === 'bottom' ? 30 : undefined}
94
+ width="fit-content"
95
+ minWidth="100%"
80
96
  zIndex={100}
97
+ tabIndex={-2000}
81
98
  >
82
99
  {DropdownContent}
83
- </Box>
100
+ </Flex>
84
101
  );
85
102
  };