1
1
import * as React from 'react' ;
2
2
import PropTypes from 'prop-types' ;
3
3
import withSideEffect from 'react-clientside-effect' ;
4
- import moveFocusInside , { focusInside , focusIsHidden , getFocusabledIn } from 'focus-lock' ;
5
- import { deferAction } from './util' ;
6
- import { mediumFocus , mediumBlur , mediumEffect } from './medium' ;
4
+ import moveFocusInside , { focusInside , focusIsHidden , getFocusabledIn } from 'focus-lock' ;
5
+ import { deferAction } from './util' ;
6
+ import { mediumFocus , mediumBlur , mediumEffect } from './medium' ;
7
7
8
8
const focusOnBody = ( ) => (
9
9
document && document . activeElement === document . body
@@ -25,7 +25,7 @@ const focusWhitelisted = activeElement => (
25
25
) ;
26
26
27
27
const recordPortal = ( observerNode , portaledElement ) => {
28
- lastPortaledElement = { observerNode, portaledElement } ;
28
+ lastPortaledElement = { observerNode, portaledElement} ;
29
29
} ;
30
30
31
31
const focusIsPortaledPair = element => (
@@ -58,11 +58,20 @@ function autoGuard(startIndex, end, step, allNodes) {
58
58
59
59
const extractRef = ref => ( ( ref && 'current' in ref ) ? ref . current : ref ) ;
60
60
61
+ const focusWasOutside = ( crossFrameOption ) => {
62
+ if ( crossFrameOption ) {
63
+ // with cross frame return true for any value
64
+ return Boolean ( focusWasOutsideWindow ) ;
65
+ }
66
+ // in other case return only of focus went a while aho
67
+ return focusWasOutsideWindow === "meanwhile"
68
+ }
69
+
61
70
const activateTrap = ( ) => {
62
71
let result = false ;
63
72
if ( lastActiveTrap ) {
64
73
const {
65
- observed, persistentFocus, autoFocus, shards,
74
+ observed, persistentFocus, autoFocus, shards, crossFrame ,
66
75
} = lastActiveTrap ;
67
76
const workingNode = observed || ( lastPortaledElement && lastPortaledElement . portaledElement ) ;
68
77
const activeElement = document && document . activeElement ;
@@ -74,7 +83,7 @@ const activateTrap = () => {
74
83
75
84
if ( ! activeElement || focusWhitelisted ( activeElement ) ) {
76
85
if (
77
- ( persistentFocus || focusWasOutsideWindow )
86
+ ( persistentFocus || focusWasOutside ( crossFrame ) )
78
87
|| ! isFreeFocus ( )
79
88
|| ( ! lastActiveFocus && autoFocus )
80
89
) {
@@ -101,12 +110,12 @@ const activateTrap = () => {
101
110
if ( document ) {
102
111
const newActiveElement = document && document . activeElement ;
103
112
const allNodes = getFocusabledIn ( workingArea ) ;
104
- const focusedItem = allNodes . find ( ( { node } ) => node === newActiveElement ) ;
113
+ const focusedItem = allNodes . find ( ( { node} ) => node === newActiveElement ) ;
105
114
if ( focusedItem ) {
106
115
// remove old focus
107
116
allNodes
108
- . filter ( ( { guard, node } ) => guard && node . dataset . focusAutoGuard )
109
- . forEach ( ( { node } ) => node . removeAttribute ( 'tabIndex' ) ) ;
117
+ . filter ( ( { guard, node} ) => guard && node . dataset . focusAutoGuard )
118
+ . forEach ( ( { node} ) => node . removeAttribute ( 'tabIndex' ) ) ;
110
119
111
120
const focusedIndex = allNodes . indexOf ( focusedItem ) ;
112
121
autoGuard ( focusedIndex , allNodes . length , + 1 , allNodes ) ;
@@ -141,7 +150,7 @@ const onFocus = (event) => {
141
150
142
151
const FocusWatcher = ( ) => null ;
143
152
144
- const FocusTrap = ( { children } ) => (
153
+ const FocusTrap = ( { children} ) => (
145
154
< div onBlur = { onBlur } onFocus = { onFocus } >
146
155
{ children }
147
156
</ div >
@@ -152,7 +161,11 @@ FocusTrap.propTypes = {
152
161
} ;
153
162
154
163
const onWindowBlur = ( ) => {
155
- focusWasOutsideWindow = true ;
164
+ focusWasOutsideWindow = "just" ;
165
+ // using setTimeout to set this variable after React/sidecar reaction
166
+ setTimeout ( ( ) => {
167
+ focusWasOutsideWindow = "meanwhile" ;
168
+ } , 0 ) ;
156
169
} ;
157
170
158
171
const attachHandler = ( ) => {
@@ -169,7 +182,7 @@ const detachHandler = () => {
169
182
170
183
function reducePropsToState ( propsList ) {
171
184
return propsList
172
- . filter ( ( { disabled } ) => ! disabled ) ;
185
+ . filter ( ( { disabled} ) => ! disabled ) ;
173
186
}
174
187
175
188
function handleStateChangeOnClient ( traps ) {
@@ -186,7 +199,7 @@ function handleStateChangeOnClient(traps) {
186
199
if ( lastTrap && ! sameTrap ) {
187
200
lastTrap . onDeactivation ( ) ;
188
201
// return focus only of last trap was removed
189
- if ( ! traps . filter ( ( { id } ) => id === lastTrap . id ) . length ) {
202
+ if ( ! traps . filter ( ( { id } ) => id === lastTrap . id ) . length ) {
190
203
// allow defer is no other trap is awaiting restore
191
204
lastTrap . returnFocus ( ! trap ) ;
192
205
}
0 commit comments