@@ -3,35 +3,53 @@ import Downshift, { DownshiftProps } from 'downshift';
33import css from '@styled-system/css' ;
44import { Input , List , ListAction } from '@codesandbox/components' ;
55
6+ type User = {
7+ id : string ;
8+ username : string ;
9+ avatar_url : string ;
10+ } ;
11+
612interface IUserAutoComplete {
713 inputValue : string ;
814 children : ( answer : {
9- users : string [ ] ;
15+ users : User [ ] ;
1016 loading : boolean ;
1117 error : Error | null ;
1218 } ) => JSX . Element ;
1319}
1420
1521const UserAutoComplete = ( { inputValue, children } : IUserAutoComplete ) => {
16- const [ users , setUsers ] = React . useState < string [ ] > ( [ ] ) ;
22+ const [ users , setUsers ] = React . useState < User [ ] > ( [ ] ) ;
1723 const [ loading , setLoading ] = React . useState < boolean > ( true ) ;
1824 const [ error , setError ] = React . useState < Error | null > ( null ) ;
1925 useEffect ( ( ) => {
2026 setLoading ( true ) ;
2127 setError ( null ) ;
28+
29+ let timeoutId : number ;
30+
2231 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 ) ;
3244 } else {
3345 setUsers ( [ ] ) ;
3446 }
47+
48+ return ( ) => {
49+ if ( timeoutId ) {
50+ clearTimeout ( timeoutId ) ;
51+ }
52+ } ;
3553 } , [ inputValue ] ) ;
3654
3755 return children ( { users, loading, error } ) ;
@@ -98,15 +116,26 @@ export const UserSearchInput = ({
98116 >
99117 { users . map ( ( item , index ) => (
100118 < ListAction
101- key = { item }
119+ key = { item . id }
102120 isActive = { highlightedIndex === index }
103121 { ...getItemProps ( {
104- item,
122+ item : item . username ,
105123 index,
106- isSelected : selectedItem === item ,
124+ isSelected : selectedItem === item . username ,
107125 } ) }
108126 >
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 }
110139 </ ListAction >
111140 ) ) }
112141 </ List >
0 commit comments