Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
fcd792d
Add interactivity runtime
luisherranz Apr 21, 2023
9b0a62e
Add it to the image block
luisherranz Apr 21, 2023
d2c0803
Add a separate webpack config
luisherranz Apr 21, 2023
ed1df51
Make sure the runtime is imported only once
luisherranz Apr 21, 2023
ed043f5
Use sideEffects instead of init
luisherranz Apr 21, 2023
c9f389f
Move script registration to a general file
luisherranz Apr 21, 2023
261dacf
Add `defer` to the interactivity scripts
luisherranz Apr 21, 2023
27cfc1f
Revert changes of the image block
luisherranz Apr 21, 2023
7cf6ba9
Fix init import name
luisherranz Apr 21, 2023
55d37ef
Add experimental setting to use Interactivity API
SantosGuillamot Apr 24, 2023
7cfbffa
Add basic `interactivity.js` file
SantosGuillamot Apr 24, 2023
2a970e3
Enqueue old script/interactivity API conditionally
SantosGuillamot Apr 24, 2023
84146ae
Add `tick()` function until Preact bug is solved
SantosGuillamot Apr 24, 2023
c2c96da
Add code to handle the overlayMenu
SantosGuillamot Apr 24, 2023
71fbd35
Add Interactivity API to submenu block
SantosGuillamot Apr 24, 2023
85bf58f
Add Interactivity API to page list block
SantosGuillamot Apr 24, 2023
027e2a1
Change code to be more declarative and simple
SantosGuillamot Apr 26, 2023
0e4a604
Use `__DIR__` instead of `__FILE__`
SantosGuillamot Apr 27, 2023
67ffd65
Change loading script conditional
SantosGuillamot Apr 27, 2023
122a154
Fix issues momentarily
SantosGuillamot Apr 27, 2023
a6b1e62
Fix some issues with focus
SantosGuillamot Apr 27, 2023
e63c002
Add tabindex to modal
SantosGuillamot Apr 27, 2023
8f388df
Revert to current navigation block
SantosGuillamot Apr 27, 2023
938d57d
Add directives through a filter
SantosGuillamot Apr 27, 2023
1d0472d
Dont add latest modifications to navigation block
SantosGuillamot Apr 27, 2023
d5250fa
Ensure focus doesn't get inside menu after closing
SantosGuillamot Apr 27, 2023
3ae8097
Add conditionals and change function names
SantosGuillamot Apr 28, 2023
624bdb0
Use `gutenberg_is_experiment_enabled` function
SantosGuillamot Apr 28, 2023
ebba7b4
Add interactivity runtime
luisherranz Apr 21, 2023
af59781
Add it to the image block
luisherranz Apr 21, 2023
cca3d60
Add a separate webpack config
luisherranz Apr 21, 2023
160a029
Make sure the runtime is imported only once
luisherranz Apr 21, 2023
7f16f27
Use sideEffects instead of init
luisherranz Apr 21, 2023
f4b2ee8
Move script registration to a general file
luisherranz Apr 21, 2023
378b041
Add `defer` to the interactivity scripts
luisherranz Apr 21, 2023
409d161
Revert changes of the image block
luisherranz Apr 21, 2023
29e11ab
Fix init import name
luisherranz Apr 21, 2023
f4b6c0a
Move and refactor the interactive scritps registration
gziolo Apr 28, 2023
3d94473
Fix code style violations
gziolo Apr 28, 2023
6ae760f
Use `wp-interactivity-` prefix for script handles
gziolo Apr 28, 2023
9d6869e
Improve the matcher for side effects in `package.json`
gziolo Apr 28, 2023
3393bc2
Merge branch 'add-interactivity-runtime' into navigation-block-with-i…
SantosGuillamot May 3, 2023
32013ae
Enqueue interactivity scripts through hook
SantosGuillamot May 3, 2023
f829206
Revert `client-assets.php` file
SantosGuillamot May 3, 2023
3258326
Adapt to latest changes in base branch
SantosGuillamot May 3, 2023
c6d02d8
Add custom useSignalEffect
DAreRodz May 4, 2023
bb36577
Merge branch 'add-interactivity-runtime' into navigation-block-with-i…
SantosGuillamot May 4, 2023
9c95302
Move role attribute to selectors
SantosGuillamot May 4, 2023
af55917
Call `init` after `store` has been initialized
DAreRodz May 4, 2023
b58e6af
Merge branch 'add-interactivity-runtime' into navigation-block-with-i…
SantosGuillamot May 5, 2023
66b765c
Change focusable elements
SantosGuillamot May 5, 2023
7f1db8c
Add namespaces to context
SantosGuillamot May 5, 2023
79fd7b7
Move PHP file to interactivity-api folder
SantosGuillamot May 5, 2023
b553b04
Add comments with the markup to the PHP filter
SantosGuillamot May 5, 2023
182ed89
Remove micromodal attributes
SantosGuillamot May 5, 2023
5751344
Add interactivity runtime
luisherranz Apr 21, 2023
e8201c2
Add it to the image block
luisherranz Apr 21, 2023
df844f0
Add a separate webpack config
luisherranz Apr 21, 2023
d883391
Make sure the runtime is imported only once
luisherranz Apr 21, 2023
b1ea5e3
Use sideEffects instead of init
luisherranz Apr 21, 2023
20d6213
Move script registration to a general file
luisherranz Apr 21, 2023
6fb8aa7
Add `defer` to the interactivity scripts
luisherranz Apr 21, 2023
6c96509
Revert changes of the image block
luisherranz Apr 21, 2023
e843b80
Fix init import name
luisherranz Apr 21, 2023
cdf74b9
Move and refactor the interactive scritps registration
gziolo Apr 28, 2023
de0e874
Fix code style violations
gziolo Apr 28, 2023
fa7c00d
Use `wp-interactivity-` prefix for script handles
gziolo Apr 28, 2023
0d88c77
Improve the matcher for side effects in `package.json`
gziolo Apr 28, 2023
142050c
Add custom useSignalEffect
DAreRodz May 4, 2023
e65b91e
Call `init` after `store` has been initialized
DAreRodz May 4, 2023
9a31bb4
Update lib/experimental/interactivity-api/script-loader.php
gziolo May 5, 2023
0cdab08
Plugin: Ensure that translations are set correctly when overriding sc…
gziolo May 5, 2023
5dcf88e
Remove unnecessary comment in webpack config
SantosGuillamot May 5, 2023
5171e47
Merge branch 'add-interactivity-runtime' into navigation-block-with-i…
SantosGuillamot May 5, 2023
5af4b51
Clean up code to fix PHP coding standards issues
SantosGuillamot May 5, 2023
d4a16f3
Remove extra space
SantosGuillamot May 5, 2023
6f34728
Merge branch 'trunk' into navigation-block-with-interactivity-api
SantosGuillamot May 5, 2023
066d946
Add tests to the navigation block interactivity
SantosGuillamot May 8, 2023
91796b9
Modify `saveSiteEditorEntities` function to wait
SantosGuillamot May 8, 2023
c358346
Fix page-list tests
SantosGuillamot May 9, 2023
68b3dec
Remove e2e tests that are already included in trunk
gziolo May 9, 2023
c6ee68a
Fix the navigation menu when the overlay is not present
gziolo May 10, 2023
15d3546
Ensure that all scripts using Intereactivity API have defer attribute
gziolo May 10, 2023
4367b4d
Remove unused param in the callback used by hook
gziolo May 10, 2023
1626f90
Merge remote-tracking branch 'origin/trunk' into navigation-block-wit…
gziolo May 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Change code to be more declarative and simple
  • Loading branch information
SantosGuillamot committed Apr 26, 2023
commit 027e2a1c81601791aed45b6a293d2aabec980cbd
36 changes: 31 additions & 5 deletions packages/block-library/src/navigation-submenu/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
);

if ( $is_interactivity_api_enabled ) {
$html = '<li data-wp-context=\' { "isSubmenuOpen": false } \'' . $wrapper_attributes . '>';
$html = '<li data-wp-context=\' { "isMenuOpen": false, "trapFocus": false } \'' . $wrapper_attributes . '>';
} else {
$html = '<li ' . $wrapper_attributes . '>';
}
Expand Down Expand Up @@ -176,15 +176,40 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
// The submenu icon is rendered in a button here
// so that there's a clickable element to open the submenu.
if ( $is_interactivity_api_enabled ) {
$html .= '<button data-wp-on.click="actions.core.navigation.openSubmenu" aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false" data-wp-bind.aria-expanded="context.isSubmenuOpen">' . block_core_navigation_submenu_render_submenu_icon() . '</button>';
// Once directives priorities are supported,
// we should be able to move the `wp-on.keydown`
// and `wp-on.focusout` to the parent <li> and
// remove it from here and the <ul>
$html .= '<button
data-wp-on.click="actions.core.navigation.openMenu"
data-wp-on.keydown="actions.core.navigation.handleMenuKeydown"
data-wp-on.focusout="actions.core.navigation.handleMenuFocusout"
aria-label="' . esc_attr( $aria_label ) . '"
class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle"
aria-expanded="false"
data-wp-bind.aria-expanded="context.isMenuOpen"
>'
. block_core_navigation_submenu_render_submenu_icon() .
'</button>';
} else {
$html .= '<button aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">' . block_core_navigation_submenu_render_submenu_icon() . '</button>';
}
}
} else {
// If menus open on click, we render the parent as a button.
if ( $is_interactivity_api_enabled ) {
$html .= '<button data-wp-on.click="actions.core.navigation.openSubmenu" aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation-item__content wp-block-navigation-submenu__toggle" aria-expanded="false" data-wp-bind.aria-expanded="context.isSubmenuOpen">';
// Once directives priorities are supported,
// we should be able to move the `wp-on.keydown`
// and `wp-on.focusout` to the parent <li> and
// remove it from here and the <ul>
$html .= '<button
data-wp-on.click="actions.core.navigation.openMenu"
data-wp-on.keydown="actions.core.navigation.handleMenuKeydown"
aria-label="' . esc_attr( $aria_label ) . '"
class="wp-block-navigation-item__content wp-block-navigation-submenu__toggle"
aria-expanded="false"
data-wp-bind.aria-expanded="context.isMenuOpen"
>';
} else {
$html .= '<button aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation-item__content wp-block-navigation-submenu__toggle" aria-expanded="false">';
}
Expand Down Expand Up @@ -253,8 +278,9 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
if ( $is_interactivity_api_enabled ) {
$html .= sprintf(
'<ul
data-wp-effect="effects.core.navigation.handleSubmenu"
data-wp-context=\'{ "submenuButton": null }\'
data-wp-effect="effects.core.navigation.initModal"
data-wp-on.focusout="actions.core.navigation.handleMenuFocusout"
data-wp-on.keydown="actions.core.navigation.handleMenuKeydown"
%s
>
%s
Expand Down
14 changes: 11 additions & 3 deletions packages/block-library/src/navigation/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -819,8 +819,14 @@ function render_block_core_navigation( $attributes, $content, $block ) {

if ( $is_interactivity_api_enabled ) {
$responsive_container_markup = sprintf(
// Once directives priorities are supported,
// we should be able to move the `wp-on.keydown`
// and `wp-on.focusout` to the parent <nav> and
// remove it from here and the <div>
'<button
data-wp-on.click="actions.core.navigation.openMenu"
data-wp-on.keydown="actions.core.navigation.handleMenuKeydown"
data-wp-on.focusout="actions.core.navigation.handleMenuFocusout"
aria-haspopup="true"
%3$s
class="%6$s""
Expand All @@ -832,8 +838,9 @@ class="%5$s"
data-wp-class.has-modal-open="context.isMenuOpen"
data-wp-class.is-menu-open="context.isMenuOpen"
data-wp-bind.aria-hidden="!context.isMenuOpen"
data-wp-effect="effects.core.navigation.focusElement"
data-wp-on.keydown="effects.core.navigation.focusElement"
data-wp-effect="effects.core.navigation.initModal"
data-wp-on.keydown="actions.core.navigation.handleMenuKeydown"
data-wp-on.focusout="actions.core.navigation.handleMenuFocusout"
style="%7$s"
id="%1$s"
>
Expand All @@ -843,6 +850,7 @@ class="wp-block-navigation__responsive-dialog"
aria-label="%8$s"
data-wp-bind.aria-modal="context.isMenuOpen"
data-wp-bind.role="context.roleAttribute"
data-wp-effect="effects.core.navigation.focusFirstElement"
>
<button
%4$s
Expand Down Expand Up @@ -898,7 +906,7 @@ class="wp-block-navigation__responsive-container-close"
return sprintf(
'<nav
data-wp-island
data-wp-context=\'{ "isMenuOpen": false, "focusedElement": null, "menuButton": null, "roleAttribute": "" }\'
data-wp-context=\'{ "isMenuOpen": false, "trapFocus": true, "roleAttribute": "" }\'
%2$s
>
%3$s
Expand Down
148 changes: 58 additions & 90 deletions packages/block-library/src/navigation/interactivity.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,126 +9,94 @@ store( {
navigation: {
openMenu: ( { context, ref } ) => {
context.isMenuOpen = true;
context.previousFocus = ref;
// Review how to move this to a selector or something similar
context.roleAttribute = 'dialog';
context.menuButton = ref;
// It adds a `has-modal-open` class to the <html> root
document.documentElement.classList.add( 'has-modal-open' );
},
closeMenu: ( { context } ) => {
context.isMenuOpen = false;
// Review how to move this to a selector or something similar
context.roleAttribute = '';
context.focusedElement = null;
context.menuButton.focus();
context.modal = null;
context.previousFocus = null;
// It removes the `has-modal-open` class to the <html> root
document.documentElement.classList.remove(
'has-modal-open'
);
},
openSubmenu: ( { context, ref } ) => {
context.isSubmenuOpen = true;
context.submenuButton = ref;
},
closeSubmenu: ( { context } ) => {
context.isSubmenuOpen = false;
},
},
},
},
effects: {
core: {
navigation: {
focusElement: async ( {
actions,
context,
tick,
ref,
event,
} ) => {
handleMenuKeydown: ( { actions, context, event } ) => {
if ( context.isMenuOpen ) {
// If Escape close the menu
if (
event?.key &&
event.key !== 'Escape' &&
event.key !== 'Tab'
event?.key === 'Escape' ||
event?.keyCode === 27
) {
return;
}

// On ESC, close the menu and focus the hamburger button
if ( event?.key === 'Escape' ) {
context.previousFocus.focus();
actions.core.navigation.closeMenu( { context } );
return;
}

// Until useSignalEffects is fixed: https://github.com/preactjs/signals/issues/228
await tick();

// Focus the first element when menu is open
if ( ! context.focusedElement ) {
ref.querySelector(
'.wp-block-navigation-item > *:first-child'
).focus();
}

// Focus the close button when it gets out of the modal
if ( event?.key === 'Tab' ) {
// Trap focus if set to true
if (
context.trapFocus &&
( event.key === 'Tab' || event.keyCode === 9 )
) {
// If shift + tab it change the direction
if (
window.document.activeElement.closest(
'.is-menu-open'
) !== ref
event.shiftKey &&
window.document.activeElement ===
context.firstFocusableElement
) {
ref.querySelector(
'button.wp-block-navigation__responsive-container-close'
).focus();
event.preventDefault();
context.lastFocusableElement.focus();
} else if (
! event.shiftKey &&
window.document.activeElement ===
context.lastFocusableElement
) {
event.preventDefault();
context.firstFocusableElement.focus();
}
}

context.focusedElement = window.document.activeElement;
}
},
handleSubmenu: async ( { actions, context, ref, tick } ) => {
if ( context.isSubmenuOpen ) {
async function closeSubmenu( e ) {
// Until useSignalEffects is fixed: https://github.com/preactjs/signals/issues/228
await tick();
// Only close submenu if it gets outside of it while tabbing
if (
e.key &&
e.key !== 'Escape' &&
ref.contains( window.document.activeElement )
) {
return;
}

if (
e.key === 'Escape' ||
! ref.contains( window.document.activeElement )
) {
document.removeEventListener(
'click',
closeSubmenu
);
document.removeEventListener(
'keydown',
closeSubmenu
);

actions.core.navigation.closeSubmenu( {
context,
} );
}

// Return focus to the button when closing with "Escape"
if ( e.key === 'Escape' ) {
context.submenuButton.focus();
}
handleMenuFocusout: ( { actions, context, event } ) => {
if ( context.isMenuOpen ) {
// If focus is outside modal (and in the document), close menu
if (
! context.modal.contains( event.relatedTarget ) &&
document.contains( event.relatedTarget )
) {
actions.core.navigation.closeMenu( { context } );
}

}
},
},
},
},
effects: {
core: {
navigation: {
initModal: async ( { context, ref } ) => {
if ( context.isMenuOpen ) {
const focusableElements = ref.querySelectorAll(
'a[href], button:not([disabled]), textarea, input[type="text"], input[type="radio"], input[type="checkbox"], select'
Copy link
Member

@gziolo gziolo Apr 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

);
context.modal = ref;
context.firstFocusableElement = focusableElements[ 0 ];
context.lastFocusableElement =
focusableElements[ focusableElements.length - 1 ];
}
},
focusFirstElement: async ( { context, tick, ref } ) => {
if ( context.isMenuOpen ) {
// Until useSignalEffects is fixed: https://github.com/preactjs/signals/issues/228
await tick();
document.addEventListener( 'click', closeSubmenu );
document.addEventListener( 'keydown', closeSubmenu );
ref.querySelector(
'.wp-block-navigation-item > *:first-child'
).focus();
}
},
},
Expand Down
30 changes: 24 additions & 6 deletions packages/block-library/src/page-list/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,24 +201,42 @@ function block_core_page_list_render_nested_page_list( $open_submenus_on_click,
);

if ( $is_interactivity_api_enabled ) {
$markup .= '<li data-wp-context=\' { "isSubmenuOpen": false } \' class="wp-block-pages-list__item' . esc_attr( $css_class ) . '"' . $style_attribute . '>';
$markup .= '<li data-wp-context=\' { "isMenuOpen": false, "trapFocus": false } \' class="wp-block-pages-list__item' . esc_attr( $css_class ) . '"' . $style_attribute . '>';

if ( isset( $page['children'] ) && $is_navigation_child && $open_submenus_on_click ) {
$markup .= '<button data-wp-on.click="actions.core.navigation.openSubmenu" data-wp-bind.aria-expanded="context.isSubmenuOpen" aria-label="' . esc_attr( $aria_label ) . '" class="' . esc_attr( $navigation_child_content_class ) . ' wp-block-navigation-submenu__toggle" aria-expanded="false">' . esc_html( $title ) .
'</button><span class="wp-block-page-list__submenu-icon wp-block-navigation__submenu-icon"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg></span>';
$markup .= '<button
data-wp-on.click="actions.core.navigation.openMenu"
data-wp-bind.aria-expanded="context.isMenuOpen"
data-wp-on.keydown="actions.core.navigation.handleMenuKeydown"
data-wp-on.focusout="actions.core.navigation.handleMenuFocusout"
aria-label="' . esc_attr( $aria_label ) . '"
class="' . esc_attr( $navigation_child_content_class ) . ' wp-block-navigation-submenu__toggle"
aria-expanded="false"
>' . esc_html( $title ) .
'</button>
<span class="wp-block-page-list__submenu-icon wp-block-navigation__submenu-icon"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg></span>';
} else {
$markup .= '<a class="wp-block-pages-list__item__link' . esc_attr( $navigation_child_content_class ) . '" href="' . esc_url( $page['link'] ) . '"' . $aria_current . '>' . $title . '</a>';
}

if ( isset( $page['children'] ) ) {
if ( $is_navigation_child && $show_submenu_icons && ! $open_submenus_on_click ) {
$markup .= '<button data-wp-on.click="actions.core.navigation.openSubmenu" data-wp-bind.aria-expanded="context.isSubmenuOpen" aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">';
$markup .= '<button
data-wp-on.click="actions.core.navigation.openMenu"
data-wp-bind.aria-expanded="context.isMenuOpen"
data-wp-on.keydown="actions.core.navigation.handleMenuKeydown"
data-wp-on.focusout="actions.core.navigation.handleMenuFocusout"
aria-label="' . esc_attr( $aria_label ) . '"
class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle"
aria-expanded="false"
>';
$markup .= '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
$markup .= '</button>';
}
$markup .= '<ul
data-wp-effect="effects.core.navigation.handleSubmenu"
data-wp-context=\'{ "submenuButton": null }\'
data-wp-effect="effects.core.navigation.initModal"
data-wp-on.focusout="actions.core.navigation.handleMenuFocusout"
data-wp-on.keydown="actions.core.navigation.handleMenuKeydown"
class="wp-block-navigation__submenu-container"
>';
$markup .= block_core_page_list_render_nested_page_list( $open_submenus_on_click, $show_submenu_icons, $is_navigation_child, $page['children'], $is_nested, $active_page_ancestor_ids, $colors, $depth + 1 );
Expand Down