Skip to content

Conversation

michalczaplinski
Copy link
Contributor

@michalczaplinski michalczaplinski commented Nov 20, 2024

What?

Implementation of Instant Search using the Search and Query Loop blocks. Added as a new experiment on the Gutenberg Experiments page.

Related to #63053

output_62afd8.mp4

How does it work?

Testing

  1. Enable the Instant Search and Query Block Gutenberg experiment.
  2. Insert a Query block anywhere on your site.
  3. Make sure to disable Reload Full Page checkbox in the Query block's Advanced Settings i.e. use "enhanced pagination" in that Query block.
  4. Insert a Search block anywhere inside of that Query block.

When the Search block is inside of the Query block using "enhanced pagination", it automatically gets "updated" to an Instant Search block.

Any search input in the Instant Search block gets passed as the ?instant-search-<queryId>=<search-term> query search param in the URL.

Multiple Query + Search blocks

It's possible to have multiple Instant Search blocks in a page/post/template. In such a case, ensuring their functionality is isolated is essential. For this to work, the queryId is part of the param syntax:

  • instant-search-<queryId>=<search-term>

Search button

The search block can contain a search button (in some configurations). However, when using the Instant Search functionality, the button is redundant because the list of posts updates as you type. For this reason, in the editor, when the Search block is placed inside the Query Loop block with enhanced pagination ON, the Block Controls related to the Search button are removed. The displayed name of the block (via label) is changed to Instant Search (Search).

On the frontend, the Search button is also always removed for each (Instant) Search block.

output_70b3a0.mp4

Pagination

The instant search functionality respects the pagination of the Query block, which uses the query-<queryId>-page syntax.

  1. Every time the search is updated, the pagination of its respective query is reset back to page 1.
  2. The pagination numbers and next/previous, are updated to reflect the number of results in the search.
  3. Clearing the search also resets the pagination back to page 1.

Limitations

Alternatives

Alternative approaches have been explored:

Further work

This is an initial prototype and the following features is intentionally not yet implemented:

  • Support for the Default queries, including multiple Default queries on a single page/post/template. Those have been prototyped already in Search and Query blocks: Add support for Default queries via pre_get_posts filter #67289.
  • Explore an alternative mechanism to convert the Search block into a Instant Search. Currently, this is done by nesting the Search inside of Query Loop with enhanced pagination ON, but a different, more explicit mechanism might be appropriate.
  • Include contents of the Query No Results block but hide them with CSS (comment)

@michalczaplinski michalczaplinski added [Block] Search Affects the Search Block - used to display a search field [Type] Feature New feature to highlight in changelogs. [Type] Experimental Experimental feature or API. [Feature] Interactivity API API to add frontend interactivity to blocks. [Packages] Interactivity /packages/interactivity labels Nov 20, 2024
Copy link

github-actions bot commented Nov 20, 2024

Size Change: +532 B (+0.03%)

Total Size: 1.86 MB

Filename Size Change
build-module/block-library/search/view.min.js 974 B +335 B (+52.43%) 🆘
build/block-library/index.min.js 228 kB +192 B (+0.08%)
build/blocks/index.min.js 52.6 kB +5 B (+0.01%)
ℹ️ View Unchanged
Filename Size
build-module/a11y/index.min.js 482 B
build-module/block-library/file/view.min.js 447 B
build-module/block-library/form/view.min.js 533 B
build-module/block-library/image/view.min.js 1.78 kB
build-module/block-library/navigation/view.min.js 1.19 kB
build-module/block-library/query/view.min.js 767 B
build-module/interactivity-router/full-page.min.js 565 B
build-module/interactivity-router/index.min.js 11.4 kB
build-module/interactivity/debug.min.js 17.5 kB
build-module/interactivity/index.min.js 13.9 kB
build/a11y/index.min.js 952 B
build/annotations/index.min.js 2.26 kB
build/api-fetch/index.min.js 2.4 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 579 B
build/block-directory/index.min.js 7.18 kB
build/block-directory/style-rtl.css 1.03 kB
build/block-directory/style.css 1.03 kB
build/block-editor/content-rtl.css 4.43 kB
build/block-editor/content.css 4.42 kB
build/block-editor/default-editor-styles-rtl.css 392 B
build/block-editor/default-editor-styles.css 392 B
build/block-editor/index.min.js 264 kB
build/block-editor/style-rtl.css 15.9 kB
build/block-editor/style.css 15.9 kB
build/block-library/blocks/archives/editor-rtl.css 84 B
build/block-library/blocks/archives/editor.css 83 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 149 B
build/block-library/blocks/audio/editor.css 151 B
build/block-library/blocks/audio/style-rtl.css 132 B
build/block-library/blocks/audio/style.css 132 B
build/block-library/blocks/audio/theme-rtl.css 134 B
build/block-library/blocks/audio/theme.css 134 B
build/block-library/blocks/avatar/editor-rtl.css 115 B
build/block-library/blocks/avatar/editor.css 115 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/button/editor-rtl.css 265 B
build/block-library/blocks/button/editor.css 265 B
build/block-library/blocks/button/style-rtl.css 554 B
build/block-library/blocks/button/style.css 554 B
build/block-library/blocks/buttons/editor-rtl.css 291 B
build/block-library/blocks/buttons/editor.css 291 B
build/block-library/blocks/buttons/style-rtl.css 349 B
build/block-library/blocks/buttons/style.css 349 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 132 B
build/block-library/blocks/categories/editor.css 131 B
build/block-library/blocks/categories/style-rtl.css 152 B
build/block-library/blocks/categories/style.css 152 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 139 B
build/block-library/blocks/code/style.css 139 B
build/block-library/blocks/code/theme-rtl.css 122 B
build/block-library/blocks/code/theme.css 122 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 420 B
build/block-library/blocks/columns/style.css 420 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 124 B
build/block-library/blocks/comment-author-avatar/editor.css 124 B
build/block-library/blocks/comment-author-name/style-rtl.css 72 B
build/block-library/blocks/comment-author-name/style.css 72 B
build/block-library/blocks/comment-content/style-rtl.css 120 B
build/block-library/blocks/comment-content/style.css 120 B
build/block-library/blocks/comment-date/style-rtl.css 65 B
build/block-library/blocks/comment-date/style.css 65 B
build/block-library/blocks/comment-edit-link/style-rtl.css 70 B
build/block-library/blocks/comment-edit-link/style.css 70 B
build/block-library/blocks/comment-reply-link/style-rtl.css 71 B
build/block-library/blocks/comment-reply-link/style.css 71 B
build/block-library/blocks/comment-template/style-rtl.css 191 B
build/block-library/blocks/comment-template/style.css 191 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 168 B
build/block-library/blocks/comments-pagination/editor.css 168 B
build/block-library/blocks/comments-pagination/style-rtl.css 201 B
build/block-library/blocks/comments-pagination/style.css 201 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 842 B
build/block-library/blocks/comments/editor.css 842 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 637 B
build/block-library/blocks/cover/editor-rtl.css 631 B
build/block-library/blocks/cover/editor.css 631 B
build/block-library/blocks/cover/style-rtl.css 1.7 kB
build/block-library/blocks/cover/style.css 1.69 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 331 B
build/block-library/blocks/embed/editor.css 331 B
build/block-library/blocks/embed/style-rtl.css 419 B
build/block-library/blocks/embed/style.css 419 B
build/block-library/blocks/embed/theme-rtl.css 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 326 B
build/block-library/blocks/file/style-rtl.css 278 B
build/block-library/blocks/file/style.css 279 B
build/block-library/blocks/footnotes/style-rtl.css 198 B
build/block-library/blocks/footnotes/style.css 197 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 229 B
build/block-library/blocks/form-input/style-rtl.css 349 B
build/block-library/blocks/form-input/style.css 349 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 344 B
build/block-library/blocks/form-submission-notification/editor.css 341 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/freeform/editor-rtl.css 2.59 kB
build/block-library/blocks/freeform/editor.css 2.59 kB
build/block-library/blocks/gallery/editor-rtl.css 688 B
build/block-library/blocks/gallery/editor.css 691 B
build/block-library/blocks/gallery/style-rtl.css 1.84 kB
build/block-library/blocks/gallery/style.css 1.84 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 334 B
build/block-library/blocks/group/editor.css 334 B
build/block-library/blocks/group/style-rtl.css 103 B
build/block-library/blocks/group/style.css 103 B
build/block-library/blocks/group/theme-rtl.css 79 B
build/block-library/blocks/group/theme.css 79 B
build/block-library/blocks/heading/style-rtl.css 188 B
build/block-library/blocks/heading/style.css 188 B
build/block-library/blocks/html/editor-rtl.css 353 B
build/block-library/blocks/html/editor.css 354 B
build/block-library/blocks/image/editor-rtl.css 763 B
build/block-library/blocks/image/editor.css 763 B
build/block-library/blocks/image/style-rtl.css 1.6 kB
build/block-library/blocks/image/style.css 1.59 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/latest-comments/style-rtl.css 355 B
build/block-library/blocks/latest-comments/style.css 354 B
build/block-library/blocks/latest-posts/editor-rtl.css 139 B
build/block-library/blocks/latest-posts/editor.css 138 B
build/block-library/blocks/latest-posts/style-rtl.css 520 B
build/block-library/blocks/latest-posts/style.css 520 B
build/block-library/blocks/list/style-rtl.css 107 B
build/block-library/blocks/list/style.css 107 B
build/block-library/blocks/loginout/style-rtl.css 61 B
build/block-library/blocks/loginout/style.css 61 B
build/block-library/blocks/media-text/editor-rtl.css 321 B
build/block-library/blocks/media-text/editor.css 320 B
build/block-library/blocks/media-text/style-rtl.css 543 B
build/block-library/blocks/media-text/style.css 542 B
build/block-library/blocks/more/editor-rtl.css 427 B
build/block-library/blocks/more/editor.css 427 B
build/block-library/blocks/navigation-link/editor-rtl.css 566 B
build/block-library/blocks/navigation-link/editor.css 568 B
build/block-library/blocks/navigation-link/style-rtl.css 192 B
build/block-library/blocks/navigation-link/style.css 191 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 295 B
build/block-library/blocks/navigation-submenu/editor.css 294 B
build/block-library/blocks/navigation/editor-rtl.css 2.23 kB
build/block-library/blocks/navigation/editor.css 2.24 kB
build/block-library/blocks/navigation/style-rtl.css 2.26 kB
build/block-library/blocks/navigation/style.css 2.25 kB
build/block-library/blocks/nextpage/editor-rtl.css 392 B
build/block-library/blocks/nextpage/editor.css 392 B
build/block-library/blocks/page-list/editor-rtl.css 378 B
build/block-library/blocks/page-list/editor.css 378 B
build/block-library/blocks/page-list/style-rtl.css 192 B
build/block-library/blocks/page-list/style.css 192 B
build/block-library/blocks/paragraph/editor-rtl.css 251 B
build/block-library/blocks/paragraph/editor.css 251 B
build/block-library/blocks/paragraph/style-rtl.css 341 B
build/block-library/blocks/paragraph/style.css 340 B
build/block-library/blocks/post-author-biography/style-rtl.css 74 B
build/block-library/blocks/post-author-biography/style.css 74 B
build/block-library/blocks/post-author-name/style-rtl.css 69 B
build/block-library/blocks/post-author-name/style.css 69 B
build/block-library/blocks/post-author/style-rtl.css 188 B
build/block-library/blocks/post-author/style.css 189 B
build/block-library/blocks/post-comments-count/style-rtl.css 72 B
build/block-library/blocks/post-comments-count/style.css 72 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 527 B
build/block-library/blocks/post-comments-form/style.css 528 B
build/block-library/blocks/post-comments-link/style-rtl.css 71 B
build/block-library/blocks/post-comments-link/style.css 71 B
build/block-library/blocks/post-content/style-rtl.css 61 B
build/block-library/blocks/post-content/style.css 61 B
build/block-library/blocks/post-date/style-rtl.css 62 B
build/block-library/blocks/post-date/style.css 62 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 155 B
build/block-library/blocks/post-excerpt/style.css 155 B
build/block-library/blocks/post-featured-image/editor-rtl.css 722 B
build/block-library/blocks/post-featured-image/editor.css 720 B
build/block-library/blocks/post-featured-image/style-rtl.css 347 B
build/block-library/blocks/post-featured-image/style.css 347 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/style-rtl.css 414 B
build/block-library/blocks/post-template/style.css 414 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 70 B
build/block-library/blocks/post-time-to-read/style.css 70 B
build/block-library/blocks/post-title/style-rtl.css 162 B
build/block-library/blocks/post-title/style.css 162 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 133 B
build/block-library/blocks/pullquote/editor.css 133 B
build/block-library/blocks/pullquote/style-rtl.css 365 B
build/block-library/blocks/pullquote/style.css 365 B
build/block-library/blocks/pullquote/theme-rtl.css 176 B
build/block-library/blocks/pullquote/theme.css 176 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 121 B
build/block-library/blocks/query-pagination-numbers/editor.css 118 B
build/block-library/blocks/query-pagination/editor-rtl.css 154 B
build/block-library/blocks/query-pagination/editor.css 154 B
build/block-library/blocks/query-pagination/style-rtl.css 237 B
build/block-library/blocks/query-pagination/style.css 237 B
build/block-library/blocks/query-title/style-rtl.css 64 B
build/block-library/blocks/query-title/style.css 64 B
build/block-library/blocks/query-total/style-rtl.css 64 B
build/block-library/blocks/query-total/style.css 64 B
build/block-library/blocks/query/editor-rtl.css 404 B
build/block-library/blocks/query/editor.css 404 B
build/block-library/blocks/quote/style-rtl.css 238 B
build/block-library/blocks/quote/style.css 238 B
build/block-library/blocks/quote/theme-rtl.css 233 B
build/block-library/blocks/quote/theme.css 236 B
build/block-library/blocks/read-more/style-rtl.css 131 B
build/block-library/blocks/read-more/style.css 131 B
build/block-library/blocks/rss/editor-rtl.css 126 B
build/block-library/blocks/rss/editor.css 126 B
build/block-library/blocks/rss/style-rtl.css 284 B
build/block-library/blocks/rss/style.css 283 B
build/block-library/blocks/search/editor-rtl.css 199 B
build/block-library/blocks/search/editor.css 199 B
build/block-library/blocks/search/style-rtl.css 674 B
build/block-library/blocks/search/style.css 671 B
build/block-library/blocks/search/theme-rtl.css 113 B
build/block-library/blocks/search/theme.css 113 B
build/block-library/blocks/separator/editor-rtl.css 100 B
build/block-library/blocks/separator/editor.css 100 B
build/block-library/blocks/separator/style-rtl.css 248 B
build/block-library/blocks/separator/style.css 248 B
build/block-library/blocks/separator/theme-rtl.css 195 B
build/block-library/blocks/separator/theme.css 195 B
build/block-library/blocks/shortcode/editor-rtl.css 286 B
build/block-library/blocks/shortcode/editor.css 286 B
build/block-library/blocks/site-logo/editor-rtl.css 773 B
build/block-library/blocks/site-logo/editor.css 770 B
build/block-library/blocks/site-logo/style-rtl.css 218 B
build/block-library/blocks/site-logo/style.css 218 B
build/block-library/blocks/site-tagline/editor-rtl.css 87 B
build/block-library/blocks/site-tagline/editor.css 87 B
build/block-library/blocks/site-tagline/style-rtl.css 65 B
build/block-library/blocks/site-tagline/style.css 65 B
build/block-library/blocks/site-title/editor-rtl.css 85 B
build/block-library/blocks/site-title/editor.css 85 B
build/block-library/blocks/site-title/style-rtl.css 143 B
build/block-library/blocks/site-title/style.css 143 B
build/block-library/blocks/social-link/editor-rtl.css 314 B
build/block-library/blocks/social-link/editor.css 314 B
build/block-library/blocks/social-links/editor-rtl.css 339 B
build/block-library/blocks/social-links/editor.css 338 B
build/block-library/blocks/social-links/style-rtl.css 1.51 kB
build/block-library/blocks/social-links/style.css 1.51 kB
build/block-library/blocks/spacer/editor-rtl.css 346 B
build/block-library/blocks/spacer/editor.css 346 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table-of-contents/style-rtl.css 83 B
build/block-library/blocks/table-of-contents/style.css 83 B
build/block-library/blocks/table/editor-rtl.css 394 B
build/block-library/blocks/table/editor.css 394 B
build/block-library/blocks/table/style-rtl.css 640 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 B
build/block-library/blocks/tag-cloud/editor-rtl.css 92 B
build/block-library/blocks/tag-cloud/editor.css 92 B
build/block-library/blocks/tag-cloud/style-rtl.css 248 B
build/block-library/blocks/tag-cloud/style.css 248 B
build/block-library/blocks/template-part/editor-rtl.css 368 B
build/block-library/blocks/template-part/editor.css 368 B
build/block-library/blocks/template-part/theme-rtl.css 113 B
build/block-library/blocks/template-part/theme.css 113 B
build/block-library/blocks/term-description/style-rtl.css 126 B
build/block-library/blocks/term-description/style.css 126 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 165 B
build/block-library/blocks/text-columns/style.css 165 B
build/block-library/blocks/verse/style-rtl.css 98 B
build/block-library/blocks/verse/style.css 98 B
build/block-library/blocks/video/editor-rtl.css 441 B
build/block-library/blocks/video/editor.css 442 B
build/block-library/blocks/video/style-rtl.css 192 B
build/block-library/blocks/video/style.css 192 B
build/block-library/blocks/video/theme-rtl.css 134 B
build/block-library/blocks/video/theme.css 134 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.08 kB
build/block-library/common.css 1.08 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 11.2 kB
build/block-library/editor.css 11.2 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/style-rtl.css 15 kB
build/block-library/style.css 15 kB
build/block-library/theme-rtl.css 715 B
build/block-library/theme.css 719 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/commands/index.min.js 16.2 kB
build/commands/style-rtl.css 956 B
build/commands/style.css 952 B
build/components/index.min.js 230 kB
build/components/style-rtl.css 12.5 kB
build/components/style.css 12.5 kB
build/compose/index.min.js 12.8 kB
build/core-commands/index.min.js 3.09 kB
build/core-data/index.min.js 74.3 kB
build/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.43 kB
build/customize-widgets/style.css 1.43 kB
build/data-controls/index.min.js 641 B
build/data/index.min.js 8.67 kB
build/date/index.min.js 18 kB
build/deprecated/index.min.js 458 B
build/dom-ready/index.min.js 325 B
build/dom/index.min.js 4.68 kB
build/edit-post/classic-rtl.css 577 B
build/edit-post/classic.css 578 B
build/edit-post/index.min.js 13.5 kB
build/edit-post/style-rtl.css 2.77 kB
build/edit-post/style.css 2.77 kB
build/edit-site/index.min.js 222 kB
build/edit-site/posts-rtl.css 7.52 kB
build/edit-site/posts.css 7.52 kB
build/edit-site/style-rtl.css 13.6 kB
build/edit-site/style.css 13.6 kB
build/edit-widgets/index.min.js 17.7 kB
build/edit-widgets/style-rtl.css 4.05 kB
build/edit-widgets/style.css 4.06 kB
build/editor/index.min.js 117 kB
build/editor/style-rtl.css 9.06 kB
build/editor/style.css 9.06 kB
build/element/index.min.js 4.82 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.08 kB
build/format-library/style-rtl.css 472 B
build/format-library/style.css 472 B
build/hooks/index.min.js 1.65 kB
build/html-entities/index.min.js 467 B
build/i18n/index.min.js 3.58 kB
build/is-shallow-equal/index.min.js 526 B
build/keyboard-shortcuts/index.min.js 1.31 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.13 kB
build/list-reusable-blocks/style-rtl.css 847 B
build/list-reusable-blocks/style.css 848 B
build/media-utils/index.min.js 3.69 kB
build/notices/index.min.js 946 B
build/nux/index.min.js 1.62 kB
build/nux/style-rtl.css 767 B
build/nux/style.css 763 B
build/patterns/index.min.js 7.36 kB
build/patterns/style-rtl.css 687 B
build/patterns/style.css 685 B
build/plugins/index.min.js 1.86 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/index.min.js 2.9 kB
build/preferences/style-rtl.css 551 B
build/preferences/style.css 552 B
build/primitives/index.min.js 829 B
build/priority-queue/index.min.js 1.54 kB
build/private-apis/index.min.js 978 B
build/react-i18n/index.min.js 630 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.76 kB
build/redux-routine/index.min.js 2.7 kB
build/reusable-blocks/index.min.js 2.53 kB
build/reusable-blocks/style-rtl.css 255 B
build/reusable-blocks/style.css 255 B
build/rich-text/index.min.js 10.3 kB
build/router/index.min.js 5.44 kB
build/server-side-render/index.min.js 1.96 kB
build/shortcode/index.min.js 1.4 kB
build/style-engine/index.min.js 2.04 kB
build/token-list/index.min.js 581 B
build/url/index.min.js 3.96 kB
build/vendors/react-dom.min.js 41.7 kB
build/vendors/react-jsx-runtime.min.js 556 B
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 965 B
build/vips/index.min.js 36.2 kB
build/warning/index.min.js 250 B
build/widgets/index.min.js 7.16 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.03 kB

compressed-size-action

@michalczaplinski michalczaplinski removed the [Type] Feature New feature to highlight in changelogs. label Nov 21, 2024
@michalczaplinski michalczaplinski changed the title Query and Search blocks: support for instant search via query_loop_block_query_vars filter Query and Search blocks: support for Instant Search via query_loop_block_query_vars filter Nov 21, 2024
@michalczaplinski michalczaplinski marked this pull request as ready for review November 25, 2024 18:36
Copy link

github-actions bot commented Nov 25, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: michalczaplinski <czapla@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: draganescu <andraganescu@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>
Co-authored-by: DAreRodz <darerodz@git.wordpress.org>
Co-authored-by: fabiankaegy <fabiankaegy@git.wordpress.org>
Co-authored-by: luisherranz <luisherranz@git.wordpress.org>
Co-authored-by: peterwilsoncc <peterwilsoncc@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@michalczaplinski
Copy link
Contributor Author

Instead of updating the block's name in the metadata when the Search block becomes an Instant Search block, I'm considering adding help text (more discussion in #67181 (comment)):

I opened a PR to add a SlotFill to support this so this PR is currently blocked until we decide on an approach.

@gziolo
Copy link
Member

gziolo commented Jan 2, 2025

I opened a #68438 so this PR is currently blocked until we decide on an approach.

Is it essential to launch an experiment behind a flag?

@michalczaplinski
Copy link
Contributor Author

Is it essential to launch an experiment behind a flag?

It's not essential 🙂. We can eliminate the indicator altogether for now and figure out a way to indicate that the block is enhanced before the block graduates from experimental status. Does that sound good?

@t-hamano
Copy link
Contributor

t-hamano commented Jan 3, 2025

probably, there's a better way to let users know that the block is enhanced.

As an alternative approach to #68438, I imagine we could upe __experimentalLabel to let users know that instant search is enabled.

  • Extend the useBlockDisplayTitle hook and getBlockLabel function to pass the clientId as a prop
  • Add the text (Instant search enabled) after the block name if the Search block is in a Query Loop block and enhancedPagination and __experimentalEnableSearchQueryBlock are enabled.
a115a6d4b8a7ad18f18581f1790bc662.mp4

Here are the changes I made to this PR to achieve this:

Diff
diff --git a/packages/block-editor/src/components/block-title/use-block-display-title.js b/packages/block-editor/src/components/block-title/use-block-display-title.js
index a51b336554a..137c4ec1603 100644
--- a/packages/block-editor/src/components/block-title/use-block-display-title.js
+++ b/packages/block-editor/src/components/block-title/use-block-display-title.js
@@ -51,7 +51,12 @@ export default function useBlockDisplayTitle( {
                        }
 
                        const attributes = getBlockAttributes( clientId );
-                       const label = getBlockLabel( blockType, attributes, context );
+                       const label = getBlockLabel(
+                               blockType,
+                               attributes,
+                               context,
+                               clientId
+                       );
                        // If the label is defined we prioritize it over a possible block variation title match.
                        if ( label !== blockType.title ) {
                                return label;
diff --git a/packages/block-library/src/search/index.js b/packages/block-library/src/search/index.js
index 85770a23268..c81abebdf79 100644
--- a/packages/block-library/src/search/index.js
+++ b/packages/block-library/src/search/index.js
@@ -1,8 +1,10 @@
 /**
  * WordPress dependencies
  */
-import { __ } from '@wordpress/i18n';
+import { __, sprintf } from '@wordpress/i18n';
 import { search as icon } from '@wordpress/icons';
+import { select } from '@wordpress/data';
+import { store as blockEditorStore } from '@wordpress/block-editor';
 
 /**
  * Internal dependencies
@@ -18,6 +20,41 @@ export { metadata, name };
 
 export const settings = {
        icon,
+       __experimentalLabel( attributes, { clientId } ) {
+               const { label } = attributes;
+               const customName = attributes?.metadata?.name;
+
+               // Check if the block is inside a Query Loop block.
+               const queryLoopBlockIds = select(
+                       blockEditorStore
+               ).getBlockParentsByBlockName( clientId, 'core/query' );
+
+               // If the block is not inside a Query Loop block, return the block label.
+               if ( ! queryLoopBlockIds.length ) {
+                       return customName || label;
+               }
+
+               const queryLoopBlock = select( blockEditorStore ).getBlock(
+                       queryLoopBlockIds[ 0 ]
+               );
+
+               // Check if the Query Loop block has enhanced pagination enabled and
+               // if the `__experimentalEnableSearchQueryBlock` flag is enabled.
+               const hasInstantSearch = !! (
+                       queryLoopBlock?.attributes?.enhancedPagination &&
+                       window?.__experimentalEnableSearchQueryBlock
+               );
+
+               if ( ! hasInstantSearch ) {
+                       return customName || label;
+               }
+
+               return sprintf(
+                       /* translators: %s: The block label */
+                       __( '%s (Instant search enabled)' ),
+                       customName || label
+               );
+       },
        example: {
                attributes: { buttonText: __( 'Search' ), label: __( 'Search' ) },
                viewportWidth: 400,
diff --git a/packages/blocks/src/api/utils.js b/packages/blocks/src/api/utils.js
index 1a215036496..2f77bf19937 100644
--- a/packages/blocks/src/api/utils.js
+++ b/packages/blocks/src/api/utils.js
@@ -153,13 +153,18 @@ export function normalizeBlockType( blockTypeOrName ) {
  * @param {Object} blockType  The block type.
  * @param {Object} attributes The values of the block's attributes.
  * @param {Object} context    The intended use for the label.
- *
+ * @param          clientId
  * @return {string} The block label.
  */
-export function getBlockLabel( blockType, attributes, context = 'visual' ) {
+export function getBlockLabel(
+       blockType,
+       attributes,
+       context = 'visual',
+       clientId
+) {
        const { __experimentalLabel: getLabel, title } = blockType;
 
-       const label = getLabel && getLabel( attributes, { context } );
+       const label = getLabel && getLabel( attributes, { context, clientId } );
 
        if ( ! label ) {
                return title;

One concern is that __experimentalLabel has no effect on the block card:

block-title

…n Search block is inside Query block with enhanced pagination. Removed checks for renaming Search block to "Instant Search" in List View and Inspector Controls, focusing on button visibility instead.
- Updated `getBlockLabel` to include `clientId` for improved label context.
- Modified `useBlockDisplayTitle` to utilize the updated `getBlockLabel` function.
- Introduced `__experimentalLabel` in the search settings to handle block labels based on query loop context and instant search status.
- Added a test to ensure the List View label updates correctly when the Search block is part of a Query block with enhanced pagination enabled.
- Verified that the label reflects "Instant search enabled" when applicable and reverts to "Search" when enhanced pagination is disabled.
- It's not needed because we fall back to 'Search' as last resort in `_experimentalLabel()` (previous commit).
@michalczaplinski
Copy link
Contributor Author

This works great @t-hamano, thank you! 👏 I'm not too worried about it not showing up in the Block Card for now. It's still better than not showing any updated label at all.

I've implemented your suggestion in 2db363a and an e2e test for it in c20526f.

I also had to add a fallback to default to "Search" string in __experimentalLabel() in 6b975c4:

customName || label || 'Search'

Otherwise, if the block had no label, depending on the circumstances it ended up showing up as undefined (Instant search enabled) or just (Instant search enabled):

Screen.Recording.2025-01-06.at.16.19.42.mov

@t-hamano
Copy link
Contributor

t-hamano commented Jan 7, 2025

Otherwise, if the block had no label, depending on the circumstances it ended up showing up as undefined (Instant search enabled) or just (Instant search enabled):

Sorry, I think the code I proposed was not complete.

Originally in the List View, the display name and label attribute were not synchronized. That means the List View only shows either "Search" or the custom name. Additionally, the text Instant search enabled may only need to be displayed in the List View.

So I think the logic should be like this:

if ( context !== 'list-view' ) {
	return;
}

const blockTitle = __( 'Search' );

if ( ! queryLoopBlockIds.length ) {
	return customName || blockTitle;
}

if ( ! hasInstantSearch ) {
	return customName || blockTitle;
}

return sprintf(
	/* translators: %s: The block label */
	__( '%s (Instant search enabled)' ),
	customName || blockTitle
);

@michalczaplinski
Copy link
Contributor Author

@t-hamano I've updated it to use the logic you mentioned and re-tested 👍.

Would you mind taking another look?

Copy link
Contributor

@t-hamano t-hamano left a comment

Choose a reason for hiding this comment

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

@michalczaplinski Sorry for the late reply!

I've resolved code conflicts and commented on things I've noticed throughout this PR to help move this PR forward. I'd be happy if you could take a look at them.

$enhanced_pagination = isset( $block->context['enhancedPagination'] ) && $block->context['enhancedPagination'];

// Check if the block is using the instant search experiment, which requires the enhanced pagination.
$gutenberg_experiments = get_option( 'gutenberg-experiments' );
Copy link
Contributor

Choose a reason for hiding this comment

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

The gutenberg-experiments option is for the Gutenberg plugin, so I'm wondering if it's appropriate to write code like this in a file that is shipped to core. Of course, I think that once Instant Search is no longer experimental, this code can be removed.

@@ -71,6 +74,62 @@ const { actions } = store(
actions.closeSearchInput();
}
},
*updateSearch( e ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

In CJK languages, an IME (Input Method Editor) is used to input complex characters. Therefore, for example, in a Japanese environment, the search results are updated even during IME composition. This is generally not desirable:

ae748c6d1de97106b860fcc0b6577c03.mp4

I guess we could address this in a follow-up, but ideally, we should ignore the event during composition and fire the updateSearch when the Enter key is pressed to commit the composition.

*
* @param this
*/
export async function openListView( this: Editor ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it's a good idea to add a new utility for E2E testing in this PR. If we want to open a list view, we should be able to simply use code like this:

await page
	.getByRole( 'region', { name: 'Editor top bar' } )
	.getByRole( 'button', { name: 'Document Overview' } )
	.click();

Comment on lines +85 to +88
// Set the Blog pages show at most 2 posts
await requestUtils.updateSiteSettings( {
posts_per_page: 2,
} );
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need to restore the default settings via afterAll. Example:

await requestUtils.updateSiteSettings( {
default_post_format: 'image',
} );
} );
test.afterAll( async ( { requestUtils } ) => {
await requestUtils.updateSiteSettings( {
default_post_format: STANDARD_FORMAT_VALUE,
} );

).toBeVisible();

// Type in search input and verify results update
await page.locator( 'input[type="search"]' ).fill( 'Unique' );
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
await page.locator( 'input[type="search"]' ).fill( 'Unique' );
await page.getByRole( 'searchbox' ).fill( 'Unique' );

Use accessible selectors whenever possible instead of page.locator.

<!-- /wp:paragraph -->
<!-- /wp:query-no-results -->
</div>
<!-- /wp:query -->`,
Copy link
Contributor

Choose a reason for hiding this comment

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

If hard-coding HTML strings is not recommended, we can also use the following approach:

Details
await admin.createNewPost();
await editor.insertBlock( {
	name: 'core/query',
	attributes: {
		enhancedPagination: true,
		queryId,
		query: {
			inherit: false,
			perPage: 2,
			order: 'desc',
			orderBy: 'date',
			offset: 0,
			search: 'Unique',
		},
	},
	innerBlocks: [
		{
			name: 'core/search',
			attributes: { label: '', buttonText: 'Search' },
		},
		{
			name: 'core/post-template',
			innerBlocks: [
				{
					name: 'core/post-title',
					attributes: { level: 3 },
				},
				{ name: 'core/post-excerpt' },
			],
		},
		{
			name: 'core/query-pagination',
			innerBlocks: [
				{ name: 'core/query-pagination-previous' },
				{ name: 'core/query-pagination-numbers' },
				{ name: 'core/query-pagination-next' },
			],
		},
		{
			name: 'core/query-no-results',
			innerBlocks: [
				{
					name: 'core/paragraph',
					attributes: {
						content: 'No results found.',
					},
				},
			],
		},
	],
} );
const id = await editor.publishPost();

However, you need to remove this code so that the front-end page is not opened when the test starts.

@peterwilsoncc
Copy link
Contributor

This looks really nice.

While testing, I noticed that there is an escaping bug for the search box when it contains quotes, they end up being escaped in the output "Pens and pencils" becomes \"Pens and pencils\" upon page refresh of an instant search URL.

escaped-quotes

If the instant search experiment is enabled, would it be possible to enable the feature on the search template with the option "Use instant search" for the search block? In that case it would be an inherited query so it's totally cool if the answer is no for the initial experiment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Search Affects the Search Block - used to display a search field [Feature] Interactivity API API to add frontend interactivity to blocks. [Type] Experimental Experimental feature or API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants