🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

react-focus-lock

Package Overview
Dependencies
Maintainers
1
Versions
110
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-focus-lock - npm Package Compare versions

Comparing version

to
1.4.6

216

_tests/FocusLock.spec.js

@@ -147,68 +147,127 @@ import React, {Component} from 'react';

if (1)
it('Should be enabled only on last node', (done) => {
const wrapper = mount(<div>
<div>
text
<button className="action1">action1</button>
text
</div>
<FocusLock>
describe('order', () => {
if (1)
it('Should be enabled only on last node', (done) => {
const wrapper = mount(<div>
<div>
text
<button className="action2">3-action2</button>
<button className="action1">action1</button>
text
</div>
</FocusLock>
<FocusLock>
<FocusLock>
<div>
text
<button className="action2">3-action2</button>
text
</div>
</FocusLock>
<FocusLock>
<div>
text
<button className="action3">action3</button>
text
</div>
</FocusLock>
</div>, mountPoint);
wrapper.find('.action1').getDOMNode().focus();
expect(document.activeElement.innerHTML).to.be.equal('action1');
setTimeout(() => {
expect(document.activeElement.innerHTML).to.be.equal('action3');
done();
}, 1);
});
/**/
if (1)
it('Should handle disabled state', (done) => {
const wrapper = mount(<div>
<div>
text
<button className="action3">action3</button>
<button className="action1">action1</button>
text
</div>
</FocusLock>
</div>, mountPoint);
wrapper.find('.action1').getDOMNode().focus();
expect(document.activeElement.innerHTML).to.be.equal('action1');
setTimeout(() => {
expect(document.activeElement.innerHTML).to.be.equal('action3');
done();
}, 1);
});
/**/
<FocusLock>
<div>
text
<button className="action2">4-action2</button>
text
</div>
</FocusLock>
<FocusLock disabled>
<div>
text
<button className="action3">action3</button>
text
</div>
</FocusLock>
</div>, mountPoint);
wrapper.find('.action1').getDOMNode().focus();
expect(document.activeElement.innerHTML).to.be.equal('action1');
setTimeout(() => {
expect(document.activeElement.innerHTML).to.be.equal('4-action2');
done();
}, 1);
});
/**/
if (1)
it('Should handle disabled state', (done) => {
const wrapper = mount(<div>
<div>
text
<button className="action1">action1</button>
text
</div>
<FocusLock>
if (1)
it('Should not pick hidden input', (done) => {
const wrapper = mount(<div>
<div>
text
<button className="action2">4-action2</button>
<button className="action1">action1</button>
text
</div>
</FocusLock>
<FocusLock disabled>
<FocusLock>
<input type="hidden" className="action2"/>
<button style={{visibility: 'hidden'}}>hidden</button>
<div style={{display: 'none'}}>
<button className="action2">5-action3</button>
</div>
<button className="action2">5-action4</button>
</FocusLock>
</div>, mountPoint);
wrapper.find('.action1').getDOMNode().focus();
expect(document.activeElement.innerHTML).to.be.equal('action1');
setTimeout(() => {
expect(document.activeElement.innerHTML).to.be.equal('5-action4');
done();
}, 1);
});
/**/
});
describe('move', () => {
if (1)
it('Should return focus on escape', (done) => {
const wrapper = mount(<div>
<div>
text
<button className="action3">action3</button>
<button className="action1">action1</button>
<button className="action1-1">action1-skip</button>
<button className="action1-1">action1-skip-</button>
text
</div>
</FocusLock>
</div>, mountPoint);
wrapper.find('.action1').getDOMNode().focus();
expect(document.activeElement.innerHTML).to.be.equal('action1');
setTimeout(() => {
expect(document.activeElement.innerHTML).to.be.equal('4-action2');
done();
}, 1);
});
/**/
<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);
});
if (1)
it('Should not pick hidden input', (done) => {
it('Should roll focus on escape', (done) => {
const wrapper = mount(<div>

@@ -221,30 +280,2 @@ <div>

<FocusLock>
<input type="hidden" className="action2" />
<button style={{visibility:'hidden'}}>hidden</button>
<div style={{display: 'none'}}>
<button className="action2">5-action3</button>
</div>
<button className="action2">5-action4</button>
</FocusLock>
</div>, mountPoint);
wrapper.find('.action1').getDOMNode().focus();
expect(document.activeElement.innerHTML).to.be.equal('action1');
setTimeout(() => {
expect(document.activeElement.innerHTML).to.be.equal('5-action4');
done();
}, 1);
});
/**/
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>

@@ -256,3 +287,3 @@ <button>6-action3</button>

expect(document.activeElement.innerHTML).to.be.equal('button-action');
setTimeout(()=> {
setTimeout(() => {
wrapper.find('.action1').simulate('focus');

@@ -263,35 +294,10 @@ wrapper.find('.action1').getDOMNode().focus();

setTimeout(() => {
expect(document.activeElement.innerHTML).to.be.equal('button-action');
expect(document.activeElement.innerHTML).to.be.equal('6-action4');
done();
}, 10);
},1);
}, 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);
});
/**/
});

@@ -298,0 +304,0 @@

@@ -40,8 +40,3 @@ 'use strict';

return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = FocusLock.__proto__ || Object.getPrototypeOf(FocusLock)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
escapeAttempts: 0,
observed: undefined
}, _this.onTrapBlur = function () {
return setImmediate(_this.update);
}, _this.onTrapFocus = function () {
return _this.update();
}, _this.onActivation = function () {

@@ -81,7 +76,4 @@ _this.originalFocusedElement = _this.originalFocusedElement || document.activeElement;

children = _props.children,
disabled = _props.disabled,
sandboxed = _props.sandboxed;
var _state = this.state,
observed = _state.observed,
escapeAttempts = _state.escapeAttempts;
disabled = _props.disabled;
var observed = this.state.observed;

@@ -98,7 +90,3 @@ return _react2.default.createElement(

observed: observed,
escapeAttempts: escapeAttempts,
disabled: disabled,
sandboxed: sandboxed,
onBlur: this.onTrapBlur,
onFocus: this.onTrapFocus,
onActivation: this.onActivation

@@ -118,4 +106,3 @@ },

disabled: _react.PropTypes.bool,
returnFocus: _react.PropTypes.bool,
sandboxed: _react.PropTypes.bool
returnFocus: _react.PropTypes.bool
};

@@ -122,0 +109,0 @@

@@ -25,22 +25,6 @@ 'use strict';

var FocusTrap = function FocusTrap(_ref) {
var children = _ref.children,
onBlur = _ref.onBlur,
onFocus = _ref.onFocus;
return _react2.default.createElement(
'div',
{ onBlur: onBlur, onFocus: onFocus },
children
);
};
FocusTrap.propTypes = {
onBlur: _propTypes2.default.func.isRequired,
onFocus: _propTypes2.default.func.isRequired,
children: _propTypes2.default.node.isRequired
};
var lastActiveTrap = 0;
var lastActiveFocus = null;
var activateTrap = function activateTrap() {
var result = false;
if (lastActiveTrap) {

@@ -53,8 +37,43 @@ var _lastActiveTrap = lastActiveTrap,

onActivation();
(0, _focusLock2.default)(observed, lastActiveFocus);
result = (0, _focusLock2.default)(observed, lastActiveFocus);
}
lastActiveFocus = document.activeElement;
}
return result;
};
var onTrap = function onTrap(event) {
if (activateTrap() && event) {
// prevent scroll jump
event.preventDefault();
}
};
var onBlur = function onBlur() {
setImmediate(activateTrap);
};
var FocusTrap = function FocusTrap(_ref) {
var children = _ref.children;
return _react2.default.createElement(
'div',
{ onBlur: onBlur },
children
);
};
FocusTrap.propTypes = {
children: _propTypes2.default.node.isRequired
};
var attachHandler = function attachHandler() {
document.addEventListener('focusin', onTrap, true);
document.addEventListener('focusout', onBlur);
};
var detachHandler = function detachHandler() {
document.removeEventListener('focusin', onTrap, true);
document.removeEventListener('focusout', onBlur);
};
function reducePropsToState(propsList) {

@@ -68,9 +87,12 @@ return propsList.filter(function (_ref2) {

function handleStateChangeOnClient(trap) {
if (trap && !lastActiveTrap) {
attachHandler();
}
lastActiveTrap = trap;
if (trap) {
_focusLock.tabHook.attach(trap.observed, trap.sandboxed);
activateTrap();
setImmediate(activateTrap);
} else {
_focusLock.tabHook.detach();
detachHandler();
lastActiveFocus = null;

@@ -77,0 +99,0 @@ }

{
"name": "react-focus-lock",
"version": "1.3.6",
"version": "1.4.6",
"description": "It is a trap! (for a focus)",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -50,5 +50,3 @@ # react-focus-lock

- `returnFocus`, to return focus into initial position on unmount(not disable).
I strongly recommend you NOT to use this feature. But sometimes it might be usable.
- `sandboxed`, to override default tab behavior. Very usable if you have elements with non-zero tabindex inside.
As long it will alter default(and preferred) behavior - __NEVER__ use it unless you have to.
This is expected behavior for Modals, but it is better to implement it by your self.

@@ -55,0 +53,0 @@

@@ -6,3 +6,2 @@ import React, { PropTypes, Component } from 'react';

state = {
escapeAttempts: 0,
observed: undefined,

@@ -27,7 +26,2 @@ };

onTrapBlur = () =>
setImmediate(this.update);
onTrapFocus = () => this.update();
onActivation = () => {

@@ -50,4 +44,4 @@ this.originalFocusedElement = this.originalFocusedElement || document.activeElement;

render() {
const { children, disabled, sandboxed } = this.props;
const { observed, escapeAttempts } = this.state;
const { children, disabled } = this.props;
const { observed } = this.state;
return (

@@ -60,7 +54,3 @@ <div

observed={observed}
escapeAttempts={escapeAttempts}
disabled={disabled}
sandboxed={sandboxed}
onBlur={this.onTrapBlur}
onFocus={this.onTrapFocus}
onActivation={this.onActivation}

@@ -79,3 +69,2 @@ >

returnFocus: PropTypes.bool,
sandboxed: PropTypes.bool,
};

@@ -82,0 +71,0 @@

import React from 'react';
import PropTypes from 'prop-types';
import withSideEffect from 'react-side-effect';
import moveFocusInside, { focusInside, tabHook } from 'focus-lock';
import moveFocusInside, { focusInside } from 'focus-lock';
const FocusTrap = ({ children, onBlur, onFocus }) => (
<div onBlur={onBlur} onFocus={onFocus}>
{children}
</div>
);
FocusTrap.propTypes = {
onBlur: PropTypes.func.isRequired,
onFocus: PropTypes.func.isRequired,
children: PropTypes.node.isRequired,
};
let lastActiveTrap = 0;
let lastActiveFocus = null;
const activateTrap = () => {
let result = false;
if (lastActiveTrap) {

@@ -25,8 +14,41 @@ const { observed, onActivation } = lastActiveTrap;

onActivation();
moveFocusInside(observed, lastActiveFocus);
result = moveFocusInside(observed, lastActiveFocus);
}
lastActiveFocus = document.activeElement;
}
return result;
};
const onTrap = (event) => {
if (activateTrap() && event) {
// prevent scroll jump
event.preventDefault();
}
};
const onBlur = () => {
setImmediate(activateTrap);
};
const FocusTrap = ({ children }) => (
<div onBlur={onBlur}>
{children}
</div>
);
FocusTrap.propTypes = {
children: PropTypes.node.isRequired,
};
const attachHandler = () => {
document.addEventListener('focusin', onTrap, true);
document.addEventListener('focusout', onBlur);
};
const detachHandler = () => {
document.removeEventListener('focusin', onTrap, true);
document.removeEventListener('focusout', onBlur);
};
function reducePropsToState(propsList) {

@@ -39,9 +61,12 @@ return propsList

function handleStateChangeOnClient(trap) {
if (trap && !lastActiveTrap) {
attachHandler();
}
lastActiveTrap = trap;
if (trap) {
tabHook.attach(trap.observed, trap.sandboxed);
activateTrap();
setImmediate(activateTrap);
} else {
tabHook.detach();
detachHandler();
lastActiveFocus = null;

@@ -48,0 +73,0 @@ }