@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
3
3
import Tag from './Tag'
4
4
import Input from './Input'
5
5
import Suggestions from './Suggestions'
6
+ import { escapeForRegExp } from './utils'
6
7
7
8
const KEYS = {
8
9
ENTER : 'Enter' ,
@@ -32,14 +33,17 @@ function pressDelimiterKey (e) {
32
33
33
34
if ( this . state . query . length >= this . props . minQueryLength ) {
34
35
// Check if the user typed in an existing suggestion.
35
- const match = this . suggestions . state . options . findIndex ( ( suggestion ) => (
36
- suggestion . name . search ( new RegExp ( `^${ this . state . query } $` , 'i' ) ) === 0
37
- ) )
36
+ const match = this . state . options . findIndex ( ( option ) => {
37
+ const query = escapeForRegExp ( this . state . query )
38
+ const regex = new RegExp ( `^${ query } $` , 'i' )
39
+
40
+ return regex . test ( option . name )
41
+ } )
38
42
39
43
const index = this . state . selected === - 1 ? match : this . state . selected
40
44
41
45
if ( index > - 1 ) {
42
- this . addTag ( this . suggestions . state . options [ index ] )
46
+ this . addTag ( this . state . options [ index ] )
43
47
} else if ( this . props . allowNew ) {
44
48
this . addTag ( { name : this . state . query } )
45
49
}
@@ -51,7 +55,7 @@ function pressUpKey (e) {
51
55
52
56
// if first item, cycle to the bottom
53
57
if ( this . state . selected <= 0 ) {
54
- this . setState ( { selected : this . suggestions . state . options . length - 1 } )
58
+ this . setState ( { selected : this . state . options . length - 1 } )
55
59
} else {
56
60
this . setState ( { selected : this . state . selected - 1 } )
57
61
}
@@ -61,7 +65,7 @@ function pressDownKey (e) {
61
65
e . preventDefault ( )
62
66
63
67
// if last item, cycle to top
64
- if ( this . state . selected >= this . suggestions . state . options . length - 1 ) {
68
+ if ( this . state . selected >= this . state . options . length - 1 ) {
65
69
this . setState ( { selected : 0 } )
66
70
} else {
67
71
this . setState ( { selected : this . state . selected + 1 } )
@@ -75,13 +79,19 @@ function pressBackspaceKey () {
75
79
}
76
80
}
77
81
82
+ function filterSuggestions ( query , suggestions ) {
83
+ const regexp = new RegExp ( `(?:^|\\s)${ escapeForRegExp ( query ) } ` , 'i' )
84
+ return suggestions . filter ( ( item ) => regexp . test ( item . name ) )
85
+ }
86
+
78
87
class ReactTags extends React . Component {
79
88
constructor ( props ) {
80
89
super ( props )
81
90
82
91
this . state = {
83
92
query : '' ,
84
93
focused : false ,
94
+ options : [ ] ,
85
95
selected : - 1 ,
86
96
classNames : Object . assign ( { } , CLASS_NAMES , this . props . classNames )
87
97
}
@@ -100,7 +110,12 @@ class ReactTags extends React.Component {
100
110
this . props . onInput ( query )
101
111
}
102
112
103
- this . setState ( { query } )
113
+ if ( query !== this . state . query ) {
114
+ const filtered = filterSuggestions ( query , this . props . suggestions )
115
+ const options = filtered . slice ( 0 , this . props . maxSuggestionsLength )
116
+
117
+ this . setState ( { query, options } )
118
+ }
104
119
}
105
120
106
121
onKeyDown ( e ) {
@@ -203,9 +218,7 @@ class ReactTags extends React.Component {
203
218
ref = { ( c ) => { this . suggestions = c } }
204
219
listboxId = { listboxId }
205
220
expanded = { expanded }
206
- suggestions = { this . props . suggestions }
207
- addTag = { this . addTag . bind ( this ) }
208
- maxSuggestionsLength = { this . props . maxSuggestionsLength } />
221
+ addTag = { this . addTag . bind ( this ) } />
209
222
</ div >
210
223
</ div >
211
224
)
0 commit comments