@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
33import Tag from './Tag'
44import Input from './Input'
55import Suggestions from './Suggestions'
6+ import { escapeForRegExp } from './utils'
67
78const KEYS = {
89 ENTER : 'Enter' ,
@@ -32,14 +33,17 @@ function pressDelimiterKey (e) {
3233
3334 if ( this . state . query . length >= this . props . minQueryLength ) {
3435 // 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+ } )
3842
3943 const index = this . state . selected === - 1 ? match : this . state . selected
4044
4145 if ( index > - 1 ) {
42- this . addTag ( this . suggestions . state . options [ index ] )
46+ this . addTag ( this . state . options [ index ] )
4347 } else if ( this . props . allowNew ) {
4448 this . addTag ( { name : this . state . query } )
4549 }
@@ -51,7 +55,7 @@ function pressUpKey (e) {
5155
5256 // if first item, cycle to the bottom
5357 if ( this . state . selected <= 0 ) {
54- this . setState ( { selected : this . suggestions . state . options . length - 1 } )
58+ this . setState ( { selected : this . state . options . length - 1 } )
5559 } else {
5660 this . setState ( { selected : this . state . selected - 1 } )
5761 }
@@ -61,7 +65,7 @@ function pressDownKey (e) {
6165 e . preventDefault ( )
6266
6367 // 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 ) {
6569 this . setState ( { selected : 0 } )
6670 } else {
6771 this . setState ( { selected : this . state . selected + 1 } )
@@ -75,13 +79,19 @@ function pressBackspaceKey () {
7579 }
7680}
7781
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+
7887class ReactTags extends React . Component {
7988 constructor ( props ) {
8089 super ( props )
8190
8291 this . state = {
8392 query : '' ,
8493 focused : false ,
94+ options : [ ] ,
8595 selected : - 1 ,
8696 classNames : Object . assign ( { } , CLASS_NAMES , this . props . classNames )
8797 }
@@ -100,7 +110,12 @@ class ReactTags extends React.Component {
100110 this . props . onInput ( query )
101111 }
102112
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+ }
104119 }
105120
106121 onKeyDown ( e ) {
@@ -203,9 +218,7 @@ class ReactTags extends React.Component {
203218 ref = { ( c ) => { this . suggestions = c } }
204219 listboxId = { listboxId }
205220 expanded = { expanded }
206- suggestions = { this . props . suggestions }
207- addTag = { this . addTag . bind ( this ) }
208- maxSuggestionsLength = { this . props . maxSuggestionsLength } />
221+ addTag = { this . addTag . bind ( this ) } />
209222 </ div >
210223 </ div >
211224 )
0 commit comments