Skip to content

Commit 9169922

Browse files
committed
feat(common): allow to select all/none in the select options
1 parent 41bcd6e commit 9169922

File tree

2 files changed

+81
-2
lines changed

2 files changed

+81
-2
lines changed

packages/common/src/select/select.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,17 @@ import useIsMounted from '../hooks/use-is-mounted';
1111
const getSelectValue = (stateValue, simpleValue, isMulti, allOptions) =>
1212
simpleValue ? allOptions.filter(({ value }) => (isMulti ? stateValue.includes(value) : isEqual(value, stateValue))) : stateValue;
1313

14-
const handleSelectChange = (option, simpleValue, isMulti, onChange) => {
14+
const handleSelectChange = (option, simpleValue, isMulti, onChange, allOptions) => {
1515
const sanitizedOption = !option && isMulti ? [] : option;
16+
17+
if (isMulti && option.find(({ selectAll }) => selectAll)) {
18+
return onChange(allOptions.filter(({ selectAll }) => !selectAll).map(({ value }) => value));
19+
}
20+
21+
if (isMulti && option.find(({ selectNone }) => selectNone)) {
22+
return onChange([]);
23+
}
24+
1625
return simpleValue
1726
? onChange(isMulti ? sanitizedOption.map((item) => item.value) : sanitizedOption ? sanitizedOption.value : undefined)
1827
: onChange(sanitizedOption);
@@ -147,7 +156,7 @@ const Select = ({
147156
classNamePrefix={classNamePrefix}
148157
isMulti={isMulti}
149158
value={getSelectValue(selectValue, simpleValue, isMulti, state.options)}
150-
onChange={(option) => handleSelectChange(option, simpleValue, isMulti, onChange)}
159+
onChange={(option) => handleSelectChange(option, simpleValue, isMulti, onChange, state.options)}
151160
onInputChange={onInputChange}
152161
isFetching={Object.values(state.promises).some((value) => value)}
153162
noOptionsMessage={renderNoOptionsMessage()}

packages/common/src/tests/select/select.test.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,76 @@ describe('Select test', () => {
313313
]);
314314
expect(inputValue).toEqual(['d', 'c']);
315315
});
316+
317+
it('selects all values', async () => {
318+
field = { ...field, isMulti: true, options: [{ label: 'Select all', selectAll: true }, ...field.options] };
319+
320+
await act(async () => {
321+
wrapper = mount(
322+
<FormRenderer
323+
{...rendererProps}
324+
schema={{
325+
fields: [
326+
{
327+
...field,
328+
component: componentTypes.SELECT,
329+
name: 'select'
330+
}
331+
]
332+
}}
333+
/>
334+
);
335+
});
336+
wrapper.update();
337+
338+
await act(async () => {
339+
wrapper
340+
.find('#onChange')
341+
.props()
342+
.onClick([{ label: 'Select all', selectAll: true }]);
343+
});
344+
wrapper.update();
345+
346+
expect(state.value).toEqual([
347+
{ label: 'Dogs', value: 'd' },
348+
{ label: 'Cats', value: 'c' },
349+
{ label: 'Hamsters', value: 'h' }
350+
]);
351+
expect(inputValue).toEqual(['d', 'c', 'h']);
352+
});
353+
354+
it('selects none', async () => {
355+
field = { ...field, isMulti: true, options: [{ label: 'Select none', selectNone: true }, ...field.options], initialValue: ['d', 'c', 'h'] };
356+
357+
await act(async () => {
358+
wrapper = mount(
359+
<FormRenderer
360+
{...rendererProps}
361+
schema={{
362+
fields: [
363+
{
364+
...field,
365+
component: componentTypes.SELECT,
366+
name: 'select'
367+
}
368+
]
369+
}}
370+
/>
371+
);
372+
});
373+
wrapper.update();
374+
375+
await act(async () => {
376+
wrapper
377+
.find('#onChange')
378+
.props()
379+
.onClick([{ label: 'Select none', selectNone: true }]);
380+
});
381+
wrapper.update();
382+
383+
expect(state.value).toEqual([]);
384+
expect(inputValue).toEqual('');
385+
});
316386
});
317387

318388
describe('loadOptions', () => {

0 commit comments

Comments
 (0)