Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-focus-lock

Package Overview
Dependencies
Maintainers
1
Versions
106
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 1.18.3 to 1.19.0

CHANGELOG.md

14

dist/cjs/Lock.js

@@ -100,5 +100,7 @@ "use strict";

(0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "setObserveNode", function (observed) {
return _this.setState({
observed: observed
});
if (_this.state.observed !== observed) {
_this.setState({
observed: observed
});
}
});

@@ -148,3 +150,5 @@ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "isActive", false);

var lockProps = (0, _objectSpread3.default)((_objectSpread2 = {}, (0, _defineProperty2.default)(_objectSpread2, _focusLock.constants.FOCUS_DISABLED, disabled && 'disabled'), (0, _defineProperty2.default)(_objectSpread2, _focusLock.constants.FOCUS_GROUP, group), _objectSpread2), containerProps);
return _react.default.createElement(Fragment, null, !noFocusGuards && [_react.default.createElement("div", {
var hasLeadingGuards = noFocusGuards !== true;
var hasTailingGuards = hasLeadingGuards && noFocusGuards !== 'tail';
return _react.default.createElement(Fragment, null, hasLeadingGuards && [_react.default.createElement("div", {
key: "guard-first",

@@ -175,3 +179,3 @@ "data-focus-guard": true,

onDeactivation: this.onDeactivation
}), children), !noFocusGuards && _react.default.createElement("div", {
}), children), hasTailingGuards && _react.default.createElement("div", {
"data-focus-guard": true,

@@ -178,0 +182,0 @@ tabIndex: disabled ? -1 : 0,

@@ -35,2 +35,3 @@ "use strict";

var lastPortaledElement = null;
var focusWasOutsideWindow = false;

@@ -104,3 +105,3 @@ var defaultWhitelist = function defaultWhitelist() {

if (!activeElement || focusWhitelisted(activeElement)) {
if (persistentFocus || !isFreeFocus() || !lastActiveFocus && autoFocus) {
if (persistentFocus || focusWasOutsideWindow || !isFreeFocus() || !lastActiveFocus && autoFocus) {
if (workingNode && !((0, _focusLock.focusInside)(workingArea) || focusIsPortaledPair(activeElement, workingNode))) {

@@ -114,2 +115,4 @@ if (document && !lastActiveFocus && activeElement && !autoFocus) {

}
focusWasOutsideWindow = false;
}

@@ -192,5 +195,10 @@

var onWindowBlur = function onWindowBlur() {
focusWasOutsideWindow = true;
};
var attachHandler = function attachHandler() {
document.addEventListener('focusin', onTrap, true);
document.addEventListener('focusout', onBlur);
window.addEventListener('blur', onWindowBlur);
};

@@ -201,2 +209,3 @@

document.removeEventListener('focusout', onBlur);
window.removeEventListener('blur', onWindowBlur);
};

@@ -203,0 +212,0 @@

@@ -73,5 +73,7 @@ import _extends from "@babel/runtime/helpers/extends";

_defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "setObserveNode", function (observed) {
return _this.setState({
observed: observed
});
if (_this.state.observed !== observed) {
_this.setState({
observed: observed
});
}
});

@@ -126,3 +128,5 @@

return React.createElement(Fragment, null, !noFocusGuards && [React.createElement("div", {
var hasLeadingGuards = noFocusGuards !== true;
var hasTailingGuards = hasLeadingGuards && noFocusGuards !== 'tail';
return React.createElement(Fragment, null, hasLeadingGuards && [React.createElement("div", {
key: "guard-first",

@@ -153,3 +157,3 @@ "data-focus-guard": true,

onDeactivation: this.onDeactivation
}), children), !noFocusGuards && React.createElement("div", {
}), children), hasTailingGuards && React.createElement("div", {
"data-focus-guard": true,

@@ -156,0 +160,0 @@ tabIndex: disabled ? -1 : 0,

@@ -18,2 +18,3 @@ import React from 'react';

var lastPortaledElement = null;
var focusWasOutsideWindow = false;

@@ -87,3 +88,3 @@ var defaultWhitelist = function defaultWhitelist() {

if (!activeElement || focusWhitelisted(activeElement)) {
if (persistentFocus || !isFreeFocus() || !lastActiveFocus && autoFocus) {
if (persistentFocus || focusWasOutsideWindow || !isFreeFocus() || !lastActiveFocus && autoFocus) {
if (workingNode && !(focusInside(workingArea) || focusIsPortaledPair(activeElement, workingNode))) {

@@ -97,2 +98,4 @@ if (document && !lastActiveFocus && activeElement && !autoFocus) {

}
focusWasOutsideWindow = false;
}

@@ -170,5 +173,10 @@

var onWindowBlur = function onWindowBlur() {
focusWasOutsideWindow = true;
};
var attachHandler = function attachHandler() {
document.addEventListener('focusin', onTrap, true);
document.addEventListener('focusout', onBlur);
window.addEventListener('blur', onWindowBlur);
};

@@ -179,2 +187,3 @@

document.removeEventListener('focusout', onBlur);
window.removeEventListener('blur', onWindowBlur);
};

@@ -181,0 +190,0 @@

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

@@ -22,3 +22,4 @@ "main": "dist/cjs/index.js",

"package-self": "package-self",
"size": "npm run build && size-limit"
"size": "npm run build && size-limit",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s"
},

@@ -37,3 +38,3 @@ "repository": {

"author": "theKashey <thekashey@gmail.com>",
"license": "ISC",
"license": "MIT",
"bugs": {

@@ -62,2 +63,3 @@ "url": "https://github.com/theKashey/react-focus-lock/issues"

"chai-enzyme": "^1.0.0-beta.0",
"conventional-changelog-cli": "^2.0.12",
"enzyme": "^3.3.0",

@@ -87,3 +89,3 @@ "enzyme-adapter-react-16": "^1.7.1",

"@babel/runtime": "^7.0.0",
"focus-lock": "^0.6.0",
"focus-lock": "^0.6.3",
"prop-types": "^15.6.2",

@@ -90,0 +92,0 @@ "react-clientside-effect": "^1.2.0"

@@ -36,3 +36,3 @@ declare module 'react-focus-lock' {

*/
noFocusGuards?: boolean;
noFocusGuards?: boolean | "tail";

@@ -39,0 +39,0 @@ /**

@@ -5,32 +5,38 @@ <div align="left">

The way to manage your focus.<br/>
The way to lock it inside.<br/>
The way to team up with a11y.<br/> <br/>
Make you site a better place. For everyone.<br/>
It is a trap! For:
- browser friendly focus lock<br/>
- matching your use cases<br/>
- trusted by best UI frameworks
[![CircleCI status](https://img.shields.io/circleci/project/github/theKashey/react-focus-lock/master.svg?style=flat-square)](https://circleci.com/gh/theKashey/react-focus-lock/tree/master)
[![npm](https://img.shields.io/npm/v/react-focus-lock.svg)](https://www.npmjs.com/package/react-focus-lock)
[![bundle size](https://badgen.net/bundlephobia/minzip/react-focus-lock)](https://bundlephobia.com/result?p=react-focus-lock)
![downloads](https://badgen.net/npm/dm/react-focus-lock)
<hr/>
</div>
It is a trap! We got your focus and will not let him out!
[![NPM](https://nodei.co/npm/react-focus-lock.png?downloads=true&stars=true)](https://nodei.co/npm/react-focus-lock/)
- Modal dialogs. You can not leave it with "Tab", ie do a "tab-out".
- Focused tasks. It will aways brings you back, as you can "lock" user inside a component.
- You have to lock _every_ modal dialog, that's what `a11y` is asking for.
This is a small library, but very useful for:
- Modal dialogs. You can not leave it with "Tab", ie do a "tab-out".
- Focused tasks. It will aways brings you back, as you can "lock" user inside a component.
### Trusted
Trusted by
[Atlassian AtlasKit](https://atlaskit.atlassian.com),
[ReachUI](https://ui.reach.tech/),
[SmoothUI](https://smooth-ui.smooth-code.com/),
[Storybook](https://storybook.js.org/)
and we will do out best to earn your trust to!
You have to lock _every_ modal dialog, that's what `a11y` is asking for.
And this is most comprehensive focus lock/trap ever built.
# Features
- no keyboard control, everything is done watching a __focus behavior__, not emulating it. 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).
- React __Portals__ support. Even if some data is in outer space - 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 one to another.
- Controllable isolation level.
> 💡 __focus__ locks is only the first part, there are also __scroll lock__ and __text-to-speech__ lock
you have to use to really "lock" the user.
Try [react-focus-on](https://github.com/theKashey/react-focus-on) to archive everything above, assembled in the right order.
# How to use

@@ -60,4 +66,6 @@ Just wrap something with focus lock, and focus will be `moved inside` on mount.

# API
FocusLock has few props to tune behavior
- `disabled`, to disable(enable) behavior without altering the tree.
> FocusLock would work perfectly even with no props set.
FocusLock has few props to tune behavior, all props are optional:
- `[disabled`, to disable(enable) behavior without altering the tree.
- `returnFocus`, to return focus into initial position on unmount(not disable).

@@ -67,10 +75,10 @@ > By default `returnFocus` is disabled, so FocusLock will not restore original focus on deactivation.

This is expected behavior for Modals, but it is better to implement it by your self.
- `persistentFocus`, default false, requires any element to be focused. This also disables text selections inside, and __outside__ focus lock.
- `autoFocus`, default true, enables or disables focusing into on Lock activation. If disabled Lock will blur an active focus.
- `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)
- `shards` an array of `ref` pointing to the nodes, which focus lock should consider and a part of it. This is another way focus scattering.
- `whiteList` you could _whitelist_ locations FocusLock should carry about. Everything outside it will ignore. For example - any modals.
- `as` if you need to change internal `div` element, to any other. Use ref forwarding to give FocusLock the node to work with.
- `lockProps` to pass any extra props (except className) to the internal wrapper.
- `persistentFocus=false`, requires any element to be focused. This also disables text selections inside, and __outside__ focus lock.
- `autoFocus=true`, enables or disables focusing into on Lock activation. If disabled Lock will blur an active focus.
- `noFocusGuards=false` 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)
- `shards=[]` an array of `ref` pointing to the nodes, which focus lock should consider and a part of it. This is another way focus scattering.
- `whiteList=fn` you could _whitelist_ locations FocusLock should carry about. Everything outside it will ignore. For example - any modals.
- `as='div'` if you need to change internal `div` element, to any other. Use ref forwarding to give FocusLock the node to work with.
- `lockProps={}` to pass any extra props (except className) to the internal wrapper.

@@ -104,14 +112,4 @@ ### Focusing in OSX (Safary/FireFox) is strange!

</FocusLock>
```
<FocusLock as="section">
<button>Click</button>
<button data-autofocus>will be focused</button>
</FocusLock>
<FocusLock as={AnotherComponent} lockProps={{anyProp: 4}}>
<button>Click</button>
<button data-autofocus>will be focused</button>
</FocusLock>
```
If there is more than one auto-focusable target - the first will be selected.

@@ -173,2 +171,16 @@ If it is a part of radio group, and __rest of radio group element are also autofocusable__(just put them into AutoFocusInside) -

### Using your own `Components`
You may use `as` prop to change _what_ Focus-Lock will render around `children`.
```js
<FocusLock as="section">
<button>Click</button>
<button data-autofocus>will be focused</button>
</FocusLock>
<FocusLock as={AnotherComponent} lockProps={{anyAnotherComponentProp: 4}}>
<button>Click</button>
<span>Hello there!</span>
</FocusLock>
```
### Guarding

@@ -183,10 +195,10 @@ As you may know - FocusLock is adding `Focus Guards` before and after lock to remove some side effects, like page scrolling.

// wrap with
<InFocusGuard>
<button>
<button />
</InFocusGuard>
//
// place before and after
<InFocusGuard />
<button>
<button />
<InFocusGuard />

@@ -196,3 +208,10 @@ ```

### Automatic potral discovery
#### Removing Tailing Guard
If only your modal is the last tabble element on the body - you might remove the Tailing Guard,
to allow user _tab_ into address bar.
```js
<InFocusGuard/>
<button />
// there is no "tailing" guard :)
```

@@ -199,0 +218,0 @@ # Unmounting and focus management

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc