-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Experimental: Navigation block with the Interactivity API #50041
Merged
Merged
Changes from all commits
Commits
Show all changes
85 commits
Select commit
Hold shift + click to select a range
fcd792d
Add interactivity runtime
luisherranz 9b0a62e
Add it to the image block
luisherranz d2c0803
Add a separate webpack config
luisherranz ed1df51
Make sure the runtime is imported only once
luisherranz ed043f5
Use sideEffects instead of init
luisherranz c9f389f
Move script registration to a general file
luisherranz 261dacf
Add `defer` to the interactivity scripts
luisherranz 27cfc1f
Revert changes of the image block
luisherranz 7cf6ba9
Fix init import name
luisherranz 55d37ef
Add experimental setting to use Interactivity API
SantosGuillamot 7cfbffa
Add basic `interactivity.js` file
SantosGuillamot 2a970e3
Enqueue old script/interactivity API conditionally
SantosGuillamot 84146ae
Add `tick()` function until Preact bug is solved
SantosGuillamot c2c96da
Add code to handle the overlayMenu
SantosGuillamot 71fbd35
Add Interactivity API to submenu block
SantosGuillamot 85bf58f
Add Interactivity API to page list block
SantosGuillamot 027e2a1
Change code to be more declarative and simple
SantosGuillamot 0e4a604
Use `__DIR__` instead of `__FILE__`
SantosGuillamot 67ffd65
Change loading script conditional
SantosGuillamot 122a154
Fix issues momentarily
SantosGuillamot a6b1e62
Fix some issues with focus
SantosGuillamot e63c002
Add tabindex to modal
SantosGuillamot 8f388df
Revert to current navigation block
SantosGuillamot 938d57d
Add directives through a filter
SantosGuillamot 1d0472d
Dont add latest modifications to navigation block
SantosGuillamot d5250fa
Ensure focus doesn't get inside menu after closing
SantosGuillamot 3ae8097
Add conditionals and change function names
SantosGuillamot 624bdb0
Use `gutenberg_is_experiment_enabled` function
SantosGuillamot ebba7b4
Add interactivity runtime
luisherranz af59781
Add it to the image block
luisherranz cca3d60
Add a separate webpack config
luisherranz 160a029
Make sure the runtime is imported only once
luisherranz 7f16f27
Use sideEffects instead of init
luisherranz f4b2ee8
Move script registration to a general file
luisherranz 378b041
Add `defer` to the interactivity scripts
luisherranz 409d161
Revert changes of the image block
luisherranz 29e11ab
Fix init import name
luisherranz f4b6c0a
Move and refactor the interactive scritps registration
gziolo 3d94473
Fix code style violations
gziolo 6ae760f
Use `wp-interactivity-` prefix for script handles
gziolo 9d6869e
Improve the matcher for side effects in `package.json`
gziolo 3393bc2
Merge branch 'add-interactivity-runtime' into navigation-block-with-i…
SantosGuillamot 32013ae
Enqueue interactivity scripts through hook
SantosGuillamot f829206
Revert `client-assets.php` file
SantosGuillamot 3258326
Adapt to latest changes in base branch
SantosGuillamot c6d02d8
Add custom useSignalEffect
DAreRodz bb36577
Merge branch 'add-interactivity-runtime' into navigation-block-with-i…
SantosGuillamot 9c95302
Move role attribute to selectors
SantosGuillamot af55917
Call `init` after `store` has been initialized
DAreRodz b58e6af
Merge branch 'add-interactivity-runtime' into navigation-block-with-i…
SantosGuillamot 66b765c
Change focusable elements
SantosGuillamot 7f1db8c
Add namespaces to context
SantosGuillamot 79fd7b7
Move PHP file to interactivity-api folder
SantosGuillamot b553b04
Add comments with the markup to the PHP filter
SantosGuillamot 182ed89
Remove micromodal attributes
SantosGuillamot 5751344
Add interactivity runtime
luisherranz e8201c2
Add it to the image block
luisherranz df844f0
Add a separate webpack config
luisherranz d883391
Make sure the runtime is imported only once
luisherranz b1ea5e3
Use sideEffects instead of init
luisherranz 20d6213
Move script registration to a general file
luisherranz 6fb8aa7
Add `defer` to the interactivity scripts
luisherranz 6c96509
Revert changes of the image block
luisherranz e843b80
Fix init import name
luisherranz cdf74b9
Move and refactor the interactive scritps registration
gziolo de0e874
Fix code style violations
gziolo fa7c00d
Use `wp-interactivity-` prefix for script handles
gziolo 0d88c77
Improve the matcher for side effects in `package.json`
gziolo 142050c
Add custom useSignalEffect
DAreRodz e65b91e
Call `init` after `store` has been initialized
DAreRodz 9a31bb4
Update lib/experimental/interactivity-api/script-loader.php
gziolo 0cdab08
Plugin: Ensure that translations are set correctly when overriding sc…
gziolo 5dcf88e
Remove unnecessary comment in webpack config
SantosGuillamot 5171e47
Merge branch 'add-interactivity-runtime' into navigation-block-with-i…
SantosGuillamot 5af4b51
Clean up code to fix PHP coding standards issues
SantosGuillamot d4a16f3
Remove extra space
SantosGuillamot 6f34728
Merge branch 'trunk' into navigation-block-with-interactivity-api
SantosGuillamot 066d946
Add tests to the navigation block interactivity
SantosGuillamot 91796b9
Modify `saveSiteEditorEntities` function to wait
SantosGuillamot c358346
Fix page-list tests
SantosGuillamot 68b3dec
Remove e2e tests that are already included in trunk
gziolo c6ee68a
Fix the navigation menu when the overlay is not present
gziolo 15d3546
Ensure that all scripts using Intereactivity API have defer attribute
gziolo 4367b4d
Remove unused param in the callback used by hook
gziolo 1626f90
Merge remote-tracking branch 'origin/trunk' into navigation-block-wit…
gziolo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
240 changes: 240 additions & 0 deletions
240
lib/experimental/interactivity-api/navigation-block-interactivity.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
<?php | ||
/** | ||
* Extend WordPress core navigation block to use the Interactivity API. | ||
* Interactivity API directives are added using the Tag Processor while it is experimental. | ||
* | ||
* @package gutenberg | ||
*/ | ||
|
||
/** | ||
* Add Interactivity API directives to the navigation block markup using the Tag Processor | ||
* The final HTML of the navigation block will look similar to this: | ||
* | ||
* <nav | ||
* data-wp-island | ||
* data-wp-context='{ "core": { "navigation": { "isMenuOpen": false, "overlay": true, "roleAttribute": "" } } }' | ||
* > | ||
* <button | ||
* class="wp-block-navigation__responsive-container-open" | ||
* data-wp-on.click="actions.core.navigation.openMenu" | ||
* data-wp-on.keydown="actions.core.navigation.handleMenuKeydown" | ||
* > | ||
* <div | ||
* class="wp-block-navigation__responsive-container" | ||
* data-wp-class.has-modal-open="context.core.navigation.isMenuOpen" | ||
* data-wp-class.is-menu-open="context.core.navigation.isMenuOpen" | ||
* data-wp-bind.aria-hidden="!context.core.navigation.isMenuOpen" | ||
* data-wp-effect="effects.core.navigation.initModal" | ||
* data-wp-on.keydow="actions.core.navigation.handleMenuKeydown" | ||
* data-wp-on.focusout="actions.core.navigation.handleMenuFocusout" | ||
* tabindex="-1" | ||
* > | ||
* <div class="wp-block-navigation__responsive-close"> | ||
* <div | ||
* class="wp-block-navigation__responsive-dialog" | ||
* data-wp-bind.aria-modal="context.core.navigation.isMenuOpen" | ||
* data-wp-bind.role="selectors.core.navigation.roleAttribute" | ||
* data-wp-effect="effects.core.navigation.focusFirstElement" | ||
* > | ||
* <button | ||
* class="wp-block-navigation__responsive-container-close" | ||
* data-wp-on.click="actions.core.navigation.closeMenu" | ||
* > | ||
* <svg> | ||
* <button> | ||
* MENU ITEMS | ||
* </div> | ||
* </div> | ||
* </div> | ||
* </nav> | ||
* | ||
* @param string $block_content Markup of the navigation block. | ||
* | ||
* @return string Navigation block markup with the proper directives | ||
*/ | ||
function gutenberg_block_core_navigation_add_directives_to_markup( $block_content ) { | ||
$w = new WP_HTML_Tag_Processor( $block_content ); | ||
// Add directives to the `<nav>` element. | ||
if ( $w->next_tag( 'nav' ) ) { | ||
$w->set_attribute( 'data-wp-island', '' ); | ||
$w->set_attribute( 'data-wp-context', '{ "core": { "navigation": { "isMenuOpen": false, "overlay": true, "roleAttribute": "" } } }' ); | ||
}; | ||
|
||
// Add directives to the open menu button. | ||
if ( $w->next_tag( | ||
array( | ||
'tag_name' => 'BUTTON', | ||
'class_name' => 'wp-block-navigation__responsive-container-open', | ||
) | ||
) ) { | ||
$w->set_attribute( 'data-wp-on.click', 'actions.core.navigation.openMenu' ); | ||
$w->set_attribute( 'data-wp-on.keydown', 'actions.core.navigation.handleMenuKeydown' ); | ||
$w->remove_attribute( 'data-micromodal-trigger' ); | ||
} else { | ||
// If the open modal button not found, we handle submenus immediately. | ||
$w = new WP_HTML_Tag_Processor( $w->get_updated_html() ); | ||
|
||
// Add directives to the menu container. | ||
if ( $w->next_tag( | ||
array( | ||
'tag_name' => 'UL', | ||
'class_name' => 'wp-block-navigation__container', | ||
) | ||
) ) { | ||
$w->set_attribute( 'data-wp-class.is-menu-open', 'context.core.navigation.isMenuOpen' ); | ||
$w->set_attribute( 'data-wp-bind.aria-hidden', '!context.core.navigation.isMenuOpen' ); | ||
$w->set_attribute( 'data-wp-effect', 'effects.core.navigation.initModal' ); | ||
$w->set_attribute( 'data-wp-on.keydown', 'actions.core.navigation.handleMenuKeydown' ); | ||
$w->set_attribute( 'data-wp-on.focusout', 'actions.core.navigation.handleMenuFocusout' ); | ||
$w->set_attribute( 'tabindex', '-1' ); | ||
}; | ||
|
||
gutenberg_block_core_navigation_add_directives_to_submenu( $w ); | ||
|
||
return $w->get_updated_html(); | ||
} | ||
|
||
// Add directives to the menu container. | ||
if ( $w->next_tag( | ||
array( | ||
'tag_name' => 'DIV', | ||
'class_name' => 'wp-block-navigation__responsive-container', | ||
) | ||
) ) { | ||
$w->set_attribute( 'data-wp-class.has-modal-open', 'context.core.navigation.isMenuOpen' ); | ||
$w->set_attribute( 'data-wp-class.is-menu-open', 'context.core.navigation.isMenuOpen' ); | ||
$w->set_attribute( 'data-wp-bind.aria-hidden', '!context.core.navigation.isMenuOpen' ); | ||
$w->set_attribute( 'data-wp-effect', 'effects.core.navigation.initModal' ); | ||
$w->set_attribute( 'data-wp-on.keydown', 'actions.core.navigation.handleMenuKeydown' ); | ||
$w->set_attribute( 'data-wp-on.focusout', 'actions.core.navigation.handleMenuFocusout' ); | ||
$w->set_attribute( 'tabindex', '-1' ); | ||
}; | ||
|
||
// Remove micromodal attribute. | ||
if ( $w->next_tag( | ||
array( | ||
'tag_name' => 'DIV', | ||
'class_name' => 'wp-block-navigation__responsive-close', | ||
) | ||
) ) { | ||
$w->remove_attribute( 'data-micromodal-close' ); | ||
}; | ||
|
||
// Add directives to the dialog container. | ||
if ( $w->next_tag( | ||
array( | ||
'tag_name' => 'DIV', | ||
'class_name' => 'wp-block-navigation__responsive-dialog', | ||
) | ||
) ) { | ||
$w->set_attribute( 'data-wp-bind.aria-modal', 'context.core.navigation.isMenuOpen' ); | ||
$w->set_attribute( 'data-wp-bind.role', 'selectors.core.navigation.roleAttribute' ); | ||
$w->set_attribute( 'data-wp-effect', 'effects.core.navigation.focusFirstElement' ); | ||
}; | ||
|
||
// Add directives to the close button. | ||
if ( $w->next_tag( | ||
array( | ||
'tag_name' => 'BUTTON', | ||
'class_name' => 'wp-block-navigation__responsive-container-close', | ||
) | ||
) ) { | ||
$w->set_attribute( 'data-wp-on.click', 'actions.core.navigation.closeMenu' ); | ||
$w->remove_attribute( 'data-micromodal-close' ); | ||
}; | ||
|
||
// Submenus. | ||
gutenberg_block_core_navigation_add_directives_to_submenu( $w ); | ||
|
||
return $w->get_updated_html(); | ||
}; | ||
|
||
/** | ||
* Add Interactivity API directives to the navigation-submenu and page-list blocks markup using the Tag Processor | ||
* The final HTML of the navigation-submenu and the page-list blocks will look similar to this: | ||
* | ||
* <li | ||
* class="has-child" | ||
* data-wp-context='{ "core": { "navigation": { "isMenuOpen": false, "overlay": false } } }' | ||
* > | ||
* <button | ||
* class="wp-block-navigation-submenu__toggle" | ||
* data-wp-on.click="actions.core.navigation.openMenu" | ||
* data-wp-bind.aria-expanded="context.core.navigation.isMenuOpen" | ||
* data-wp-on.keydown="actions.core.navigation.handleMenuKeydown" | ||
* data-wp-on.focusout="actions.core.navigation.handleMenuFocusout" | ||
* > | ||
* </button> | ||
* <span>Title</span> | ||
* <ul | ||
* class="wp-block-navigation__submenu-container" | ||
* data-wp-effect="effects.core.navigation.initModal" | ||
* data-wp-on.focusout="actions.core.navigation.handleMenuFocusout" | ||
* data-wp-on.keydown="actions.core.navigation.handleMenuKeydown" | ||
* > | ||
* SUBMENU ITEMS | ||
* </ul> | ||
* </li> | ||
* | ||
* @param string $w Markup of the navigation block. | ||
* | ||
* @return void | ||
*/ | ||
function gutenberg_block_core_navigation_add_directives_to_submenu( $w ) { | ||
while ( $w->next_tag( | ||
array( | ||
'tag_name' => 'LI', | ||
'class_name' => 'has-child', | ||
) | ||
) ) { | ||
// Add directives to the parent `<li>`. | ||
$w->set_attribute( 'data-wp-context', '{ "core": { "navigation": { "isMenuOpen": false, "overlay": false } } }' ); | ||
|
||
// Add directives to the toggle submenu button. | ||
if ( $w->next_tag( | ||
array( | ||
'tag_name' => 'BUTTON', | ||
'class_name' => 'wp-block-navigation-submenu__toggle', | ||
) | ||
) ) { | ||
$w->set_attribute( 'data-wp-on.click', 'actions.core.navigation.openMenu' ); | ||
$w->set_attribute( 'data-wp-bind.aria-expanded', 'context.core.navigation.isMenuOpen' ); | ||
$w->set_attribute( 'data-wp-on.keydown', 'actions.core.navigation.handleMenuKeydown' ); | ||
$w->set_attribute( 'data-wp-on.focusout', 'actions.core.navigation.handleMenuFocusout' ); | ||
}; | ||
|
||
// Add directives to the `<ul>` containing the subitems. | ||
if ( $w->next_tag( | ||
array( | ||
'tag_name' => 'UL', | ||
'class_name' => 'wp-block-navigation__submenu-container', | ||
) | ||
) ) { | ||
$w->set_attribute( 'data-wp-effect', 'effects.core.navigation.initModal' ); | ||
$w->set_attribute( 'data-wp-on.focusout', 'actions.core.navigation.handleMenuFocusout' ); | ||
$w->set_attribute( 'data-wp-on.keydown', 'actions.core.navigation.handleMenuKeydown' ); | ||
}; | ||
// Iterate through subitems if exist. | ||
gutenberg_block_core_navigation_add_directives_to_submenu( $w ); | ||
} | ||
}; | ||
|
||
add_filter( 'render_block_core/navigation', 'gutenberg_block_core_navigation_add_directives_to_markup', 10, 1 ); | ||
|
||
// Enqueue the `interactivity.js` file with the store. | ||
add_filter( | ||
'block_type_metadata', | ||
function ( $metadata ) { | ||
if ( 'core/navigation' === $metadata['name'] ) { | ||
wp_register_script( | ||
'wp-block-navigation-view', | ||
gutenberg_url( 'build/block-library/interactive-blocks/navigation.min.js' ), | ||
array( 'wp-interactivity-runtime' ) | ||
); | ||
$metadata['viewScript'] = array( 'wp-block-navigation-view' ); | ||
} | ||
return $metadata; | ||
}, | ||
10, | ||
1 | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SantosGuillamot, would it make sense to rename the effect to reflect the fact it works with the menu when there is no modal, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed it to
initMenu
in this commit.