@wordpress/block-library 8.14.0 → 8.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/avatar/edit.js +1 -0
  3. package/build/avatar/edit.js.map +1 -1
  4. package/build/block/index.js +2 -1
  5. package/build/block/index.js.map +1 -1
  6. package/build/buttons/edit.js +2 -2
  7. package/build/buttons/edit.js.map +1 -1
  8. package/build/column/edit.native.js +1 -4
  9. package/build/column/edit.native.js.map +1 -1
  10. package/build/columns/edit.js +1 -0
  11. package/build/columns/edit.js.map +1 -1
  12. package/build/comment-author-avatar/edit.js +1 -0
  13. package/build/comment-author-avatar/edit.js.map +1 -1
  14. package/build/cover/deprecated.js +4 -2
  15. package/build/cover/deprecated.js.map +1 -1
  16. package/build/embed/embed-placeholder.native.js +37 -13
  17. package/build/embed/embed-placeholder.native.js.map +1 -1
  18. package/build/file/index.js +1 -2
  19. package/build/file/index.js.map +1 -1
  20. package/build/file/inspector.js +1 -0
  21. package/build/file/inspector.js.map +1 -1
  22. package/build/file/view-interactivity.js +23 -0
  23. package/build/file/view-interactivity.js.map +1 -0
  24. package/build/file/view.js +1 -15
  25. package/build/file/view.js.map +1 -1
  26. package/build/footnotes/edit.js +20 -1
  27. package/build/footnotes/edit.js.map +1 -1
  28. package/build/footnotes/format.js +19 -16
  29. package/build/footnotes/format.js.map +1 -1
  30. package/build/footnotes/index.js +0 -1
  31. package/build/footnotes/index.js.map +1 -1
  32. package/build/gallery/edit.js +1 -1
  33. package/build/gallery/edit.js.map +1 -1
  34. package/build/latest-comments/edit.js +1 -0
  35. package/build/latest-comments/edit.js.map +1 -1
  36. package/build/latest-posts/edit.js +2 -0
  37. package/build/latest-posts/edit.js.map +1 -1
  38. package/build/list/edit.js +4 -4
  39. package/build/list/edit.js.map +1 -1
  40. package/build/media-text/media-container.native.js +2 -1
  41. package/build/media-text/media-container.native.js.map +1 -1
  42. package/build/missing/edit.native.js +7 -5
  43. package/build/missing/edit.native.js.map +1 -1
  44. package/build/navigation/constants.js +10 -4
  45. package/build/navigation/constants.js.map +1 -1
  46. package/build/navigation/edit/index.js +16 -2
  47. package/build/navigation/edit/index.js.map +1 -1
  48. package/build/navigation/edit/inner-blocks.js +2 -2
  49. package/build/navigation/edit/inner-blocks.js.map +1 -1
  50. package/build/navigation/edit/unsaved-inner-blocks.js +2 -2
  51. package/build/navigation/edit/unsaved-inner-blocks.js.map +1 -1
  52. package/build/navigation/edit/use-convert-classic-menu-to-block-menu.js +10 -15
  53. package/build/navigation/edit/use-convert-classic-menu-to-block-menu.js.map +1 -1
  54. package/build/navigation/index.js +2 -3
  55. package/build/navigation/index.js.map +1 -1
  56. package/build/navigation/use-navigation-menu.js +33 -45
  57. package/build/navigation/use-navigation-menu.js.map +1 -1
  58. package/build/navigation/view-interactivity.js +185 -0
  59. package/build/navigation/view-interactivity.js.map +1 -0
  60. package/build/navigation/view-modal.js +64 -0
  61. package/build/navigation/view-modal.js.map +1 -0
  62. package/build/navigation/view.js +50 -174
  63. package/build/navigation/view.js.map +1 -1
  64. package/build/navigation-link/edit.js +12 -7
  65. package/build/navigation-link/edit.js.map +1 -1
  66. package/build/navigation-submenu/edit.js +2 -2
  67. package/build/navigation-submenu/edit.js.map +1 -1
  68. package/build/query-pagination/edit.js +1 -1
  69. package/build/query-pagination/edit.js.map +1 -1
  70. package/build/query-title/edit.js +43 -1
  71. package/build/query-title/edit.js.map +1 -1
  72. package/build/quote/transforms.js +8 -0
  73. package/build/quote/transforms.js.map +1 -1
  74. package/build/rss/edit.js +3 -0
  75. package/build/rss/edit.js.map +1 -1
  76. package/build/search/edit.js +4 -3
  77. package/build/search/edit.js.map +1 -1
  78. package/build/search/index.js +1 -0
  79. package/build/search/index.js.map +1 -1
  80. package/build/site-logo/edit.js +1 -0
  81. package/build/site-logo/edit.js.map +1 -1
  82. package/build/tag-cloud/edit.js +1 -0
  83. package/build/tag-cloud/edit.js.map +1 -1
  84. package/build/template-part/edit/index.js +1 -1
  85. package/build/template-part/edit/index.js.map +1 -1
  86. package/build/text-columns/edit.js +1 -0
  87. package/build/text-columns/edit.js.map +1 -1
  88. package/build-module/avatar/edit.js +1 -0
  89. package/build-module/avatar/edit.js.map +1 -1
  90. package/build-module/block/index.js +2 -1
  91. package/build-module/block/index.js.map +1 -1
  92. package/build-module/buttons/edit.js +2 -2
  93. package/build-module/buttons/edit.js.map +1 -1
  94. package/build-module/column/edit.native.js +1 -4
  95. package/build-module/column/edit.native.js.map +1 -1
  96. package/build-module/columns/edit.js +1 -0
  97. package/build-module/columns/edit.js.map +1 -1
  98. package/build-module/comment-author-avatar/edit.js +1 -0
  99. package/build-module/comment-author-avatar/edit.js.map +1 -1
  100. package/build-module/cover/deprecated.js +4 -2
  101. package/build-module/cover/deprecated.js.map +1 -1
  102. package/build-module/embed/embed-placeholder.native.js +37 -14
  103. package/build-module/embed/embed-placeholder.native.js.map +1 -1
  104. package/build-module/file/index.js +1 -2
  105. package/build-module/file/index.js.map +1 -1
  106. package/build-module/file/inspector.js +1 -0
  107. package/build-module/file/inspector.js.map +1 -1
  108. package/build-module/file/view-interactivity.js +19 -0
  109. package/build-module/file/view-interactivity.js.map +1 -0
  110. package/build-module/file/view.js +2 -15
  111. package/build-module/file/view.js.map +1 -1
  112. package/build-module/footnotes/edit.js +18 -2
  113. package/build-module/footnotes/edit.js.map +1 -1
  114. package/build-module/footnotes/format.js +19 -16
  115. package/build-module/footnotes/format.js.map +1 -1
  116. package/build-module/footnotes/index.js +0 -1
  117. package/build-module/footnotes/index.js.map +1 -1
  118. package/build-module/gallery/edit.js +1 -1
  119. package/build-module/gallery/edit.js.map +1 -1
  120. package/build-module/latest-comments/edit.js +1 -0
  121. package/build-module/latest-comments/edit.js.map +1 -1
  122. package/build-module/latest-posts/edit.js +2 -0
  123. package/build-module/latest-posts/edit.js.map +1 -1
  124. package/build-module/list/edit.js +4 -4
  125. package/build-module/list/edit.js.map +1 -1
  126. package/build-module/media-text/media-container.native.js +2 -1
  127. package/build-module/media-text/media-container.native.js.map +1 -1
  128. package/build-module/missing/edit.native.js +8 -6
  129. package/build-module/missing/edit.native.js.map +1 -1
  130. package/build-module/navigation/constants.js +8 -3
  131. package/build-module/navigation/constants.js.map +1 -1
  132. package/build-module/navigation/edit/index.js +17 -3
  133. package/build-module/navigation/edit/index.js.map +1 -1
  134. package/build-module/navigation/edit/inner-blocks.js +2 -2
  135. package/build-module/navigation/edit/inner-blocks.js.map +1 -1
  136. package/build-module/navigation/edit/unsaved-inner-blocks.js +2 -2
  137. package/build-module/navigation/edit/unsaved-inner-blocks.js.map +1 -1
  138. package/build-module/navigation/edit/use-convert-classic-menu-to-block-menu.js +10 -14
  139. package/build-module/navigation/edit/use-convert-classic-menu-to-block-menu.js.map +1 -1
  140. package/build-module/navigation/index.js +2 -3
  141. package/build-module/navigation/index.js.map +1 -1
  142. package/build-module/navigation/use-navigation-menu.js +35 -47
  143. package/build-module/navigation/use-navigation-menu.js.map +1 -1
  144. package/build-module/navigation/view-interactivity.js +182 -0
  145. package/build-module/navigation/view-interactivity.js.map +1 -0
  146. package/build-module/navigation/view-modal.js +58 -0
  147. package/build-module/navigation/view-modal.js.map +1 -0
  148. package/build-module/navigation/view.js +50 -173
  149. package/build-module/navigation/view.js.map +1 -1
  150. package/build-module/navigation-link/edit.js +12 -7
  151. package/build-module/navigation-link/edit.js.map +1 -1
  152. package/build-module/navigation-submenu/edit.js +2 -2
  153. package/build-module/navigation-submenu/edit.js.map +1 -1
  154. package/build-module/query-pagination/edit.js +1 -1
  155. package/build-module/query-pagination/edit.js.map +1 -1
  156. package/build-module/query-title/edit.js +44 -3
  157. package/build-module/query-title/edit.js.map +1 -1
  158. package/build-module/quote/transforms.js +8 -0
  159. package/build-module/quote/transforms.js.map +1 -1
  160. package/build-module/rss/edit.js +3 -0
  161. package/build-module/rss/edit.js.map +1 -1
  162. package/build-module/search/edit.js +4 -3
  163. package/build-module/search/edit.js.map +1 -1
  164. package/build-module/search/index.js +1 -0
  165. package/build-module/search/index.js.map +1 -1
  166. package/build-module/site-logo/edit.js +1 -0
  167. package/build-module/site-logo/edit.js.map +1 -1
  168. package/build-module/tag-cloud/edit.js +1 -0
  169. package/build-module/tag-cloud/edit.js.map +1 -1
  170. package/build-module/template-part/edit/index.js +1 -1
  171. package/build-module/template-part/edit/index.js.map +1 -1
  172. package/build-module/text-columns/edit.js +1 -0
  173. package/build-module/text-columns/edit.js.map +1 -1
  174. package/build-style/details/style-rtl.css +4 -2
  175. package/build-style/details/style.css +4 -2
  176. package/build-style/footnotes/style-rtl.css +4 -3
  177. package/build-style/footnotes/style.css +4 -3
  178. package/build-style/navigation/style-rtl.css +14 -2
  179. package/build-style/navigation/style.css +14 -2
  180. package/build-style/query-pagination/style-rtl.css +4 -2
  181. package/build-style/query-pagination/style.css +4 -2
  182. package/build-style/style-rtl.css +26 -9
  183. package/build-style/style.css +26 -9
  184. package/package.json +33 -32
  185. package/src/audio/test/__snapshots__/edit.native.js.snap +58 -33
  186. package/src/avatar/edit.js +1 -0
  187. package/src/block/block.json +2 -1
  188. package/src/block/editor.native.scss +2 -2
  189. package/src/buttons/edit.js +2 -2
  190. package/src/column/edit.native.js +4 -10
  191. package/src/column/editor.native.scss +0 -4
  192. package/src/columns/edit.js +1 -0
  193. package/src/comment-author-avatar/edit.js +1 -0
  194. package/src/comment-template/index.php +5 -2
  195. package/src/cover/deprecated.js +2 -0
  196. package/src/embed/embed-placeholder.native.js +80 -47
  197. package/src/embed/styles.native.scss +54 -18
  198. package/src/embed/test/index.native.js +5 -5
  199. package/src/file/block.json +1 -2
  200. package/src/file/index.php +19 -1
  201. package/src/file/inspector.js +1 -0
  202. package/src/file/test/__snapshots__/edit.native.js.snap +58 -33
  203. package/src/file/view-interactivity.js +18 -0
  204. package/src/file/view.js +5 -14
  205. package/src/footnotes/block.json +0 -1
  206. package/src/footnotes/edit.js +21 -2
  207. package/src/footnotes/format.js +22 -20
  208. package/src/footnotes/style.scss +6 -3
  209. package/src/gallery/edit.js +1 -1
  210. package/src/gallery/test/index.native.js +17 -16
  211. package/src/home-link/index.php +15 -2
  212. package/src/image/index.php +47 -8
  213. package/src/image/test/edit.native.js +1 -1
  214. package/src/latest-comments/edit.js +1 -0
  215. package/src/latest-posts/edit.js +2 -0
  216. package/src/list/edit.js +6 -4
  217. package/src/list/test/edit.native.js +129 -33
  218. package/src/media-text/media-container.native.js +1 -0
  219. package/src/missing/edit.native.js +12 -10
  220. package/src/missing/style.native.scss +19 -12
  221. package/src/missing/test/__snapshots__/edit.native.js.snap +21 -13
  222. package/src/navigation/block.json +2 -3
  223. package/src/navigation/constants.js +12 -6
  224. package/src/navigation/edit/index.js +29 -1
  225. package/src/navigation/edit/inner-blocks.js +2 -2
  226. package/src/navigation/edit/unsaved-inner-blocks.js +2 -2
  227. package/src/navigation/edit/use-convert-classic-menu-to-block-menu.js +17 -21
  228. package/src/navigation/index.php +24 -6
  229. package/src/navigation/style.scss +27 -8
  230. package/src/navigation/use-navigation-menu.js +39 -63
  231. package/src/navigation/view-interactivity.js +196 -0
  232. package/src/navigation/view-modal.js +78 -0
  233. package/src/navigation/view.js +67 -189
  234. package/src/navigation-link/edit.js +61 -47
  235. package/src/navigation-submenu/edit.js +2 -2
  236. package/src/paragraph/test/__snapshots__/edit.native.js.snap +1 -0
  237. package/src/paragraph/test/edit.native.js +26 -0
  238. package/src/post-template/index.php +4 -2
  239. package/src/post-title/index.php +6 -3
  240. package/src/preformatted/test/__snapshots__/edit.native.js.snap +2 -0
  241. package/src/query-pagination/edit.js +17 -14
  242. package/src/query-title/edit.js +48 -6
  243. package/src/quote/test/__snapshots__/transforms.native.js.snap +10 -0
  244. package/src/quote/test/transforms.native.js +5 -1
  245. package/src/quote/transforms.js +13 -0
  246. package/src/rss/edit.js +3 -0
  247. package/src/search/block.json +1 -0
  248. package/src/search/edit.js +4 -3
  249. package/src/search/index.php +22 -4
  250. package/src/search/test/__snapshots__/edit.native.js.snap +7 -0
  251. package/src/site-logo/edit.js +1 -0
  252. package/src/tag-cloud/edit.js +1 -0
  253. package/src/template-part/edit/index.js +1 -1
  254. package/src/template-part/index.php +9 -15
  255. package/src/text-columns/edit.js +1 -0
  256. package/build/gallery/shared-icon.native.js +0 -38
  257. package/build/gallery/shared-icon.native.js.map +0 -1
  258. package/build-module/gallery/shared-icon.native.js +0 -24
  259. package/build-module/gallery/shared-icon.native.js.map +0 -1
  260. package/src/gallery/shared-icon.native.js +0 -23
@@ -31,6 +31,7 @@ $navigation-icon-size: 24px;
31
31
 
32
32
  // Menu item container.
33
33
  .wp-block-navigation-item {
34
+ background-color: inherit;
34
35
  display: flex;
35
36
  align-items: center;
36
37
  position: relative;
@@ -398,15 +399,26 @@ button.wp-block-navigation-item__content {
398
399
  }
399
400
 
400
401
  // Default background and font color.
401
- .wp-block-navigation:not(.has-background) {
402
+ .wp-block-navigation:not(.has-background) .wp-block-navigation__submenu-container {
403
+ // Set a background color for submenus so that they're not transparent.
404
+ // NOTE TO DEVS - if refactoring this code, please double-check that
405
+ // submenus have a default background color, this feature has regressed
406
+ // several times, so care needs to be taken.
407
+ background-color: #fff;
408
+ border: 1px solid rgba(0, 0, 0, 0.15);
409
+ }
410
+
411
+ // If we do have a background color selected, inherit it from the navigation block
412
+ .wp-block-navigation.has-background {
402
413
  .wp-block-navigation__submenu-container {
403
- // Set a background color for submenus so that they're not transparent.
404
- // NOTE TO DEVS - if refactoring this code, please double-check that
405
- // submenus have a default background color, this feature has regressed
406
- // several times, so care needs to be taken.
407
- background-color: #fff;
414
+ background-color: inherit;
415
+ }
416
+ }
417
+
418
+ .wp-block-navigation:not(.has-text-color) {
419
+ .wp-block-navigation__submenu-container {
420
+ // Set a default color for submenu text if none is selected
408
421
  color: #000;
409
- border: 1px solid rgba(0, 0, 0, 0.15);
410
422
  }
411
423
  }
412
424
 
@@ -458,7 +470,8 @@ button.wp-block-navigation-item__content {
458
470
  right: 0;
459
471
  bottom: 0;
460
472
 
461
- .wp-block-navigation-link a {
473
+ // Low specificity so that themes can override.
474
+ & :where(.wp-block-navigation-item a) {
462
475
  color: inherit;
463
476
  }
464
477
 
@@ -579,6 +592,7 @@ button.wp-block-navigation-item__content {
579
592
  // Remove background colors for items inside the overlay menu.
580
593
  // Has to be !important to override global styles.
581
594
  .wp-block-navigation-item .wp-block-navigation__submenu-container,
595
+ .wp-block-navigation__container,
582
596
  .wp-block-navigation-item,
583
597
  .wp-block-page-list {
584
598
  color: inherit !important;
@@ -620,9 +634,14 @@ button.wp-block-navigation-item__content {
620
634
  .wp-block-navigation:not(.has-background)
621
635
  .wp-block-navigation__responsive-container.is-menu-open {
622
636
  background-color: #fff;
637
+ }
638
+
639
+ .wp-block-navigation:not(.has-text-color)
640
+ .wp-block-navigation__responsive-container.is-menu-open {
623
641
  color: #000;
624
642
  }
625
643
 
644
+
626
645
  // Overlay menu toggle button label
627
646
  .wp-block-navigation__toggle_button_label {
628
647
  font-size: 1rem;
@@ -4,85 +4,61 @@
4
4
  import {
5
5
  store as coreStore,
6
6
  useResourcePermissions,
7
+ useEntityRecords,
7
8
  } from '@wordpress/core-data';
8
9
  import { useSelect } from '@wordpress/data';
9
10
 
10
11
  /**
11
12
  * Internal dependencies
12
13
  */
13
- import { SELECT_NAVIGATION_MENUS_ARGS } from './constants';
14
+ import { PRELOADED_NAVIGATION_MENUS_QUERY } from './constants';
14
15
 
15
16
  export default function useNavigationMenu( ref ) {
16
17
  const permissions = useResourcePermissions( 'navigation', ref );
17
18
 
18
- return useSelect(
19
+ const {
20
+ navigationMenu,
21
+ isNavigationMenuResolved,
22
+ isNavigationMenuMissing,
23
+ } = useSelect(
19
24
  ( select ) => {
20
- const {
21
- canCreate,
22
- canUpdate,
23
- canDelete,
24
- isResolving,
25
- hasResolved,
26
- } = permissions;
27
-
28
- const {
29
- navigationMenus,
30
- isResolvingNavigationMenus,
31
- hasResolvedNavigationMenus,
32
- } = selectNavigationMenus( select );
33
-
34
- const {
35
- navigationMenu,
36
- isNavigationMenuResolved,
37
- isNavigationMenuMissing,
38
- } = selectExistingMenu( select, ref );
39
-
40
- return {
41
- navigationMenus,
42
- isResolvingNavigationMenus,
43
- hasResolvedNavigationMenus,
44
-
45
- navigationMenu,
46
- isNavigationMenuResolved,
47
- isNavigationMenuMissing,
48
-
49
- canSwitchNavigationMenu: ref
50
- ? navigationMenus?.length > 1
51
- : navigationMenus?.length > 0,
52
-
53
- canUserCreateNavigationMenu: canCreate,
54
- isResolvingCanUserCreateNavigationMenu: isResolving,
55
- hasResolvedCanUserCreateNavigationMenu: hasResolved,
56
-
57
- canUserUpdateNavigationMenu: canUpdate,
58
- hasResolvedCanUserUpdateNavigationMenu: ref
59
- ? hasResolved
60
- : undefined,
61
-
62
- canUserDeleteNavigationMenu: canDelete,
63
- hasResolvedCanUserDeleteNavigationMenu: ref
64
- ? hasResolved
65
- : undefined,
66
- };
25
+ return selectExistingMenu( select, ref );
67
26
  },
68
- [ ref, permissions ]
27
+ [ ref ]
69
28
  );
70
- }
71
29
 
72
- function selectNavigationMenus( select ) {
73
- const { getEntityRecords, hasFinishedResolution, isResolving } =
74
- select( coreStore );
30
+ const { canCreate, canUpdate, canDelete, isResolving, hasResolved } =
31
+ permissions;
32
+
33
+ const {
34
+ records: navigationMenus,
35
+ isResolving: isResolvingNavigationMenus,
36
+ hasResolved: hasResolvedNavigationMenus,
37
+ } = useEntityRecords(
38
+ 'postType',
39
+ `wp_navigation`,
40
+ PRELOADED_NAVIGATION_MENUS_QUERY
41
+ );
42
+
43
+ const canSwitchNavigationMenu = ref
44
+ ? navigationMenus?.length > 1
45
+ : navigationMenus?.length > 0;
75
46
 
76
47
  return {
77
- navigationMenus: getEntityRecords( ...SELECT_NAVIGATION_MENUS_ARGS ),
78
- isResolvingNavigationMenus: isResolving(
79
- 'getEntityRecords',
80
- SELECT_NAVIGATION_MENUS_ARGS
81
- ),
82
- hasResolvedNavigationMenus: hasFinishedResolution(
83
- 'getEntityRecords',
84
- SELECT_NAVIGATION_MENUS_ARGS
85
- ),
48
+ navigationMenu,
49
+ isNavigationMenuResolved,
50
+ isNavigationMenuMissing,
51
+ navigationMenus,
52
+ isResolvingNavigationMenus,
53
+ hasResolvedNavigationMenus,
54
+ canSwitchNavigationMenu,
55
+ canUserCreateNavigationMenu: canCreate,
56
+ isResolvingCanUserCreateNavigationMenu: isResolving,
57
+ hasResolvedCanUserCreateNavigationMenu: hasResolved,
58
+ canUserUpdateNavigationMenu: canUpdate,
59
+ hasResolvedCanUserUpdateNavigationMenu: ref ? hasResolved : undefined,
60
+ canUserDeleteNavigationMenu: canDelete,
61
+ hasResolvedCanUserDeleteNavigationMenu: ref ? hasResolved : undefined,
86
62
  };
87
63
  }
88
64
 
@@ -0,0 +1,196 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { store as wpStore } from '@wordpress/interactivity';
5
+
6
+ const focusableSelectors = [
7
+ 'a[href]',
8
+ 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',
9
+ 'select:not([disabled]):not([aria-hidden])',
10
+ 'textarea:not([disabled]):not([aria-hidden])',
11
+ 'button:not([disabled]):not([aria-hidden])',
12
+ '[contenteditable]',
13
+ '[tabindex]:not([tabindex^="-"])',
14
+ ];
15
+
16
+ const openMenu = ( store, menuOpenedOn ) => {
17
+ const { context, ref, selectors } = store;
18
+ selectors.core.navigation.menuOpenedBy( store )[ menuOpenedOn ] = true;
19
+ context.core.navigation.previousFocus = ref;
20
+ if ( context.core.navigation.type === 'overlay' ) {
21
+ // Add a `has-modal-open` class to the <html> root.
22
+ document.documentElement.classList.add( 'has-modal-open' );
23
+ }
24
+ };
25
+
26
+ const closeMenu = ( store, menuClosedOn ) => {
27
+ const { context, selectors } = store;
28
+ selectors.core.navigation.menuOpenedBy( store )[ menuClosedOn ] = false;
29
+ // Check if the menu is still open or not.
30
+ if ( ! selectors.core.navigation.isMenuOpen( store ) ) {
31
+ if (
32
+ context.core.navigation.modal?.contains(
33
+ window.document.activeElement
34
+ )
35
+ ) {
36
+ context.core.navigation.previousFocus.focus();
37
+ }
38
+ context.core.navigation.modal = null;
39
+ context.core.navigation.previousFocus = null;
40
+ if ( context.core.navigation.type === 'overlay' ) {
41
+ document.documentElement.classList.remove( 'has-modal-open' );
42
+ }
43
+ }
44
+ };
45
+
46
+ wpStore( {
47
+ effects: {
48
+ core: {
49
+ navigation: {
50
+ initMenu: ( store ) => {
51
+ const { context, selectors, ref } = store;
52
+ if ( selectors.core.navigation.isMenuOpen( store ) ) {
53
+ const focusableElements =
54
+ ref.querySelectorAll( focusableSelectors );
55
+ context.core.navigation.modal = ref;
56
+ context.core.navigation.firstFocusableElement =
57
+ focusableElements[ 0 ];
58
+ context.core.navigation.lastFocusableElement =
59
+ focusableElements[ focusableElements.length - 1 ];
60
+ }
61
+ },
62
+ focusFirstElement: ( store ) => {
63
+ const { selectors, ref } = store;
64
+ if ( selectors.core.navigation.isMenuOpen( store ) ) {
65
+ ref.querySelector(
66
+ '.wp-block-navigation-item > *:first-child'
67
+ ).focus();
68
+ }
69
+ },
70
+ },
71
+ },
72
+ },
73
+ selectors: {
74
+ core: {
75
+ navigation: {
76
+ roleAttribute: ( store ) => {
77
+ const { context, selectors } = store;
78
+ return context.core.navigation.type === 'overlay' &&
79
+ selectors.core.navigation.isMenuOpen( store )
80
+ ? 'dialog'
81
+ : '';
82
+ },
83
+ isMenuOpen: ( { context } ) =>
84
+ // The menu is opened if either `click`, `hover` or `focus` is true.
85
+ Object.values(
86
+ context.core.navigation[
87
+ context.core.navigation.type === 'overlay'
88
+ ? 'overlayOpenedBy'
89
+ : 'submenuOpenedBy'
90
+ ]
91
+ ).filter( Boolean ).length > 0,
92
+ menuOpenedBy: ( { context } ) =>
93
+ context.core.navigation[
94
+ context.core.navigation.type === 'overlay'
95
+ ? 'overlayOpenedBy'
96
+ : 'submenuOpenedBy'
97
+ ],
98
+ },
99
+ },
100
+ },
101
+ actions: {
102
+ core: {
103
+ navigation: {
104
+ openMenuOnHover( store ) {
105
+ const { navigation } = store.context.core;
106
+ if (
107
+ navigation.type === 'submenu' &&
108
+ // Only open on hover if the overlay is closed.
109
+ Object.values(
110
+ navigation.overlayOpenedBy || {}
111
+ ).filter( Boolean ).length === 0
112
+ )
113
+ openMenu( store, 'hover' );
114
+ },
115
+ closeMenuOnHover( store ) {
116
+ closeMenu( store, 'hover' );
117
+ },
118
+ openMenuOnClick( store ) {
119
+ openMenu( store, 'click' );
120
+ },
121
+ closeMenuOnClick( store ) {
122
+ closeMenu( store, 'click' );
123
+ closeMenu( store, 'focus' );
124
+ },
125
+ openMenuOnFocus( store ) {
126
+ openMenu( store, 'focus' );
127
+ },
128
+ toggleMenuOnClick: ( store ) => {
129
+ const { selectors } = store;
130
+ const menuOpenedBy =
131
+ selectors.core.navigation.menuOpenedBy( store );
132
+ if ( menuOpenedBy.click || menuOpenedBy.focus ) {
133
+ closeMenu( store, 'click' );
134
+ closeMenu( store, 'focus' );
135
+ } else {
136
+ openMenu( store, 'click' );
137
+ }
138
+ },
139
+ handleMenuKeydown: ( store ) => {
140
+ const { context, selectors, event } = store;
141
+ if (
142
+ selectors.core.navigation.menuOpenedBy( store ).click
143
+ ) {
144
+ // If Escape close the menu.
145
+ if ( event?.key === 'Escape' ) {
146
+ closeMenu( store, 'click' );
147
+ closeMenu( store, 'focus' );
148
+ return;
149
+ }
150
+
151
+ // Trap focus if it is an overlay (main menu).
152
+ if (
153
+ context.core.navigation.type === 'overlay' &&
154
+ event.key === 'Tab'
155
+ ) {
156
+ // If shift + tab it change the direction.
157
+ if (
158
+ event.shiftKey &&
159
+ window.document.activeElement ===
160
+ context.core.navigation
161
+ .firstFocusableElement
162
+ ) {
163
+ event.preventDefault();
164
+ context.core.navigation.lastFocusableElement.focus();
165
+ } else if (
166
+ ! event.shiftKey &&
167
+ window.document.activeElement ===
168
+ context.core.navigation.lastFocusableElement
169
+ ) {
170
+ event.preventDefault();
171
+ context.core.navigation.firstFocusableElement.focus();
172
+ }
173
+ }
174
+ }
175
+ },
176
+ handleMenuFocusout: ( store ) => {
177
+ const { context, event } = store;
178
+ // If focus is outside modal, and in the document, close menu
179
+ // event.target === The element losing focus
180
+ // event.relatedTarget === The element receiving focus (if any)
181
+ // When focusout is outsite the document,
182
+ // `window.document.activeElement` doesn't change.
183
+ if (
184
+ ! context.core.navigation.modal?.contains(
185
+ event.relatedTarget
186
+ ) &&
187
+ event.target !== window.document.activeElement
188
+ ) {
189
+ closeMenu( store, 'click' );
190
+ closeMenu( store, 'focus' );
191
+ }
192
+ },
193
+ },
194
+ },
195
+ },
196
+ } );
@@ -0,0 +1,78 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import MicroModal from 'micromodal';
5
+
6
+ // Responsive navigation toggle.
7
+ function navigationToggleModal( modal ) {
8
+ const dialogContainer = modal.querySelector(
9
+ `.wp-block-navigation__responsive-dialog`
10
+ );
11
+
12
+ const isHidden = 'true' === modal.getAttribute( 'aria-hidden' );
13
+
14
+ modal.classList.toggle( 'has-modal-open', ! isHidden );
15
+ dialogContainer.toggleAttribute( 'aria-modal', ! isHidden );
16
+
17
+ if ( isHidden ) {
18
+ dialogContainer.removeAttribute( 'role' );
19
+ dialogContainer.removeAttribute( 'aria-modal' );
20
+ } else {
21
+ dialogContainer.setAttribute( 'role', 'dialog' );
22
+ dialogContainer.setAttribute( 'aria-modal', 'true' );
23
+ }
24
+
25
+ // Add a class to indicate the modal is open.
26
+ const htmlElement = document.documentElement;
27
+ htmlElement.classList.toggle( 'has-modal-open' );
28
+ }
29
+
30
+ function isLinkToAnchorOnCurrentPage( node ) {
31
+ return (
32
+ node.hash &&
33
+ node.protocol === window.location.protocol &&
34
+ node.host === window.location.host &&
35
+ node.pathname === window.location.pathname &&
36
+ node.search === window.location.search
37
+ );
38
+ }
39
+
40
+ window.addEventListener( 'load', () => {
41
+ MicroModal.init( {
42
+ onShow: navigationToggleModal,
43
+ onClose: navigationToggleModal,
44
+ openClass: 'is-menu-open',
45
+ } );
46
+
47
+ // Close modal automatically on clicking anchor links inside modal.
48
+ const navigationLinks = document.querySelectorAll(
49
+ '.wp-block-navigation-item__content'
50
+ );
51
+
52
+ navigationLinks.forEach( function ( link ) {
53
+ // Ignore non-anchor links and anchor links which open on a new tab.
54
+ if (
55
+ ! isLinkToAnchorOnCurrentPage( link ) ||
56
+ link.attributes?.target === '_blank'
57
+ ) {
58
+ return;
59
+ }
60
+
61
+ // Find the specific parent modal for this link
62
+ // since .close() won't work without an ID if there are
63
+ // multiple navigation menus in a post/page.
64
+ const modal = link.closest(
65
+ '.wp-block-navigation__responsive-container'
66
+ );
67
+ const modalId = modal?.getAttribute( 'id' );
68
+
69
+ link.addEventListener( 'click', () => {
70
+ // check if modal exists and is open before trying to close it
71
+ // otherwise Micromodal will toggle the `has-modal-open` class
72
+ // on the html tag which prevents scrolling
73
+ if ( modalId && modal.classList.contains( 'has-modal-open' ) ) {
74
+ MicroModal.close( modalId );
75
+ }
76
+ } );
77
+ } );
78
+ } );