react-focus-lock
Advanced tools
Comparing version 1.7.0 to 1.8.0
@@ -7,2 +7,4 @@ 'use strict'; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
@@ -24,4 +26,8 @@ | ||
var _focusLock = require('focus-lock'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -108,2 +114,4 @@ | ||
value: function render() { | ||
var _lockProps; | ||
var _props = this.props, | ||
@@ -115,3 +123,4 @@ children = _props.children, | ||
autoFocus = _props.autoFocus, | ||
allowTextSelection = _props.allowTextSelection; | ||
allowTextSelection = _props.allowTextSelection, | ||
group = _props.group; | ||
var observed = this.state.observed; | ||
@@ -125,2 +134,4 @@ | ||
var lockProps = (_lockProps = {}, _defineProperty(_lockProps, _focusLock.constants.FOCUS_DISABLED, disabled && "disabled"), _defineProperty(_lockProps, _focusLock.constants.FOCUS_GROUP, group), _lockProps); | ||
return _react2.default.createElement( | ||
@@ -133,5 +144,5 @@ Fragment, | ||
'div', | ||
{ | ||
_extends({ | ||
ref: this.setObserveNode | ||
}, | ||
}, lockProps), | ||
_react2.default.createElement( | ||
@@ -165,4 +176,5 @@ _Trap2.default, | ||
autoFocus: _propTypes2.default.bool, | ||
persistentFocus: _propTypes2.default.bool | ||
persistentFocus: _propTypes2.default.bool, | ||
group: _propTypes2.default.string | ||
}; | ||
@@ -176,5 +188,6 @@ | ||
persistentFocus: false, | ||
allowTextSelection: undefined | ||
allowTextSelection: undefined, | ||
group: undefined | ||
}; | ||
exports.default = FocusLock; |
@@ -33,2 +33,15 @@ 'use strict'; | ||
var lastActiveFocus = null; | ||
var lastPortaledElement = null; | ||
var recordPortal = function recordPortal(observerNode, portaledElement) { | ||
lastPortaledElement = [portaledElement, observerNode]; | ||
}; | ||
var isPortaledPair = function isPortaledPair(element, observed) { | ||
return lastPortaledElement && lastPortaledElement[0] === element && (0, _focusLock.getAllAffectedNodes)(observed).reduce(function (result, node) { | ||
return result || node.contains(lastPortaledElement[1]); | ||
}, false); | ||
}; | ||
var activateTrap = function activateTrap() { | ||
@@ -45,12 +58,14 @@ var result = false; | ||
if (persistentFocus || !focusOnBody() || !lastActiveFocus && autoFocus) { | ||
if (observed && !(0, _focusLock.focusInside)(observed)) { | ||
onActivation(); | ||
if (document && !lastActiveFocus && document.activeElement && !autoFocus) { | ||
document.activeElement.blur(); | ||
document.body.focus(); | ||
} else { | ||
result = (0, _focusLock2.default)(observed, lastActiveFocus); | ||
if (!isPortaledPair(document && document.activeElement, observed)) { | ||
if (observed && !(0, _focusLock.focusInside)(observed)) { | ||
onActivation(); | ||
if (document && !lastActiveFocus && document.activeElement && !autoFocus) { | ||
document.activeElement.blur(); | ||
document.body.focus(); | ||
} else { | ||
result = (0, _focusLock2.default)(observed, lastActiveFocus); | ||
} | ||
} | ||
lastActiveFocus = document && document.activeElement; | ||
} | ||
lastActiveFocus = document && document.activeElement; | ||
} | ||
@@ -73,2 +88,11 @@ } | ||
var onFocus = function onFocus(event) { | ||
// detect portal | ||
var source = event.target; | ||
var currentNode = event.currentTarget; | ||
if (!currentNode.contains(source)) { | ||
recordPortal(currentNode, source); | ||
} | ||
}; | ||
var FocusTrap = function FocusTrap(_ref) { | ||
@@ -78,3 +102,3 @@ var children = _ref.children; | ||
'div', | ||
{ onBlur: onBlur }, | ||
{ onBlur: onBlur, onFocus: onFocus }, | ||
children | ||
@@ -81,0 +105,0 @@ ); |
{ | ||
"name": "react-focus-lock", | ||
"version": "1.7.0", | ||
"version": "1.8.0", | ||
"description": "It is a trap! (for a focus)", | ||
@@ -50,4 +50,5 @@ "main": "dist/index.js", | ||
"chai": "^4.1.0", | ||
"chai-enzyme": "^0.8.0", | ||
"enzyme": "^2.9.1", | ||
"chai-enzyme": "^1.0.0-beta.0", | ||
"enzyme": "^3.3.0", | ||
"enzyme-adapter-react-16": "^1.1.1", | ||
"eslint": "^4.2.0", | ||
@@ -63,6 +64,7 @@ "eslint-config-airbnb": "15.1.0", | ||
"package-self": "^1.1.1", | ||
"react": "^15.6.1", | ||
"react-dom": "^15.6.1", | ||
"react": "^16.2.0", | ||
"react-compat": "^0.0.1", | ||
"react-dom": "^16.2.0", | ||
"react-hot-loader": "^3.0.0-beta.7", | ||
"react-test-renderer": "^15.6.1", | ||
"react-test-renderer": "^16.2.0", | ||
"sinon": "3.2.1", | ||
@@ -73,6 +75,6 @@ "size-limit": "^0.14.1" | ||
"dependencies": { | ||
"focus-lock": "^0.1.0", | ||
"prop-types": "^15.5.10", | ||
"focus-lock": "^0.2.0", | ||
"prop-types": "^15.0.0", | ||
"react-side-effect": "^1.1.3" | ||
} | ||
} |
@@ -14,3 +14,12 @@ # react-focus-lock | ||
You have to use it in _every_ modal dialog, or you `a11y` will be shitty. | ||
This is most comprehensive focus lock/trap ever built. | ||
# Features | ||
- no keyboard control, everything is done watching a __focus behavior__. Thus works always and everywhere. | ||
- React __Portals__ support. Even if some data is in outerspace - it is [still in lock](https://github.com/theKashey/react-focus-lock/issues/19). | ||
- _Scattered_ locks, or focus lock groups - you can setup different isolated locks, and _tab_ from from to another. | ||
- Controllable isolation level. | ||
# How to use | ||
@@ -47,2 +56,3 @@ Just wrap something with focus lock, and focus will be `moved inside` on mount. | ||
- `noFocusGuards` disabled _focus guards_ - virtual inputs which secure tab index. | ||
- `group` named focus group for focus scattering aka [combined lock targets](https://github.com/theKashey/vue-focus-lock/issues/2) | ||
@@ -49,0 +59,0 @@ # Behavior |
@@ -15,2 +15,3 @@ import React from 'react'; | ||
import JumpCase from './Jump'; | ||
import GroupCase from './Group'; | ||
@@ -45,1 +46,4 @@ const frameStyle = { | ||
storiesOf('Group', module) | ||
.add('focus group', () => <Frame><GroupCase /></Frame>); | ||
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
39266
18
962
118
31
+ Addedfocus-lock@0.2.4(transitive)
- Removedfocus-lock@0.1.0(transitive)
Updatedfocus-lock@^0.2.0
Updatedprop-types@^15.0.0