@@ -46,13 +46,13 @@ class Dropdown extends React.Component {
46
46
} ] ;
47
47
48
48
this . state = { } ;
49
+
50
+ this . lastOpenEventType = null ;
51
+ this . isKeyboardClick = false ;
49
52
}
50
53
51
54
componentDidMount ( ) {
52
- let menu = this . refs . menu ;
53
- if ( this . props . open && menu . focusNext ) {
54
- menu . focusNext ( ) ;
55
- }
55
+ this . focusNextOnOpen ( ) ;
56
56
}
57
57
58
58
componentWillUpdate ( nextProps ) {
@@ -65,10 +65,8 @@ class Dropdown extends React.Component {
65
65
}
66
66
67
67
componentDidUpdate ( prevProps ) {
68
- let menu = this . refs . menu ;
69
-
70
- if ( this . props . open && ! prevProps . open && menu . focusNext ) {
71
- menu . focusNext ( ) ;
68
+ if ( this . props . open && ! prevProps . open ) {
69
+ this . focusNextOnOpen ( ) ;
72
70
}
73
71
74
72
if ( ! this . props . open && prevProps . open ) {
@@ -105,9 +103,13 @@ class Dropdown extends React.Component {
105
103
) ;
106
104
}
107
105
108
- toggleOpen ( ) {
106
+ toggleOpen ( eventType = null ) {
109
107
let open = ! this . props . open ;
110
108
109
+ if ( open ) {
110
+ this . lastOpenEventType = eventType ;
111
+ }
112
+
111
113
if ( this . props . onToggle ) {
112
114
this . props . onToggle ( open ) ;
113
115
}
@@ -118,29 +120,32 @@ class Dropdown extends React.Component {
118
120
return ;
119
121
}
120
122
121
- this . toggleOpen ( ) ;
123
+ this . toggleOpen ( this . isKeyboardClick ? 'keydown' : 'click' ) ;
124
+ this . isKeyboardClick = false ;
122
125
}
123
126
124
127
handleKeyDown ( event ) {
125
- let focusNext = ( ) => {
126
- if ( this . refs . menu . focusNext ) {
127
- this . refs . menu . focusNext ( ) ;
128
- }
129
- } ;
128
+ if ( this . props . disabled ) {
129
+ return ;
130
+ }
130
131
131
132
switch ( event . keyCode ) {
132
133
case keycode . codes . down :
133
134
if ( ! this . props . open ) {
134
- this . toggleOpen ( ) ;
135
- } else {
136
- focusNext ( ) ;
135
+ this . toggleOpen ( 'keydown' ) ;
136
+ } else if ( this . refs . menu . focusNext ) {
137
+ this . refs . menu . focusNext ( ) ;
137
138
}
138
139
event . preventDefault ( ) ;
139
140
break ;
140
141
case keycode . codes . esc :
141
142
case keycode . codes . tab :
142
143
this . handleClose ( event ) ;
143
144
break ;
145
+ case keycode . codes . space :
146
+ case keycode . codes . enter :
147
+ this . isKeyboardClick = true ;
148
+ break ;
144
149
default :
145
150
}
146
151
}
@@ -153,6 +158,20 @@ class Dropdown extends React.Component {
153
158
this . toggleOpen ( ) ;
154
159
}
155
160
161
+ focusNextOnOpen ( ) {
162
+ const { menu} = this . refs ;
163
+ if ( ! menu . focusNext ) {
164
+ return ;
165
+ }
166
+
167
+ if (
168
+ this . lastOpenEventType === 'keydown' ||
169
+ this . props . alwaysFocusNextOnOpen
170
+ ) {
171
+ menu . focusNext ( ) ;
172
+ }
173
+ }
174
+
156
175
focus ( ) {
157
176
let toggle = React . findDOMNode ( this . refs [ TOGGLE_REF ] ) ;
158
177
@@ -232,7 +251,8 @@ Dropdown.TOGGLE_ROLE = TOGGLE_ROLE;
232
251
Dropdown . MENU_ROLE = MENU_ROLE ;
233
252
234
253
Dropdown . defaultProps = {
235
- componentClass : ButtonGroup
254
+ componentClass : ButtonGroup ,
255
+ alwaysFocusNextOnOpen : false
236
256
} ;
237
257
238
258
Dropdown . propTypes = {
@@ -270,7 +290,7 @@ Dropdown.propTypes = {
270
290
disabled : React . PropTypes . bool ,
271
291
272
292
/**
273
- * Align the menu to the right side of the Dropdown toggle
293
+ * Align the menu to the right side of the Dropdown toggle
274
294
*/
275
295
pullRight : React . PropTypes . bool ,
276
296
@@ -304,7 +324,12 @@ Dropdown.propTypes = {
304
324
* function(Object event, Any eventKey)
305
325
* ```
306
326
*/
307
- onSelect : React . PropTypes . func
327
+ onSelect : React . PropTypes . func ,
328
+
329
+ /**
330
+ * Focus first menu item on menu open on all events, not just keydown events.
331
+ */
332
+ alwaysFocusNextOnOpen : React . PropTypes . bool
308
333
} ;
309
334
310
335
Dropdown = uncontrollable ( Dropdown , { open : 'onToggle' } ) ;
0 commit comments