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