react-focus-lock
Advanced tools
Comparing version 1.1.2 to 1.3.2
@@ -8,17 +8,2 @@ import React, {Component} from 'react'; | ||
/* | ||
render true | ||
deactivate d-action2 | ||
render false | ||
✓ Should return focus (58ms) | ||
render true | ||
deactivate d-action2 | ||
render false | ||
1) Should return focus | ||
*/ | ||
describe('react-focus-lock', () => { | ||
@@ -65,3 +50,3 @@ | ||
it('Should return focus', (done) => { | ||
it('Should return focus to the original place', (done) => { | ||
class Test extends Component { | ||
@@ -228,2 +213,58 @@ state = { | ||
if (1) | ||
it('Should return focus on escape', (done) => { | ||
const wrapper = mount(<div> | ||
<div> | ||
text | ||
<button className="action1">action1</button> | ||
<button className="action1-1">action1-skip</button> | ||
<button className="action1-1">action1-skip-</button> | ||
text | ||
</div> | ||
<FocusLock> | ||
<button className="action2">button-action</button> | ||
<button>6-action3</button> | ||
<button>6-action4</button> | ||
</FocusLock> | ||
</div>, mountPoint); | ||
expect(document.activeElement.innerHTML).to.be.equal('button-action'); | ||
setTimeout(()=> { | ||
wrapper.find('.action1').simulate('focus'); | ||
wrapper.find('.action1').getDOMNode().focus(); | ||
expect(document.activeElement.innerHTML).to.be.equal('action1'); | ||
wrapper.find('.action2').simulate('blur'); | ||
setTimeout(() => { | ||
expect(document.activeElement.innerHTML).to.be.equal('button-action'); | ||
done(); | ||
}, 10); | ||
},1); | ||
}); | ||
it('Should roll focus on escape', (done) => { | ||
const wrapper = mount(<div> | ||
<div> | ||
text | ||
<button className="action1">action1</button> | ||
text | ||
</div> | ||
<FocusLock> | ||
<button className="action2">button-action</button> | ||
<button>6-action3</button> | ||
<button>6-action4</button> | ||
</FocusLock> | ||
</div>, mountPoint); | ||
expect(document.activeElement.innerHTML).to.be.equal('button-action'); | ||
setTimeout(()=> { | ||
wrapper.find('.action1').simulate('focus'); | ||
wrapper.find('.action1').getDOMNode().focus(); | ||
expect(document.activeElement.innerHTML).to.be.equal('action1'); | ||
wrapper.find('.action2').simulate('blur'); | ||
setTimeout(() => { | ||
expect(document.activeElement.innerHTML).to.be.equal('6-action4'); | ||
done(); | ||
}, 10); | ||
},1); | ||
}); | ||
/**/ | ||
}); | ||
@@ -230,0 +271,0 @@ |
import {expect} from 'chai'; | ||
import tabSort from '../src/tabOrder'; | ||
import { tabSort, orderByTabIndex} from '../src/utils/tabOrder'; | ||
@@ -5,0 +5,0 @@ const r = (tabIndex, index, key) => ({tabIndex, index, key}); |
{ | ||
"name": "react-focus-lock", | ||
"version": "1.1.2", | ||
"version": "1.3.2", | ||
"description": "It is a trap! (for a focus)", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -27,12 +27,9 @@ import React, { PropTypes, Component } from 'react'; | ||
onTrapBlur = () => | ||
// first focus leaves node, next it lands somewhere.... | ||
setImmediate(() => | ||
this.setState(prevState => ({ | ||
escapeAttempts: prevState.escapeAttempts + 1, | ||
})), | ||
); | ||
setImmediate(this.update); | ||
onTrapFocus = () => this.update(); | ||
onActivation = () => { | ||
this.originalFocusedElement = this.originalFocusedElement || document.activeElement; | ||
} | ||
}; | ||
@@ -44,2 +41,7 @@ setObserveNode = observed => | ||
update =() => | ||
this.setState(prevState => ({ | ||
escapeAttempts: prevState.escapeAttempts + 1, | ||
})); | ||
originalFocusedElement = null; | ||
@@ -61,2 +63,3 @@ | ||
onBlur={this.onTrapBlur} | ||
onFocus={this.onTrapFocus} | ||
onActivation={this.onActivation} | ||
@@ -63,0 +66,0 @@ > |
@@ -1,40 +0,3 @@ | ||
import tabbables from './tabbables'; | ||
import tabSort from './tabOrder'; | ||
import getFocusMerge from './utils/focusMerge'; | ||
const isElementHidden = computedStyle => ( | ||
computedStyle.getPropertyValue('display') === 'none' || | ||
computedStyle.getPropertyValue('visibility') === 'hidden' | ||
); | ||
const isVisible = node => ( | ||
(!node || node === document) || | ||
( | ||
!isElementHidden(window.getComputedStyle(node, null)) && | ||
isVisible(node.parentNode) | ||
) | ||
); | ||
const notHiddenInput = node => | ||
node.tagName !== 'INPUT' && node.type !== 'hidden'; | ||
const findFocusable = nodes => | ||
[...nodes] | ||
.filter(node => isVisible(node)) | ||
.filter(node => notHiddenInput(node)); | ||
const orderByTabIndex = nodes => | ||
nodes | ||
.map((node, index) => ({ | ||
node, | ||
index, | ||
tabIndex: node.tabIndex, | ||
})) | ||
.filter(data => data.tabIndex >= 0) | ||
.sort(tabSort); | ||
export const getTabbableNodes = topNode => | ||
orderByTabIndex( | ||
findFocusable(topNode.querySelectorAll(tabbables.join(','))), | ||
); | ||
export const focusOn = (target) => { | ||
@@ -47,4 +10,4 @@ target.focus(); | ||
export default (topNode) => { | ||
const focusable = getTabbableNodes(topNode)[0]; | ||
export default (topNode, lastNode) => { | ||
const focusable = getFocusMerge(topNode, lastNode); | ||
@@ -51,0 +14,0 @@ if (focusable) { |
@@ -1,2 +0,3 @@ | ||
import { getTabbableNodes, focusOn } from './setFocus'; | ||
import { focusOn } from './setFocus'; | ||
import { getTabbableNodes } from './utils/focusMerge'; | ||
@@ -3,0 +4,0 @@ let target; |
import React, { PropTypes } from 'react'; | ||
import withSideEffect from 'react-side-effect'; | ||
import focusInside from './focusInside'; | ||
import focusInside from './utils/focusInside'; | ||
import moveFocusInside from './setFocus'; | ||
import tabHook from './tabHook'; | ||
const FocusTrap = ({ children, onBlur }) => ( | ||
<div onBlur={onBlur}> | ||
const FocusTrap = ({ children, onBlur, onFocus }) => ( | ||
<div onBlur={onBlur} onFocus={onFocus}> | ||
{children} | ||
@@ -15,2 +15,3 @@ </div> | ||
onBlur: PropTypes.func.isRequired, | ||
onFocus: PropTypes.func.isRequired, | ||
children: PropTypes.node.isRequired, | ||
@@ -20,2 +21,3 @@ }; | ||
let lastActiveTrap = 0; | ||
let lastActiveFocus = null; | ||
const activateTrap = () => { | ||
@@ -26,4 +28,5 @@ if (lastActiveTrap) { | ||
onActivation(); | ||
moveFocusInside(observed); | ||
moveFocusInside(observed, lastActiveFocus); | ||
} | ||
lastActiveFocus = document.activeElement; | ||
} | ||
@@ -46,2 +49,3 @@ }; | ||
tabHook.detach(); | ||
lastActiveFocus = null; | ||
} | ||
@@ -48,0 +52,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
147956
22
625