@massds/mayflower-react
Version:
React versions of Mayflower design system UI components
67 lines (63 loc) • 3 kB
JavaScript
;
exports.__esModule = true;
exports["default"] = void 0;
/**
* focusTrapping: Trap keyboard focus inside of a modal
* @param {string} focusableSelectors(requied): css selectors for all the focusable elements inside of the modal
* @param {string} modalSelector(requied): css selector for the modal container
* @param {string} closeButtonSelector(optional): If the modal close button is outside of the modal container, add the css selector for it to be included as the first focusable element
* @param {event} key(requied): keydown event
*/
// check if an element is visibly displayed using computed style
var isDisplayed = function isDisplayed(el) {
var style = window.getComputedStyle(el);
return style.display !== 'none' && style.visibility !== 'hidden';
};
// filter out elements from array which are not visibly displayed
var filterDisplayedElements = function filterDisplayedElements(elements) {
return elements.length > 0 && elements.filter(function (el) {
return isDisplayed(el);
});
};
var _default = exports["default"] = function _default(_ref) {
var _ref$focusableSelecto = _ref.focusableSelectors,
focusableSelectors = _ref$focusableSelecto === void 0 ? 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' : _ref$focusableSelecto,
closeButtonSelector = _ref.closeButtonSelector,
modalSelector = _ref.modalSelector,
keyEvent = _ref.keyEvent;
// add all the elements inside modal which you want to make focusable
var focusableElements = focusableSelectors;
var modal = document.querySelector(modalSelector); // select the modal by its id
var key = keyEvent.key;
var action = {
tab: key === 'Tab',
// tab
shift: key.shift // shift
};
if (modal) {
var focusableNodeArray = Array.from(modal.querySelectorAll(focusableElements));
var focusableContent = modal && filterDisplayedElements(focusableNodeArray);
if (closeButtonSelector) {
var closeButton = document.querySelector(closeButtonSelector);
focusableContent = [closeButton].concat(focusableContent);
}
var focusedElement = document.activeElement;
var firstFocusableElement = focusableContent[0]; // get first element to be focused inside modal
var lastFocusableElement = focusableContent[focusableContent.length - 1]; // get last element to be focused inside modal
var isTabPressed = action.tab;
if (!isTabPressed) {
return;
}
if (action.shift) {
// if shift key pressed for shift + tab combination
if (focusedElement === firstFocusableElement) {
lastFocusableElement.focus(); // add focus for the last focusable element
}
} else if (focusedElement === lastFocusableElement) {
// if tab key is pressed
// if focused has reached to last focusable element then focus first focusable element after pressing tab
firstFocusableElement.focus(); // add focus for the first focusable element
}
}
};
module.exports = exports.default;