Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/gentle-eyes-sell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'react-select': patch
'storybook': patch
---

Introduces a new optional prop allowEmptySearch to the Async Select component.
10 changes: 9 additions & 1 deletion packages/react-select/src/useAsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ export interface AsyncAdditionalProps<Option, Group extends GroupBase<Option>> {
* Async select is not currently waiting for loadOptions to resolve
*/
isLoading?: boolean;
/**
* When set to `true`, the `loadOptions` function will be called even when the input is empty (`''`).
* This allows consumers to handle empty input searches (e.g., return a default set of results).
* If `false` (default), the input will reset without triggering `loadOptions('')`.
*/
allowEmptySearch?: boolean;
}

export type AsyncProps<
Expand All @@ -55,6 +61,7 @@ export default function useAsync<
isLoading: propsIsLoading = false,
onInputChange: propsOnInputChange,
filterOption = null,
allowEmptySearch,
...restSelectProps
}: AsyncProps<Option, IsMulti, Group> & AdditionalProps): StateManagerProps<
Option,
Expand Down Expand Up @@ -143,7 +150,7 @@ export default function useAsync<
actionMeta,
propsOnInputChange
);
if (!inputValue) {
if (!inputValue && !allowEmptySearch) {
lastRequest.current = undefined;
setStateInputValue('');
setLoadedInputValue('');
Expand Down Expand Up @@ -183,6 +190,7 @@ export default function useAsync<
loadedInputValue,
optionsCache,
propsOnInputChange,
allowEmptySearch,
]
);

Expand Down
44 changes: 44 additions & 0 deletions storybook/stories/AsyncPromisesWithAllowEmptySearch.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { ComponentMeta } from '@storybook/react';
import * as React from 'react';
import AsyncSelect from 'react-select/async';

import { Field } from '../components';
import { ColourOption, colourOptions } from '../data';

export default {
title: 'Select/AsyncPromises',
component: AsyncSelect,
argTypes: {},
} as ComponentMeta<typeof AsyncSelect>;

export function AsyncPromises() {
return (
<Field label="Async Promises" htmlFor="async-promises">
<AsyncSelect
inputId="async-promises"
cacheOptions
defaultOptions
loadOptions={promiseOptions}
allowEmptySearch
/>
</Field>
);
}

// =============================================================================
// Utils
// =============================================================================

function filterColors(inputValue: string) {
return colourOptions.filter((i) =>
i.label.toLowerCase().includes(inputValue.toLowerCase())
);
}

function promiseOptions(inputValue: string) {
return new Promise<ColourOption[]>((resolve) => {
setTimeout(() => {
resolve(filterColors(inputValue));
}, 1000);
});
}