@@ -3,35 +3,53 @@ import Downshift, { DownshiftProps } from 'downshift';
3
3
import css from '@styled-system/css' ;
4
4
import { Input , List , ListAction } from '@codesandbox/components' ;
5
5
6
+ type User = {
7
+ id : string ;
8
+ username : string ;
9
+ avatar_url : string ;
10
+ } ;
11
+
6
12
interface IUserAutoComplete {
7
13
inputValue : string ;
8
14
children : ( answer : {
9
- users : string [ ] ;
15
+ users : User [ ] ;
10
16
loading : boolean ;
11
17
error : Error | null ;
12
18
} ) => JSX . Element ;
13
19
}
14
20
15
21
const UserAutoComplete = ( { inputValue, children } : IUserAutoComplete ) => {
16
- const [ users , setUsers ] = React . useState < string [ ] > ( [ ] ) ;
22
+ const [ users , setUsers ] = React . useState < User [ ] > ( [ ] ) ;
17
23
const [ loading , setLoading ] = React . useState < boolean > ( true ) ;
18
24
const [ error , setError ] = React . useState < Error | null > ( null ) ;
19
25
useEffect ( ( ) => {
20
26
setLoading ( true ) ;
21
27
setError ( null ) ;
28
+
29
+ let timeoutId : number ;
30
+
22
31
if ( inputValue . length > 2 && ! inputValue . includes ( '@' ) ) {
23
- fetch ( `/api/v1/users/search?username=${ inputValue } ` )
24
- . then ( x => x . json ( ) )
25
- . then ( x => {
26
- setUsers ( x . map ( user => user . username ) ) ;
27
- setLoading ( false ) ;
28
- } )
29
- . catch ( e => {
30
- setError ( e ) ;
31
- } ) ;
32
+ // Small debounce
33
+ timeoutId = window . setTimeout ( ( ) => {
34
+ fetch ( `/api/v1/users/search?username=${ inputValue } ` )
35
+ . then ( x => x . json ( ) )
36
+ . then ( x => {
37
+ setUsers ( x ) ;
38
+ setLoading ( false ) ;
39
+ } )
40
+ . catch ( e => {
41
+ setError ( e ) ;
42
+ } ) ;
43
+ } , 300 ) ;
32
44
} else {
33
45
setUsers ( [ ] ) ;
34
46
}
47
+
48
+ return ( ) => {
49
+ if ( timeoutId ) {
50
+ clearTimeout ( timeoutId ) ;
51
+ }
52
+ } ;
35
53
} , [ inputValue ] ) ;
36
54
37
55
return children ( { users, loading, error } ) ;
@@ -98,15 +116,26 @@ export const UserSearchInput = ({
98
116
>
99
117
{ users . map ( ( item , index ) => (
100
118
< ListAction
101
- key = { item }
119
+ key = { item . id }
102
120
isActive = { highlightedIndex === index }
103
121
{ ...getItemProps ( {
104
- item,
122
+ item : item . username ,
105
123
index,
106
- isSelected : selectedItem === item ,
124
+ isSelected : selectedItem === item . username ,
107
125
} ) }
108
126
>
109
- { item }
127
+ < img
128
+ alt = { item . username }
129
+ css = { css ( {
130
+ borderRadius : 2 ,
131
+ marginRight : 2 ,
132
+ paddingY : 1 ,
133
+ } ) }
134
+ width = { 24 }
135
+ height = { 24 }
136
+ src = { item . avatar_url }
137
+ /> { ' ' }
138
+ { item . username }
110
139
</ ListAction >
111
140
) ) }
112
141
</ List >
0 commit comments