@@ -22,34 +22,35 @@ const defaultFilter = (term, item) => {
22
22
class SLDSLookup extends React . Component {
23
23
constructor ( props ) {
24
24
super ( props ) ;
25
- this . props . items . map ( ( item , index ) => {
26
- return item . id = 'item-' + index ;
27
- } )
25
+
26
+ //Dynamically assign ids to list items to reference for focusing and selecting items
27
+ this . props . items . map ( ( item , index ) => { return item . id = 'item-' + index ; } )
28
28
29
29
this . state = {
30
30
searchTerm : '' ,
31
31
isOpen :false ,
32
- activeItem :null ,
32
+ currentFocus :null ,
33
+ focusIndex :null ,
33
34
selectedIndex : null ,
34
- activeIndex :null ,
35
35
listLength :this . props . items . length
36
36
} ;
37
37
}
38
38
39
39
//=================================================
40
- // Set Active Descendant (on key down/up, set currently focused/hovered item in list)
40
+ // Using down/up keys, set Focus on list item and assign it to aria-activedescendant attribute in input.
41
+ // Need to keep track of filtered list length to be able to increment/decrement the focus index so it's contained to the number of available list items.
41
42
increaseIndex ( ) {
42
43
let items = this . state . listLength - 1 ;
43
- this . setState ( { activeIndex : this . state . activeIndex < items ? this . state . activeIndex + 1 : 0 } )
44
+ this . setState ( { focusIndex : this . state . focusIndex < items ? this . state . focusIndex + 1 : 0 } )
44
45
}
45
46
46
47
decreaseIndex ( ) {
47
48
let items = this . state . listLength - 1 ;
48
- this . setState ( { activeIndex : this . state . activeIndex > 0 ? this . state . activeIndex - 1 : items } )
49
+ this . setState ( { focusIndex : this . state . focusIndex > 0 ? this . state . focusIndex - 1 : items } )
49
50
}
50
51
51
- setActiveDescendant ( id ) {
52
- this . setState ( { activeItem :id } ) ;
52
+ setFocus ( id ) {
53
+ this . setState ( { currentFocus :id } ) ;
53
54
}
54
55
55
56
getListLength ( qty ) {
@@ -61,7 +62,6 @@ class SLDSLookup extends React.Component {
61
62
//=================================================
62
63
// Select menu item (onClick or on key enter/space)
63
64
selectItem ( itemId ) {
64
- //console.log('selectItem fired');
65
65
let index = itemId . replace ( 'item-' , '' ) ;
66
66
this . setState ( {
67
67
selectedIndex : index ,
@@ -81,7 +81,7 @@ class SLDSLookup extends React.Component {
81
81
handleClose ( ) {
82
82
this . setState ( {
83
83
isOpen :false ,
84
- activeIndex :null
84
+ focusIndex :null
85
85
} )
86
86
}
87
87
@@ -108,25 +108,25 @@ class SLDSLookup extends React.Component {
108
108
event . keyCode === KEYS . ESCAPE ? this . handleClose ( ) : this . handleClick ( ) ;
109
109
110
110
//If user hits tab key, move aria activedescendant to first menu item
111
- if ( event . keyCode === KEYS . TAB && this . state . activeIndex === null ) {
112
- this . setState ( { activeIndex : 0 } ) ;
111
+ if ( event . keyCode === KEYS . TAB && this . state . focusIndex === null ) {
112
+ this . setState ( { focusIndex : 0 } ) ;
113
113
EventUtil . trapImmediate ( event ) ;
114
114
}
115
115
//If user hits down key, advance aria activedescendant to next item
116
- else if ( event . keyCode === KEYS . DOWN && this . state . activeIndex !== null ) {
116
+ else if ( event . keyCode === KEYS . DOWN && this . state . focusIndex !== null ) {
117
117
EventUtil . trapImmediate ( event ) ;
118
118
this . increaseIndex ( ) ;
119
119
}
120
120
//If user hits up key, advance aria activedescendant to previous item
121
- else if ( event . keyCode === KEYS . UP && this . state . activeIndex !== null ) {
121
+ else if ( event . keyCode === KEYS . UP && this . state . focusIndex !== null ) {
122
122
EventUtil . trapImmediate ( event ) ;
123
123
this . decreaseIndex ( ) ;
124
124
}
125
125
126
126
//If user hits enter/space key, select current activedescendant item
127
- else if ( ( event . keyCode === KEYS . ENTER || event . keyCode === KEYS . SPACE ) && this . state . activeIndex !== null ) {
127
+ else if ( ( event . keyCode === KEYS . ENTER || event . keyCode === KEYS . SPACE ) && this . state . focusIndex !== null ) {
128
128
EventUtil . trapImmediate ( event ) ;
129
- this . selectItem ( this . state . activeItem ) ;
129
+ this . selectItem ( this . state . currentFocus ) ;
130
130
}
131
131
}
132
132
}
@@ -141,10 +141,10 @@ class SLDSLookup extends React.Component {
141
141
onSelect = { this . selectItem . bind ( this ) }
142
142
label = { this . props . label }
143
143
items = { this . props . items }
144
- setActiveDescendant = { this . setActiveDescendant . bind ( this ) }
144
+ setFocus = { this . setFocus . bind ( this ) }
145
145
getListLength = { this . getListLength . bind ( this ) }
146
146
listLength = { this . state . listLength }
147
- activeIndex = { this . state . activeIndex } /> ;
147
+ focusIndex = { this . state . focusIndex } /> ;
148
148
} else {
149
149
return null ;
150
150
}
@@ -169,11 +169,10 @@ class SLDSLookup extends React.Component {
169
169
170
170
render ( ) {
171
171
let inputClasses = this . state . selectedIndex === null ? 'slds-input' :'slds-input slds-hide' ;
172
- let compClasses = this . state . selectedIndex === null ? "slds-lookup ignore-react-onclickoutside" :"slds-lookup ignore-react-onclickoutside slds-has-selection" ;
173
- console . log ( 'activeIndex ' , this . state . activeIndex ) ;
172
+ let componentClasses = this . state . selectedIndex === null ? "slds-lookup ignore-react-onclickoutside" :"slds-lookup ignore-react-onclickoutside slds-has-selection" ;
174
173
175
174
return (
176
- < div className = { compClasses } data-select = "single" data-scope = "single" data-typeahead = "true" >
175
+ < div className = { componentClasses } data-select = "single" data-scope = "single" data-typeahead = "true" >
177
176
< section className = "slds-form-element" >
178
177
< label className = "slds-form-element__label" forHTML = "lookup" > { this . props . label } </ label >
179
178
@@ -187,7 +186,7 @@ class SLDSLookup extends React.Component {
187
186
aria-label = "lookup"
188
187
aria-haspopup = "true"
189
188
aria-autocomplete = "list"
190
- aria-activedescendant = { this . state . activeItem ? this . state . activeItem :"" }
189
+ aria-activedescendant = { this . state . currentFocus ? this . state . currentFocus :"" }
191
190
aria-expanded = { this . state . isOpen }
192
191
role = "combobox"
193
192
onChange = { this . handleChange . bind ( this ) }
@@ -205,11 +204,18 @@ class SLDSLookup extends React.Component {
205
204
}
206
205
}
207
206
207
+
208
+ SLDSLookup . propTypes = {
209
+ items : React . PropTypes . array ,
210
+ label : React . PropTypes . string ,
211
+ } ;
212
+
208
213
SLDSLookup . defaultProps = {
209
214
filterWith : defaultFilter ,
210
215
onItemSelect : function ( item ) {
211
- //console.log('onItemSelect should be defined');
216
+ //console.log('onItemSelect should be defined');
212
217
}
213
218
} ;
219
+
214
220
module . exports = SLDSLookup ;
215
221
0 commit comments