UNPKG

react-modal

Version:

Accessible modal dialog component for React.JS

96 lines (74 loc) 2.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = scopeTab; var _tabbable = require("./tabbable"); var _tabbable2 = _interopRequireDefault(_tabbable); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function getActiveElement() { var el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document; return el.activeElement.shadowRoot ? getActiveElement(el.activeElement.shadowRoot) : el.activeElement; } function scopeTab(node, event) { var tabbable = (0, _tabbable2.default)(node); if (!tabbable.length) { // Do nothing, since there are no elements that can receive focus. event.preventDefault(); return; } var target = void 0; var shiftKey = event.shiftKey; var head = tabbable[0]; var tail = tabbable[tabbable.length - 1]; var activeElement = getActiveElement(); // proceed with default browser behavior on tab. // Focus on last element on shift + tab. if (node === activeElement) { if (!shiftKey) return; target = tail; } if (tail === activeElement && !shiftKey) { target = head; } if (head === activeElement && shiftKey) { target = tail; } if (target) { event.preventDefault(); target.focus(); return; } // Safari radio issue. // // Safari does not move the focus to the radio button, // so we need to force it to really walk through all elements. // // This is very error prone, since we are trying to guess // if it is a safari browser from the first occurence between // chrome or safari. // // The chrome user agent contains the first ocurrence // as the 'chrome/version' and later the 'safari/version'. var checkSafari = /(\bChrome\b|\bSafari\b)\//.exec(navigator.userAgent); var isSafariDesktop = checkSafari != null && checkSafari[1] != "Chrome" && /\biPod\b|\biPad\b/g.exec(navigator.userAgent) == null; // If we are not in safari desktop, let the browser control // the focus if (!isSafariDesktop) return; var x = tabbable.indexOf(activeElement); if (x > -1) { x += shiftKey ? -1 : 1; } target = tabbable[x]; // If the tabbable element does not exist, // focus head/tail based on shiftKey if (typeof target === "undefined") { event.preventDefault(); target = shiftKey ? tail : head; target.focus(); return; } event.preventDefault(); target.focus(); } module.exports = exports["default"];