import _extends from "@babel/runtime/helpers/esm/extends"; import * as React from 'react'; import { node, bool, string, any, arrayOf, oneOfType, object, func } from 'prop-types'; import * as constants from 'focus-lock/constants'; import { useMergeRefs } from 'use-callback-ref'; import { useEffect } from 'react'; import { hiddenGuard } from './FocusGuard'; import { mediumFocus, mediumBlur, mediumSidecar } from './medium'; var emptyArray = []; var FocusLock = /*#__PURE__*/React.forwardRef(function FocusLockUI(props, parentRef) { var _extends2; var _React$useState = React.useState(), realObserved = _React$useState[0], setObserved = _React$useState[1]; var observed = React.useRef(); var isActive = React.useRef(false); var originalFocusedElement = React.useRef(null); var children = props.children, disabled = props.disabled, noFocusGuards = props.noFocusGuards, persistentFocus = props.persistentFocus, crossFrame = props.crossFrame, autoFocus = props.autoFocus, allowTextSelection = props.allowTextSelection, group = props.group, className = props.className, whiteList = props.whiteList, hasPositiveIndices = props.hasPositiveIndices, _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, focusOptions = props.focusOptions, onActivationCallback = props.onActivation, onDeactivationCallback = props.onDeactivation; var _React$useState2 = React.useState({}), id = _React$useState2[0]; // SIDE EFFECT CALLBACKS var onActivation = React.useCallback(function () { originalFocusedElement.current = originalFocusedElement.current || document && document.activeElement; if (observed.current && onActivationCallback) { onActivationCallback(observed.current); } isActive.current = true; }, [onActivationCallback]); var onDeactivation = React.useCallback(function () { isActive.current = false; if (onDeactivationCallback) { onDeactivationCallback(observed.current); } }, [onDeactivationCallback]); useEffect(function () { if (!disabled) { // cleanup return focus on trap deactivation // sideEffect/returnFocus should happen by this time originalFocusedElement.current = null; } }, []); var returnFocus = React.useCallback(function (allowDefer) { var returnFocusTo = originalFocusedElement.current; if (returnFocusTo && returnFocusTo.focus) { var howToReturnFocus = typeof shouldReturnFocus === 'function' ? shouldReturnFocus(returnFocusTo) : shouldReturnFocus; if (howToReturnFocus) { var returnFocusOptions = typeof howToReturnFocus === 'object' ? howToReturnFocus : undefined; originalFocusedElement.current = null; if (allowDefer) { // React might return focus after update // it's safer to defer the action Promise.resolve().then(function () { return returnFocusTo.focus(returnFocusOptions); }); } else { returnFocusTo.focus(returnFocusOptions); } } } }, [shouldReturnFocus]); // MEDIUM CALLBACKS var onFocus = React.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 = React.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.useEffect(function () { // report incorrect integration - https://github.com/theKashey/react-focus-lock/issues/123 if (!observed.current && typeof Container !== 'string') { // eslint-disable-next-line no-console console.error('FocusLock: could not obtain ref to internal node'); } }, []); } var lockProps = _extends((_extends2 = {}, _extends2[constants.FOCUS_DISABLED] = disabled && 'disabled', _extends2[constants.FOCUS_GROUP] = group, _extends2), containerProps); var hasLeadingGuards = noFocusGuards !== true; var hasTailingGuards = hasLeadingGuards && noFocusGuards !== 'tail'; var mergedRef = useMergeRefs([parentRef, setObserveNode]); return /*#__PURE__*/React.createElement(React.Fragment, null, hasLeadingGuards && [ /*#__PURE__*/ // nearest focus guard React.createElement("div", { key: "guard-first", "data-focus-guard": true, tabIndex: disabled ? -1 : 0, style: hiddenGuard }), // first tabbed element guard hasPositiveIndices ? /*#__PURE__*/React.createElement("div", { key: "guard-nearest", "data-focus-guard": true, tabIndex: disabled ? -1 : 1, style: hiddenGuard }) : null], !disabled && /*#__PURE__*/React.createElement(SideCar, { id: id, sideCar: mediumSidecar, observed: realObserved, disabled: disabled, persistentFocus: persistentFocus, crossFrame: crossFrame, autoFocus: autoFocus, whiteList: whiteList, shards: shards, onActivation: onActivation, onDeactivation: onDeactivation, returnFocus: returnFocus, focusOptions: focusOptions }), /*#__PURE__*/React.createElement(Container, _extends({ ref: mergedRef }, lockProps, { className: className, onBlur: onBlur, onFocus: onFocus }), children), hasTailingGuards && /*#__PURE__*/React.createElement("div", { "data-focus-guard": true, tabIndex: disabled ? -1 : 0, style: hiddenGuard })); }); FocusLock.propTypes = process.env.NODE_ENV !== "production" ? { children: node, disabled: bool, returnFocus: oneOfType([bool, object, func]), focusOptions: object, noFocusGuards: bool, hasPositiveIndices: bool, allowTextSelection: bool, autoFocus: bool, persistentFocus: bool, crossFrame: bool, group: string, className: string, whiteList: func, shards: arrayOf(any), as: oneOfType([string, func, object]), lockProps: object, onActivation: func, onDeactivation: func, sideCar: any.isRequired } : {}; FocusLock.defaultProps = { children: undefined, disabled: false, returnFocus: false, focusOptions: undefined, noFocusGuards: false, autoFocus: true, persistentFocus: false, crossFrame: true, hasPositiveIndices: undefined, allowTextSelection: undefined, group: undefined, className: undefined, whiteList: undefined, shards: undefined, as: 'div', lockProps: {}, onActivation: undefined, onDeactivation: undefined }; export default FocusLock;