@@ -7,16 +7,17 @@ import { useFocusAway } from '../use-focus-away';
7
7
describe ( 'useFocusAway' , ( ) => {
8
8
let handler ;
9
9
10
- const events = [ new Event ( 'focus' ) ] ;
11
-
12
10
// Create a fake component to mount in tests that uses the hook
13
11
function FakeComponent ( { enabled = true } ) {
14
12
const myRef = useRef ( ) ;
15
13
const hookOpts = enabled === true ? undefined : { enabled } ;
16
14
useFocusAway ( myRef , handler , hookOpts ) ;
17
15
return (
18
- < div ref = { myRef } >
19
- < button > Hi</ button >
16
+ < div >
17
+ < button data-testid = "outer-button" > Hi</ button >
18
+ < div ref = { myRef } data-testid = "container" >
19
+ < button data-testid = "inner-button" > Hi</ button >
20
+ </ div >
20
21
</ div >
21
22
) ;
22
23
}
@@ -25,45 +26,62 @@ describe('useFocusAway', () => {
25
26
return mount ( < FakeComponent { ...props } /> ) ;
26
27
}
27
28
29
+ function getContainer ( wrapper ) {
30
+ return wrapper . find ( '[data-testid="container"]' ) . getDOMNode ( ) ;
31
+ }
32
+
33
+ function getOuterButton ( wrapper ) {
34
+ return wrapper . find ( '[data-testid="outer-button"]' ) . getDOMNode ( ) ;
35
+ }
36
+
37
+ function getInnerButton ( wrapper ) {
38
+ return wrapper . find ( '[data-testid="inner-button"]' ) . getDOMNode ( ) ;
39
+ }
40
+
28
41
beforeEach ( ( ) => {
29
42
handler = sinon . stub ( ) ;
30
43
} ) ;
31
44
32
- events . forEach ( event => {
33
- it ( `should invoke callback once for events outside of element (${ event . type } )` , ( ) => {
34
- const wrapper = createComponent ( ) ;
35
-
45
+ it ( 'should invoke callback when focus moves outside of container' , ( ) => {
46
+ const wrapper = createComponent ( ) ;
47
+ const focusOut = ( ) =>
36
48
act ( ( ) => {
37
- document . body . dispatchEvent ( event ) ;
49
+ getInnerButton ( wrapper ) . dispatchEvent (
50
+ new FocusEvent ( 'focusout' , {
51
+ bubbles : true ,
52
+ relatedTarget : getOuterButton ( wrapper ) ,
53
+ } ) ,
54
+ ) ;
38
55
} ) ;
39
- wrapper . update ( ) ;
40
56
41
- assert . calledOnce ( handler ) ;
57
+ focusOut ( ) ;
58
+ wrapper . update ( ) ;
42
59
43
- // Update the component to change it and re-execute the hook
44
- wrapper . setProps ( { enabled : false } ) ;
60
+ assert . calledOnce ( handler ) ;
45
61
46
- act ( ( ) => {
47
- document . body . dispatchEvent ( new Event ( 'focus' ) ) ;
48
- } ) ;
62
+ // Update the component to change it and re-execute the hook
63
+ wrapper . setProps ( { enabled : false } ) ;
49
64
50
- // Cleanup of hook should have removed eventListeners, so the callback
51
- // is not called again
52
- assert . calledOnce ( handler ) ;
53
- } ) ;
54
- } ) ;
65
+ focusOut ( ) ;
55
66
56
- events . forEach ( event => {
57
- it ( `should not invoke callback on events inside of container ( ${ event . type } )` , ( ) => {
58
- const wrapper = createComponent ( ) ;
59
- const button = wrapper . find ( 'button' ) ;
67
+ // Cleanup of hook should have removed eventListeners, so the callback
68
+ // is not called again
69
+ assert . calledOnce ( handler ) ;
70
+ } ) ;
60
71
61
- act ( ( ) => {
62
- button . getDOMNode ( ) . dispatchEvent ( event ) ;
63
- } ) ;
64
- wrapper . update ( ) ;
72
+ it ( 'should not invoke callback when focus moves inside of container' , ( ) => {
73
+ const wrapper = createComponent ( ) ;
65
74
66
- assert . equal ( handler . callCount , 0 ) ;
75
+ act ( ( ) => {
76
+ getContainer ( wrapper ) . dispatchEvent (
77
+ new FocusEvent ( 'focusout' , {
78
+ bubbles : true ,
79
+ relatedTarget : getInnerButton ( wrapper ) ,
80
+ } ) ,
81
+ ) ;
67
82
} ) ;
83
+ wrapper . update ( ) ;
84
+
85
+ assert . notCalled ( handler ) ;
68
86
} ) ;
69
87
} ) ;
0 commit comments