sbwb-ds 3.36.2 → 3.37.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.
- package/dist/sbwb-ds.js +6285 -6268
- package/dist/sbwb-ds.umd.cjs +403 -403
- package/dist/src/presentation/components/molecules/Autocomplete/hooks/useAutocomplete.d.ts +1 -1
- package/dist/src/presentation/components/molecules/Autocomplete/index.d.ts +1 -0
- package/dist/src/presentation/components/molecules/MultiSelect/MultiSelect.component.d.ts +1 -0
- package/dist/src/presentation/components/molecules/MultiSelect/index.spec.d.ts +1 -0
- package/dist/src/presentation/components/molecules/MultiSelect/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/presentation/components/molecules/Autocomplete/Autocomplete.stories.tsx +5 -0
- package/src/presentation/components/molecules/Autocomplete/documentation/index.tsx +7 -0
- package/src/presentation/components/molecules/Autocomplete/hooks/useAutocomplete.tsx +8 -2
- package/src/presentation/components/molecules/Autocomplete/index.spec.tsx +89 -3
- package/src/presentation/components/molecules/Autocomplete/index.tsx +16 -2
- package/src/presentation/components/molecules/MultiSelect/MultiSelect.component.tsx +27 -12
- package/src/presentation/components/molecules/MultiSelect/MultiSelect.stories.tsx +5 -0
- package/src/presentation/components/molecules/MultiSelect/documentation/index.tsx +6 -0
- package/src/presentation/components/molecules/MultiSelect/index.spec.tsx +63 -0
- package/src/presentation/components/molecules/MultiSelect/types.ts +1 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { SelectOption } from '../../../../../models/select-option';
|
|
3
3
|
import { AutocompleteProps } from '..';
|
|
4
|
-
export declare const useAutocomplete: (handleOption: (value: SelectOption | SelectOption[] | undefined) => void, { value, options, size, variant, }: Pick<AutocompleteProps, 'value' | 'options' | 'size' | 'variant'>) => {
|
|
4
|
+
export declare const useAutocomplete: (handleOption: (value: SelectOption | SelectOption[] | undefined) => void, { value, options, size, variant, clearSearchOnSelect, }: Pick<AutocompleteProps, 'value' | 'options' | 'size' | 'variant' | 'clearSearchOnSelect'>) => {
|
|
5
5
|
isOpen: boolean;
|
|
6
6
|
setIsOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
7
7
|
expanded: boolean;
|
|
@@ -25,6 +25,7 @@ export interface AutocompleteProps extends CustomDataAttributes {
|
|
|
25
25
|
onEnter?: (option: SelectOption) => void;
|
|
26
26
|
onInputEnter?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
27
27
|
disableSelectOnEnter?: boolean;
|
|
28
|
+
clearSearchOnSelect?: boolean;
|
|
28
29
|
/** @deprecated Use `onChange` instead */
|
|
29
30
|
onSearchTextChange?: (value: string) => void;
|
|
30
31
|
/** @deprecated Use `onSelect` instead */
|
|
@@ -12,6 +12,7 @@ declare const MultiSelect: React.ForwardRefExoticComponent<{
|
|
|
12
12
|
label?: React.ReactNode;
|
|
13
13
|
onChange: (values: string[]) => void;
|
|
14
14
|
onSearchChange?: (searchText: string) => void;
|
|
15
|
+
clearSearchOnSelect?: boolean;
|
|
15
16
|
disabled?: boolean;
|
|
16
17
|
enableSearch?: boolean;
|
|
17
18
|
width?: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
package/package.json
CHANGED
|
@@ -95,6 +95,11 @@ const meta: Meta<typeof Autocomplete> = {
|
|
|
95
95
|
description:
|
|
96
96
|
'Prevents selecting the focused option when pressing Enter; pair with onInputEnter to handle filtering.',
|
|
97
97
|
},
|
|
98
|
+
clearSearchOnSelect: {
|
|
99
|
+
control: 'boolean',
|
|
100
|
+
description:
|
|
101
|
+
'Clears the search term after selecting an option. Set to false for withTag to keep filtering during multiple selections.',
|
|
102
|
+
},
|
|
98
103
|
onSearchTextChange: {
|
|
99
104
|
description: 'Function to be called when the search text is changed.',
|
|
100
105
|
},
|
|
@@ -166,6 +166,13 @@ export default Example;`}
|
|
|
166
166
|
autocomplete input. Options include "singleValue" for single selection
|
|
167
167
|
and "withTag" for multi-selection with tags.
|
|
168
168
|
</li>
|
|
169
|
+
<li>
|
|
170
|
+
<InlineCode>clearSearchOnSelect</InlineCode>: Clears the search term
|
|
171
|
+
after selecting an option. Defaults to <InlineCode>true</InlineCode>;
|
|
172
|
+
set it to <InlineCode>false</InlineCode> with{' '}
|
|
173
|
+
<InlineCode>variant="withTag"</InlineCode> to keep filtering while the
|
|
174
|
+
menu remains open.
|
|
175
|
+
</li>
|
|
169
176
|
<li>
|
|
170
177
|
<InlineCode>onTagClose</InlineCode>: A callback function that handles
|
|
171
178
|
the removal of a tag in multi-select mode.
|
|
@@ -11,7 +11,11 @@ export const useAutocomplete = (
|
|
|
11
11
|
options,
|
|
12
12
|
size,
|
|
13
13
|
variant,
|
|
14
|
-
|
|
14
|
+
clearSearchOnSelect,
|
|
15
|
+
}: Pick<
|
|
16
|
+
AutocompleteProps,
|
|
17
|
+
'value' | 'options' | 'size' | 'variant' | 'clearSearchOnSelect'
|
|
18
|
+
>
|
|
15
19
|
) => {
|
|
16
20
|
const [isOpen, setIsOpen] = useState(false);
|
|
17
21
|
const [expanded, setExpanded] = useState(false);
|
|
@@ -57,7 +61,9 @@ export const useAutocomplete = (
|
|
|
57
61
|
}, [options]);
|
|
58
62
|
|
|
59
63
|
function autocompleteOption(option: SelectOption) {
|
|
60
|
-
|
|
64
|
+
if (clearSearchOnSelect || variant === 'singleValue') {
|
|
65
|
+
setInputValue('');
|
|
66
|
+
}
|
|
61
67
|
setExpanded(variant === 'singleValue' ? false : true);
|
|
62
68
|
setIsOpen(variant === 'singleValue' ? false : true);
|
|
63
69
|
inputContainerRef?.current && inputContainerRef.current.focus();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { render, screen, act, fireEvent } from '@testing-library/react';
|
|
2
2
|
import '@testing-library/jest-dom';
|
|
3
|
+
import { useState } from 'react';
|
|
3
4
|
import { SelectOption } from '../../../../models/select-option';
|
|
4
5
|
import { Autocomplete } from '../../atoms/index';
|
|
5
6
|
|
|
@@ -28,7 +29,7 @@ describe('Autocomplete component', () => {
|
|
|
28
29
|
/>
|
|
29
30
|
);
|
|
30
31
|
|
|
31
|
-
const autocomplete = screen.getByTestId(
|
|
32
|
+
const autocomplete = screen.getByTestId('autocomplete');
|
|
32
33
|
|
|
33
34
|
act(() => {
|
|
34
35
|
fireEvent.click(autocomplete);
|
|
@@ -52,7 +53,7 @@ describe('Autocomplete component', () => {
|
|
|
52
53
|
size="Small"
|
|
53
54
|
/>
|
|
54
55
|
);
|
|
55
|
-
const autocomplete = screen.getByTestId(
|
|
56
|
+
const autocomplete = screen.getByTestId('autocomplete');
|
|
56
57
|
|
|
57
58
|
act(() => {
|
|
58
59
|
fireEvent.click(autocomplete);
|
|
@@ -186,7 +187,7 @@ describe('Autocomplete component', () => {
|
|
|
186
187
|
/>
|
|
187
188
|
);
|
|
188
189
|
|
|
189
|
-
const autocomplete = screen.getByTestId(
|
|
190
|
+
const autocomplete = screen.getByTestId('autocomplete');
|
|
190
191
|
|
|
191
192
|
act(() => {
|
|
192
193
|
fireEvent.click(autocomplete);
|
|
@@ -200,4 +201,89 @@ describe('Autocomplete component', () => {
|
|
|
200
201
|
|
|
201
202
|
expect(option).not.toBeInTheDocument();
|
|
202
203
|
});
|
|
204
|
+
|
|
205
|
+
it('should preserve the search term after selecting a withTag option when clearSearchOnSelect is false', () => {
|
|
206
|
+
const WithTagAutocomplete = () => {
|
|
207
|
+
const [value, setValue] = useState<SelectOption[]>([]);
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
<Autocomplete
|
|
211
|
+
options={options}
|
|
212
|
+
value={value}
|
|
213
|
+
variant="withTag"
|
|
214
|
+
clearSearchOnSelect={false}
|
|
215
|
+
onSelect={(nextValue) =>
|
|
216
|
+
setValue((nextValue as SelectOption[]) ?? [])
|
|
217
|
+
}
|
|
218
|
+
/>
|
|
219
|
+
);
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
render(<WithTagAutocomplete />);
|
|
223
|
+
|
|
224
|
+
const input = screen.getByTestId('autocomplete-input');
|
|
225
|
+
fireEvent.change(input, { target: { value: 'th' } });
|
|
226
|
+
fireEvent.click(screen.getByTestId('3'));
|
|
227
|
+
|
|
228
|
+
expect(input).toHaveValue('th');
|
|
229
|
+
expect(
|
|
230
|
+
screen.getByTestId('autocomplete-menu-multi-select')
|
|
231
|
+
).toBeInTheDocument();
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('should clear the preserved search term after closing the withTag menu', () => {
|
|
235
|
+
const WithTagAutocomplete = () => {
|
|
236
|
+
const [value, setValue] = useState<SelectOption[]>([]);
|
|
237
|
+
|
|
238
|
+
return (
|
|
239
|
+
<Autocomplete
|
|
240
|
+
options={options}
|
|
241
|
+
value={value}
|
|
242
|
+
variant="withTag"
|
|
243
|
+
clearSearchOnSelect={false}
|
|
244
|
+
onSelect={(nextValue) =>
|
|
245
|
+
setValue((nextValue as SelectOption[]) ?? [])
|
|
246
|
+
}
|
|
247
|
+
/>
|
|
248
|
+
);
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
render(<WithTagAutocomplete />);
|
|
252
|
+
|
|
253
|
+
const input = screen.getByTestId('autocomplete-input');
|
|
254
|
+
fireEvent.change(input, { target: { value: 'th' } });
|
|
255
|
+
fireEvent.click(screen.getByTestId('3'));
|
|
256
|
+
fireEvent.mouseDown(document.body);
|
|
257
|
+
|
|
258
|
+
expect(input).toHaveValue('');
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it('should clear the preserved search term when pressing Escape', () => {
|
|
262
|
+
const WithTagAutocomplete = () => {
|
|
263
|
+
const [value, setValue] = useState<SelectOption[]>([]);
|
|
264
|
+
|
|
265
|
+
return (
|
|
266
|
+
<Autocomplete
|
|
267
|
+
options={options}
|
|
268
|
+
value={value}
|
|
269
|
+
variant="withTag"
|
|
270
|
+
clearSearchOnSelect={false}
|
|
271
|
+
onSelect={(nextValue) =>
|
|
272
|
+
setValue((nextValue as SelectOption[]) ?? [])
|
|
273
|
+
}
|
|
274
|
+
/>
|
|
275
|
+
);
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
render(<WithTagAutocomplete />);
|
|
279
|
+
|
|
280
|
+
const input = screen.getByTestId('autocomplete-input');
|
|
281
|
+
fireEvent.change(input, { target: { value: 'th' } });
|
|
282
|
+
fireEvent.keyDown(input, { key: 'Escape' });
|
|
283
|
+
|
|
284
|
+
expect(input).toHaveValue('');
|
|
285
|
+
expect(
|
|
286
|
+
screen.queryByTestId('autocomplete-menu-multi-select')
|
|
287
|
+
).not.toBeInTheDocument();
|
|
288
|
+
});
|
|
203
289
|
});
|
|
@@ -2,7 +2,7 @@ import { Icons } from '../../../../main/helpers/functions/icons';
|
|
|
2
2
|
import { SelectOption } from '../../../../models/select-option';
|
|
3
3
|
import * as C from './styles';
|
|
4
4
|
import { useAutocomplete } from './hooks/useAutocomplete';
|
|
5
|
-
import { forwardRef, ReactNode
|
|
5
|
+
import { forwardRef, ReactNode } from 'react';
|
|
6
6
|
import MenuSelect from '../MenuSelect';
|
|
7
7
|
import MenuMultiSelect from '../../atoms/MenuMultiSelect';
|
|
8
8
|
import Tag from '../../atoms/Tag';
|
|
@@ -35,6 +35,7 @@ export interface AutocompleteProps extends CustomDataAttributes {
|
|
|
35
35
|
onEnter?: (option: SelectOption) => void;
|
|
36
36
|
onInputEnter?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
37
37
|
disableSelectOnEnter?: boolean;
|
|
38
|
+
clearSearchOnSelect?: boolean;
|
|
38
39
|
|
|
39
40
|
/** @deprecated Use `onChange` instead */
|
|
40
41
|
onSearchTextChange?: (value: string) => void;
|
|
@@ -101,6 +102,7 @@ const Autocomplete: React.FC<AutocompleteProps> = forwardRef<
|
|
|
101
102
|
onEnter,
|
|
102
103
|
onInputEnter,
|
|
103
104
|
disableSelectOnEnter = false,
|
|
105
|
+
clearSearchOnSelect = true,
|
|
104
106
|
onSearchTextChange,
|
|
105
107
|
onChange,
|
|
106
108
|
errorMessage,
|
|
@@ -151,7 +153,13 @@ const Autocomplete: React.FC<AutocompleteProps> = forwardRef<
|
|
|
151
153
|
isValue,
|
|
152
154
|
handleRemoveOption,
|
|
153
155
|
handleBackspace,
|
|
154
|
-
} = useAutocomplete(handlerOption, {
|
|
156
|
+
} = useAutocomplete(handlerOption, {
|
|
157
|
+
value,
|
|
158
|
+
options,
|
|
159
|
+
size,
|
|
160
|
+
variant,
|
|
161
|
+
clearSearchOnSelect,
|
|
162
|
+
});
|
|
155
163
|
|
|
156
164
|
const hasError = !!errorMessage;
|
|
157
165
|
|
|
@@ -173,6 +181,12 @@ const Autocomplete: React.FC<AutocompleteProps> = forwardRef<
|
|
|
173
181
|
} else if (!Array.isArray(value) && value) {
|
|
174
182
|
handleBackspace();
|
|
175
183
|
}
|
|
184
|
+
} else if (e.key === 'Escape') {
|
|
185
|
+
e.preventDefault();
|
|
186
|
+
setInputValue('');
|
|
187
|
+
setIsOpen(false);
|
|
188
|
+
setExpanded(false);
|
|
189
|
+
inputContainerRef.current?.blur();
|
|
176
190
|
} else if (e.key === 'Enter') {
|
|
177
191
|
e.preventDefault();
|
|
178
192
|
if (onInputEnter) {
|
|
@@ -33,6 +33,7 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
|
|
|
33
33
|
onChange,
|
|
34
34
|
onSearchChange, // Nova prop para capturar mudanças no texto de busca
|
|
35
35
|
searchValue, // Nova prop para controlar o valor de busca externamente
|
|
36
|
+
clearSearchOnSelect = true,
|
|
36
37
|
disabled = false,
|
|
37
38
|
enableSearch = true,
|
|
38
39
|
width = '100%',
|
|
@@ -126,6 +127,11 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
|
|
|
126
127
|
setIsFocused(false);
|
|
127
128
|
}, []);
|
|
128
129
|
|
|
130
|
+
const clearSearch = useCallback(() => {
|
|
131
|
+
setInternalSearchText('');
|
|
132
|
+
onSearchChange?.('');
|
|
133
|
+
}, [onSearchChange]);
|
|
134
|
+
|
|
129
135
|
const selectableOptions = useMemo(
|
|
130
136
|
() => options.filter((opt) => !opt.disabled),
|
|
131
137
|
[options]
|
|
@@ -150,14 +156,16 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
|
|
|
150
156
|
: [...values, optionValue];
|
|
151
157
|
handleChange(newValues);
|
|
152
158
|
}
|
|
153
|
-
|
|
154
|
-
|
|
159
|
+
if (clearSearchOnSelect) {
|
|
160
|
+
clearSearch();
|
|
161
|
+
}
|
|
155
162
|
handleInputFocus();
|
|
156
163
|
},
|
|
157
164
|
[
|
|
158
165
|
values,
|
|
159
166
|
handleChange,
|
|
160
|
-
|
|
167
|
+
clearSearch,
|
|
168
|
+
clearSearchOnSelect,
|
|
161
169
|
handleInputFocus,
|
|
162
170
|
enableSelectAll,
|
|
163
171
|
isAllSelected,
|
|
@@ -172,13 +180,14 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
|
|
|
172
180
|
}
|
|
173
181
|
if (e.key === 'Escape') {
|
|
174
182
|
setIsOpen(false);
|
|
183
|
+
clearSearch();
|
|
175
184
|
inputRef.current?.blur();
|
|
176
185
|
}
|
|
177
186
|
if (e.key === 'Enter') {
|
|
178
187
|
e.preventDefault();
|
|
179
188
|
}
|
|
180
189
|
},
|
|
181
|
-
[searchText, values, handleChange]
|
|
190
|
+
[searchText, values, handleChange, clearSearch]
|
|
182
191
|
);
|
|
183
192
|
|
|
184
193
|
const handleKeyUp = useCallback(
|
|
@@ -225,16 +234,14 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
|
|
|
225
234
|
!selectContainerRef.current.contains(target)
|
|
226
235
|
) {
|
|
227
236
|
setIsOpen(false);
|
|
228
|
-
|
|
229
|
-
setInternalSearchText('');
|
|
230
|
-
}
|
|
237
|
+
clearSearch();
|
|
231
238
|
}
|
|
232
239
|
};
|
|
233
240
|
document.addEventListener('mousedown', handleClickOutside);
|
|
234
241
|
return () => {
|
|
235
242
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
236
243
|
};
|
|
237
|
-
}, [isOpen,
|
|
244
|
+
}, [isOpen, clearSearch]);
|
|
238
245
|
|
|
239
246
|
useEffect(() => {
|
|
240
247
|
if (!ref) return;
|
|
@@ -242,14 +249,17 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
|
|
|
242
249
|
focus: () => inputRef.current?.focus(),
|
|
243
250
|
blur: () => inputRef.current?.blur(),
|
|
244
251
|
open: () => setIsOpen(true),
|
|
245
|
-
close: () =>
|
|
252
|
+
close: () => {
|
|
253
|
+
clearSearch();
|
|
254
|
+
setIsOpen(false);
|
|
255
|
+
},
|
|
246
256
|
};
|
|
247
257
|
if (typeof ref === 'function') {
|
|
248
258
|
ref(handle);
|
|
249
259
|
} else {
|
|
250
260
|
ref.current = handle;
|
|
251
261
|
}
|
|
252
|
-
}, [ref]);
|
|
262
|
+
}, [ref, clearSearch]);
|
|
253
263
|
|
|
254
264
|
return (
|
|
255
265
|
<C.SelectContainer
|
|
@@ -262,7 +272,7 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
|
|
|
262
272
|
onBlur={() => {
|
|
263
273
|
setIsFocused(false);
|
|
264
274
|
if (!isOpen) {
|
|
265
|
-
|
|
275
|
+
clearSearch();
|
|
266
276
|
}
|
|
267
277
|
}}
|
|
268
278
|
data-status={multiSelectStatus}
|
|
@@ -402,7 +412,12 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
|
|
|
402
412
|
<C.WrapperIcon
|
|
403
413
|
onClick={(e) => {
|
|
404
414
|
e.stopPropagation();
|
|
405
|
-
if (!disabled)
|
|
415
|
+
if (!disabled) {
|
|
416
|
+
if (isOpen) {
|
|
417
|
+
clearSearch();
|
|
418
|
+
}
|
|
419
|
+
setIsOpen((prev) => !prev);
|
|
420
|
+
}
|
|
406
421
|
}}
|
|
407
422
|
>
|
|
408
423
|
<Icon
|
|
@@ -40,6 +40,11 @@ const meta: Meta<typeof MultiSelect> = {
|
|
|
40
40
|
control: false,
|
|
41
41
|
description: 'Callback fired when the search input changes.',
|
|
42
42
|
},
|
|
43
|
+
clearSearchOnSelect: {
|
|
44
|
+
control: 'boolean',
|
|
45
|
+
description:
|
|
46
|
+
'Clears the search term after selecting an option. Set to false to keep filtering during multiple selections.',
|
|
47
|
+
},
|
|
43
48
|
disabled: { description: 'Disables the multiSelect.' },
|
|
44
49
|
enableSearch: {
|
|
45
50
|
control: { type: 'boolean' },
|
|
@@ -136,6 +136,12 @@ export default Example;`}
|
|
|
136
136
|
<InlineCode>onChange</InlineCode>: A callback function that is triggered
|
|
137
137
|
when the selection changes.
|
|
138
138
|
</li>
|
|
139
|
+
<li>
|
|
140
|
+
<InlineCode>clearSearchOnSelect</InlineCode>: Clears the search term
|
|
141
|
+
after selecting an option. Defaults to <InlineCode>true</InlineCode>;
|
|
142
|
+
set it to <InlineCode>false</InlineCode> to keep filtering while the
|
|
143
|
+
menu remains open.
|
|
144
|
+
</li>
|
|
139
145
|
<li>
|
|
140
146
|
<InlineCode>disabled</InlineCode>: Disables the MultiSelect input,
|
|
141
147
|
preventing user interaction.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import MultiSelect from './';
|
|
5
|
+
import { MultiSelectOption } from './types';
|
|
6
|
+
|
|
7
|
+
const options: MultiSelectOption[] = [
|
|
8
|
+
{ label: 'North Port', value: 'north-port' },
|
|
9
|
+
{ label: 'Portland', value: 'portland' },
|
|
10
|
+
{ label: 'South', value: 'south' },
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
describe('MultiSelect search preservation', () => {
|
|
14
|
+
it('should preserve the search term after selecting an option when clearSearchOnSelect is false', () => {
|
|
15
|
+
const MultiSelectHarness = () => {
|
|
16
|
+
const [values, setValues] = useState<string[]>([]);
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<MultiSelect
|
|
20
|
+
options={options}
|
|
21
|
+
values={values}
|
|
22
|
+
onChange={setValues}
|
|
23
|
+
clearSearchOnSelect={false}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
render(<MultiSelectHarness />);
|
|
29
|
+
|
|
30
|
+
const input = screen.getByTestId('multi-select-input');
|
|
31
|
+
fireEvent.change(input, { target: { value: 'port' } });
|
|
32
|
+
fireEvent.click(screen.getByTestId('north-port'));
|
|
33
|
+
|
|
34
|
+
expect(input).toHaveValue('port');
|
|
35
|
+
expect(
|
|
36
|
+
screen.getByTestId('multi-select-menu-multi-select')
|
|
37
|
+
).toBeInTheDocument();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should clear the preserved search term after closing the menu', () => {
|
|
41
|
+
const MultiSelectHarness = () => {
|
|
42
|
+
const [values, setValues] = useState<string[]>([]);
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<MultiSelect
|
|
46
|
+
options={options}
|
|
47
|
+
values={values}
|
|
48
|
+
onChange={setValues}
|
|
49
|
+
clearSearchOnSelect={false}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
render(<MultiSelectHarness />);
|
|
55
|
+
|
|
56
|
+
const input = screen.getByTestId('multi-select-input');
|
|
57
|
+
fireEvent.change(input, { target: { value: 'port' } });
|
|
58
|
+
fireEvent.click(screen.getByTestId('north-port'));
|
|
59
|
+
fireEvent.mouseDown(document.body);
|
|
60
|
+
|
|
61
|
+
expect(input).toHaveValue('');
|
|
62
|
+
});
|
|
63
|
+
});
|