Skip to content

feat(block-theme): add search overlay block#4729

Draft
laurelfulford wants to merge 22 commits into
trunkfrom
feat/search-overlay-block
Draft

feat(block-theme): add search overlay block#4729
laurelfulford wants to merge 22 commits into
trunkfrom
feat/search-overlay-block

Conversation

@laurelfulford
Copy link
Copy Markdown
Contributor

@laurelfulford laurelfulford commented May 14, 2026

All Submissions:

Changes proposed in this Pull Request:

This PR adds a Search Overlay Block to be used in the Newspack Block Theme. It's inserted as a button into the block theme, and when clicked, will open an overlay with the search block in it. The button appearance (colours, fonts, border radius), label (changing text or hiding text/icon) and overlay (colour) are customizeable, but the search -- for now -- is not).

When Jetpack's instant search is enabled, it will be opened instead.

A version of this functionality is currently baked into the theme using template parts. The downside is that that's pretty fragile - changing the structure or a class name could break how it works. My moving the functionality to block, we make sure it's easier to use, add, and customize.

Closes NPPD-1449.

How to test the changes in this Pull Request:

  1. On a test site using the Block Theme, open the Site Editor.
  2. Add the Search Overlay block (under the Newspack category).
  3. Save and view on the frontend in a separate tab so you can flip between editor and frontend.
  4. Try clicking the search button and confirm it opens a search overlay:
CleanShot 2026-05-14 at 13 08 32
  1. Try running a search from the overlay and confirm it redirects you to the search results page.
  2. Open the search a few times and confirm you can close it:
    • With the close button (top-right corner)
    • By clicking the overlay background
    • By hitting the Esc key
  3. While you're testing the above, also confirm that the input is focused on when you open the search overlay.

Test the visual stuff

  1. In the editor sidebar > Styles, confirm you have three options: Default, Icon only, Text only.
  2. Try testing each and toggling between the editor and front-end to review:
    • Default should show the search icon and text
    • Icon only should show only the icon, with the text wrapped in a screen-reader-text CSS class.
    • Text only should show only the text label.
  3. With the text visible, try editing the text on the button to change the label to something other than "Search".
  4. Try testing the customization options -- color settings, typography settings, border radius... confirm everything's applied and looks right on the front-end.
  5. Try changing the overlay colour specifically and testing on the front-end -- the close button in the-top right corner should remain contrast-y against the overlay, so it should be black against a really light colour, and white against a darker colour.

Confirm the block is accessible

  1. With overlay closed, inspect the button on the front-end -- it should have the attributes aria-expanded="false", aria-controls="newspack-search-overlay-panel-…"
  2. Inspect the panel itself and confirm it has thearia-hidden="true", inert attributes
  3. Open the and confirm the button switches to aria-expanded="true" and the panel loses aria-hidden and inert
  4. Close the overlay → attributes flip back.

Jetpack Instant Search

  1. Enable Jetpack's instant search
  2. Try opening an overlay and running a search - confirm Jetpack's instant search is opened instead of redirecting you to the search results page.

Get weird & throw a search party!

  1. Set up a few instances of the search button on the same page. Give the overlays different settings so you can tell them apart.
  2. Test triggering them from the front-end. Each search button should open is own overlay.

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully ran tests with your changes locally?

laurelfulford and others added 21 commits May 13, 2026 16:11
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The class file is only included from the wp_is_block_theme() branch in
class-blocks.php, so re-checking inside register_block() is dead code
and diverges from the overlay-menu pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Matches the my-account-button pattern: blockClassName is applied to
both the outer wp-block-buttons wrapper and the button's classnames()
call, so block-style classes propagate consistently across editor and
frontend output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-overlay

Calling the hook at the top of the component (alongside the other
use* hooks) reads more clearly than spreading the call inline in JSX,
and matches the surrounding pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
render_trigger_button already returns a string; the buffer was extra
indirection that masked the simpler return path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
z-index raised to 99999 so the panel isn't occluded by newspack-ui
modals or the content banner. Default background and content max-width
now read from the active theme's tokens, with the original literal
values kept as CSS-fallbacks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The overlay color rendered in its own InspectorControls panel below
the standard Color section, which was easy to miss. Moving it under
InspectorControls group="color" with panelId={ clientId } slots it
into the existing Color ToolsPanel alongside Background and Text,
matching the overlay-menu pattern. Label shortened to "Overlay" so it
reads naturally next to "Background" and "Text".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces hard-coded 2rem padding with the spacing tokens
(--wp--preset--spacing--30/40, responsive at the tablet breakpoint),
adds overflow-y: auto so tall content can scroll, and locks document
scrolling while any instance is open via the menu-open--search-overlay-
body class selector. Matches the established overlay-menu defaults.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The theme's [class*="newspack-icon"] span selector hides spans
off-screen — it expects icons rendered via CSS background/pseudo-
element, not the inline-SVG-in-a-span pattern this block uses. With
newspack-icon-close present, the visible SVG span was being pushed
to left: -99999em and the close button rendered empty on the front
end. Dropping the class matches the overlay-menu close button and
restores the icon.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two small frontend tweaks on the search-overlay panel:
- The close button color is now set inline based on the panel's
  computed background color, using the same YIQ formula the plugin's
  getContrast helper uses. Works for hex, rgba, theme-token defaults,
  and palette swatches uniformly because it reads the resolved CSS
  background via getComputedStyle.
- Clicking the panel scrim (the colored area outside the search form
  and close button) now closes the overlay, matching the standard
  modal-with-scrim interaction. The handler uses e.target === panel
  so clicks on any inner element still behave as expected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the dense \$html .= concatenation in render_trigger_button,
render_jetpack_trigger, and render_panel with ob_start() and inline
PHP templates so the HTML structure is visible at a glance. Matches
the overlay-menu-panel pattern (the closer reference) and follows
the same phpcs:ignore conventions for outputting pre-escaped HTML
(self::ICON_* constants and render_block() return values). Output is
byte-identical to the previous implementation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The panel acts as a full-screen scrim — same idea as overlay-menu's
.overlay-menu__scrim, just without a separate panel underneath. The
opaque theme-base default treated it like a search-page takeover;
rgba(0, 0, 0, 0.5) matches the scrim's lightbox/modal feel by default.
The block's overlayColor attribute still overrides this when set.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@laurelfulford laurelfulford requested a review from Copilot May 14, 2026 20:09
Port the higher anchor, darker scrim, and slide-down content
animation from newspack-block-theme's search overlay. Also wire
the Overlay color control into the ToolsPanel reset flow so it
clears with the rest of the color settings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a Search Overlay block for Newspack block themes, rendering a customizable trigger that opens a full-screen search dialog and hands off to Jetpack Instant Search when detected.

Changes:

  • Registers the new Search Overlay block in editor/server block registration.
  • Adds frontend overlay behavior, styling, editor UI, and dynamic PHP rendering.
  • Adds a dedicated frontend bundle entry for the overlay script.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
webpack.config.js Adds the search overlay frontend script bundle.
src/blocks/search-overlay/view.js Implements frontend open/close behavior, focus handling, and contrast color selection.
src/blocks/search-overlay/style.scss Adds trigger, panel, close button, and body scroll-lock styles.
src/blocks/search-overlay/index.js Registers block styles and editor settings.
src/blocks/search-overlay/edit.js Adds editor controls and trigger label editing.
src/blocks/search-overlay/class-search-overlay-block.php Adds server-side dynamic rendering and Jetpack handoff markup.
src/blocks/search-overlay/block.json Defines block metadata, supports, styles, and view script.
src/blocks/index.js Adds the block to client-side registration and block-theme gating.
includes/class-blocks.php Includes the server-side block class for block themes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

inert="true"
aria-label="<?php \esc_attr_e( 'Search', 'newspack-plugin' ); ?>"
<?php if ( '' !== $overlay_color ) : ?>
style="background:<?php echo \esc_attr( $overlay_color ); ?>"
Comment on lines +36 to +41
const [ r, g, b ] = match[ 1 ].split( ',' ).map( s => parseFloat( s.trim() ) );
if ( ! Number.isFinite( r ) || ! Number.isFinite( g ) || ! Number.isFinite( b ) ) {
return 'white';
}
const yiq = ( r * 299 + g * 587 + b * 114 ) / 1000;
return yiq >= 128 ? 'black' : 'white';
Comment on lines +131 to +135
setTimeout( () => {
const searchInput = panel.querySelector( 'input[type="search"]' );
const focusTarget = searchInput || getVisibleFocusable( panel )[ 0 ] || closeBtn;
if ( focusTarget && document.contains( focusTarget ) ) {
focusTarget.focus();
* @param array $attributes Block attributes.
* @return string Block HTML.
*/
public static function render_block( $attributes ) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants