+
}
);
@@ -144,7 +144,7 @@ FocusLock.propTypes = {
className: PropTypes.string,
whiteList: PropTypes.func,
- shards: PropTypes.arrayOf(PropTypes.shape({current: PropTypes.instanceOf(Element)})),
+ shards: PropTypes.arrayOf(PropTypes.shape({ current: PropTypes.instanceOf(Element) })),
as: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.object]),
lockProps: PropTypes.object,
@@ -166,6 +166,7 @@ FocusLock.defaultProps = {
shards: undefined,
as: 'div',
lockProps: {},
+
onActivation: undefined,
onDeactivation: undefined,
};
diff --git a/src/Trap.js b/src/Trap.js
index 11c6524..07120fd 100644
--- a/src/Trap.js
+++ b/src/Trap.js
@@ -1,8 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import withSideEffect from 'react-clientside-effect';
-import moveFocusInside, {focusInside, focusIsHidden, getFocusabledIn} from 'focus-lock';
-import {deferAction} from './util';
+import moveFocusInside, { focusInside, focusIsHidden, getFocusabledIn } from 'focus-lock';
+import { deferAction } from './util';
const focusOnBody = () => (
document && document.activeElement === document.body
@@ -22,7 +22,7 @@ const focusWhitelisted = activeElement => (
);
const recordPortal = (observerNode, portaledElement) => {
- lastPortaledElement = {observerNode, portaledElement};
+ lastPortaledElement = { observerNode, portaledElement };
};
const focusIsPortaledPair = element => (
@@ -47,14 +47,19 @@ function autoGuard(startIndex, end, step, allNodes) {
}
}
+const extractRef = ref => ((ref && 'current' in ref) ? ref.current : ref);
+
const activateTrap = () => {
let result = false;
if (lastActiveTrap) {
- const {observed, persistentFocus, autoFocus, shards} = lastActiveTrap;
+ const { observed, persistentFocus, autoFocus, shards } = lastActiveTrap;
const workingNode = observed || (lastPortaledElement && lastPortaledElement.portaledElement);
const activeElement = document && document.activeElement;
if (workingNode) {
- const workingArea = [workingNode, ...shards.map(({current}) => current)];
+ const workingArea = [
+ workingNode,
+ ...shards.map(extractRef).filter(Boolean),
+ ];
if (!activeElement || focusWhitelisted(activeElement)) {
if (persistentFocus || !isFreeFocus() || (!lastActiveFocus && autoFocus)) {
@@ -80,12 +85,12 @@ const activateTrap = () => {
if (document) {
const newActiveElement = document && document.activeElement;
const allNodes = getFocusabledIn(workingArea);
- const focusedItem = allNodes.find(({node}) => node === newActiveElement);
+ const focusedItem = allNodes.find(({ node }) => node === newActiveElement);
if (focusedItem) {
// remove old focus
allNodes
- .filter(({guard, node}) => guard && node.dataset.focusAutoGuard)
- .forEach(({node}) => node.removeAttribute('tabIndex'));
+ .filter(({ guard, node }) => guard && node.dataset.focusAutoGuard)
+ .forEach(({ node }) => node.removeAttribute('tabIndex'));
const focusedIndex = allNodes.indexOf(focusedItem);
autoGuard(focusedIndex, allNodes.length, +1, allNodes);
@@ -120,7 +125,7 @@ export const onFocus = (event) => {
const FocusWatcher = () => null;
-const FocusTrap = ({children}) => (
+const FocusTrap = ({ children }) => (
{children}
@@ -140,10 +145,9 @@ const detachHandler = () => {
document.removeEventListener('focusout', onBlur);
};
-
function reducePropsToState(propsList) {
return propsList
- .filter(({disabled}) => !disabled)
+ .filter(({ disabled }) => !disabled)
.slice(-1)[0];
}
diff --git a/stories/index.js b/stories/index.js
index 2329c0f..47998ba 100644
--- a/stories/index.js
+++ b/stories/index.js
@@ -17,7 +17,7 @@ import {PortalCase, ShardPortalCase} from './Portal';
import {MUISelect, MUISelectWhite} from './MUI';
import Fight from './FocusFighting';
import {StyledComponent, StyledSection} from "./Custom";
-import {DisabledForm, DisabledFormWithTabIndex} from "./Disabled";
+import {AutoDisabledForm, DisabledForm, DisabledFormWithTabIndex} from "./Disabled";
const frameStyle = {
width: '400px',