Skip to content

Commit 1d29d7a

Browse files
committed
Move async emptyLabel rendering out of useAsync
1 parent 0209220 commit 1d29d7a

File tree

3 files changed

+52
-36
lines changed

3 files changed

+52
-36
lines changed
Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,55 @@
1-
import React, { forwardRef } from 'react';
1+
import React, { forwardRef, ReactNode } from 'react';
22

33
import { TypeaheadRef } from '../../core';
44
import { useAsync, UseAsyncProps } from '../../hooks';
55

6-
import Typeahead from '../Typeahead';
6+
import Typeahead, { TypeaheadComponentProps } from '../Typeahead';
77

8-
const AsyncTypeahead = forwardRef<TypeaheadRef, UseAsyncProps>((props, ref) => {
9-
return <Typeahead {...useAsync(props)} ref={ref} />;
10-
});
8+
export interface AsyncTypeaheadProps
9+
extends UseAsyncProps,
10+
Omit<TypeaheadComponentProps, 'isLoading'> {
11+
/**
12+
* Message displayed in the menu when there is no user input.
13+
*/
14+
promptText?: ReactNode;
15+
/**
16+
* Message displayed in the menu while the request is pending.
17+
*/
18+
searchText?: ReactNode;
19+
}
20+
21+
const AsyncTypeahead = forwardRef<TypeaheadRef, AsyncTypeaheadProps>(
22+
(props, ref) => {
23+
const {
24+
emptyLabel,
25+
isLoading,
26+
promptText = 'Type to search...',
27+
searchText = 'Searching...',
28+
} = props;
29+
30+
const { query, ...asyncProps } = useAsync(props);
31+
32+
function getEmptyLabel() {
33+
if (!query.length) {
34+
return promptText;
35+
}
36+
37+
if (isLoading) {
38+
return searchText;
39+
}
40+
41+
return emptyLabel;
42+
}
43+
44+
return (
45+
<Typeahead
46+
{...props}
47+
{...asyncProps}
48+
emptyLabel={getEmptyLabel()}
49+
ref={ref}
50+
/>
51+
);
52+
}
53+
);
1154

1255
export default AsyncTypeahead;

src/core/useTypeahead.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import {
2424
FilterByCallback,
2525
InternalProps,
2626
Option,
27-
SelectEvent,
2827
TypeaheadProps,
2928
TypeaheadState,
3029
} from '../types';
@@ -39,9 +38,7 @@ import {
3938
getIsOnlyResult,
4039
getMenuProps,
4140
getOptionLabel,
42-
getOptionProperty,
4341
getStringLabelKey,
44-
getTruncatedOptions,
4542
getUpdatedActiveIndex,
4643
isFunction,
4744
isShown,

src/hooks/useAsync.tsx

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import debounce from 'lodash.debounce';
2-
import { ChangeEvent, ReactNode, useCallback, useEffect, useRef } from 'react';
2+
import { ChangeEvent, useCallback, useEffect, useRef } from 'react';
33
import useForceUpdate from '@restart/hooks/useForceUpdate';
44
import usePrevious from '@restart/hooks/usePrevious';
55

66
import { isFunction } from '../utils';
77

8-
import { TypeaheadComponentProps } from '../components/Typeahead';
9-
import type { Option } from '../types';
8+
import type { Option, TypeaheadProps } from '../types';
109

11-
export interface UseAsyncProps extends TypeaheadComponentProps {
10+
export interface UseAsyncProps extends TypeaheadProps {
1211
/**
1312
* Delay, in milliseconds, before performing search.
1413
*/
@@ -22,14 +21,6 @@ export interface UseAsyncProps extends TypeaheadComponentProps {
2221
* Callback to perform when the search is executed.
2322
*/
2423
onSearch: (query: string) => void;
25-
/**
26-
* Message displayed in the menu when there is no user input.
27-
*/
28-
promptText?: ReactNode;
29-
/**
30-
* Message displayed in the menu while the request is pending.
31-
*/
32-
searchText?: ReactNode;
3324
/**
3425
* Whether or not the component should cache query results.
3526
*/
@@ -54,14 +45,11 @@ function useAsync(props: UseAsyncProps) {
5445
const {
5546
allowNew,
5647
delay = 200,
57-
emptyLabel,
5848
isLoading,
5949
minLength = 2,
6050
onInputChange,
6151
onSearch,
6252
options = [],
63-
promptText = 'Type to search...',
64-
searchText = 'Searching...',
6553
useCache = true,
6654
...otherProps
6755
} = props;
@@ -114,18 +102,6 @@ function useAsync(props: UseAsyncProps) {
114102
}
115103
});
116104

117-
const getEmptyLabel = () => {
118-
if (!queryRef.current.length) {
119-
return promptText;
120-
}
121-
122-
if (isLoading) {
123-
return searchText;
124-
}
125-
126-
return emptyLabel;
127-
};
128-
129105
const handleInputChange = useCallback(
130106
(query: string, e: ChangeEvent<HTMLInputElement>) => {
131107
onInputChange && onInputChange(query, e);
@@ -142,11 +118,11 @@ function useAsync(props: UseAsyncProps) {
142118
...otherProps,
143119
// Disable custom selections during a search if `allowNew` isn't a function.
144120
allowNew: isFunction(allowNew) ? allowNew : allowNew && !isLoading,
145-
emptyLabel: getEmptyLabel(),
146121
isLoading,
147122
minLength,
148123
onInputChange: handleInputChange,
149124
options: useCache && cachedQuery ? cachedQuery : options,
125+
query: queryRef.current,
150126
};
151127
}
152128

0 commit comments

Comments
 (0)