@xqmsg/ui-core 0.24.3 → 0.24.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.
- package/dist/components/input/StackedMultiSelect/index.d.ts +1 -0
- package/dist/components/input/StackedSelect/index.d.ts +1 -0
- package/dist/components/input/components/dropdown/index.d.ts +1 -0
- package/dist/components/input/index.d.ts +2 -1
- package/dist/ui-core.cjs.development.js +48 -20
- package/dist/ui-core.cjs.development.js.map +1 -1
- package/dist/ui-core.cjs.production.min.js +1 -1
- package/dist/ui-core.cjs.production.min.js.map +1 -1
- package/dist/ui-core.esm.js +48 -20
- package/dist/ui-core.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/input/Input.stories.tsx +9 -0
- package/src/components/input/StackedMultiSelect/index.tsx +296 -284
- package/src/components/input/StackedSelect/index.tsx +19 -11
- package/src/components/input/components/dropdown/index.tsx +23 -2
- package/src/components/input/index.tsx +4 -0
package/package.json
CHANGED
|
@@ -132,6 +132,7 @@ const Template: Story<InputProps<StoryFormSchema>> = args => {
|
|
|
132
132
|
isInvalid={!!form.formState.errors['prop5']?.message}
|
|
133
133
|
errorText={form.formState.errors['prop5']?.message}
|
|
134
134
|
name="prop5"
|
|
135
|
+
loadingOptions={true}
|
|
135
136
|
/>
|
|
136
137
|
<Input
|
|
137
138
|
{...args}
|
|
@@ -206,6 +207,14 @@ const Template: Story<InputProps<StoryFormSchema>> = args => {
|
|
|
206
207
|
name="prop4"
|
|
207
208
|
defaultValue={'value1'}
|
|
208
209
|
/>
|
|
210
|
+
<Input
|
|
211
|
+
{...args}
|
|
212
|
+
inputType="select"
|
|
213
|
+
setValue={form.setValue}
|
|
214
|
+
name="prop4"
|
|
215
|
+
defaultValue={'value1'}
|
|
216
|
+
loadingOptions={true}
|
|
217
|
+
/>
|
|
209
218
|
<Input
|
|
210
219
|
{...args}
|
|
211
220
|
inputType="select"
|
|
@@ -30,6 +30,7 @@ export interface StackedMultiSelectProps extends ReactSelectFieldProps {
|
|
|
30
30
|
setError: UseFormSetError<FieldValues>;
|
|
31
31
|
clearErrors: UseFormClearErrors<FieldValues>;
|
|
32
32
|
control: Control<FieldValues, any>;
|
|
33
|
+
loadingOptions?: boolean;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
/**
|
|
@@ -38,319 +39,330 @@ export interface StackedMultiSelectProps extends ReactSelectFieldProps {
|
|
|
38
39
|
const StackedMultiSelect = React.forwardRef<
|
|
39
40
|
HTMLInputElement,
|
|
40
41
|
StackedMultiSelectProps
|
|
41
|
-
>(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
// gets latest watched form value (common delimited) from RHF state and creates a list
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
if (watchedValue !== undefined && !watchedValue.length && !isInit) {
|
|
77
|
-
setLocalValues([]);
|
|
78
|
-
setIsInit(true);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (watchedValue !== undefined && watchedValue?.length && !isInit) {
|
|
82
|
-
if (shouldSideScroll) {
|
|
83
|
-
(scrollRef.current as HTMLDivElement).scrollTo({
|
|
84
|
-
left: scrollRef.current?.scrollWidth,
|
|
85
|
-
behavior: 'smooth',
|
|
86
|
-
});
|
|
87
|
-
setShouldSideScroll(false);
|
|
42
|
+
>(
|
|
43
|
+
(
|
|
44
|
+
{ options, setValue, control, name, placeholder, disabled, loadingOptions },
|
|
45
|
+
_ref
|
|
46
|
+
) => {
|
|
47
|
+
const watchedValue = useWatch({ control, name: name as string });
|
|
48
|
+
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
49
|
+
const dropdownMenuRef = useRef<HTMLDivElement>(null);
|
|
50
|
+
const scrollRef = useRef<HTMLDivElement>(null);
|
|
51
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
52
|
+
|
|
53
|
+
const [isInit, setIsInit] = useState(false);
|
|
54
|
+
const [localValues, setLocalValues] = useState<FieldOptions>([]);
|
|
55
|
+
const [localOptions, setLocalOptions] = useState<FieldOptions>(options);
|
|
56
|
+
const [filteredOptions, setFilteredOptions] = useState<FieldOptions>(
|
|
57
|
+
localOptions
|
|
58
|
+
);
|
|
59
|
+
const [isFocussed, setIsFocussed] = useState(false);
|
|
60
|
+
const [shouldSideScroll, setShouldSideScroll] = useState(false);
|
|
61
|
+
const [optionIndex, setOptionIndex] = useState<number | null>(null);
|
|
62
|
+
|
|
63
|
+
const [position, setPosition] = useState<'top' | 'bottom'>('top');
|
|
64
|
+
const [searchValue, setSearchValue] = useState('');
|
|
65
|
+
// const [debouncedSearchValue, setDebouncedSearchValue] = useState('');
|
|
66
|
+
|
|
67
|
+
const boundingClientRect = dropdownRef.current?.getBoundingClientRect() as DOMRect;
|
|
68
|
+
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (window.innerHeight - (boundingClientRect?.y + 240) >= 0) {
|
|
71
|
+
setPosition('top');
|
|
72
|
+
} else {
|
|
73
|
+
setPosition('bottom');
|
|
88
74
|
}
|
|
75
|
+
}, [boundingClientRect]);
|
|
89
76
|
|
|
90
|
-
|
|
77
|
+
useOnClickOutside(dropdownRef, () => setIsFocussed(false));
|
|
91
78
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
79
|
+
// gets latest watched form value (common delimited) from RHF state and creates a list
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (watchedValue !== undefined && !watchedValue.length && !isInit) {
|
|
82
|
+
setLocalValues([]);
|
|
83
|
+
setIsInit(true);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (watchedValue !== undefined && watchedValue?.length && !isInit) {
|
|
87
|
+
if (shouldSideScroll) {
|
|
88
|
+
(scrollRef.current as HTMLDivElement).scrollTo({
|
|
89
|
+
left: scrollRef.current?.scrollWidth,
|
|
90
|
+
behavior: 'smooth',
|
|
91
|
+
});
|
|
92
|
+
setShouldSideScroll(false);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (isInit) return;
|
|
96
|
+
|
|
97
|
+
setLocalValues(
|
|
98
|
+
watchedValue
|
|
99
|
+
.split(',')
|
|
100
|
+
.filter(Boolean)
|
|
101
|
+
.map((value: string) =>
|
|
102
|
+
options.find(option => option.value === value)
|
|
103
|
+
)
|
|
104
|
+
);
|
|
105
|
+
// Filter out options that are already selected
|
|
106
|
+
setLocalOptions(prevLocalOptions =>
|
|
107
|
+
prevLocalOptions.filter(
|
|
108
|
+
localOption =>
|
|
109
|
+
!watchedValue
|
|
110
|
+
.split(',')
|
|
111
|
+
.filter(Boolean)
|
|
112
|
+
.map((value: string) =>
|
|
113
|
+
options.find(option => option.value === value)
|
|
114
|
+
)
|
|
115
|
+
.includes(localOption)
|
|
98
116
|
)
|
|
99
|
-
|
|
100
|
-
// Filter out options that are already selected
|
|
101
|
-
setLocalOptions(prevLocalOptions =>
|
|
102
|
-
prevLocalOptions.filter(
|
|
103
|
-
localOption =>
|
|
104
|
-
!watchedValue
|
|
105
|
-
.split(',')
|
|
106
|
-
.filter(Boolean)
|
|
107
|
-
.map((value: string) =>
|
|
108
|
-
options.find(option => option.value === value)
|
|
109
|
-
)
|
|
110
|
-
.includes(localOption)
|
|
111
|
-
)
|
|
112
|
-
);
|
|
117
|
+
);
|
|
113
118
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
setLocalOptions(prevLocalOptions =>
|
|
137
|
-
prevLocalOptions.filter(prevLocalOption => prevLocalOption !== option)
|
|
138
|
-
);
|
|
119
|
+
setIsInit(true);
|
|
120
|
+
}
|
|
121
|
+
}, [
|
|
122
|
+
isInit,
|
|
123
|
+
localOptions,
|
|
124
|
+
localValues,
|
|
125
|
+
options,
|
|
126
|
+
shouldSideScroll,
|
|
127
|
+
watchedValue,
|
|
128
|
+
]);
|
|
129
|
+
|
|
130
|
+
const handleChange = (option: FieldOption) => {
|
|
131
|
+
setShouldSideScroll(true);
|
|
132
|
+
const newValue = [...localValues, option]
|
|
133
|
+
.map(({ value }) => value)
|
|
134
|
+
.join(',');
|
|
135
|
+
|
|
136
|
+
setValue(name as string, newValue, {
|
|
137
|
+
shouldValidate: true,
|
|
138
|
+
shouldDirty: true,
|
|
139
|
+
});
|
|
139
140
|
|
|
140
|
-
|
|
141
|
+
setLocalOptions(prevLocalOptions =>
|
|
142
|
+
prevLocalOptions.filter(prevLocalOption => prevLocalOption !== option)
|
|
143
|
+
);
|
|
141
144
|
|
|
142
|
-
|
|
143
|
-
setSearchValue('');
|
|
144
|
-
};
|
|
145
|
+
setLocalValues(prevLocalValues => [...prevLocalValues, option]);
|
|
145
146
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
.map(({ value }) => value)
|
|
150
|
-
.join(',');
|
|
147
|
+
// reset search on value select
|
|
148
|
+
setSearchValue('');
|
|
149
|
+
};
|
|
151
150
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
const handleDelete = (option: FieldOption) => {
|
|
152
|
+
const newValue = localValues
|
|
153
|
+
.filter(localValue => localValue !== option)
|
|
154
|
+
.map(({ value }) => value)
|
|
155
|
+
.join(',');
|
|
156
156
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
setValue(name as string, newValue, {
|
|
158
|
+
shouldValidate: true,
|
|
159
|
+
shouldDirty: true,
|
|
160
|
+
});
|
|
160
161
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
};
|
|
162
|
+
setLocalOptions(prevLocalOptions =>
|
|
163
|
+
[...prevLocalOptions, option].sort((a, b) => a.sortValue - b.sortValue)
|
|
164
|
+
);
|
|
165
165
|
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
setLocalValues(prevLocalValues =>
|
|
167
|
+
prevLocalValues.filter(prevLocalValue => prevLocalValue !== option)
|
|
168
|
+
);
|
|
169
|
+
};
|
|
168
170
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
(e.key === 'Enter' || e.key === 'ArrowUp' || e.key === 'ArrowDown')
|
|
172
|
-
) {
|
|
173
|
-
setIsFocussed(true);
|
|
174
|
-
return setOptionIndex(initialOptionIndex);
|
|
175
|
-
}
|
|
171
|
+
const handleOnKeyDown: KeyboardEventHandler<HTMLInputElement> = e => {
|
|
172
|
+
const initialOptionIndex = options[0].value === 'section_header' ? 1 : 0;
|
|
176
173
|
|
|
177
|
-
if (isFocussed) {
|
|
178
174
|
if (
|
|
179
|
-
|
|
175
|
+
!isFocussed &&
|
|
180
176
|
(e.key === 'Enter' || e.key === 'ArrowUp' || e.key === 'ArrowDown')
|
|
181
177
|
) {
|
|
178
|
+
setIsFocussed(true);
|
|
182
179
|
return setOptionIndex(initialOptionIndex);
|
|
183
180
|
}
|
|
184
181
|
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
182
|
+
if (isFocussed) {
|
|
183
|
+
if (
|
|
184
|
+
optionIndex === null &&
|
|
185
|
+
(e.key === 'Enter' || e.key === 'ArrowUp' || e.key === 'ArrowDown')
|
|
186
|
+
) {
|
|
187
|
+
return setOptionIndex(initialOptionIndex);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (e.key === 'ArrowUp' && optionIndex !== null && optionIndex > 0) {
|
|
191
|
+
const incrementValue =
|
|
192
|
+
filteredOptions[optionIndex - 1] &&
|
|
193
|
+
filteredOptions[optionIndex - 1].value === 'section_header'
|
|
194
|
+
? 2
|
|
195
|
+
: 1;
|
|
196
|
+
setOptionIndex(optionIndex - incrementValue);
|
|
197
|
+
|
|
198
|
+
return dropdownMenuRef.current?.scrollTo({
|
|
199
|
+
top: optionIndex * 24,
|
|
200
|
+
behavior: 'smooth',
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (
|
|
205
|
+
e.key === 'ArrowDown' &&
|
|
206
|
+
optionIndex !== null &&
|
|
207
|
+
optionIndex < filteredOptions.length
|
|
208
|
+
) {
|
|
209
|
+
const incrementValue =
|
|
210
|
+
filteredOptions[optionIndex + 1] &&
|
|
211
|
+
filteredOptions[optionIndex + 1].value === 'section_header'
|
|
212
|
+
? 2
|
|
213
|
+
: 1;
|
|
214
|
+
setOptionIndex(optionIndex + incrementValue);
|
|
215
|
+
|
|
216
|
+
return dropdownMenuRef.current?.scrollTo({
|
|
217
|
+
top: optionIndex * 24,
|
|
218
|
+
behavior: 'smooth',
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (e.key === 'Enter' && optionIndex !== null) {
|
|
223
|
+
const option = filteredOptions.find((_, idx) => optionIndex === idx);
|
|
224
|
+
if (!option) return;
|
|
225
|
+
|
|
226
|
+
handleChange(option);
|
|
227
|
+
|
|
228
|
+
return setIsFocussed(false);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (e.key === 'Tab') {
|
|
232
|
+
return setIsFocussed(false);
|
|
233
|
+
}
|
|
197
234
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return dropdownMenuRef.current?.scrollTo({
|
|
212
|
-
top: optionIndex * 24,
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
useEffect(() => {
|
|
238
|
+
if (searchValue.length) {
|
|
239
|
+
const idx = options.findIndex(
|
|
240
|
+
option =>
|
|
241
|
+
option.label.substring(0, searchValue.length).toLowerCase() ===
|
|
242
|
+
searchValue.toLowerCase()
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
dropdownMenuRef.current?.scrollTo({
|
|
246
|
+
top: idx * 27,
|
|
213
247
|
behavior: 'smooth',
|
|
214
248
|
});
|
|
215
249
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (e.key === 'Tab') {
|
|
227
|
-
return setIsFocussed(false);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
useEffect(() => {
|
|
233
|
-
if (searchValue.length) {
|
|
234
|
-
const idx = options.findIndex(
|
|
235
|
-
option =>
|
|
236
|
-
option.label.substring(0, searchValue.length).toLowerCase() ===
|
|
237
|
-
searchValue.toLowerCase()
|
|
250
|
+
}, [options, searchValue]);
|
|
251
|
+
|
|
252
|
+
useEffect(() => {
|
|
253
|
+
setFilteredOptions(
|
|
254
|
+
localOptions.filter(element => {
|
|
255
|
+
return element.label
|
|
256
|
+
.toLowerCase()
|
|
257
|
+
.includes(searchValue.toLowerCase());
|
|
258
|
+
})
|
|
238
259
|
);
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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);
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
return (
|
|
265
|
-
<Box ref={dropdownRef} position="relative" onKeyDown={handleOnKeyDown}>
|
|
266
|
-
<Flex
|
|
267
|
-
fontSize="13px"
|
|
268
|
-
h="26px"
|
|
269
|
-
border={isFocussed ? '2px solid' : '.5px solid'}
|
|
270
|
-
borderColor={isFocussed ? colors.border.focus : colors.border.default}
|
|
271
|
-
py="5px"
|
|
272
|
-
pl="8px"
|
|
273
|
-
borderRadius="4px"
|
|
274
|
-
alignItems="center"
|
|
275
|
-
justifyContent="space-between"
|
|
276
|
-
onClick={() => {
|
|
277
|
-
if (!disabled) {
|
|
278
|
-
if (isFocussed) {
|
|
279
|
-
return setIsFocussed(false);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
inputRef.current?.focus();
|
|
283
|
-
setIsFocussed(true);
|
|
284
|
-
}
|
|
285
|
-
}}
|
|
286
|
-
bg={disabled ? colors.fill.light.quaternary : '#ffffff'}
|
|
287
|
-
cursor={disabled ? 'not-allowed' : 'pointer'}
|
|
288
|
-
>
|
|
260
|
+
}, [localOptions, searchValue]);
|
|
261
|
+
|
|
262
|
+
const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
263
|
+
const initialOptionIndex =
|
|
264
|
+
filteredOptions[0]?.value === 'section_header' ? 1 : 0;
|
|
265
|
+
setOptionIndex(initialOptionIndex);
|
|
266
|
+
const { value } = e.target;
|
|
267
|
+
setSearchValue(value);
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
return (
|
|
271
|
+
<Box ref={dropdownRef} position="relative" onKeyDown={handleOnKeyDown}>
|
|
289
272
|
<Flex
|
|
273
|
+
fontSize="13px"
|
|
274
|
+
h="26px"
|
|
275
|
+
border={isFocussed ? '2px solid' : '.5px solid'}
|
|
276
|
+
borderColor={isFocussed ? colors.border.focus : colors.border.default}
|
|
277
|
+
py="5px"
|
|
278
|
+
pl="8px"
|
|
279
|
+
borderRadius="4px"
|
|
290
280
|
alignItems="center"
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
},
|
|
281
|
+
justifyContent="space-between"
|
|
282
|
+
onClick={() => {
|
|
283
|
+
if (!disabled) {
|
|
284
|
+
if (isFocussed) {
|
|
285
|
+
return setIsFocussed(false);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
inputRef.current?.focus();
|
|
289
|
+
setIsFocussed(true);
|
|
290
|
+
}
|
|
302
291
|
}}
|
|
303
|
-
|
|
292
|
+
bg={disabled ? colors.fill.light.quaternary : '#ffffff'}
|
|
293
|
+
cursor={disabled ? 'not-allowed' : 'pointer'}
|
|
304
294
|
>
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
295
|
+
<Flex
|
|
296
|
+
alignItems="center"
|
|
297
|
+
h="inherit"
|
|
298
|
+
width="90%"
|
|
299
|
+
overflowX="scroll"
|
|
300
|
+
style={{
|
|
301
|
+
scrollbarWidth: 'none' /* Firefox */,
|
|
302
|
+
msOverflowStyle: 'none',
|
|
303
|
+
}}
|
|
304
|
+
sx={{
|
|
305
|
+
'::-webkit-scrollbar': {
|
|
306
|
+
display: 'none',
|
|
307
|
+
},
|
|
308
|
+
}}
|
|
309
|
+
ref={scrollRef}
|
|
310
|
+
>
|
|
311
|
+
{localValues.length ? (
|
|
312
|
+
localValues.map((option, idx) => (
|
|
313
|
+
<Box
|
|
314
|
+
key={idx}
|
|
315
|
+
mr="4px"
|
|
316
|
+
width="fit-content"
|
|
317
|
+
h="16px"
|
|
318
|
+
borderRadius="full"
|
|
319
|
+
>
|
|
320
|
+
<Token
|
|
321
|
+
label={option.label}
|
|
322
|
+
onDelete={() => handleDelete(option)}
|
|
323
|
+
/>
|
|
324
|
+
</Box>
|
|
325
|
+
))
|
|
326
|
+
) : (
|
|
327
|
+
<Text color={colors.label.secondary.light} fontSize="13px">
|
|
328
|
+
{placeholder}
|
|
329
|
+
</Text>
|
|
330
|
+
)}
|
|
331
|
+
</Flex>
|
|
332
|
+
<Input
|
|
333
|
+
padding={0}
|
|
334
|
+
border="none"
|
|
335
|
+
height="0"
|
|
336
|
+
width="0"
|
|
337
|
+
autoComplete="off"
|
|
338
|
+
type="text"
|
|
339
|
+
ref={inputRef}
|
|
340
|
+
tabIndex={-1}
|
|
341
|
+
_focus={{ boxShadow: 'none !important' }}
|
|
342
|
+
/>
|
|
343
|
+
<Flex mr="4px" justifyContent="center" alignItems="center">
|
|
344
|
+
<DropdownIcon boxSize="12px" disabled={disabled} />
|
|
345
|
+
</Flex>
|
|
339
346
|
</Flex>
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
347
|
+
{isFocussed && (
|
|
348
|
+
<Dropdown
|
|
349
|
+
dropdownRef={dropdownMenuRef}
|
|
350
|
+
onSelectItem={option => handleChange(option)}
|
|
351
|
+
options={filteredOptions}
|
|
352
|
+
position={position}
|
|
353
|
+
optionIndex={optionIndex}
|
|
354
|
+
loading={loadingOptions}
|
|
355
|
+
>
|
|
356
|
+
<Input
|
|
357
|
+
value={searchValue}
|
|
358
|
+
onChange={handleInput}
|
|
359
|
+
disabled={loadingOptions}
|
|
360
|
+
/>
|
|
361
|
+
</Dropdown>
|
|
362
|
+
)}
|
|
363
|
+
</Box>
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
);
|
|
355
367
|
|
|
356
368
|
export default StackedMultiSelect;
|