[ 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.mjs
   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  function getFocusableElements(ref) {
  18    const focusableElements = ref.querySelectorAll(focusableSelectors);
  19    return Array.from(focusableElements).filter((element) => {
  20      if (typeof element.checkVisibility === "function") {
  21        return element.checkVisibility({
  22          checkOpacity: false,
  23          checkVisibilityCSS: true
  24        });
  25      }
  26      return element.offsetParent !== null;
  27    });
  28  }
  29  document.addEventListener("click", () => {
  30  });
  31  var { state, actions } = store(
  32    "core/navigation",
  33    {
  34      state: {
  35        get roleAttribute() {
  36          const ctx = getContext();
  37          return ctx.type === "overlay" && state.isMenuOpen ? "dialog" : null;
  38        },
  39        get ariaModal() {
  40          const ctx = getContext();
  41          return ctx.type === "overlay" && state.isMenuOpen ? "true" : null;
  42        },
  43        get ariaLabel() {
  44          const ctx = getContext();
  45          return ctx.type === "overlay" && state.isMenuOpen ? ctx.ariaLabel : null;
  46        },
  47        get isMenuOpen() {
  48          return Object.values(state.menuOpenedBy).filter(Boolean).length > 0;
  49        },
  50        get menuOpenedBy() {
  51          const ctx = getContext();
  52          return ctx.type === "overlay" ? ctx.overlayOpenedBy : ctx.submenuOpenedBy;
  53        },
  54        get isSubmenuOpen() {
  55          const ctx = getContext();
  56          const isOverlayOpen = Object.values(ctx.overlayOpenedBy || {}).filter(Boolean).length > 0;
  57          return isOverlayOpen || state.isMenuOpen;
  58        }
  59      },
  60      actions: {
  61        openMenuOnHover(event) {
  62          if (event?.pointerType === "touch") {
  63            return;
  64          }
  65          const { type } = getContext();
  66          if (type === "submenu") {
  67            actions.openMenu("hover");
  68          }
  69        },
  70        closeMenuOnHover(event) {
  71          if (event?.pointerType === "touch") {
  72            return;
  73          }
  74          const { type } = getContext();
  75          if (type === "submenu") {
  76            actions.closeMenu("hover");
  77          }
  78        },
  79        openMenuOnClick() {
  80          const ctx = getContext();
  81          const { ref } = getElement();
  82          ctx.previousFocus = ref;
  83          actions.openMenu("click");
  84        },
  85        closeMenuOnClick() {
  86          actions.closeMenu("click");
  87          actions.closeMenu("focus");
  88        },
  89        openMenuOnFocus() {
  90          actions.openMenu("focus");
  91        },
  92        toggleMenuOnClick() {
  93          const ctx = getContext();
  94          const { ref } = getElement();
  95          if (window.document.activeElement !== ref) {
  96            ref.focus();
  97          }
  98          const { menuOpenedBy } = state;
  99          if (menuOpenedBy.click || menuOpenedBy.focus) {
 100            actions.closeMenu("click");
 101            actions.closeMenu("focus");
 102            actions.closeMenu("hover");
 103          } else {
 104            ctx.previousFocus = ref;
 105            actions.openMenu("click");
 106          }
 107        },
 108        handleMenuKeydown: withSyncEvent((event) => {
 109          const { type, firstFocusableElement, lastFocusableElement } = getContext();
 110          if (state.menuOpenedBy.click) {
 111            if (event.key === "Escape") {
 112              event.stopPropagation();
 113              actions.closeMenu("click");
 114              actions.closeMenu("focus");
 115              return;
 116            }
 117            if (type === "overlay" && event.key === "Tab") {
 118              if (event.shiftKey && window.document.activeElement === firstFocusableElement) {
 119                event.preventDefault();
 120                lastFocusableElement.focus();
 121              } else if (!event.shiftKey && window.document.activeElement === lastFocusableElement) {
 122                event.preventDefault();
 123                firstFocusableElement.focus();
 124              }
 125            }
 126          }
 127        }),
 128        handleMenuFocusout: withSyncEvent((event) => {
 129          const { modal, type } = getContext();
 130          if (event.relatedTarget === null || !modal?.contains(event.relatedTarget) && event.target !== window.document.activeElement && type === "submenu") {
 131            actions.closeMenu("click");
 132            actions.closeMenu("focus");
 133          }
 134        }),
 135        openMenu(menuOpenedOn = "click") {
 136          const { type } = getContext();
 137          state.menuOpenedBy[menuOpenedOn] = true;
 138          if (type === "overlay") {
 139            document.documentElement.classList.add("has-modal-open");
 140          }
 141        },
 142        closeMenu(menuClosedOn = "click") {
 143          const ctx = getContext();
 144          state.menuOpenedBy[menuClosedOn] = false;
 145          if (!state.isMenuOpen) {
 146            if (ctx.modal?.contains(window.document.activeElement)) {
 147              ctx.previousFocus?.focus();
 148            }
 149            ctx.modal = null;
 150            ctx.previousFocus = null;
 151            if (ctx.type === "overlay") {
 152              document.documentElement.classList.remove(
 153                "has-modal-open"
 154              );
 155            }
 156          }
 157        }
 158      },
 159      callbacks: {
 160        initMenu() {
 161          const ctx = getContext();
 162          const { ref } = getElement();
 163          if (state.isMenuOpen) {
 164            const focusableElements = getFocusableElements(ref);
 165            ctx.modal = ref;
 166            ctx.firstFocusableElement = focusableElements[0];
 167            ctx.lastFocusableElement = focusableElements[focusableElements.length - 1];
 168          }
 169        },
 170        focusFirstElement() {
 171          const { ref } = getElement();
 172          if (state.isMenuOpen) {
 173            const focusableElements = getFocusableElements(ref);
 174            focusableElements?.[0]?.focus();
 175          }
 176        }
 177      }
 178    },
 179    { lock: true }
 180  );


Generated : Tue Aug 18 08:20:25 2026 Cross-referenced by PHPXref