@@ -46,13 +46,13 @@ class Dropdown extends React.Component {
4646 } ] ;
4747
4848 this . state = { } ;
49+
50+ this . lastOpenEventType = null ;
51+ this . isKeyboardClick = false ;
4952 }
5053
5154 componentDidMount ( ) {
52- let menu = this . refs . menu ;
53- if ( this . props . open && menu . focusNext ) {
54- menu . focusNext ( ) ;
55- }
55+ this . focusNextOnOpen ( ) ;
5656 }
5757
5858 componentWillUpdate ( nextProps ) {
@@ -65,10 +65,8 @@ class Dropdown extends React.Component {
6565 }
6666
6767 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 ( ) ;
7270 }
7371
7472 if ( ! this . props . open && prevProps . open ) {
@@ -105,9 +103,13 @@ class Dropdown extends React.Component {
105103 ) ;
106104 }
107105
108- toggleOpen ( ) {
106+ toggleOpen ( eventType = null ) {
109107 let open = ! this . props . open ;
110108
109+ if ( open ) {
110+ this . lastOpenEventType = eventType ;
111+ }
112+
111113 if ( this . props . onToggle ) {
112114 this . props . onToggle ( open ) ;
113115 }
@@ -118,29 +120,32 @@ class Dropdown extends React.Component {
118120 return ;
119121 }
120122
121- this . toggleOpen ( ) ;
123+ this . toggleOpen ( this . isKeyboardClick ? 'keydown' : 'click' ) ;
124+ this . isKeyboardClick = false ;
122125 }
123126
124127 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+ }
130131
131132 switch ( event . keyCode ) {
132133 case keycode . codes . down :
133134 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 ( ) ;
137138 }
138139 event . preventDefault ( ) ;
139140 break ;
140141 case keycode . codes . esc :
141142 case keycode . codes . tab :
142143 this . handleClose ( event ) ;
143144 break ;
145+ case keycode . codes . space :
146+ case keycode . codes . enter :
147+ this . isKeyboardClick = true ;
148+ break ;
144149 default :
145150 }
146151 }
@@ -153,6 +158,20 @@ class Dropdown extends React.Component {
153158 this . toggleOpen ( ) ;
154159 }
155160
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+
156175 focus ( ) {
157176 let toggle = React . findDOMNode ( this . refs [ TOGGLE_REF ] ) ;
158177
@@ -232,7 +251,8 @@ Dropdown.TOGGLE_ROLE = TOGGLE_ROLE;
232251Dropdown . MENU_ROLE = MENU_ROLE ;
233252
234253Dropdown . defaultProps = {
235- componentClass : ButtonGroup
254+ componentClass : ButtonGroup ,
255+ alwaysFocusNextOnOpen : false
236256} ;
237257
238258Dropdown . propTypes = {
@@ -270,7 +290,7 @@ Dropdown.propTypes = {
270290 disabled : React . PropTypes . bool ,
271291
272292 /**
273- * Align the menu to the right side of the Dropdown toggle
293+ * Align the menu to the right side of the Dropdown toggle
274294 */
275295 pullRight : React . PropTypes . bool ,
276296
@@ -304,7 +324,12 @@ Dropdown.propTypes = {
304324 * function(Object event, Any eventKey)
305325 * ```
306326 */
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
308333} ;
309334
310335Dropdown = uncontrollable ( Dropdown , { open : 'onToggle' } ) ;
0 commit comments