UNPKG

jobiqo-cl

Version:

[![CircleCI](https://circleci.com/gh/jobiqo/jobiqo-cl.svg?style=svg&circle-token=5a24efa5b8bbc4879276123e77d0d3f35ca7144c)](https://circleci.com/gh/jobiqo/jobiqo-cl)

254 lines (207 loc) 7.16 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('react'); var React__default = _interopDefault(React); var index = require('../../../prop-types/index.js'); var medium = require('./medium.js'); var index_es = require('../../../react-clientside-effect/lib/index.es.js'); var focusMerge = require('../../../focus-lock/dist/es2015/focusMerge.js'); var focusInside = require('../../../focus-lock/dist/es2015/focusInside.js'); var focusIsHidden = require('../../../focus-lock/dist/es2015/focusIsHidden.js'); var index$1 = require('../../../focus-lock/dist/es2015/index.js'); var util = require('./util.js'); var focusOnBody = function focusOnBody() { return document && document.activeElement === document.body; }; var isFreeFocus = function isFreeFocus() { return focusOnBody() || focusIsHidden.default(); }; var lastActiveTrap = null; var lastActiveFocus = null; var lastPortaledElement = null; var focusWasOutsideWindow = false; var defaultWhitelist = function defaultWhitelist() { return true; }; var focusWhitelisted = function focusWhitelisted(activeElement) { return (lastActiveTrap.whiteList || defaultWhitelist)(activeElement); }; var recordPortal = function recordPortal(observerNode, portaledElement) { lastPortaledElement = { observerNode: observerNode, portaledElement: portaledElement }; }; var focusIsPortaledPair = function focusIsPortaledPair(element) { return lastPortaledElement && lastPortaledElement.portaledElement === element; }; function autoGuard(startIndex, end, step, allNodes) { var lastGuard = null; var i = startIndex; do { var item = allNodes[i]; if (item.guard) { if (item.node.dataset.focusAutoGuard) { lastGuard = item; } } else if (item.lockItem) { if (i !== startIndex) { // we will tab to the next element return; } lastGuard = null; } else { break; } } while ((i += step) !== end); if (lastGuard) { lastGuard.node.tabIndex = 0; } } var extractRef = function extractRef(ref) { return ref && 'current' in ref ? ref.current : ref; }; var activateTrap = function activateTrap() { var result = false; if (lastActiveTrap) { var _lastActiveTrap = lastActiveTrap, observed = _lastActiveTrap.observed, persistentFocus = _lastActiveTrap.persistentFocus, autoFocus = _lastActiveTrap.autoFocus, shards = _lastActiveTrap.shards; var workingNode = observed || lastPortaledElement && lastPortaledElement.portaledElement; var activeElement = document && document.activeElement; if (workingNode) { var workingArea = [workingNode].concat(shards.map(extractRef).filter(Boolean)); if (!activeElement || focusWhitelisted(activeElement)) { if (persistentFocus || focusWasOutsideWindow || !isFreeFocus() || !lastActiveFocus && autoFocus) { if (workingNode && !(focusInside.default(workingArea) || focusIsPortaledPair(activeElement))) { if (document && !lastActiveFocus && activeElement && !autoFocus) { activeElement.blur(); document.body.focus(); } else { result = index$1.default(workingArea, lastActiveFocus); lastPortaledElement = {}; } } focusWasOutsideWindow = false; lastActiveFocus = document && document.activeElement; } } if (document) { var newActiveElement = document && document.activeElement; var allNodes = focusMerge.getFocusabledIn(workingArea); var focusedItem = allNodes.find(function (_ref) { var node = _ref.node; return node === newActiveElement; }); if (focusedItem) { // remove old focus allNodes.filter(function (_ref2) { var guard = _ref2.guard, node = _ref2.node; return guard && node.dataset.focusAutoGuard; }).forEach(function (_ref3) { var node = _ref3.node; return node.removeAttribute('tabIndex'); }); var focusedIndex = allNodes.indexOf(focusedItem); autoGuard(focusedIndex, allNodes.length, +1, allNodes); autoGuard(focusedIndex, -1, -1, allNodes); } } } } return result; }; var onTrap = function onTrap(event) { if (activateTrap() && event) { // prevent scroll jump event.stopPropagation(); event.preventDefault(); } }; var onBlur = function onBlur() { return util.deferAction(activateTrap); }; var onFocus = function onFocus(event) { // detect portal var source = event.target; var currentNode = event.currentTarget; if (!currentNode.contains(source)) { recordPortal(currentNode, source); } }; var FocusWatcher = function FocusWatcher() { return null; }; var FocusTrap = function FocusTrap(_ref4) { var children = _ref4.children; return React__default.createElement("div", { onBlur: onBlur, onFocus: onFocus }, children); }; FocusTrap.propTypes = process.env.NODE_ENV !== "production" ? { children: index.default.node.isRequired } : {}; var onWindowBlur = function onWindowBlur() { focusWasOutsideWindow = true; }; var attachHandler = function attachHandler() { document.addEventListener('focusin', onTrap, true); document.addEventListener('focusout', onBlur); window.addEventListener('blur', onWindowBlur); }; var detachHandler = function detachHandler() { document.removeEventListener('focusin', onTrap, true); document.removeEventListener('focusout', onBlur); window.removeEventListener('blur', onWindowBlur); }; function reducePropsToState(propsList) { return propsList.filter(function (_ref5) { var disabled = _ref5.disabled; return !disabled; }); } function handleStateChangeOnClient(traps) { var trap = traps.slice(-1)[0]; if (trap && !lastActiveTrap) { attachHandler(); } var lastTrap = lastActiveTrap; var sameTrap = lastTrap && trap && trap.id === lastTrap.id; lastActiveTrap = trap; if (lastTrap && !sameTrap) { lastTrap.onDeactivation(); // return focus only of last trap was removed if (!traps.filter(function (_ref6) { var id = _ref6.id; return id === lastTrap.id; }).length) { // allow defer is no other trap is awaiting restore lastTrap.returnFocus(!trap); } } if (trap) { lastActiveFocus = null; if (!sameTrap || lastTrap.observed !== trap.observed) { trap.onActivation(); } activateTrap(); util.deferAction(activateTrap); } else { detachHandler(); lastActiveFocus = null; } } // bind medium medium.mediumFocus.assignSyncMedium(onFocus); medium.mediumBlur.assignMedium(onBlur); medium.mediumEffect.assignMedium(function (cb) { return cb({ moveFocusInside: index$1.default, focusInside: focusInside.default }); }); var FocusTrap$1 = index_es.default(reducePropsToState, handleStateChangeOnClient)(FocusWatcher); exports.default = FocusTrap$1;