feat(block-theme): add overlay block for the block theme#4578
feat(block-theme): add overlay block for the block theme#4578laurelfulford merged 22 commits intotrunkfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new composite “Overlay Menu” Gutenberg block (parent + trigger + panel) for block themes, including frontend behavior (open/close, scrim, focus handling) and editor controls for previewing/configuring the panel.
Changes:
- Registers new overlay-menu blocks (parent/trigger/panel) and loads their PHP render callbacks under the block-theme gate.
- Adds a dedicated frontend script bundle (
overlay-menu-block) and associated styles for panel/scrim behavior. - Implements editor UI for trigger text/styles and panel settings (direction + colors) with a shared preview toggle.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| webpack.config.js | Adds overlay-menu-block entry to build the frontend script bundle. |
| src/blocks/index.js | Registers overlay-menu blocks and gates them to block themes. |
| includes/class-blocks.php | Requires the new overlay-menu PHP block classes under wp_is_block_theme(). |
| src/blocks/overlay-menu/block.json | Defines parent block metadata, context, and viewScript. |
| src/blocks/overlay-menu/index.js | Registers the parent block (editor) and imports styles. |
| src/blocks/overlay-menu/edit.js | Parent edit UI with locked InnerBlocks template and preview toggle. |
| src/blocks/overlay-menu/class-overlay-menu-block.php | Server render callback for the parent wrapper + data-overlay-id. |
| src/blocks/overlay-menu/style.scss | Frontend/editor styles for trigger, panel, and scrim. |
| src/blocks/overlay-menu/view.js | Frontend open/close logic, scrim creation, and focus trapping. |
| src/blocks/overlay-menu/panel-preview-toggle.js | Shared toolbar toggle for editor preview open/close. |
| src/blocks/overlay-menu/trigger/block.json | Trigger block metadata and supports (colors/typography/spacing/border). |
| src/blocks/overlay-menu/trigger/index.js | Registers trigger block styles and editor settings. |
| src/blocks/overlay-menu/trigger/edit.js | Trigger edit UI with RichText label and preview toggle integration. |
| src/blocks/overlay-menu/trigger/class-overlay-menu-trigger-block.php | Dynamic PHP render for the trigger button. |
| src/blocks/overlay-menu/panel/block.json | Panel block metadata and attributes (direction/colors/preview state). |
| src/blocks/overlay-menu/panel/index.js | Registers panel block and saves InnerBlocks content. |
| src/blocks/overlay-menu/panel/edit.js | Panel editor UI (direction + colors) and in-editor preview overlay/scrim. |
| src/blocks/overlay-menu/panel/class-overlay-menu-panel-block.php | Dynamic PHP render for the panel wrapper + close button. |
| src/blocks/overlay-menu/NOTES.md | Development notes documenting architecture and behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
I tested all 6 sections from the PR description in an isolated environment with the block theme. Everything works well - block insertion, button editing (color/text/styles), panel settings (direction/colors), editor content, multiple independent instances, and keyboard accessibility.
A few items to address below.
| 'data-direction' => $direction, | ||
| 'data-overlay-color' => $overlay_color, | ||
| 'aria-hidden' => 'true', | ||
| 'role' => 'dialog', |
There was a problem hiding this comment.
Accessibility bug: The panel renders aria-hidden="true" but is missing the inert attribute. The JS adds/removes inert on open/close (view.js lines 144 and 192), but on initial page load the panel is closed without inert. This means screen readers and keyboard navigation can reach hidden panel content before any JS runs (or if JS fails to load).
Add 'inert' => true to $extra_attributes here so the initial server-rendered state matches what JS produces after a close:
'aria-hidden' => 'true',
'inert' => true,
'role' => 'dialog',| // Lock document scrolling while any overlay menu instance is open. | ||
| body:is( [class*=" menu-open--overlay-menu-"] ) { | ||
| overflow: hidden !important; // !important to temporarily override style from block theme's overlay approach. | ||
| } |
There was a problem hiding this comment.
CSS edge case: The *=" menu-open--overlay-menu-" selector requires a leading space before the class name. If this happens to be the first class on <body> (no leading space in the attribute string), the selector won't match and scroll lock won't apply.
Fix with an additional selector for the start-of-attribute case:
body:is(
[class^="menu-open--overlay-menu-"],
[class*=" menu-open--overlay-menu-"]
) {| overlay = null; | ||
| el.style.opacity = '0'; | ||
| // Remove from DOM once the CSS opacity transition finishes. | ||
| el.addEventListener( 'transitionend', () => el.remove(), { once: true } ); |
There was a problem hiding this comment.
Potential bug with prefers-reduced-motion: If the CSS transition is skipped (e.g., prefers-reduced-motion is active, element is hidden, or the browser collapses the transition), transitionend never fires and the scrim element stays in the DOM forever.
Consider adding a fallback timeout:
const el = overlay;
overlay = null;
el.style.opacity = '0';
const cleanup = () => el.remove();
el.addEventListener( 'transitionend', cleanup, { once: true } );
setTimeout( cleanup, 600 ); // Fallback if transition is skipped.| "default": "" | ||
| }, | ||
| "isPreviewOpen": { | ||
| "type": "boolean", |
There was a problem hiding this comment.
Minor: isPreviewOpen is defined in block.json, which means it gets serialized to post content. The edit component resets it to false on mount, but saving a post with the panel open will still write isPreviewOpen: true to the database -- and loading that post could briefly mark it as dirty when the mount effect clears it.
This is editor-only UI state. Consider managing it outside of block attributes entirely (e.g., via a module-level Map keyed by clientId, or a React ref), which would avoid the persist/reset cycle.
There was a problem hiding this comment.
Moved out of the block attributes in f19d8fc.
| "navigation", | ||
| "overlay", | ||
| "hamburger" | ||
| ], |
There was a problem hiding this comment.
Nit: "overlay" appears twice in the keywords array (lines 12 and 15). Same duplication exists in index.js.
There was a problem hiding this comment.
🤦♀️ Thanks for catching that 😆 Got it down to one mention in each file in b5355d6.
| // Fade panel covers the full viewport; starts slightly offset so it slides in. | ||
| .overlay-menu__panel--fade { | ||
| inset: 0; | ||
| max-width: 100%; |
There was a problem hiding this comment.
Nit: The .overlay-menu__panel--fade class (lines 122-125) is defined in CSS but unreachable -- the editor UI only offers "left" and "right" directions, and the PHP validation allowlist ($valid_directions) only permits those two values. Either remove this dead CSS or add it as a documented follow-up.
| @@ -0,0 +1,218 @@ | |||
| /** | |||
There was a problem hiding this comment.
Nit: The file header says "Flyout Menu Block" but the block is named "Overlay Menu" -- looks like a remnant from an earlier naming iteration.
There was a problem hiding this comment.
Switched to "Overlay Menu Block" in 488d3ae!
|
Thanks @adekbadek! I've made the updates - just let me know if anything else needs changing! |
|
Sweet! Thanks @adekbadek! 🙌 |
|
Hey @laurelfulford, good job getting this PR merged! 🎉 Now, the Please check if this PR needs to be included in the "Upcoming Changes" and "Release Notes" doc. If it doesn't, simply remove the label. If it does, please add an entry to our shared document, with screenshots and testing instructions if applicable, then remove the label. Thank you! ❤️ |
# [6.38.0-alpha.1](v6.37.0...v6.38.0-alpha.1) (2026-04-16) ### Bug Fixes * `is_donor` read-only only on WooCommerce-backed donations ([1dde930](1dde930)) * **access-control:** fix incorrect class name ([#4638](#4638)) ([a7a7908](a7a7908)) * **access-control:** hide My Account group features if Memberships is still active ([#4650](#4650)) ([214fa0d](214fa0d)) * add object-level authorization to corrections REST endpoint ([#4643](#4643)) ([a39a62d](a39a62d)) * address false positives in subscription status alerts on My Account ([f7d6bb8](f7d6bb8)) * address false positives in subscription status alerts on My Account ([31c8313](31c8313)) * clear stored referrer data where referrer is none or local ([c7ef6f3](c7ef6f3)) * count `pending-cancel` by testing against our canonical constant ([2a1f85b](2a1f85b)) * count `pending-cancel` by testing against our canonical constant ([8906b64](8906b64)) * include products without children when reviewing active subscriptions ([d714f3c](d714f3c)) * include products without children when reviewing active subscriptions ([aae3da2](aae3da2)) * limit success and notice snackbar treatments to My Account page ([3b40bec](3b40bec)) * **my-account:** limit notice/success snackbar overrides to My Account ([49517c1](49517c1)) * normalize referrer data when comparing ([d377afb](d377afb)) * **reader-activation:** clear referrer data when none provided ([696012b](696012b)) * **reader-data:** make is_donor read-only only when platform has server-side tracking ([92b0d34](92b0d34)) * update docblock to reflect simple product support ([ea1f03e](ea1f03e)) * update docblock to reflect simple product support ([ba14f85](ba14f85)) * **woocommerce:** image handling in paginated block ([#4149](#4149)) ([1c91f6c](1c91f6c)) ### Features * **access-control:** advanced settings for RSS content restriction ([#4613](#4613)) ([85aa560](85aa560)) * **access-control:** update default patterns ([#4569](#4569)) ([7f9a6c9](7f9a6c9)) * add filter for future integrations to self-declare server-side (secure?) donor tracking ([76e40fc](76e40fc)) * add README.md for the Overlay Block ([#4651](#4651)) ([6d7de6e](6d7de6e)) * **advertising:** replace placements UI with inline expandable cards ([#4625](#4625)) ([e5de003](e5de003)) * **block-theme:** add overlay block for the block theme ([#4578](#4578)) ([af1e4b9](af1e4b9)) * **components:** update CardFeature button size and variant ([#4609](#4609)) ([1d03d4c](1d03d4c)) * **content-gate:** add per-block access control for Group, Stack, and Row blocks ([#4646](#4646)) ([5bdf458](5bdf458)) * **content-gate:** add POST method for external IP access checks ([#4598](#4598)) ([36bfeea](36bfeea)) * **google-site-kit:** enable custom GA frontend params by default ([#4664](#4664)) ([19830ce](19830ce)) * **handoff:** add URL-based handoff with customizable banner text ([#4603](#4603)) ([be59c68](be59c68)) * **integrations:** add My Account menu hook to integration abstraction ([#4640](#4640)) ([4ef2c91](4ef2c91)) * **integrations:** add subscription and donation metadata ([#4597](#4597)) ([ca928f8](ca928f8)) * **integrations:** implement profile metadata ([#4624](#4624)) ([b1daf85](b1daf85)) * make it easier to do "Block until consent given" setups in Complianz and improve blocking ([#4549](#4549)) ([44dda72](44dda72)) * reader activation segments ([#4604](#4604)) ([3821fed](3821fed)) * **reader-data:** add engagement fields ([#4594](#4594)) ([1cba4ef](1cba4ef)) * **reader-data:** store sync reconciliation ([#4633](#4633)) ([69bdda4](69bdda4)) * require reader to set name when commenting ([#4647](#4647)) ([db5ad73](db5ad73)) * session hydration ([#4618](#4618)) ([665b152](665b152)) ### Reverts * address false positives in subscription status alerts on My Account ([9d203b0](9d203b0))
|
🎉 This PR is included in version 6.38.0-alpha.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
All Submissions:
Changes proposed in this Pull Request:
This PR adds an overlay menu block for the block theme.
The block is technically comprised of three blocks:
Once this block has been merged and added to the Newspack Block theme, there's also some file cleanup we can do to get rid of the current menu template part, etc.
Closes NPPD-1279.
How to test the changes in this Pull Request:
There's a few different groups of settings to be tested in this block:
Test inserting the block
Edit the button
Edit the Panel's settings
Adding editor content
Add several many blocks
Test accessibility
Other information: