| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
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 );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Tue Aug 18 08:20:25 2026 | Cross-referenced by PHPXref |