jobiqo-cl
Version:
[](https://circleci.com/gh/jobiqo/jobiqo-cl)
187 lines (168 loc) • 6.51 kB
JavaScript
import React__default, { useState, useRef, useCallback } from 'react';
import _extends from '../../../@babel/runtime/helpers/esm/extends.js';
import { node as propTypes_1, bool as propTypes_2, oneOfType as propTypes_6, object as propTypes_7, string as propTypes_3, func as propTypes_8, arrayOf as propTypes_5, any as propTypes_4 } from '../../../prop-types/index.js';
import { FOCUS_DISABLED, FOCUS_GROUP } from '../../../focus-lock/dist/es2015/constants.js';
import '../../../use-callback-ref/dist/es2015/assignRef.js';
import '../../../use-callback-ref/dist/es2015/useRef.js';
import { useMergeRefs } from '../../../use-callback-ref/dist/es2015/useMergeRef.js';
import { hiddenGuard } from './FocusGuard.js';
import { mediumFocus, mediumSidecar, mediumBlur } from './medium.js';
var emptyArray = [];
var FocusLock = React__default.forwardRef(function (props, parentRef) {
var _extends2;
var _useState = useState(),
realObserved = _useState[0],
setObserved = _useState[1];
var observed = useRef();
var isActive = useRef(false);
var originalFocusedElement = useRef(null);
var children = props.children,
disabled = props.disabled,
noFocusGuards = props.noFocusGuards,
persistentFocus = props.persistentFocus,
autoFocus = props.autoFocus,
allowTextSelection = props.allowTextSelection,
group = props.group,
className = props.className,
whiteList = props.whiteList,
_props$shards = props.shards,
shards = _props$shards === void 0 ? emptyArray : _props$shards,
_props$as = props.as,
Container = _props$as === void 0 ? 'div' : _props$as,
_props$lockProps = props.lockProps,
containerProps = _props$lockProps === void 0 ? {} : _props$lockProps,
SideCar = props.sideCar,
shouldReturnFocus = props.returnFocus,
onActivationCallback = props.onActivation,
onDeactivationCallback = props.onDeactivation;
var _useState2 = useState({}),
id = _useState2[0]; // SIDE EFFECT CALLBACKS
var onActivation = useCallback(function () {
originalFocusedElement.current = originalFocusedElement.current || document && document.activeElement;
if (observed.current && onActivationCallback) {
onActivationCallback(observed.current);
}
isActive.current = true;
}, [onActivationCallback]);
var onDeactivation = useCallback(function () {
isActive.current = false;
if (onDeactivationCallback) {
onDeactivationCallback(observed.current);
}
}, [onDeactivationCallback]);
var returnFocus = useCallback(function (allowDefer) {
var current = originalFocusedElement.current;
if (Boolean(shouldReturnFocus) && current && current.focus) {
var focusOptions = typeof shouldReturnFocus === 'object' ? shouldReturnFocus : undefined;
originalFocusedElement.current = null;
if (allowDefer) {
// React might return focus after update
// it's safer to defer the action
Promise.resolve().then(function () {
return current.focus(focusOptions);
});
} else {
current.focus(focusOptions);
}
}
}, [shouldReturnFocus]); // MEDIUM CALLBACKS
var onFocus = useCallback(function (event) {
if (isActive.current) {
mediumFocus.useMedium(event);
}
}, []);
var onBlur = mediumBlur.useMedium; // REF PROPAGATION
// not using real refs due to race conditions
var setObserveNode = useCallback(function (newObserved) {
if (observed.current !== newObserved) {
observed.current = newObserved;
setObserved(newObserved);
}
}, []);
if (process.env.NODE_ENV !== 'production') {
if (typeof allowTextSelection !== 'undefined') {
// eslint-disable-next-line no-console
console.warn('React-Focus-Lock: allowTextSelection is deprecated and enabled by default');
}
React__default.useEffect(function () {
if (!observed.current) {
// eslint-disable-next-line no-console
console.error('FocusLock: could not obtain ref to internal node');
}
}, []);
}
var lockProps = _extends((_extends2 = {}, _extends2[FOCUS_DISABLED] = disabled && 'disabled', _extends2[FOCUS_GROUP] = group, _extends2), containerProps);
var hasLeadingGuards = noFocusGuards !== true;
var hasTailingGuards = hasLeadingGuards && noFocusGuards !== 'tail';
var mergedRef = useMergeRefs([parentRef, setObserveNode]);
return React__default.createElement(React__default.Fragment, null, hasLeadingGuards && [React__default.createElement("div", {
key: "guard-first",
"data-focus-guard": true,
tabIndex: disabled ? -1 : 0,
style: hiddenGuard
}), // nearest focus guard
React__default.createElement("div", {
key: "guard-nearest",
"data-focus-guard": true,
tabIndex: disabled ? -1 : 1,
style: hiddenGuard
})], !disabled && React__default.createElement(SideCar, {
id: id,
sideCar: mediumSidecar,
observed: realObserved,
disabled: disabled,
persistentFocus: persistentFocus,
autoFocus: autoFocus,
whiteList: whiteList,
shards: shards,
onActivation: onActivation,
onDeactivation: onDeactivation,
returnFocus: returnFocus
}), React__default.createElement(Container, _extends({
ref: mergedRef
}, lockProps, {
className: className,
onBlur: onBlur,
onFocus: onFocus
}), children), hasTailingGuards && React__default.createElement("div", {
"data-focus-guard": true,
tabIndex: disabled ? -1 : 0,
style: hiddenGuard
}));
});
FocusLock.propTypes = process.env.NODE_ENV !== "production" ? {
children: propTypes_1,
disabled: propTypes_2,
returnFocus: propTypes_6([propTypes_2, propTypes_7]),
noFocusGuards: propTypes_2,
allowTextSelection: propTypes_2,
autoFocus: propTypes_2,
persistentFocus: propTypes_2,
group: propTypes_3,
className: propTypes_3,
whiteList: propTypes_8,
shards: propTypes_5(propTypes_4),
as: propTypes_6([propTypes_3, propTypes_8, propTypes_7]),
lockProps: propTypes_7,
onActivation: propTypes_8,
onDeactivation: propTypes_8,
sideCar: propTypes_4.isRequired
} : {};
FocusLock.defaultProps = {
children: undefined,
disabled: false,
returnFocus: false,
noFocusGuards: false,
autoFocus: true,
persistentFocus: false,
allowTextSelection: undefined,
group: undefined,
className: undefined,
whiteList: undefined,
shards: undefined,
as: 'div',
lockProps: {},
onActivation: undefined,
onDeactivation: undefined
};
export default FocusLock;