Skip to content

Commit 6221875

Browse files
kangzjmatticbot
authored andcommitted
Search Blocks: add a No Results block for the search empty state (#51164)
* Search Blocks: add a No Results block for the search empty state The empty-state copy lived in two plain-string attributes on the results-list block and was escaped with esc_html() on render, so an author could not put a link, an image, or any other markup in it. A partner site moving to Jetpack Search lost the link its previous no-results page had (SEARCH-308). Add jetpack-search/no-results, modelled on core/query-no-results: an ancestor-scoped container whose inner blocks are whatever the author wants. Core decides visibility server-side by re-running the query; the Search blocks fetch client-side, so visibility is a data-wp-bind--hidden binding instead. A filterState attribute ("Display when") lets a second block cover the filters-active case, which core has no equivalent for. Empty blocks fall back to the localized default copy rather than rendering nothing, so the shipped templates can carry a self-closing block and still translate. With the default filterState that fallback is the same two-<p> hasActiveFilters swap results-list has always emitted, leaving stock installs unchanged. Saved content keeps working untouched: results-list still renders its legacy message region, now gated on state.showLegacyNoResults. The new block seeds state.hasNoResultsBlock, and because interactivity state is serialized once at footer time that suppression resolves regardless of render order — no parent walking, no HTML surgery, and the surviving message stays in its authored position. The legacy inspector fields hand off to the block when one is present. * Fix CI: phan suppressions and an i18n-safe editor label Phan flagged `$content` as an undeclared global on the echo path and the `(string)` cast as redundant — match the suppression shape the sibling container blocks already use. The production minifier folded the three `__()` calls in the canvas-label helper into one call with a computed msgid, which i18n-check-webpack-plugin rejects and which would have shipped the labels untranslatable. Keying the labels off an object keeps each msgid a literal. * Address review: seed no-results coverage per filter state A lone No Results block scoped to one filter state seeded a flat "a block exists" flag, which stood the legacy results-list message down for both states — so an unfiltered empty search on a template whose only block was scoped to "Filters are active" rendered no empty state at all. Seed the states each block actually covers instead; the legacy region now fills whatever is left, and two scoped blocks still compose into full coverage because wp_interactivity_state() deep-merges and nothing seeds false. The results-list inspector mirrors it — only the covered field hands off. Also from review: - Scope the layout presentation (centering, 12rem floor, 36ch measure, muted opacity and font size) to the default-copy modifier. Applied to authored content it squashed exactly the Columns rows, full-width images and buttons the block exists to allow. A stock install is unchanged. - Keep role="status" on the default fallback only. Announcing an author's whole composition verbatim on every empty search is worse than not announcing it, and core/query-no-results has no live region. - Give the default copy one source per side — Search_Blocks::no_results_default_messages() and blocks/default-messages.js — rather than four literals that can drift into near-identical translator strings. - Drop spacing.blockGap, which had no layout support to attach to. - getBlockCount instead of getBlocks for the emptiness check, reset the interactivity singleton between tests in No_Results_Render_Test, bump the results-list block version, and use margin-block-end. AGENTS.md: correct the claim that a block can never see its siblings — a container can and does (the powered-by auto-append), it just can't help here, since the interactivity store is a single page-global namespace. * Address review: let a scoped No Results block win over an unscoped one An unscoped block bound to `showNoResults` and a scoped one bound to `showNoResultsFiltered` were both visible on a filtered empty search — and that is the pairing the UI steers authors toward, since every shipped template carries an unscoped block and the inspector help says to add a second one for the filters-active case. Scoped blocks now additionally claim their state, and the unscoped block yields wherever something more specific claimed it — the same relationship it already has with the legacy results-list region, one level up. Two unscoped blocks stacking stays author error, as it is for core/query-no-results. Also from review: - Pass a single client id to getClientIdsOfDescendants. The installed @wordpress/block-editor normalizes both shapes and the hand-off was verified working either way, but the string form is the documented signature. The jest mock is argument-aware now so a wrong call shape can't pass unnoticed. - Return flat booleans from the results-list useSelect mapper. A fresh nested object failed isShallowEqual on every editor store change, re-rendering the block on each keystroke anywhere in the canvas. - Reset the interactivity singleton in tearDown as well as setUp, so the last test's seeded coverage can't escape into the next class. * Search Blocks: deprecate the Results List no-results settings The No Results block is now the way to author the search empty state, so the two message fields on Results List are no longer offered in the inspector — a short note points authors at the block instead, plus a shortcut to select it when the results region already has one. The attributes stay registered and `render.php` keeps emitting them. Dropping an attribute makes the block parser discard it on load, which would silently blank the empty state on every page saved before the block existed; `state.showLegacyNoResults` already keeps the legacy region and the block from both showing. With the inspector fields gone, `blocks/default-messages.js` had a single consumer left, so it folds back into `no-results/edit.jsx`. * Search Blocks: cover the deprecated no-results attributes The compat path had a hole: `noResultsWithFiltersMessage` was not even registered in the render test's inline harness, so nothing exercised the filtered variant an author may have customized before the No Results block existed. Adds custom-copy, whitespace-fallback, and escaping cases for it, plus one asserting both messages render together bound to the complementary `state.hasActiveFilters` branches — the pair that makes the legacy region filter-aware. Also guards the two things that would silently break the compat path: `block.json` still declaring both attributes (the parser discards what it does not recognize, which would blank the empty state on load), and the editor never clearing them while another setting changes. Each new assertion was checked against a mutated source to confirm it fails when the behavior it describes is removed. * Fix CI: cast json_decode before array access in the block.json guard * Search Blocks: offer to add a No Results block from Results List A layout saved before the block existed keeps rendering the deprecated message, and with the text fields gone its empty state now reads as unconfigurable. The Results List panel says so directly: when the results region has no No Results block it explains the empty state is a plain message and offers an "Add No Results block" button; when it has one, the existing "Edit No Results block" shortcut. The block inserts as Results List's own next sibling rather than being appended to the `search-results` ancestor, so a nested layout (a Group around the list) doesn't put it somewhere the author didn't expect. * Search Blocks: use logical properties in the No Results default styles * Search Blocks: trim No Results "Display when" to two options "No filters are active" earned less than it cost. Because an unscoped block already yields wherever a `filtered` one claimed the state, the `any` + `filtered` pairing expresses every combination an author needs — one message everywhere, or different content per filter state. The third value only said "show nothing on a filtered search", and even that did not hold, since the uncovered state falls through to the legacy region's default copy anyway. Drops `showNoResultsUnfiltered` and `hasScopedNoResultsUnfiltered` outright, and collapses the render-side coverage seeding to a single branch. Still covers both no-results messages Kathryn asked to keep customizable on SEARCH-308. * Search Blocks: cover the error state with the No Results block Kathryn asked for this in all three messages, not just the two no-results ones. Rather than a second near-identical block, `filterState` gains a `Search failed` option: `showNoResults` requires `! hasError` and `showError` requires `hasError`, so the states are mutually exclusive in the store and one block with one binding per option can never double-render. The error value is disjoint from the two no-results ones in both directions — it seeds only `hasErrorBlock`, retiring `results-list`'s legacy error region via the new `showLegacyError`, and an `any` block never seeds it. That keeps `any` the safe default: a page whose only block is unscoped still shows the legacy error copy when a request fails, so no template change is needed. The fallback also swaps to `role="alert"`, matching the assertive/polite split `results-list` already emitted between its two regions. `errorMessage` is deprecated the same way as the other two, which leaves the Results List panel with no message fields at all. * Search Blocks: describe Results List without the error message The block description still claimed Results List renders the error message; it hands both the empty and error states to No Results now. The string shows in the editor sidebar, so it was visible in the screenshots. * Search Blocks: hold each No Results condition in its own variant One block per condition meant an author who wanted different copy for a filtered search had to find the inserter, add a second No Results block and know to scope it — and List View then showed two entries with the same name, since a per-instance label needs `__experimentalLabel`, which this tree avoids on principle. `no-results` becomes a container of `no-results-slot` variants, one per condition. Adding a condition is a button in the container's inspector, so the author never leaves the block. `allowedBlocks` is the variant alone and the default appender is suppressed — it would insert a second `any` variant that the renderer would stack on the first — and a button disappears once a variant covers its condition. An empty container still stands in for an unscoped variant: same filter-aware default pair, same seeded coverage. That keeps the shipped templates' self-closing `<!-- wp:jetpack-search/no-results /-->` working untouched, verified against a live env in all three conditions. Four helpers on `Search_Blocks` are now the single implementation the container's fallback and the variant share, rather than the condition logic living twice in two render.php files. * Search Blocks: show every No Results condition by default Starting the container empty behind "add a variant" buttons hid the two conditions an author most needs to know exist. It now creates a variant per condition up front, and the templates and pattern carry the same three, so opening one doesn't auto-insert anything and mark it dirty on mere inspection. An author sees all three empty states, edits the ones they care about, and leaves the rest to render their localized default — so a stock install still reads exactly as it did before the block. The inspector buttons stay as a recovery path for a deleted condition. Also from review: - Front-end styles move to the container. A variant only renders inside one, but not the reverse, and `no-results-slot.css` is only enqueued when a variant actually renders — so the stock template's default copy had lost its muted/centered/12rem treatment entirely. Confirmed against a live env before and after. - Inner blocks that aren't variants are wrapped as one unscoped variant rather than emitted bare, which put them behind the region-level binding and showed them on a failed request too. - `showLegacyNoResults` had lost its docblock to `showLegacyError`. * Search Blocks: describe No Results by what it ships with The description still told authors to add a variant per condition; the block now creates one per condition up front. * Search Blocks: nest the No Results variant inside its parent block The variant only ever renders inside `no-results`, so it now lives in `blocks/no-results/slot/` rather than beside the block it belongs to — the relationship is visible in the tree instead of implied by a name. `register_blocks()` walks one level into each registered block directory for nested `block.json` files, which also means a child inherits its parent's gating for free: a skipped parent never reaches the recursion. Nesting it made an existing redundancy obvious, so the variant drops its view module too. It carries interactivity directives but no behavior of its own, and the container's view module already registers the shared store — which is guaranteed loaded, since a variant cannot render outside one. That leaves the variant with no build output at all. * Search Blocks: fix the PHP 7.2 matrix and cover block discovery `assertMatchesRegularExpression()` landed in PHPUnit 9.1, and the PHP 7.2 CI matrix still runs PHPUnit 8.5, so both new render tests errored there while passing locally on 8.5.9. Swapped for `preg_match()` — the same workaround `ai-answer` and `clear-filters` already document. The nested-registration walk had no test, which the coverage check caught. Extracted it as `block_directories()` so what gets registered is assertable without standing up WordPress, and pinned the three properties that matter: a child directory is discovered, a parent is listed before its child, and a gated-off parent takes its children with it. Verified by deleting the descent and watching two of them fail. * Search Blocks: select through the block-editor store object Review feedback: the three edit components reached for the store by its 'core/block-editor' string. Swapped for the exported store object, which keeps the dependency explicit and survives a store rename. The data mocks ignored the selector's argument, so nothing would have caught a regression here. They now record what the component hands to `select()`, and each of the three suites asserts it is the store the component imported — verified by putting the string back and watching the assertion fail. * Search Blocks: keep the overlay pre-render out of the page's coverage flags `enqueue_block_template_overlay_assets()` runs `do_blocks()` over the overlay template on every front-end request, so its variants were seeding the page-global `hasNoResults*` / `hasErrorBlock` flags whether or not a visitor ever opened the overlay. A page that also carries pre-block results markup — a `results-list` with an authored `noResultsMessage` and no No Results block of its own — then had its legacy region retired by markup parked in an inert `<template>`, and a search through the in-page input left the results area blank where the author's copy used to be. The overlay knows its own composition, so it no longer needs the flags: the pass reads coverage off the parsed template up front, `seed_no_results_coverage()` no-ops while it is set, and the legacy regions resolve server-side — dropped outright where a variant covers them, bound to the plain condition getters where one doesn't. The page's own render path is unchanged. * Search Blocks: collapse a No Results container with nothing to show The container carries the block's color and spacing supports and unhides for the whole empty-state region, while each variant hides itself per condition. A container missing the live condition — a deleted variant, or two variants pointed at the same one — therefore painted an author's background and padding around nothing. The inline comment called that harmless on the grounds that block supports are opt-in, which the supports the block advertises contradict. Collapse it in CSS instead, keyed on the render-time binding so the rule can't reach the editor canvas, where an empty container has to stay selectable. * Search Blocks: anchor the pre-hydration hidden assertions per element `/<div[^>]*\shidden\s*>/` was anchored to nothing and stopped at the first match, but the default render emits two divs carrying a bare `hidden` — the container and the default copy's wrapper. Either one could lose the attribute and the test would still pass, while the region flashed on hydration exactly as the test name says it must not. * Search Blocks: fold the No Results changelog entries into one per project Four entries described one feature. Adds the plugin-side entries too — the block ships to users through both Jetpack and Jetpack Search. * Search Blocks: drop the No Results variant's "Display when" control The setting is left over from when the block was one block per condition. The container now seeds a variant for every condition, the templates ship all three, and the container's inspector re-adds a deleted one with the right value — so the radio could only ever move a variant onto a condition another already covers, stacking two messages there and leaving the vacated one to fall back to the legacy region. `condition` stays a registered attribute; it just has no editing affordance, the same shape as the deprecated Results List message settings. This also closes the second way to reach an empty container: the only remaining one is deleting a variant, which the CSS collapse already covers. * Search Blocks: move the empty-state logic to a No_Results class The condition helpers had accumulated into ten methods and a static on `Search_Blocks`, which is already 3,700 lines of registration, gating and template plumbing they have nothing to do with. They are one cohesive thing — which renderer covers which condition, the copy, and the store getter that reveals it — so they get their own class. The overlay's scope handling comes out better for it. `render_self_contained()` owns the whole invariant (collect coverage, render, always clear) rather than leaving the caller to set a static and remember a `finally`, and it gives the tests a real seam: the coverage and leak assertions now go through the public method instead of reaching for the private static with Reflection. Also trims the AGENTS.md notes that came with the last two commits. * Search Blocks: collapse an untouched No Results message in the editor Three stacked previews, each with its own appender, pushed the rest of the search template off-screen — and only one of the three can ever be on screen for a visitor. An untouched message is now a single labelled line and expands when selected. One holding authored content always renders in full, so nothing an author wrote is ever behind the compact form. * Fix CI: read the coverage static into a local before indexing it Phan doesn't narrow a static property through a `null !==` guard, so all four array accesses tripped PhanTypeArraySuspiciousNullable. A local reads better than repeating the property name anyway. * Address review: wrap stray blocks that sit beside No Results variants `$has_variants` was a boolean over all inner blocks, so one variant was enough to send the whole of `$content` out bare — non-variant siblings included. The wrap-as-unscoped path only ran when there were *zero* variants, which is not what the comment beside it (or AGENTS.md) claimed. Two ways that bit. On a failed request the container unhides for the error condition, no variant matches, and the stray content renders anyway — exactly the "shows on an error too" outcome the wrapping exists to prevent. And because a stray carries no `hidden`, `:not(:has(> :not([hidden])))` can never match, so the container also keeps painting its background and padding around it. `$content` is one concatenated string, so the strays can't be lifted back out of it — the mixed case re-renders each child in document order instead and gathers runs of strays into an unscoped variant. Re-rendering re-seeds, which is idempotent. The all-variants path still echoes `$content` untouched. Reachable through the document Code Editor, a paste, or an import: `allowedBlocks` governs the block UI, not the markup. * Address review: restore the self-contained scope instead of clearing it The `finally` reset to null rather than to the previous value. Nothing nests today — the only caller fires once on `wp_enqueue_scripts` — but AGENTS.md invites more callers, and a nested one would have failed silently and badly: the outer render drops back onto the page-global getters *and* resumes seeding, which is the leak this class exists to prevent. Also notes the one blind spot in `collect_coverage()`: `parse_blocks()` sees a synced pattern as a leaf, so a block reachable only through one reads as uncovered. Dereferencing refs would cost a post fetch on every front-end request for a shape the editor can't produce, so it's documented rather than resolved. * Address review: keep a drop target on a collapsed No Results message Collapsing unmounted `InnerBlocks` entirely, and the inner drop target comes from `useInnerBlocksProps` — so dragging a block from the inserter onto a collapsed message resolved to the container instead, whose `allowedBlocks` is the variant alone and rejects it. Since a stock container renders all three collapsed, that was every drag on a fresh template. It stays mounted now; only the appender goes. Empty and appender-less it has no size, so the one-line row is unchanged. * Address review: two Results List inaccuracies The render docblock still described the error region as gated by `state.showError`; it moved to `state.showLegacyError`. And the empty-state help text rendered outside a Search Results ancestor, where the button it refers to is suppressed — so the panel named an action it wasn't offering. * Fix CI: declare the probe array's keys for static analysis The closure fills them by reference from a `render_block` filter, which Phan can't follow — it saw writes to an array it had typed as empty. * Search Blocks: collapse authored No Results messages too Only one condition can ever be on screen for a visitor, so three stacked messages are three times the height the page will ever use — and an authored message is taller than the default-copy preview, not shorter. Every message now collapses when it isn't selected, not just the untouched ones. The row summarises an authored message with its own first line of copy (depth first, so a paragraph inside a Group still reads), so it still says what's in there rather than going blank. The blocks are hidden rather than unmounted: `useInnerBlocksProps` is where the inner drop target comes from, and an empty variant has no size to hide anyway. * Search Blocks: give No Results messages a layout so content can be aligned A message takes arbitrary blocks, but alignment is a property of the layout its parent provides — with none, an author couldn't centre an image inside one and `alignwide`/`alignfull` never appeared in the toolbar. Constrained layout, the same shape core/group uses, so children get a content width and the alignment controls mean something. `blockGap` comes back with it, for the same reason it went away: now there's a layout to attach it to. The stock empty state is unchanged — it has no author content to align, and its own centering is its own CSS. * Fix CodeQL: strip tags until the result stops changing `<[^>]*>` in one pass turns `<scr<a>ipt>` into `<script>` — the tags it removes reassembling into a new one. Not exploitable here (the summary is a React text node, so it's escaped either way), but it is an incomplete sanitizer and CodeQL is right to flag it. A rich-text attribute already carries plain text as `.text`, so use that when it's there and loop the strip until stable otherwise. * Search Blocks: outline and name the No Results block in the editor Three dashed rows with nothing around them read as three unrelated things. An outline and a label group them as one block, so it's clear which conditions belong to it. * Address review: announce authored empty-state copy too The live region wrapped only the localized fallback, on the reasoning that reading out an author's whole composition is worse than reading nothing. That trade was wrong: `results-list` put its custom `noResultsMessage` inside `role="status"` and its custom `errorMessage` inside `role="alert"`, so an author who moves their copy into the block lost the announcement they had. Results arrive client-side, so there is no page load to announce it instead — a screen reader user just gets silence where results used to be. Every message carries the live region now, authored or not, keeping the assertive/polite split by condition. * Address review: count stray children as covering the unscoped condition `render.php` wraps stray children as an unscoped variant, but `collect_coverage()` only counted variants — so the two disagreed about what a container covers. In a self-contained render that put the wrapped strays and `results-list`'s legacy region on the same getter, showing both at once on an unfiltered empty search. * Search Blocks: correct a stale note about who owns the error state `search-results/edit.jsx` still said `results-list` owns the error message internally. It is a No Results condition now. --------- Co-authored-by: Jasper Kang <jasper@Jaspers-MacBook-Pro16.local> Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/31658606462 Upstream-Ref: Automattic/jetpack@7d04ad7
1 parent e0df9fe commit 6221875

49 files changed

Lines changed: 738 additions & 124 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [7.0.2-alpha] - unreleased
8+
## [7.1.0-alpha] - unreleased
99

1010
This is an alpha version! The changes listed here are not final.
1111

12+
### Added
13+
- Search Blocks: add a No Results block so the search empty state can hold any blocks — links, images, buttons — instead of plain text. The Results List message settings are deprecated and keep rendering.
14+
1215
## [7.0.1] - 2026-07-22
1316
### Changed
1417
- Add a results-per-page setting to the Search Results block, falling back to the site's Reading setting when unset. [#50652]
@@ -331,7 +334,7 @@ This is an alpha version! The changes listed here are not final.
331334

332335
[1.1.0-beta]: https://github.com/Automattic/jetpack-search-plugin/compare/1.0.0...1.1.0-beta
333336
[1.2.0-beta]: https://github.com/Automattic/jetpack-search-plugin/compare/1.1.0...1.2.0-beta
334-
[7.0.2-alpha]: https://github.com/Automattic/jetpack-search-plugin/compare/7.0.1...7.0.2-alpha
337+
[7.1.0-alpha]: https://github.com/Automattic/jetpack-search-plugin/compare/7.0.1...7.1.0-alpha
335338
[7.0.1]: https://github.com/Automattic/jetpack-search-plugin/compare/7.0.0...7.0.1
336339
[7.0.0]: https://github.com/Automattic/jetpack-search-plugin/compare/6.0.0...7.0.0
337340
[6.0.0]: https://github.com/Automattic/jetpack-search-plugin/compare/5.2.2...6.0.0

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"automattic/jetpack-config": "^3.1.3",
1010
"automattic/jetpack-connection": "^8.10.1",
1111
"automattic/jetpack-my-jetpack": "^5.42.3",
12-
"automattic/jetpack-search": "^7.3.4-alpha",
12+
"automattic/jetpack-search": "^7.4.0-alpha",
1313
"automattic/jetpack-stats": "^0.20.2-alpha",
1414
"automattic/jetpack-status": "^6.3.1-alpha",
1515
"automattic/jetpack-sync": "^4.45.3"
@@ -52,7 +52,7 @@
5252
},
5353
"config": {
5454
"sort-packages": true,
55-
"autoloader-suffix": "b462338fb66be23595d68a93345c9e3d_jetpack_searchⓥ7_0_2_alpha",
55+
"autoloader-suffix": "b462338fb66be23595d68a93345c9e3d_jetpack_searchⓥ7_1_0_alpha",
5656
"allow-plugins": {
5757
"automattic/jetpack-autoloader": true,
5858
"automattic/jetpack-composer-plugin": true,

jetpack-search.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Plugin Name: Jetpack Search
55
* Plugin URI: https://jetpack.com/search/
66
* Description: Easily add cloud-powered instant search and filters to your website or WooCommerce store with advanced algorithms that boost your search results based on traffic to your site.
7-
* Version: 7.0.2-alpha
7+
* Version: 7.1.0-alpha
88
* Author: Automattic - Jetpack Search team
99
* Author URI: https://jetpack.com/
1010
* License: GPLv2 or later
@@ -26,7 +26,7 @@
2626
define( 'JETPACK_SEARCH_PLUGIN__FILE', __FILE__ );
2727
define( 'JETPACK_SEARCH_PLUGIN__FILE_RELATIVE_PATH', plugin_basename( __FILE__ ) );
2828
define( 'JETPACK_SEARCH_PLUGIN__SLUG', 'jetpack-search' );
29-
define( 'JETPACK_SEARCH_PLUGIN__VERSION', '7.0.2-alpha' );
29+
define( 'JETPACK_SEARCH_PLUGIN__VERSION', '7.1.0-alpha' );
3030
defined( 'JETPACK_CLIENT__AUTH_LOCATION' ) || define( 'JETPACK_CLIENT__AUTH_LOCATION', 'header' );
3131

3232
defined( 'JETPACK__API_BASE' ) || define( 'JETPACK__API_BASE', 'https://jetpack.wordpress.com/jetpack.' );

jetpack_vendor/automattic/jetpack-search/CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [7.3.4-alpha] - unreleased
8+
## [7.4.0-alpha] - unreleased
99

1010
This is an alpha version! The changes listed here are not final.
1111

12+
### Added
13+
- Search Blocks: add a No Results block so the search empty state can hold any blocks — links, images, buttons — instead of plain text. The Results List message settings are deprecated and keep rendering.
14+
1215
### Changed
1316
- Update package dependencies.
1417

@@ -1876,7 +1879,7 @@ This is an alpha version! The changes listed here are not final.
18761879
- Updated package dependencies.
18771880
- Update PHPUnit configs to include just what needs coverage rather than include everything then try to exclude stuff that doesn't.
18781881

1879-
[7.3.4-alpha]: https://github.com/Automattic/jetpack-search/compare/v7.3.3...v7.3.4-alpha
1882+
[7.4.0-alpha]: https://github.com/Automattic/jetpack-search/compare/v7.3.3...v7.4.0-alpha
18801883
[7.3.3]: https://github.com/Automattic/jetpack-search/compare/v7.3.2...v7.3.3
18811884
[7.3.2]: https://github.com/Automattic/jetpack-search/compare/v7.3.1...v7.3.2
18821885
[7.3.1]: https://github.com/Automattic/jetpack-search/compare/v7.3.0...v7.3.1
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-primitives'), 'version' => 'f0ad556fa9827dadb832');
1+
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-primitives'), 'version' => '9a34085f882fe8480185');

jetpack_vendor/automattic/jetpack-search/build/search-blocks-editor/register-blocks.js

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?php return array('dependencies' => array('jetpack-search/store'), 'version' => 'f3cad0460f3fc31b94e8', 'type' => 'module');

jetpack_vendor/automattic/jetpack-search/build/search-blocks/no-results.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jetpack_vendor/automattic/jetpack-search/build/search-blocks/no-results.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jetpack_vendor/automattic/jetpack-search/build/search-blocks/no-results.rtl.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)