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

@charlietango/use-focus-trap

Package Overview
Dependencies
Maintainers
2
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@charlietango/use-focus-trap - npm Package Compare versions

Comparing version 1.2.9 to 1.2.10

6

CHANGELOG.md

@@ -6,2 +6,8 @@ # Change Log

## [1.2.10](https://github.com/charlie-tango/hooks/compare/@charlietango/use-focus-trap@1.2.9...@charlietango/use-focus-trap@1.2.10) (2020-01-29)
### Bug Fixes
- **useFocusTrap:** delay setting focus a single frame ([6e2f583](https://github.com/charlie-tango/hooks/commit/6e2f58307b30e235591baa70dcb98d1898476c46))
## [1.2.9](https://github.com/charlie-tango/hooks/compare/@charlietango/use-focus-trap@1.2.8...@charlietango/use-focus-trap@1.2.9) (2020-01-28)

@@ -8,0 +14,0 @@

5

lib/helpers/tabbable.d.ts

@@ -0,1 +1,2 @@

export declare const focusSelector = "a, input, select, textarea, button, object, [tabindex]";
export declare function focusable(element: HTMLElement): boolean | "";

@@ -7,5 +8,1 @@ export declare function tabbable(element: HTMLElement): boolean | "";

export declare function findTabbableDescendants(element: HTMLElement): Array<HTMLElement>;
/**
* Focusable elements are elements that can receive focus in one way or the other
* */
export declare function findFocusableDescendants(element: HTMLElement): Array<HTMLElement>;

71

lib/useFocusTrap.cjs.js

@@ -19,3 +19,3 @@ 'use strict';

var tabbableNode = /input|select|textarea|button|object/;
var selector = 'a, input, select, textarea, button, object, [tabindex]';
var focusSelector = 'a, input, select, textarea, button, object, [tabindex]';

@@ -62,12 +62,5 @@ function hidden(el) {

function findTabbableDescendants(element) {
return Array.from(element.querySelectorAll(selector)).filter(tabbable);
return Array.from(element.querySelectorAll(focusSelector)).filter(tabbable);
}
/**
* Focusable elements are elements that can receive focus in one way or the other
* */
function findFocusableDescendants(element) {
return Array.from(element.querySelectorAll(selector)).filter(focusable);
}
var focusLaterElements = [];

@@ -198,3 +191,8 @@ var focusElement = null;

var ref = react.useRef();
var restoreAria = react.useRef(null);
var setRef = react.useCallback(function (node) {
if (restoreAria.current) {
restoreAria.current();
}
if (ref.current) {

@@ -208,26 +206,43 @@ returnFocus();

markForFocusLater();
var focusElement = null;
if (options.focusSelector) {
focusElement = typeof options.focusSelector === 'string' ? node.querySelector(options.focusSelector) : options.focusSelector;
}
var processNode = function processNode(node) {
// See if we should disable aria
restoreAria.current = !options.disableAriaHider ? createAriaHider(node) : null; // Find the initial focus element
if (!focusElement) {
var children = findTabbableDescendants(node); // If no tabbable children are found, see if we can find an element that can receive focus instead
var focusElement = null;
if (!children.length) children = findFocusableDescendants(node);
if (options.focusSelector) {
focusElement = typeof options.focusSelector === 'string' ? node.querySelector(options.focusSelector) : options.focusSelector;
}
if (children.length) {
focusElement = children[0];
if (!focusElement) {
var children = Array.from(node.querySelectorAll(focusSelector));
focusElement = // Prefer tabbable elements, But fallback to any focusable element
children.find(tabbable) || // But fallback to any focusable element
children.find(focusable) || // Nothing found
null; // If everything else fails, see if the node itself can handle focus
if (!focusElement && focusable(node)) focusElement = node;
}
}
if (!focusElement && focusable(node)) {
focusElement = node;
}
if (focusElement) {
// Set the initial focus inside the traps
focusElement.focus();
} else {
if (process.env.NODE_ENV === 'development') {
// eslint-disable-next-line no-console
console.warn('[useFocusTrap]: Failed to find a focusable element after activating the focus trap. Make sure to include at an element that can recieve focus. As a fallback, you can also set "tabIndex={-1}" on the focus trap node.', node);
}
}
}; // Delay processing the HTML node by a frame. This ensures focus is assigned correctly.
if (focusElement) {
focusElement.focus();
}
setTimeout(function () {
if (node.ownerDocument) {
processNode(node);
} else if (process.env.NODE_ENV === 'development') {
// eslint-disable-next-line no-console
console.warn('[useFocusTrap]: The focus trap is not part of the DOM yet, so it is unable to correctly set focus. Make sure to render the ref node.', node);
}
});
ref.current = node;

@@ -237,3 +252,3 @@ } else {

}
}, [active, options.focusSelector]);
}, [active, options.focusSelector, options.disableAriaHider]);
react.useEffect(function () {

@@ -248,9 +263,7 @@ if (!active) return undefined;

var restoreAria = ref.current && !options.disableAriaHider ? createAriaHider(ref.current) : undefined;
document.addEventListener('keydown', handleKeyDown);
return function () {
document.removeEventListener('keydown', handleKeyDown);
if (restoreAria) restoreAria();
};
}, [active, options.disableAriaHider]);
}, [active]);
return setRef;

@@ -257,0 +270,0 @@ }

@@ -15,3 +15,3 @@ import { useRef, useCallback, useEffect } from 'react';

var tabbableNode = /input|select|textarea|button|object/;
var selector = 'a, input, select, textarea, button, object, [tabindex]';
var focusSelector = 'a, input, select, textarea, button, object, [tabindex]';

@@ -58,12 +58,5 @@ function hidden(el) {

function findTabbableDescendants(element) {
return Array.from(element.querySelectorAll(selector)).filter(tabbable);
return Array.from(element.querySelectorAll(focusSelector)).filter(tabbable);
}
/**
* Focusable elements are elements that can receive focus in one way or the other
* */
function findFocusableDescendants(element) {
return Array.from(element.querySelectorAll(selector)).filter(focusable);
}
var focusLaterElements = [];

@@ -194,3 +187,8 @@ var focusElement = null;

var ref = useRef();
var restoreAria = useRef(null);
var setRef = useCallback(function (node) {
if (restoreAria.current) {
restoreAria.current();
}
if (ref.current) {

@@ -204,26 +202,43 @@ returnFocus();

markForFocusLater();
var focusElement = null;
if (options.focusSelector) {
focusElement = typeof options.focusSelector === 'string' ? node.querySelector(options.focusSelector) : options.focusSelector;
}
var processNode = function processNode(node) {
// See if we should disable aria
restoreAria.current = !options.disableAriaHider ? createAriaHider(node) : null; // Find the initial focus element
if (!focusElement) {
var children = findTabbableDescendants(node); // If no tabbable children are found, see if we can find an element that can receive focus instead
var focusElement = null;
if (!children.length) children = findFocusableDescendants(node);
if (options.focusSelector) {
focusElement = typeof options.focusSelector === 'string' ? node.querySelector(options.focusSelector) : options.focusSelector;
}
if (children.length) {
focusElement = children[0];
if (!focusElement) {
var children = Array.from(node.querySelectorAll(focusSelector));
focusElement = // Prefer tabbable elements, But fallback to any focusable element
children.find(tabbable) || // But fallback to any focusable element
children.find(focusable) || // Nothing found
null; // If everything else fails, see if the node itself can handle focus
if (!focusElement && focusable(node)) focusElement = node;
}
}
if (!focusElement && focusable(node)) {
focusElement = node;
}
if (focusElement) {
// Set the initial focus inside the traps
focusElement.focus();
} else {
if (process.env.NODE_ENV === 'development') {
// eslint-disable-next-line no-console
console.warn('[useFocusTrap]: Failed to find a focusable element after activating the focus trap. Make sure to include at an element that can recieve focus. As a fallback, you can also set "tabIndex={-1}" on the focus trap node.', node);
}
}
}; // Delay processing the HTML node by a frame. This ensures focus is assigned correctly.
if (focusElement) {
focusElement.focus();
}
setTimeout(function () {
if (node.ownerDocument) {
processNode(node);
} else if (process.env.NODE_ENV === 'development') {
// eslint-disable-next-line no-console
console.warn('[useFocusTrap]: The focus trap is not part of the DOM yet, so it is unable to correctly set focus. Make sure to render the ref node.', node);
}
});
ref.current = node;

@@ -233,3 +248,3 @@ } else {

}
}, [active, options.focusSelector]);
}, [active, options.focusSelector, options.disableAriaHider]);
useEffect(function () {

@@ -244,9 +259,7 @@ if (!active) return undefined;

var restoreAria = ref.current && !options.disableAriaHider ? createAriaHider(ref.current) : undefined;
document.addEventListener('keydown', handleKeyDown);
return function () {
document.removeEventListener('keydown', handleKeyDown);
if (restoreAria) restoreAria();
};
}, [active, options.disableAriaHider]);
}, [active]);
return setRef;

@@ -253,0 +266,0 @@ }

{
"name": "@charlietango/use-focus-trap",
"description": "Trap keyboard focus inside a DOM element, to prevent the user navigating outside a modal",
"version": "1.2.9",
"version": "1.2.10",
"private": false,

@@ -41,3 +41,3 @@ "sideEffects": false,

},
"gitHead": "55c2d9eaed9ea775bc9b8f0627b55780d251d5ca"
"gitHead": "8bf83428b83f8104c0ccc60509b9097162f37603"
}
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