content: /* eslint-disable consistent-return, jsx-a11y/no-noninteractive-tabindex */
  import React from 'react';
  import ReactDOM from 'react-dom';
  import PropTypes from 'prop-types';
  import ownerDocument from '../utils/ownerDocument';
  import useForkRef from '../utils/useForkRef';
  /**
   * @ignore - internal component.
   */
  
  function TrapFocus(props) {
    var children = props.children,
        _props$disableAutoFoc = props.disableAutoFocus,
        disableAutoFocus = _props$disableAutoFoc === void 0 ? false : _props$disableAutoFoc,
        _props$disableEnforce = props.disableEnforceFocus,
        disableEnforceFocus = _props$disableEnforce === void 0 ? false : _props$disableEnforce,
        _props$disableRestore = props.disableRestoreFocus,
        disableRestoreFocus = _props$disableRestore === void 0 ? false : _props$disableRestore,
        getDoc = props.getDoc,
        isEnabled = props.isEnabled,
        open = props.open;
    var ignoreNextEnforceFocus = React.useRef();
    var sentinelStart = React.useRef(null);
    var sentinelEnd = React.useRef(null);
    var nodeToRestore = React.useRef();
    var rootRef = React.useRef(null); // can be removed once we drop support for non ref forwarding class components
  
    var handleOwnRef = React.useCallback(function (instance) {
      // #StrictMode ready
      rootRef.current = ReactDOM.findDOMNode(instance);
    }, []);
    var handleRef = useForkRef(children.ref, handleOwnRef); // ⚠️ You may rely on React.useMemo as a performance optimization, not as a semantic guarantee.
    // https://reactjs.org/docs/hooks-reference.html#usememo
  
    React.useMemo(function () {
      if (!open || typeof window === 'undefined') {
        return;
      }
  
      nodeToRestore.current = getDoc().activeElement;
    }, [open]); // eslint-disable-line react-hooks/exhaustive-deps
  
    React.useEffect(function () {
      if (!open) {
        return;
      }
  
      var doc = ownerDocument(rootRef.current); // We might render an empty child.
  
      if (!disableAutoFocus && rootRef.current && !rootRef.current.contains(doc.activeElement)) {
        if (!rootRef.current.hasAttribute('tabIndex')) {
          if (process.env.NODE_ENV !== 'production') {
            console.error(['Material-UI: the modal content node does not accept focus.', 'For the benefit of assistive technologies, ' + 'the tabIndex of the node is being set to "-1".'].join('\n'));
          }
  
          rootRef.current.setAttribute('tabIndex', -1);
        }
  
        rootRef.current.focus();
      }
  
      var contain = function contain() {
        if (disableEnforceFocus || !isEnabled() || ignoreNextEnforceFocus.current) {
          ignoreNextEnforceFocus.current = false;
          return;
        }
  
        if (rootRef.current && !rootRef.current.contains(doc.activeElement)) {
          rootRef.current.focus();
        }
      };
  
      var loopFocus = function loopFocus(event) {
        // 9 = Tab
        if (disableEnforceFocus || !isEnabled() || event.keyCode !== 9) {
          return;
        } // Make sure the next tab starts from the right place.
  
  
        if (doc.activeElement === rootRef.current) {
          // We need to ignore the next contain as
          // it will try to move the focus back to the rootRef element.
          ignoreNextEnforceFocus.current = true;
  
          if (event.shiftKey) {
            sentinelEnd.current.focus();
          } else {
            sentinelStart.current.focus();
          }
        }
      };
  
      doc.addEventListener('focus', contain, true);
      doc.addEventListener('keydown', loopFocus, true); // With Edge, Safari and Firefox, no focus related events are fired when the focused area stops being a focused area
      // e.g. https://bugzilla.mozilla.org/show_bug.cgi?id=559561.
      //
      // The whatwg spec defines how the browser should behave but does not explicitly mention any events:
      // https://html.spec.whatwg.org/multipage/interaction.html#focus-fixup-rule.
  
      var interval = setInterval(function () {
        contain();
      }, 50);
      return function () {
        clearInterval(interval);
        doc.removeEventListener('focus', contain, true);
        doc.removeEventListener('keydown', loopFocus, true); // restoreLastFocus()
  
        if (!disableRestoreFocus) {
          // In IE 11 it is possible for document.activeElement to be null resulting
          // in nodeToRestore.current being null.
          // Not all elements in IE 11 have a focus method.
          // Once IE 11 support is dropped the focus() call can be unconditional.
          if (nodeToRestore.current && nodeToRestore.current.focus) {
            nodeToRestore.current.focus();
          }
  
          nodeToRestore.current = null;
        }
      };
    }, [disableAutoFocus, disableEnforceFocus, disableRestoreFocus, isEnabled, open]);
    return React.createElement(React.Fragment, null, React.createElement("div", {
      tabIndex: 0,
      ref: sentinelStart,
      "data-test": "sentinelStart"
    }), React.cloneElement(children, {
      ref: handleRef
    }), React.createElement("div", {
      tabIndex: 0,
      ref: sentinelEnd,
      "data-test": "sentinelEnd"
    }));
  }
  
  process.env.NODE_ENV !== "production" ? TrapFocus.propTypes = {
    /**
     * A single child content element.
     */
    children: PropTypes.element.isRequired,
  
    /**
     * If `true`, the modal will not automatically shift focus to itself when it opens, and
     * replace it to the last focused element when it closes.
     * This also works correctly with any modal children that have the `disableAutoFocus` prop.
     *
     * Generally this should never be set to `true` as it makes the modal less
     * accessible to assistive technologies, like screen readers.
     */
    disableAutoFocus: PropTypes.bool,
  
    /**
     * If `true`, the modal will not prevent focus from leaving the modal while open.
     *
     * Generally this should never be set to `true` as it makes the modal less
     * accessible to assistive technologies, like screen readers.
     */
    disableEnforceFocus: PropTypes.bool,
  
    /**
     * If `true`, the modal will not restore focus to previously focused element once
     * modal is hidden.
     */
    disableRestoreFocus: PropTypes.bool,
  
    /**
     * Return the document to consider.
     * We use it to implement the restore focus between different browser documents.
     */
    getDoc: PropTypes.func.isRequired,
  
    /**
     * Do we still want to enforce the focus?
     * This prop helps nesting TrapFocus elements.
     */
    isEnabled: PropTypes.func.isRequired,
  
    /**
     * If `true`, the modal is open.
     */
    open: PropTypes.bool.isRequired
  } : void 0;
  /*
  
  In the future, we should be able to replace TrapFocus with:
  https://github.com/facebook/react/blob/master/packages/react-events/docs/FocusScope.md
  
  ```jsx
  import FocusScope from 'react-dom/FocusScope';
  
  function TrapFocus(props) {
    const {
      children
      disableAutoFocus = false,
      disableEnforceFocus = false,
      disableRestoreFocus = false,
      open,
    } = props;
  
    if (!open) {
      return children;
    }
  
    return (
      <FocusScope
        autoFocus={!disableAutoFocus}
        contain={!disableEnforceFocus}
        restoreFocus={!disableRestoreFocus}
      >
        {children}
      </FocusScope>
    );
  }
  ```
  
  */
  
  export default TrapFocus;