@@ -3,6 +3,7 @@ import React from 'react';
33import ReactDOM from 'react-dom' ;
44import { act } from 'react-dom/test-utils' ;
55import simulant from 'simulant' ;
6+ import { activeElement } from 'dom-helpers' ;
67import Dropdown from '../src/Dropdown' ;
78
89describe ( '<Dropdown>' , ( ) => {
@@ -15,20 +16,21 @@ describe('<Dropdown>', () => {
1516 } ) => (
1617 < Dropdown . Menu
1718 flip
18- popperConfig = { popperConfig }
1919 usePopper = { usePopper }
20+ popperConfig = { popperConfig }
2021 rootCloseEvent = { rootCloseEvent }
2122 >
22- { ( args ) => {
23- renderSpy && renderSpy ( args ) ;
24- const { show, close, props : menuProps } = args ;
23+ { ( menuProps , meta ) => {
24+ const { show, toggle } = meta ;
25+ renderSpy && renderSpy ( meta ) ;
26+
2527 return (
2628 < div
2729 { ...props }
2830 { ...menuProps }
2931 data-show = { show }
3032 className = "menu"
31- onClick = { close }
33+ onClick = { ( ) => toggle ( false ) }
3234 style = { { display : show ? 'flex' : 'none' } }
3335 />
3436 ) ;
@@ -38,39 +40,46 @@ describe('<Dropdown>', () => {
3840
3941 const Toggle = ( props ) => (
4042 < Dropdown . Toggle >
41- { ( { toggle , props : toggleProps } ) => (
43+ { ( toggleProps ) => (
4244 < button
4345 { ...props }
4446 { ...toggleProps }
4547 id = "test-id"
4648 type = "button"
4749 className = "toggle"
48- onClick = { toggle }
4950 />
5051 ) }
5152 </ Dropdown . Toggle >
5253 ) ;
5354
5455 const SimpleDropdown = ( { children, menuSpy, usePopper, ...outer } ) => (
5556 < Dropdown { ...outer } >
56- { ( { props } ) => (
57- < div tabIndex = "-1" { ...props } >
58- { children || (
59- < >
60- < Toggle key = "toggle" > Child Title</ Toggle > ,
61- < Menu key = "menu" renderSpy = { menuSpy } usePopper = { usePopper } >
62- < button type = "button" > Item 1</ button >
63- < button type = "button" > Item 2</ button >
64- < button type = "button" > Item 3</ button >
65- < button type = "button" > Item 4</ button >
66- </ Menu >
67- </ >
68- ) }
69- </ div >
57+ { children || (
58+ < >
59+ < Toggle key = "toggle" > Child Title</ Toggle > ,
60+ < Menu key = "menu" renderSpy = { menuSpy } usePopper = { usePopper } >
61+ < button type = "button" > Item 1</ button >
62+ < button type = "button" > Item 2</ button >
63+ < button type = "button" > Item 3</ button >
64+ < button type = "button" > Item 4</ button >
65+ </ Menu >
66+ </ >
7067 ) }
7168 </ Dropdown >
7269 ) ;
7370
71+ let focusableContainer ;
72+
73+ beforeEach ( ( ) => {
74+ focusableContainer = document . createElement ( 'div' ) ;
75+ document . body . appendChild ( focusableContainer ) ;
76+ } ) ;
77+
78+ afterEach ( ( ) => {
79+ ReactDOM . unmountComponentAtNode ( focusableContainer ) ;
80+ document . body . removeChild ( focusableContainer ) ;
81+ } ) ;
82+
7483 it ( 'renders toggle with Dropdown.Toggle' , ( ) => {
7584 const buttonNode = mount ( < SimpleDropdown /> )
7685 . assertSingle ( 'button.toggle' )
@@ -84,8 +93,8 @@ describe('<Dropdown>', () => {
8493 } ) ;
8594
8695 it ( 'forwards alignEnd to menu' , ( ) => {
87- const renderSpy = sinon . spy ( ( args ) => {
88- args . alignEnd . should . equal ( true ) ;
96+ const renderSpy = sinon . spy ( ( meta ) => {
97+ meta . alignEnd . should . equal ( true ) ;
8998 } ) ;
9099
91100 mount (
@@ -108,6 +117,7 @@ describe('<Dropdown>', () => {
108117 wrapper . assertSingle ( 'ReactOverlaysDropdown' ) ;
109118
110119 wrapper . assertSingle ( 'div[data-show=true]' ) ;
120+
111121 wrapper . assertSingle ( 'button[aria-expanded=true]' ) . simulate ( 'click' ) ;
112122
113123 wrapper . assertNone ( '.show' ) ;
@@ -135,15 +145,13 @@ describe('<Dropdown>', () => {
135145
136146 const wrapper = mount (
137147 < Dropdown onToggle = { closeSpy } id = "test-id" >
138- { ( ) => (
139- < div >
140- < Toggle > Child Title</ Toggle > ,
141- < Menu rootCloseEvent = "mousedown" >
142- < button type = "button" > Item 1</ button >
143- < button type = "button" > Item 2</ button >
144- </ Menu >
145- </ div >
146- ) }
148+ < div >
149+ < Toggle > Child Title</ Toggle > ,
150+ < Menu rootCloseEvent = "mousedown" >
151+ < button type = "button" > Item 1</ button >
152+ < button type = "button" > Item 2</ button >
153+ </ Menu >
154+ </ div >
147155 </ Dropdown > ,
148156 ) ;
149157
@@ -160,11 +168,13 @@ describe('<Dropdown>', () => {
160168 } ) ;
161169
162170 it ( 'when focused and closed toggles open when the key "down" is pressed' , ( ) => {
163- const wrapper = mount ( < SimpleDropdown /> ) ;
171+ const wrapper = mount ( < SimpleDropdown /> , { attachTo : focusableContainer } ) ;
164172
165- wrapper . find ( '.toggle' ) . simulate ( 'keyDown' , { key : 'ArrowDown' } ) ;
173+ simulant . fire ( wrapper . find ( '.toggle' ) . getDOMNode ( ) , 'keydown' , {
174+ key : 'ArrowDown' ,
175+ } ) ;
166176
167- wrapper . assertSingle ( 'ReactOverlaysDropdownMenu div' ) ;
177+ wrapper . update ( ) . assertSingle ( 'ReactOverlaysDropdownMenu div' ) ;
168178 } ) ;
169179
170180 it ( 'closes when item is clicked' , ( ) => {
@@ -207,29 +217,15 @@ describe('<Dropdown>', () => {
207217 } ) ;
208218
209219 describe ( 'focusable state' , ( ) => {
210- let focusableContainer ;
211-
212- beforeEach ( ( ) => {
213- focusableContainer = document . createElement ( 'div' ) ;
214- document . body . appendChild ( focusableContainer ) ;
215- } ) ;
216-
217- afterEach ( ( ) => {
218- ReactDOM . unmountComponentAtNode ( focusableContainer ) ;
219- document . body . removeChild ( focusableContainer ) ;
220- } ) ;
221-
222220 it ( 'when focus should not be moved to first item when focusFirstItemOnShow is `false`' , ( ) => {
223221 const wrapper = mount (
224222 < Dropdown focusFirstItemOnShow = { false } >
225- { ( { props } ) => (
226- < div { ...props } >
227- < Toggle > Child Title</ Toggle > ,
228- < Menu >
229- < button type = "button" > Item 1</ button >
230- </ Menu >
231- </ div >
232- ) }
223+ < div >
224+ < Toggle > Child Title</ Toggle > ,
225+ < Menu >
226+ < button type = "button" > Item 1</ button >
227+ </ Menu >
228+ </ div >
233229 </ Dropdown > ,
234230 { attachTo : focusableContainer } ,
235231 ) ;
@@ -244,40 +240,39 @@ describe('<Dropdown>', () => {
244240 it ( 'when focused and closed sets focus on first menu item when the key "down" is pressed for role="menu"' , ( ) => {
245241 const wrapper = mount (
246242 < Dropdown >
247- { ( { props } ) => (
248- < div { ...props } >
249- < Toggle > Child Title</ Toggle > ,
250- < Menu role = "menu" >
251- < button type = "button" > Item 1</ button >
252- < button type = "button" > Item 2</ button >
253- </ Menu >
254- </ div >
255- ) }
243+ < div >
244+ < Toggle > Child Title</ Toggle > ,
245+ < Menu role = "menu" >
246+ < button type = "button" > Item 1</ button >
247+ < button type = "button" > Item 2</ button >
248+ </ Menu >
249+ </ div >
256250 </ Dropdown > ,
257251 { attachTo : focusableContainer } ,
258252 ) ;
259253
260- wrapper . find ( '.toggle' ) . getDOMNode ( ) . focus ( ) ;
254+ const toggle = wrapper . find ( '.toggle' ) . getDOMNode ( ) ;
255+ toggle . focus ( ) ;
261256
262- wrapper . find ( '.toggle' ) . simulate ( 'keyDown' , { key : 'ArrowDown' } ) ;
257+ simulant . fire ( toggle , 'keydown' , {
258+ key : 'ArrowDown' ,
259+ } ) ;
263260
264261 document . activeElement . should . equal (
265- wrapper . find ( '.menu > button' ) . first ( ) . getDOMNode ( ) ,
262+ wrapper . update ( ) . find ( '.menu > button' ) . first ( ) . getDOMNode ( ) ,
266263 ) ;
267264 } ) ;
268265
269266 it ( 'when focused and closed sets focus on first menu item when the focusFirstItemOnShow is true' , ( ) => {
270267 const wrapper = mount (
271268 < Dropdown focusFirstItemOnShow >
272- { ( { props } ) => (
273- < div { ...props } >
274- < Toggle > Child Title</ Toggle > ,
275- < Menu >
276- < button type = "button" > Item 1</ button >
277- < button type = "button" > Item 2</ button >
278- </ Menu >
279- </ div >
280- ) }
269+ < div >
270+ < Toggle > Child Title</ Toggle > ,
271+ < Menu >
272+ < button type = "button" > Item 1</ button >
273+ < button type = "button" > Item 2</ button >
274+ </ Menu >
275+ </ div >
281276 </ Dropdown > ,
282277 { attachTo : focusableContainer } ,
283278 ) ;
@@ -296,39 +291,42 @@ describe('<Dropdown>', () => {
296291 attachTo : focusableContainer ,
297292 } ) ;
298293
299- const firstItem = wrapper . find ( '.menu > button' ) . first ( ) ;
294+ const firstItem = wrapper . find ( '.menu > button' ) . first ( ) . getDOMNode ( ) ;
300295
301- firstItem . getDOMNode ( ) . focus ( ) ;
302- document . activeElement . should . equal ( firstItem . getDOMNode ( ) ) ;
296+ firstItem . focus ( ) ;
297+ document . activeElement . should . equal ( firstItem ) ;
303298
304- firstItem . simulate ( 'keyDown' , { key : 'Escape' } ) ;
299+ act ( ( ) => {
300+ simulant . fire ( firstItem , 'keydown' , {
301+ key : 'Escape' ,
302+ } ) ;
303+ } ) ;
305304
306- document . activeElement . should . equal ( wrapper . find ( '.toggle' ) . getDOMNode ( ) ) ;
305+ console . log ( document . activeElement ) ;
306+ document . activeElement . should . equal (
307+ wrapper . update ( ) . find ( '.toggle' ) . getDOMNode ( ) ,
308+ ) ;
307309 } ) ;
308310
309- it ( 'when open and the key "tab" is pressed the menu is closed and focus is progress to the next focusable element' , ( done ) => {
311+ it ( 'when open and the key "tab" is pressed the menu is closed and focus is progress to the next focusable element' , ( ) => {
310312 const wrapper = mount (
311313 < div >
312314 < SimpleDropdown defaultShow />
313315 < input type = "text" id = "next-focusable" />
314316 </ div > ,
315- focusableContainer ,
317+ { attachTo : focusableContainer } ,
316318 ) ;
317319
318- // Need to use Container instead of div above to make instance a composite
319- // element, to make this call legal.
320+ const toggle = wrapper . find ( '.toggle' ) . getDOMNode ( ) ;
320321
321- wrapper . find ( '. toggle' ) . simulate ( 'keyDown' , { key : 'Tab' } ) ;
322+ toggle . focus ( ) ;
322323
323- setTimeout ( ( ) => {
324- wrapper
325- . find ( '.toggle' )
326- . getDOMNode ( )
327- . getAttribute ( 'aria-expanded' )
328- . should . equal ( 'false' ) ;
329- done ( ) ;
324+ simulant . fire ( toggle , 'keydown' , {
325+ key : 'Tab' ,
330326 } ) ;
331327
328+ toggle . getAttribute ( 'aria-expanded' ) . should . equal ( 'false' ) ;
329+
332330 // simulating a tab event doesn't actually shift focus.
333331 // at least that seems to be the case according to SO.
334332 // hence no assert on the input having focus.
@@ -351,15 +349,13 @@ describe('<Dropdown>', () => {
351349
352350 mount (
353351 < Dropdown show id = "test-id" >
354- { ( ) => (
355- < div >
356- < Toggle > Child Title</ Toggle >
357- < Menu popperConfig = { popper } >
358- < button type = "button" > Item 1</ button >
359- < button type = "button" > Item 2</ button >
360- </ Menu >
361- </ div >
362- ) }
352+ < div >
353+ < Toggle > Child Title</ Toggle >
354+ < Menu popperConfig = { popper } >
355+ < button type = "button" > Item 1</ button >
356+ < button type = "button" > Item 2</ button >
357+ </ Menu >
358+ </ div >
363359 </ Dropdown > ,
364360 ) ;
365361
0 commit comments