"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// packages/block-editor/src/components/writing-flow/use-tab-nav.js
var use_tab_nav_exports = {};
__export(use_tab_nav_exports, {
  default: () => useTabNav
});
module.exports = __toCommonJS(use_tab_nav_exports);
var import_dom = require("@wordpress/dom");
var import_keycodes = require("@wordpress/keycodes");
var import_data = require("@wordpress/data");
var import_compose = require("@wordpress/compose");
var import_element = require("@wordpress/element");
var import_store = require("../../store");
var import_dom2 = require("../../utils/dom");
var import_lock_unlock = require("../../lock-unlock");
var import_jsx_runtime = require("react/jsx-runtime");
function useTabNav() {
  const containerRef = (
    /** @type {typeof useRef<HTMLElement>} */
    (0, import_element.useRef)()
  );
  const focusCaptureBeforeRef = (0, import_element.useRef)();
  const focusCaptureAfterRef = (0, import_element.useRef)();
  const {
    hasMultiSelection,
    getSelectedBlockClientId,
    getBlockCount,
    getBlockOrder,
    getLastFocus,
    getSectionRootClientId,
    isZoomOut
  } = (0, import_lock_unlock.unlock)((0, import_data.useSelect)(import_store.store));
  const { setLastFocus } = (0, import_lock_unlock.unlock)((0, import_data.useDispatch)(import_store.store));
  const noCaptureRef = (0, import_element.useRef)();
  function onFocusCapture(event) {
    const canvasElement = containerRef.current.ownerDocument === event.target.ownerDocument ? containerRef.current : containerRef.current.ownerDocument.defaultView.frameElement;
    if (noCaptureRef.current) {
      noCaptureRef.current = null;
    } else if (hasMultiSelection()) {
      containerRef.current.focus();
    } else if (getSelectedBlockClientId()) {
      if (getLastFocus()?.current) {
        getLastFocus().current.focus();
      } else {
        containerRef.current.querySelector(
          `[data-block="${getSelectedBlockClientId()}"]`
        ).focus();
      }
    } else if (isZoomOut()) {
      const sectionRootClientId = getSectionRootClientId();
      const sectionBlocks = getBlockOrder(sectionRootClientId);
      if (sectionBlocks.length) {
        containerRef.current.querySelector(`[data-block="${sectionBlocks[0]}"]`).focus();
      } else if (sectionRootClientId) {
        containerRef.current.querySelector(`[data-block="${sectionRootClientId}"]`).focus();
      } else {
        canvasElement.focus();
      }
    } else {
      const isBefore = (
        // eslint-disable-next-line no-bitwise
        event.target.compareDocumentPosition(canvasElement) & event.target.DOCUMENT_POSITION_FOLLOWING
      );
      const tabbables = import_dom.focus.tabbable.find(containerRef.current);
      if (tabbables.length) {
        const next = isBefore ? tabbables[0] : tabbables[tabbables.length - 1];
        next.focus();
      }
    }
  }
  const before = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    "div",
    {
      ref: focusCaptureBeforeRef,
      tabIndex: "0",
      onFocus: onFocusCapture
    }
  );
  const after = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    "div",
    {
      ref: focusCaptureAfterRef,
      tabIndex: "0",
      onFocus: onFocusCapture
    }
  );
  const ref = (0, import_compose.useRefEffect)((node) => {
    function onKeyDown(event) {
      if (event.defaultPrevented) {
        return;
      }
      if (event.keyCode !== import_keycodes.TAB) {
        return;
      }
      if (
        // Bails in case the focus capture elements aren’t present. They
        // may be omitted to avoid silent tab stops in preview mode.
        // See: https://github.com/WordPress/gutenberg/pull/59317
        !focusCaptureAfterRef.current || !focusCaptureBeforeRef.current
      ) {
        return;
      }
      const { target, shiftKey: isShift } = event;
      const direction = isShift ? "findPrevious" : "findNext";
      const nextTabbable = import_dom.focus.tabbable[direction](target);
      const currentBlock = target.closest("[data-block]");
      const isElementPartOfSelectedBlock = currentBlock && nextTabbable && ((0, import_dom2.isInSameBlock)(currentBlock, nextTabbable) || (0, import_dom2.isInsideRootBlock)(currentBlock, nextTabbable));
      if ((0, import_dom.isFormElement)(nextTabbable) && isElementPartOfSelectedBlock) {
        return;
      }
      const next = isShift ? focusCaptureBeforeRef : focusCaptureAfterRef;
      noCaptureRef.current = true;
      next.current.focus({ preventScroll: true });
    }
    function onFocusOut(event) {
      setLastFocus({ ...getLastFocus(), current: event.target });
      const { ownerDocument: ownerDocument2 } = node;
      if (!event.relatedTarget && event.target.hasAttribute("data-block") && ownerDocument2.activeElement === ownerDocument2.body && getBlockCount() === 0) {
        node.focus();
      }
    }
    function preventScrollOnTab(event) {
      if (event.keyCode !== import_keycodes.TAB) {
        return;
      }
      if (event.target?.getAttribute("role") === "region") {
        return;
      }
      if (containerRef.current === event.target) {
        return;
      }
      const isShift = event.shiftKey;
      const direction = isShift ? "findPrevious" : "findNext";
      const target = import_dom.focus.tabbable[direction](event.target);
      if (target === focusCaptureBeforeRef.current || target === focusCaptureAfterRef.current) {
        event.preventDefault();
        target.focus({ preventScroll: true });
      }
    }
    const { ownerDocument } = node;
    const { defaultView } = ownerDocument;
    defaultView.addEventListener("keydown", preventScrollOnTab);
    node.addEventListener("keydown", onKeyDown);
    node.addEventListener("focusout", onFocusOut);
    return () => {
      defaultView.removeEventListener("keydown", preventScrollOnTab);
      node.removeEventListener("keydown", onKeyDown);
      node.removeEventListener("focusout", onFocusOut);
    };
  }, []);
  const mergedRefs = (0, import_compose.useMergeRefs)([containerRef, ref]);
  return [before, mergedRefs, after];
}
//# sourceMappingURL=use-tab-nav.js.map
