PluginProbe
Gutenberg / 23.2.0
Gutenberg v23.2.0
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
gutenberg / build / modules / block-library / navigation / view.js
build/modules/block-library/navigation
view.js 5.8 KB 5 months ago view.js.map 11.7 KB 5 months ago view.min.asset.php 180 B 5 months ago view.min.js 3.0 KB 5 months ago view.min.js.map 11.9 KB 5 months ago

view.js in Gutenberg 23.2.0, at build/modules/block-library/navigation/view.js

179 lines 5.8 KB Raw Download Zip
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 },
55 actions: {
56 openMenuOnHover(event) {
57 if (event?.pointerType === "touch") {
58 return;
59 }
60 const { type, overlayOpenedBy } = getContext();
61 if (type === "submenu" && // Only open on hover if the overlay is closed.
62 Object.values(overlayOpenedBy || {}).filter(Boolean).length === 0) {
63 actions.openMenu("hover");
64 }
65 },
66 closeMenuOnHover(event) {
67 if (event?.pointerType === "touch") {
68 return;
69 }
70 const { type, overlayOpenedBy } = getContext();
71 if (type === "submenu" && // Only close on hover if the overlay is closed.
72 Object.values(overlayOpenedBy || {}).filter(Boolean).length === 0) {
73 actions.closeMenu("hover");
74 }
75 },
76 openMenuOnClick() {
77 const ctx = getContext();
78 const { ref } = getElement();
79 ctx.previousFocus = ref;
80 actions.openMenu("click");
81 },
82 closeMenuOnClick() {
83 actions.closeMenu("click");
84 actions.closeMenu("focus");
85 },
86 openMenuOnFocus() {
87 actions.openMenu("focus");
88 },
89 toggleMenuOnClick() {
90 const ctx = getContext();
91 const { ref } = getElement();
92 if (window.document.activeElement !== ref) {
93 ref.focus();
94 }
95 const { menuOpenedBy } = state;
96 if (menuOpenedBy.click || menuOpenedBy.focus) {
97 actions.closeMenu("click");
98 actions.closeMenu("focus");
99 actions.closeMenu("hover");
100 } else {
101 ctx.previousFocus = ref;
102 actions.openMenu("click");
103 }
104 },
105 handleMenuKeydown: withSyncEvent((event) => {
106 const { type, firstFocusableElement, lastFocusableElement } = getContext();
107 if (state.menuOpenedBy.click) {
108 if (event.key === "Escape") {
109 event.stopPropagation();
110 actions.closeMenu("click");
111 actions.closeMenu("focus");
112 return;
113 }
114 if (type === "overlay" && event.key === "Tab") {
115 if (event.shiftKey && window.document.activeElement === firstFocusableElement) {
116 event.preventDefault();
117 lastFocusableElement.focus();
118 } else if (!event.shiftKey && window.document.activeElement === lastFocusableElement) {
119 event.preventDefault();
120 firstFocusableElement.focus();
121 }
122 }
123 }
124 }),
125 handleMenuFocusout: withSyncEvent((event) => {
126 const { modal, type } = getContext();
127 if (event.relatedTarget === null || !modal?.contains(event.relatedTarget) && event.target !== window.document.activeElement && type === "submenu") {
128 actions.closeMenu("click");
129 actions.closeMenu("focus");
130 }
131 }),
132 openMenu(menuOpenedOn = "click") {
133 const { type } = getContext();
134 state.menuOpenedBy[menuOpenedOn] = true;
135 if (type === "overlay") {
136 document.documentElement.classList.add("has-modal-open");
137 }
138 },
139 closeMenu(menuClosedOn = "click") {
140 const ctx = getContext();
141 state.menuOpenedBy[menuClosedOn] = false;
142 if (!state.isMenuOpen) {
143 if (ctx.modal?.contains(window.document.activeElement)) {
144 ctx.previousFocus?.focus();
145 }
146 ctx.modal = null;
147 ctx.previousFocus = null;
148 if (ctx.type === "overlay") {
149 document.documentElement.classList.remove(
150 "has-modal-open"
151 );
152 }
153 }
154 }
155 },
156 callbacks: {
157 initMenu() {
158 const ctx = getContext();
159 const { ref } = getElement();
160 if (state.isMenuOpen) {
161 const focusableElements = getFocusableElements(ref);
162 ctx.modal = ref;
163 ctx.firstFocusableElement = focusableElements[0];
164 ctx.lastFocusableElement = focusableElements[focusableElements.length - 1];
165 }
166 },
167 focusFirstElement() {
168 const { ref } = getElement();
169 if (state.isMenuOpen) {
170 const focusableElements = getFocusableElements(ref);
171 focusableElements?.[0]?.focus();
172 }
173 }
174 }
175 },
176 { lock: true }
177 );
178 //# sourceMappingURL=view.js.map
179