[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/script-modules/block-library/navigation/ -> view.js (source)

   1  // packages/block-library/build-module/navigation/view.js
   2  import {
   3    store,
   4    getContext,
   5    getElement,
   6    withSyncEvent
   7  } from "@wordpress/interactivity";
   8  var focusableSelectors = [
   9    "a[href]",
  10    'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',
  11    "select:not([disabled]):not([aria-hidden])",
  12    "textarea:not([disabled]):not([aria-hidden])",
  13    "button:not([disabled]):not([aria-hidden])",
  14    "[contenteditable]",
  15    '[tabindex]:not([tabindex^="-"])'
  16  ];
  17  document.addEventListener("click", () => {
  18  });
  19  var { state, actions } = store(
  20    "core/navigation",
  21    {
  22      state: {
  23        get roleAttribute() {
  24          const ctx = getContext();
  25          return ctx.type === "overlay" && state.isMenuOpen ? "dialog" : null;
  26        },
  27        get ariaModal() {
  28          const ctx = getContext();
  29          return ctx.type === "overlay" && state.isMenuOpen ? "true" : null;
  30        },
  31        get ariaLabel() {
  32          const ctx = getContext();
  33          return ctx.type === "overlay" && state.isMenuOpen ? ctx.ariaLabel : null;
  34        },
  35        get isMenuOpen() {
  36          return Object.values(state.menuOpenedBy).filter(Boolean).length > 0;
  37        },
  38        get menuOpenedBy() {
  39          const ctx = getContext();
  40          return ctx.type === "overlay" ? ctx.overlayOpenedBy : ctx.submenuOpenedBy;
  41        }
  42      },
  43      actions: {
  44        openMenuOnHover() {
  45          const { type, overlayOpenedBy } = getContext();
  46          if (type === "submenu" && // Only open on hover if the overlay is closed.
  47          Object.values(overlayOpenedBy || {}).filter(Boolean).length === 0) {
  48            actions.openMenu("hover");
  49          }
  50        },
  51        closeMenuOnHover() {
  52          const { type, overlayOpenedBy } = getContext();
  53          if (type === "submenu" && // Only close on hover if the overlay is closed.
  54          Object.values(overlayOpenedBy || {}).filter(Boolean).length === 0) {
  55            actions.closeMenu("hover");
  56          }
  57        },
  58        openMenuOnClick() {
  59          const ctx = getContext();
  60          const { ref } = getElement();
  61          ctx.previousFocus = ref;
  62          actions.openMenu("click");
  63        },
  64        closeMenuOnClick() {
  65          actions.closeMenu("click");
  66          actions.closeMenu("focus");
  67        },
  68        openMenuOnFocus() {
  69          actions.openMenu("focus");
  70        },
  71        toggleMenuOnClick() {
  72          const ctx = getContext();
  73          const { ref } = getElement();
  74          if (window.document.activeElement !== ref) {
  75            ref.focus();
  76          }
  77          const { menuOpenedBy } = state;
  78          if (menuOpenedBy.click || menuOpenedBy.focus) {
  79            actions.closeMenu("click");
  80            actions.closeMenu("focus");
  81          } else {
  82            ctx.previousFocus = ref;
  83            actions.openMenu("click");
  84          }
  85        },
  86        handleMenuKeydown: withSyncEvent((event) => {
  87          const { type, firstFocusableElement, lastFocusableElement } = getContext();
  88          if (state.menuOpenedBy.click) {
  89            if (event.key === "Escape") {
  90              event.stopPropagation();
  91              actions.closeMenu("click");
  92              actions.closeMenu("focus");
  93              return;
  94            }
  95            if (type === "overlay" && event.key === "Tab") {
  96              if (event.shiftKey && window.document.activeElement === firstFocusableElement) {
  97                event.preventDefault();
  98                lastFocusableElement.focus();
  99              } else if (!event.shiftKey && window.document.activeElement === lastFocusableElement) {
 100                event.preventDefault();
 101                firstFocusableElement.focus();
 102              }
 103            }
 104          }
 105        }),
 106        handleMenuFocusout: withSyncEvent((event) => {
 107          const { modal, type } = getContext();
 108          if (event.relatedTarget === null || !modal?.contains(event.relatedTarget) && event.target !== window.document.activeElement && type === "submenu") {
 109            actions.closeMenu("click");
 110            actions.closeMenu("focus");
 111          }
 112        }),
 113        openMenu(menuOpenedOn = "click") {
 114          const { type } = getContext();
 115          state.menuOpenedBy[menuOpenedOn] = true;
 116          if (type === "overlay") {
 117            document.documentElement.classList.add("has-modal-open");
 118          }
 119        },
 120        closeMenu(menuClosedOn = "click") {
 121          const ctx = getContext();
 122          state.menuOpenedBy[menuClosedOn] = false;
 123          if (!state.isMenuOpen) {
 124            if (ctx.modal?.contains(window.document.activeElement)) {
 125              ctx.previousFocus?.focus();
 126            }
 127            ctx.modal = null;
 128            ctx.previousFocus = null;
 129            if (ctx.type === "overlay") {
 130              document.documentElement.classList.remove(
 131                "has-modal-open"
 132              );
 133            }
 134          }
 135        }
 136      },
 137      callbacks: {
 138        initMenu() {
 139          const ctx = getContext();
 140          const { ref } = getElement();
 141          if (state.isMenuOpen) {
 142            const focusableElements = ref.querySelectorAll(focusableSelectors);
 143            ctx.modal = ref;
 144            ctx.firstFocusableElement = focusableElements[0];
 145            ctx.lastFocusableElement = focusableElements[focusableElements.length - 1];
 146          }
 147        },
 148        focusFirstElement() {
 149          const { ref } = getElement();
 150          if (state.isMenuOpen) {
 151            const focusableElements = ref.querySelectorAll(focusableSelectors);
 152            focusableElements?.[0]?.focus();
 153          }
 154        }
 155      }
 156    },
 157    { lock: true }
 158  );


Generated : Thu Apr 30 08:20:13 2026 Cross-referenced by PHPXref