react-focus-on
Version:
The final solution for WAI ARIA compatible modal dialogs or full-screen tasks.
103 lines (102 loc) • 4.04 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Effect = void 0;
var tslib_1 = require("tslib");
var React = require("react");
var aria_hidden_1 = require("aria-hidden");
var InteractivityDisabler_1 = require("./InteractivityDisabler");
var medium_1 = require("./medium");
var react_1 = require("react");
var extractRef = function (ref) {
return 'current' in ref ? ref.current : ref;
};
function Effect(_a) {
var setLockProps = _a.setLockProps, onEscapeKey = _a.onEscapeKey, onClickOutside = _a.onClickOutside, shards = _a.shards, onActivation = _a.onActivation, onDeactivation = _a.onDeactivation, noIsolation = _a.noIsolation, activeNode = _a.activeNode;
var lastEventTarget = react_1.useRef(null);
var mouseTouches = react_1.useRef(0);
React.useEffect(function () {
var onKeyDown = function (event) {
if (!event.defaultPrevented) {
if ((event.code === 'Escape' ||
event.key === 'Escape' ||
event.keyCode === 27) &&
onEscapeKey) {
onEscapeKey(event);
}
}
};
var onMouseDown = function (event) {
if (event.defaultPrevented ||
event.target === lastEventTarget.current ||
(event instanceof MouseEvent && event.button !== 0)) {
return;
}
if (shards &&
shards
.map(extractRef)
.some(function (node) {
return (node && node.contains(event.target)) ||
node === event.target;
})) {
return;
}
if (onClickOutside) {
onClickOutside(event);
}
};
var onTouchStart = function (event) {
onMouseDown(event);
mouseTouches.current = event.touches.length;
};
var onTouchEnd = function (event) {
mouseTouches.current = event.touches.length;
};
if (activeNode) {
activeNode.ownerDocument.addEventListener('keydown', onKeyDown);
activeNode.ownerDocument.addEventListener('mousedown', onMouseDown);
activeNode.ownerDocument.addEventListener('touchstart', onTouchStart);
activeNode.ownerDocument.addEventListener('touchend', onTouchEnd);
return function () {
activeNode.ownerDocument.removeEventListener('keydown', onKeyDown);
activeNode.ownerDocument.removeEventListener('mousedown', onMouseDown);
activeNode.ownerDocument.removeEventListener('touchstart', onTouchStart);
activeNode.ownerDocument.removeEventListener('touchend', onTouchEnd);
};
}
return;
}, [activeNode, onClickOutside, onEscapeKey]);
react_1.useEffect(function () {
if (activeNode) {
if (onActivation) {
onActivation(activeNode);
}
return function () {
if (onDeactivation) {
onDeactivation();
}
};
}
return;
}, [!!activeNode]);
react_1.useEffect(function () {
if (noIsolation || !activeNode) {
return;
}
return aria_hidden_1.hideOthers(tslib_1.__spreadArrays([activeNode], (shards || []).map(extractRef)), activeNode.ownerDocument.body, medium_1.focusHiddenMarker);
}, [activeNode, noIsolation]);
react_1.useEffect(function () {
setLockProps({
onMouseDown: function (e) {
lastEventTarget.current = e.target;
},
onTouchStart: function (e) {
lastEventTarget.current = e.target;
},
});
return function () {
setLockProps(false);
};
}, []);
return React.createElement(InteractivityDisabler_1.InteractivityDisabler, null);
}
exports.Effect = Effect;