PluginProbe
Gutenberg / 16.6.0
Gutenberg v16.6.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 / block-library / blocks / navigation / view-interactivity.js

view-interactivity.js in Gutenberg 16.6.0, at build/block-library/blocks/navigation/view-interactivity.js

178 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ "use strict";
3 var __webpack_exports__ = {};
4
5 ;// CONCATENATED MODULE: external ["wp","interactivity"]
6 const external_wp_interactivity_namespaceObject = window["wp"]["interactivity"];
7 ;// CONCATENATED MODULE: ./packages/block-library/build-module/navigation/view-interactivity.js
8 /**
9 * WordPress dependencies
10 */
11
12 const focusableSelectors = ['a[href]', 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])', 'select:not([disabled]):not([aria-hidden])', 'textarea:not([disabled]):not([aria-hidden])', 'button:not([disabled]):not([aria-hidden])', '[contenteditable]', '[tabindex]:not([tabindex^="-"])'];
13 const openMenu = (store, menuOpenedOn) => {
14 const {
15 context,
16 ref,
17 selectors
18 } = store;
19 selectors.core.navigation.menuOpenedBy(store)[menuOpenedOn] = true;
20 context.core.navigation.previousFocus = ref;
21 if (context.core.navigation.type === 'overlay') {
22 // Add a `has-modal-open` class to the <html> root.
23 document.documentElement.classList.add('has-modal-open');
24 }
25 };
26 const closeMenu = (store, menuClosedOn) => {
27 const {
28 context,
29 selectors
30 } = store;
31 selectors.core.navigation.menuOpenedBy(store)[menuClosedOn] = false;
32 // Check if the menu is still open or not.
33 if (!selectors.core.navigation.isMenuOpen(store)) {
34 if (context.core.navigation.modal?.contains(window.document.activeElement)) {
35 context.core.navigation.previousFocus.focus();
36 }
37 context.core.navigation.modal = null;
38 context.core.navigation.previousFocus = null;
39 if (context.core.navigation.type === 'overlay') {
40 document.documentElement.classList.remove('has-modal-open');
41 }
42 }
43 };
44 (0,external_wp_interactivity_namespaceObject.store)({
45 effects: {
46 core: {
47 navigation: {
48 initMenu: store => {
49 const {
50 context,
51 selectors,
52 ref
53 } = store;
54 if (selectors.core.navigation.isMenuOpen(store)) {
55 const focusableElements = ref.querySelectorAll(focusableSelectors);
56 context.core.navigation.modal = ref;
57 context.core.navigation.firstFocusableElement = focusableElements[0];
58 context.core.navigation.lastFocusableElement = focusableElements[focusableElements.length - 1];
59 }
60 },
61 focusFirstElement: store => {
62 const {
63 selectors,
64 ref
65 } = store;
66 if (selectors.core.navigation.isMenuOpen(store)) {
67 ref.querySelector('.wp-block-navigation-item > *:first-child').focus();
68 }
69 }
70 }
71 }
72 },
73 selectors: {
74 core: {
75 navigation: {
76 roleAttribute: store => {
77 const {
78 context,
79 selectors
80 } = store;
81 return context.core.navigation.type === 'overlay' && selectors.core.navigation.isMenuOpen(store) ? 'dialog' : '';
82 },
83 isMenuOpen: ({
84 context
85 }) =>
86 // The menu is opened if either `click`, `hover` or `focus` is true.
87 Object.values(context.core.navigation[context.core.navigation.type === 'overlay' ? 'overlayOpenedBy' : 'submenuOpenedBy']).filter(Boolean).length > 0,
88 menuOpenedBy: ({
89 context
90 }) => context.core.navigation[context.core.navigation.type === 'overlay' ? 'overlayOpenedBy' : 'submenuOpenedBy']
91 }
92 }
93 },
94 actions: {
95 core: {
96 navigation: {
97 openMenuOnHover(store) {
98 const {
99 navigation
100 } = store.context.core;
101 if (navigation.type === 'submenu' &&
102 // Only open on hover if the overlay is closed.
103 Object.values(navigation.overlayOpenedBy || {}).filter(Boolean).length === 0) openMenu(store, 'hover');
104 },
105 closeMenuOnHover(store) {
106 closeMenu(store, 'hover');
107 },
108 openMenuOnClick(store) {
109 openMenu(store, 'click');
110 },
111 closeMenuOnClick(store) {
112 closeMenu(store, 'click');
113 closeMenu(store, 'focus');
114 },
115 openMenuOnFocus(store) {
116 openMenu(store, 'focus');
117 },
118 toggleMenuOnClick: store => {
119 const {
120 selectors
121 } = store;
122 const menuOpenedBy = selectors.core.navigation.menuOpenedBy(store);
123 if (menuOpenedBy.click || menuOpenedBy.focus) {
124 closeMenu(store, 'click');
125 closeMenu(store, 'focus');
126 } else {
127 openMenu(store, 'click');
128 }
129 },
130 handleMenuKeydown: store => {
131 const {
132 context,
133 selectors,
134 event
135 } = store;
136 if (selectors.core.navigation.menuOpenedBy(store).click) {
137 // If Escape close the menu.
138 if (event?.key === 'Escape') {
139 closeMenu(store, 'click');
140 closeMenu(store, 'focus');
141 return;
142 }
143
144 // Trap focus if it is an overlay (main menu).
145 if (context.core.navigation.type === 'overlay' && event.key === 'Tab') {
146 // If shift + tab it change the direction.
147 if (event.shiftKey && window.document.activeElement === context.core.navigation.firstFocusableElement) {
148 event.preventDefault();
149 context.core.navigation.lastFocusableElement.focus();
150 } else if (!event.shiftKey && window.document.activeElement === context.core.navigation.lastFocusableElement) {
151 event.preventDefault();
152 context.core.navigation.firstFocusableElement.focus();
153 }
154 }
155 }
156 },
157 handleMenuFocusout: store => {
158 const {
159 context,
160 event
161 } = store;
162 // If focus is outside modal, and in the document, close menu
163 // event.target === The element losing focus
164 // event.relatedTarget === The element receiving focus (if any)
165 // When focusout is outsite the document,
166 // `window.document.activeElement` doesn't change.
167 if (!context.core.navigation.modal?.contains(event.relatedTarget) && event.target !== window.document.activeElement) {
168 closeMenu(store, 'click');
169 closeMenu(store, 'focus');
170 }
171 }
172 }
173 }
174 }
175 });
176
177 /******/ })()
178 ;