@wordpress/block-library 9.13.0 → 9.13.1-next.a9f418477.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/build/block/edit.js +2 -29
  2. package/build/block/edit.js.map +1 -1
  3. package/build/cover/edit/index.js +4 -2
  4. package/build/cover/edit/index.js.map +1 -1
  5. package/build/cover/edit/inspector-controls.js +6 -4
  6. package/build/cover/edit/inspector-controls.js.map +1 -1
  7. package/build/form/index.js +1 -2
  8. package/build/form/index.js.map +1 -1
  9. package/build/form/view.js +10 -5
  10. package/build/form/view.js.map +1 -1
  11. package/build/list-item/hooks/use-merge.js +2 -2
  12. package/build/list-item/hooks/use-merge.js.map +1 -1
  13. package/build/navigation/edit/deleted-navigation-warning.js +9 -2
  14. package/build/navigation/edit/deleted-navigation-warning.js.map +1 -1
  15. package/build/navigation-link/edit.js +1 -2
  16. package/build/navigation-link/edit.js.map +1 -1
  17. package/build/navigation-submenu/edit.js +3 -1
  18. package/build/navigation-submenu/edit.js.map +1 -1
  19. package/build/pattern/recursion-detector.js +0 -1
  20. package/build/pattern/recursion-detector.js.map +1 -1
  21. package/build/query/edit/index.js +2 -2
  22. package/build/query/edit/index.js.map +1 -1
  23. package/build/query/edit/inspector-controls/author-control.js +0 -1
  24. package/build/query/edit/inspector-controls/author-control.js.map +1 -1
  25. package/build/query/edit/inspector-controls/parent-control.js +0 -1
  26. package/build/query/edit/inspector-controls/parent-control.js.map +1 -1
  27. package/build/query/edit/inspector-controls/taxonomy-controls.js +0 -1
  28. package/build/query/edit/inspector-controls/taxonomy-controls.js.map +1 -1
  29. package/build/query/edit/{pattern-selection-modal.js → pattern-selection.js} +55 -36
  30. package/build/query/edit/pattern-selection.js.map +1 -0
  31. package/build/query/edit/query-content.js +5 -8
  32. package/build/query/edit/query-content.js.map +1 -1
  33. package/build/query/edit/query-placeholder.js +5 -11
  34. package/build/query/edit/query-placeholder.js.map +1 -1
  35. package/build/query/edit/query-toolbar.js +31 -11
  36. package/build/query/edit/query-toolbar.js.map +1 -1
  37. package/build/separator/deprecated.js +2 -1
  38. package/build/separator/deprecated.js.map +1 -1
  39. package/build/separator/edit.js +29 -4
  40. package/build/separator/edit.js.map +1 -1
  41. package/build/separator/index.js +5 -0
  42. package/build/separator/index.js.map +1 -1
  43. package/build/separator/save.js +3 -2
  44. package/build/separator/save.js.map +1 -1
  45. package/build/template-part/edit/import-controls.js +0 -1
  46. package/build/template-part/edit/import-controls.js.map +1 -1
  47. package/build-module/block/edit.js +3 -30
  48. package/build-module/block/edit.js.map +1 -1
  49. package/build-module/cover/edit/index.js +4 -2
  50. package/build-module/cover/edit/index.js.map +1 -1
  51. package/build-module/cover/edit/inspector-controls.js +6 -4
  52. package/build-module/cover/edit/inspector-controls.js.map +1 -1
  53. package/build-module/form/index.js +1 -2
  54. package/build-module/form/index.js.map +1 -1
  55. package/build-module/form/view.js +10 -5
  56. package/build-module/form/view.js.map +1 -1
  57. package/build-module/list-item/hooks/use-merge.js +2 -2
  58. package/build-module/list-item/hooks/use-merge.js.map +1 -1
  59. package/build-module/navigation/edit/deleted-navigation-warning.js +10 -3
  60. package/build-module/navigation/edit/deleted-navigation-warning.js.map +1 -1
  61. package/build-module/navigation-link/edit.js +1 -2
  62. package/build-module/navigation-link/edit.js.map +1 -1
  63. package/build-module/navigation-submenu/edit.js +3 -1
  64. package/build-module/navigation-submenu/edit.js.map +1 -1
  65. package/build-module/pattern/recursion-detector.js +0 -1
  66. package/build-module/pattern/recursion-detector.js.map +1 -1
  67. package/build-module/query/edit/index.js +1 -1
  68. package/build-module/query/edit/index.js.map +1 -1
  69. package/build-module/query/edit/inspector-controls/author-control.js +0 -1
  70. package/build-module/query/edit/inspector-controls/author-control.js.map +1 -1
  71. package/build-module/query/edit/inspector-controls/parent-control.js +0 -1
  72. package/build-module/query/edit/inspector-controls/parent-control.js.map +1 -1
  73. package/build-module/query/edit/inspector-controls/taxonomy-controls.js +0 -1
  74. package/build-module/query/edit/inspector-controls/taxonomy-controls.js.map +1 -1
  75. package/build-module/query/edit/{pattern-selection-modal.js → pattern-selection.js} +53 -36
  76. package/build-module/query/edit/pattern-selection.js.map +1 -0
  77. package/build-module/query/edit/query-content.js +5 -8
  78. package/build-module/query/edit/query-content.js.map +1 -1
  79. package/build-module/query/edit/query-placeholder.js +6 -12
  80. package/build-module/query/edit/query-placeholder.js.map +1 -1
  81. package/build-module/query/edit/query-toolbar.js +31 -13
  82. package/build-module/query/edit/query-toolbar.js.map +1 -1
  83. package/build-module/separator/deprecated.js +2 -1
  84. package/build-module/separator/deprecated.js.map +1 -1
  85. package/build-module/separator/edit.js +32 -7
  86. package/build-module/separator/edit.js.map +1 -1
  87. package/build-module/separator/index.js +5 -0
  88. package/build-module/separator/index.js.map +1 -1
  89. package/build-module/separator/save.js +3 -2
  90. package/build-module/separator/save.js.map +1 -1
  91. package/build-module/template-part/edit/import-controls.js +0 -1
  92. package/build-module/template-part/edit/import-controls.js.map +1 -1
  93. package/build-style/button/style-rtl.css +3 -3
  94. package/build-style/button/style.css +3 -3
  95. package/build-style/comments/editor-rtl.css +1 -1
  96. package/build-style/comments/editor.css +1 -1
  97. package/build-style/comments/style-rtl.css +1 -1
  98. package/build-style/comments/style.css +1 -1
  99. package/build-style/comments-pagination/editor-rtl.css +1 -0
  100. package/build-style/comments-pagination/editor.css +1 -0
  101. package/build-style/comments-pagination/style-rtl.css +1 -0
  102. package/build-style/comments-pagination/style.css +1 -0
  103. package/build-style/common-rtl.css +17 -17
  104. package/build-style/common.css +17 -17
  105. package/build-style/editor-rtl.css +72 -41
  106. package/build-style/editor.css +72 -41
  107. package/build-style/gallery/style-rtl.css +2 -2
  108. package/build-style/gallery/style.css +2 -2
  109. package/build-style/heading/style-rtl.css +11 -11
  110. package/build-style/heading/style.css +11 -11
  111. package/build-style/image/style-rtl.css +4 -3
  112. package/build-style/image/style.css +4 -3
  113. package/build-style/latest-comments/style-rtl.css +4 -4
  114. package/build-style/latest-comments/style.css +4 -4
  115. package/build-style/latest-posts/style-rtl.css +2 -1
  116. package/build-style/latest-posts/style.css +2 -1
  117. package/build-style/more/editor-rtl.css +1 -1
  118. package/build-style/more/editor.css +1 -1
  119. package/build-style/nextpage/editor-rtl.css +1 -1
  120. package/build-style/nextpage/editor.css +1 -1
  121. package/build-style/post-comments-form/style-rtl.css +2 -2
  122. package/build-style/post-comments-form/style.css +2 -2
  123. package/build-style/post-featured-image/editor-rtl.css +27 -27
  124. package/build-style/post-featured-image/editor.css +27 -27
  125. package/build-style/pullquote/style-rtl.css +1 -0
  126. package/build-style/pullquote/style.css +1 -0
  127. package/build-style/query/editor-rtl.css +30 -0
  128. package/build-style/query/editor.css +30 -0
  129. package/build-style/read-more/style-rtl.css +2 -2
  130. package/build-style/read-more/style.css +2 -2
  131. package/build-style/social-link/editor-rtl.css +2 -2
  132. package/build-style/social-link/editor.css +2 -2
  133. package/build-style/social-links/editor-rtl.css +2 -2
  134. package/build-style/social-links/editor.css +2 -2
  135. package/build-style/social-links/style-rtl.css +2 -2
  136. package/build-style/social-links/style.css +2 -2
  137. package/build-style/style-rtl.css +55 -51
  138. package/build-style/style.css +55 -51
  139. package/build-style/text-columns/style-rtl.css +3 -3
  140. package/build-style/text-columns/style.css +3 -3
  141. package/build-types/lock-unlock.d.ts +1 -1
  142. package/build-types/lock-unlock.d.ts.map +1 -1
  143. package/package.json +35 -34
  144. package/src/block/edit.js +6 -51
  145. package/src/comments-pagination/editor.scss +1 -0
  146. package/src/comments-pagination/style.scss +1 -0
  147. package/src/cover/edit/index.js +4 -1
  148. package/src/cover/edit/inspector-controls.js +10 -3
  149. package/src/cover/index.php +2 -2
  150. package/src/form/block.json +1 -2
  151. package/src/form/index.php +1 -20
  152. package/src/form/view.js +18 -5
  153. package/src/image/style.scss +4 -3
  154. package/src/latest-posts/style.scss +2 -1
  155. package/src/list-item/hooks/use-merge.js +2 -2
  156. package/src/missing/test/edit.native.js +0 -1
  157. package/src/navigation/README.md +1 -0
  158. package/src/navigation/edit/deleted-navigation-warning.js +11 -2
  159. package/src/navigation/index.php +9 -35
  160. package/src/navigation-link/edit.js +0 -6
  161. package/src/navigation-submenu/edit.js +5 -6
  162. package/src/navigation-submenu/index.php +17 -1
  163. package/src/pullquote/style.scss +1 -0
  164. package/src/query/edit/index.js +1 -1
  165. package/src/query/edit/{pattern-selection-modal.js → pattern-selection.js} +53 -33
  166. package/src/query/edit/query-content.js +4 -10
  167. package/src/query/edit/query-placeholder.js +5 -14
  168. package/src/query/edit/query-toolbar.js +38 -17
  169. package/src/query/editor.scss +30 -0
  170. package/src/search/index.php +3 -3
  171. package/src/separator/block.json +5 -0
  172. package/src/separator/deprecated.js +1 -0
  173. package/src/separator/edit.js +28 -3
  174. package/src/separator/save.js +2 -2
  175. package/src/separator/test/edit.js +1 -0
  176. package/tsconfig.tsbuildinfo +1 -1
  177. package/build/query/edit/pattern-selection-modal.js.map +0 -1
  178. package/build-module/query/edit/pattern-selection-modal.js.map +0 -1
@@ -14,6 +14,7 @@
14
14
  * @return string The content of the block being rendered.
15
15
  */
16
16
  function render_block_core_form( $attributes, $content ) {
17
+ wp_enqueue_script_module( '@wordpress/block-library/form/view' );
17
18
 
18
19
  $processed_content = new WP_HTML_Tag_Processor( $content );
19
20
  $processed_content->next_tag( 'form' );
@@ -42,26 +43,6 @@ function render_block_core_form( $attributes, $content ) {
42
43
  );
43
44
  }
44
45
 
45
- /**
46
- * Additional data to add to the view.js script for this block.
47
- */
48
- function block_core_form_view_script() {
49
- if ( ! gutenberg_is_experiment_enabled( 'gutenberg-form-blocks' ) ) {
50
- return;
51
- }
52
-
53
- wp_localize_script(
54
- 'wp-block-form-view',
55
- 'wpBlockFormSettings',
56
- array(
57
- 'nonce' => wp_create_nonce( 'wp-block-form' ),
58
- 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
59
- 'action' => 'wp_block_form_email_submit',
60
- )
61
- );
62
- }
63
- add_action( 'wp_enqueue_scripts', 'block_core_form_view_script' );
64
-
65
46
  /**
66
47
  * Adds extra fields to the form.
67
48
  *
package/src/form/view.js CHANGED
@@ -1,8 +1,21 @@
1
+ let formSettings;
2
+ try {
3
+ formSettings = JSON.parse(
4
+ document.getElementById(
5
+ 'wp-script-module-data-@wordpress/block-library/form/view'
6
+ )?.textContent
7
+ );
8
+ } catch {}
9
+
1
10
  // eslint-disable-next-line eslint-comments/disable-enable-pair
2
11
  /* eslint-disable no-undef */
3
12
  document.querySelectorAll( 'form.wp-block-form' ).forEach( function ( form ) {
4
- // Bail If the form is not using the mailto: action.
5
- if ( ! form.action || ! form.action.startsWith( 'mailto:' ) ) {
13
+ // Bail If the form settings not provided or the form is not using the mailto: action.
14
+ if (
15
+ ! formSettings ||
16
+ ! form.action ||
17
+ ! form.action.startsWith( 'mailto:' )
18
+ ) {
6
19
  return;
7
20
  }
8
21
 
@@ -18,13 +31,13 @@ document.querySelectorAll( 'form.wp-block-form' ).forEach( function ( form ) {
18
31
  // Get the form data and merge it with the form action and nonce.
19
32
  const formData = Object.fromEntries( new FormData( form ).entries() );
20
33
  formData.formAction = form.action;
21
- formData._ajax_nonce = wpBlockFormSettings.nonce;
22
- formData.action = wpBlockFormSettings.action;
34
+ formData._ajax_nonce = formSettings.nonce;
35
+ formData.action = formSettings.action;
23
36
  formData._wp_http_referer = window.location.href;
24
37
  formData.formAction = form.action;
25
38
 
26
39
  try {
27
- const response = await fetch( wpBlockFormSettings.ajaxUrl, {
40
+ const response = await fetch( formSettings.ajaxUrl, {
28
41
  method: 'POST',
29
42
  headers: {
30
43
  'Content-Type': 'application/x-www-form-urlencoded',
@@ -1,6 +1,7 @@
1
1
  .wp-block-image {
2
2
 
3
- a {
3
+ > a,
4
+ > figure > a {
4
5
  display: inline-block;
5
6
  }
6
7
 
@@ -42,8 +43,8 @@
42
43
  text-align: center;
43
44
  }
44
45
 
45
- &.alignfull a,
46
- &.alignwide a {
46
+ &.alignfull > a,
47
+ &.alignwide > a {
47
48
  width: 100%;
48
49
  }
49
50
 
@@ -57,7 +57,8 @@
57
57
  font-size: 0.8125em;
58
58
  }
59
59
 
60
- .wp-block-latest-posts__post-excerpt {
60
+ .wp-block-latest-posts__post-excerpt,
61
+ .wp-block-latest-posts__post-full-content {
61
62
  margin-top: 0.5em;
62
63
  margin-bottom: 1em;
63
64
  }
@@ -49,7 +49,7 @@ export default function useMerge( clientId, onMerge ) {
49
49
  * return the next list item of the parent list item if it exists.
50
50
  *
51
51
  * @param {string} id A list item client ID.
52
- * @return {string?} The client ID of the next list item.
52
+ * @return {?string} The client ID of the next list item.
53
53
  */
54
54
  function _getNextId( id ) {
55
55
  const next = getNextBlockClientId( id );
@@ -68,7 +68,7 @@ export default function useMerge( clientId, onMerge ) {
68
68
  * line, regardless of indentation level.
69
69
  *
70
70
  * @param {string} id The client ID of the current list item.
71
- * @return {string?} The client ID of the next list item.
71
+ * @return {?string} The client ID of the next list item.
72
72
  */
73
73
  function getNextId( id ) {
74
74
  const order = getBlockOrder( id );
@@ -10,7 +10,6 @@ import { Text } from 'react-native';
10
10
  import { BottomSheet, Icon } from '@wordpress/components';
11
11
  import { help, plugins } from '@wordpress/icons';
12
12
  import { storeConfig } from '@wordpress/block-editor';
13
- jest.mock( '@wordpress/blocks' );
14
13
  jest.mock( '@wordpress/block-editor/src/store/selectors' );
15
14
 
16
15
  /**
@@ -10,4 +10,5 @@ The structural CSS for the navigation block targets generic classnames across me
10
10
  - `.wp-block-navigation-item` is applied to every menu item.
11
11
  - `.wp-block-navigation-item__content` is applied to the link inside a menu item.
12
12
  - `.wp-block-navigation-item__label` is applied to the innermost container around the menu item text label.
13
+ - `.wp-block-navigation-item__description` is applied to the innermost container around the menu item description.
13
14
  - `.wp-block-navigation__submenu-icon` is applied to the submenu indicator (chevron).
@@ -4,9 +4,16 @@
4
4
  import { Warning } from '@wordpress/block-editor';
5
5
  import { Button, Notice } from '@wordpress/components';
6
6
  import { __ } from '@wordpress/i18n';
7
- import { createInterpolateElement } from '@wordpress/element';
7
+ import { useState, createInterpolateElement } from '@wordpress/element';
8
8
 
9
9
  function DeletedNavigationWarning( { onCreateNew, isNotice = false } ) {
10
+ const [ isButtonDisabled, setIsButtonDisabled ] = useState( false );
11
+
12
+ const handleButtonClick = () => {
13
+ setIsButtonDisabled( true );
14
+ onCreateNew();
15
+ };
16
+
10
17
  const message = createInterpolateElement(
11
18
  __(
12
19
  'Navigation Menu has been deleted or is unavailable. <button>Create a new Menu?</button>'
@@ -15,8 +22,10 @@ function DeletedNavigationWarning( { onCreateNew, isNotice = false } ) {
15
22
  button: (
16
23
  <Button
17
24
  __next40pxDefaultSize
18
- onClick={ onCreateNew }
25
+ onClick={ handleButtonClick }
19
26
  variant="link"
27
+ disabled={ isButtonDisabled }
28
+ accessibleWhenDisabled
20
29
  />
21
30
  ),
22
31
  }
@@ -567,13 +567,14 @@ class WP_Navigation_Block_Renderer {
567
567
  $is_responsive_menu = static::is_responsive( $attributes );
568
568
  $style = static::get_styles( $attributes );
569
569
  $class = static::get_classes( $attributes );
570
- $wrapper_attributes = get_block_wrapper_attributes(
571
- array(
572
- 'class' => $class,
573
- 'style' => $style,
574
- 'aria-label' => $nav_menu_name,
575
- )
570
+ $extra_attributes = array(
571
+ 'class' => $class,
572
+ 'style' => $style,
576
573
  );
574
+ if ( ! empty( $nav_menu_name ) ) {
575
+ $extra_attributes['aria-label'] = $nav_menu_name;
576
+ }
577
+ $wrapper_attributes = get_block_wrapper_attributes( $extra_attributes );
577
578
 
578
579
  if ( $is_responsive_menu ) {
579
580
  $nav_element_directives = static::get_nav_element_directives( $is_interactive );
@@ -1436,20 +1437,6 @@ function block_core_navigation_get_most_recently_published_navigation() {
1436
1437
  return null;
1437
1438
  }
1438
1439
 
1439
- /**
1440
- * Accepts the serialized markup of a block and its inner blocks, and returns serialized markup of the inner blocks.
1441
- *
1442
- * @since 6.5.0
1443
- *
1444
- * @param string $serialized_block The serialized markup of a block and its inner blocks.
1445
- * @return string
1446
- */
1447
- function block_core_navigation_remove_serialized_parent_block( $serialized_block ) {
1448
- $start = strpos( $serialized_block, '-->' ) + strlen( '-->' );
1449
- $end = strrpos( $serialized_block, '<!--' );
1450
- return substr( $serialized_block, $start, $end - $start );
1451
- }
1452
-
1453
1440
  /**
1454
1441
  * Mock a parsed block for the Navigation block given its inner blocks and the `wp_navigation` post object.
1455
1442
  * The `wp_navigation` post's `_wp_ignored_hooked_blocks` meta is queried to add the `metadata.ignoredHookedBlocks` attribute.
@@ -1504,19 +1491,6 @@ function block_core_navigation_mock_parsed_block( $inner_blocks, $post ) {
1504
1491
  function block_core_navigation_insert_hooked_blocks( $inner_blocks, $post ) {
1505
1492
  $mock_navigation_block = block_core_navigation_mock_parsed_block( $inner_blocks, $post );
1506
1493
 
1507
- if ( function_exists( 'apply_block_hooks_to_content' ) ) {
1508
- $mock_navigation_block_markup = serialize_block( $mock_navigation_block );
1509
- return apply_block_hooks_to_content( $mock_navigation_block_markup, $post, 'insert_hooked_blocks' );
1510
- }
1511
-
1512
- $hooked_blocks = get_hooked_blocks();
1513
- $before_block_visitor = null;
1514
- $after_block_visitor = null;
1515
-
1516
- if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ) ) {
1517
- $before_block_visitor = make_before_block_visitor( $hooked_blocks, $post, 'insert_hooked_blocks' );
1518
- $after_block_visitor = make_after_block_visitor( $hooked_blocks, $post, 'insert_hooked_blocks' );
1519
- }
1520
-
1521
- return traverse_and_serialize_block( $mock_navigation_block, $before_block_visitor, $after_block_visitor );
1494
+ $mock_navigation_block_markup = serialize_block( $mock_navigation_block );
1495
+ return apply_block_hooks_to_content( $mock_navigation_block_markup, $post, 'insert_hooked_blocks' );
1522
1496
  }
@@ -527,12 +527,6 @@ export default function NavigationLinkEdit( {
527
527
  ) }
528
528
  placeholder={ itemLabelPlaceholder }
529
529
  withoutInteractiveFormatting
530
- allowedFormats={ [
531
- 'core/bold',
532
- 'core/italic',
533
- 'core/image',
534
- 'core/strikethrough',
535
- ] }
536
530
  />
537
531
  { description && (
538
532
  <span className="wp-block-navigation-item__description">
@@ -461,12 +461,6 @@ export default function NavigationSubmenuEdit( {
461
461
  aria-label={ __( 'Navigation link text' ) }
462
462
  placeholder={ itemLabelPlaceholder }
463
463
  withoutInteractiveFormatting
464
- allowedFormats={ [
465
- 'core/bold',
466
- 'core/italic',
467
- 'core/image',
468
- 'core/strikethrough',
469
- ] }
470
464
  onClick={ () => {
471
465
  if ( ! openSubmenusOnClick && ! url ) {
472
466
  setIsLinkOpen( true );
@@ -474,6 +468,11 @@ export default function NavigationSubmenuEdit( {
474
468
  }
475
469
  } }
476
470
  />
471
+ { description && (
472
+ <span className="wp-block-navigation-item__description">
473
+ { description }
474
+ </span>
475
+ ) }
477
476
  { ! openSubmenusOnClick && isLinkOpen && (
478
477
  <LinkUI
479
478
  clientId={ clientId }
@@ -159,7 +159,16 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
159
159
  $html .= '>';
160
160
  // End appending HTML attributes to anchor tag.
161
161
 
162
+ $html .= '<span class="wp-block-navigation-item__label">';
162
163
  $html .= $label;
164
+ $html .= '</span>';
165
+
166
+ // Add description if available.
167
+ if ( ! empty( $attributes['description'] ) ) {
168
+ $html .= '<span class="wp-block-navigation-item__description">';
169
+ $html .= wp_kses_post( $attributes['description'] );
170
+ $html .= '</span>';
171
+ }
163
172
 
164
173
  $html .= '</a>';
165
174
  // End anchor tag content.
@@ -180,6 +189,13 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
180
189
 
181
190
  $html .= '</span>';
182
191
 
192
+ // Add description if available.
193
+ if ( ! empty( $attributes['description'] ) ) {
194
+ $html .= '<span class="wp-block-navigation-item__description">';
195
+ $html .= wp_kses_post( $attributes['description'] );
196
+ $html .= '</span>';
197
+ }
198
+
183
199
  $html .= '</button>';
184
200
 
185
201
  $html .= '<span class="wp-block-navigation__submenu-icon">' . block_core_navigation_submenu_render_submenu_icon() . '</span>';
@@ -222,7 +238,7 @@ function render_block_core_navigation_submenu( $attributes, $content, $block ) {
222
238
 
223
239
  if ( strpos( $inner_blocks_html, 'current-menu-item' ) ) {
224
240
  $tag_processor = new WP_HTML_Tag_Processor( $html );
225
- while ( $tag_processor->next_tag( array( 'class_name' => 'wp-block-navigation-item__content' ) ) ) {
241
+ while ( $tag_processor->next_tag( array( 'class_name' => 'wp-block-navigation-item' ) ) ) {
226
242
  $tag_processor->add_class( 'current-menu-ancestor' );
227
243
  }
228
244
  $html = $tag_processor->get_updated_html();
@@ -72,4 +72,5 @@
72
72
 
73
73
  .wp-block-pullquote cite {
74
74
  color: inherit;
75
+ display: block;
75
76
  }
@@ -10,7 +10,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
10
10
  */
11
11
  import QueryContent from './query-content';
12
12
  import QueryPlaceholder from './query-placeholder';
13
- import PatternSelectionModal from './pattern-selection-modal';
13
+ import { PatternSelectionModal } from './pattern-selection';
14
14
 
15
15
  const QueryEdit = ( props ) => {
16
16
  const { clientId, attributes } = props;
@@ -21,48 +21,67 @@ import {
21
21
  } from '../utils';
22
22
  import { searchPatterns } from '../../utils/search-patterns';
23
23
 
24
- export default function PatternSelectionModal( {
24
+ export function PatternSelectionModal( {
25
25
  clientId,
26
26
  attributes,
27
27
  setIsPatternSelectionModalOpen,
28
+ } ) {
29
+ return (
30
+ <Modal
31
+ overlayClassName="block-library-query-pattern__selection-modal"
32
+ title={ __( 'Choose a pattern' ) }
33
+ onRequestClose={ () => setIsPatternSelectionModalOpen( false ) }
34
+ isFullScreen
35
+ >
36
+ <PatternSelection clientId={ clientId } attributes={ attributes } />
37
+ </Modal>
38
+ );
39
+ }
40
+
41
+ export function useBlockPatterns( clientId, attributes ) {
42
+ const blockNameForPatterns = useBlockNameForPatterns(
43
+ clientId,
44
+ attributes
45
+ );
46
+ return usePatterns( clientId, blockNameForPatterns );
47
+ }
48
+
49
+ export default function PatternSelection( {
50
+ clientId,
51
+ attributes,
52
+ showTitlesAsTooltip = false,
53
+ showSearch = true,
28
54
  } ) {
29
55
  const [ searchValue, setSearchValue ] = useState( '' );
30
56
  const { replaceBlock, selectBlock } = useDispatch( blockEditorStore );
31
- const onBlockPatternSelect = ( pattern, blocks ) => {
32
- const { newBlocks, queryClientIds } = getTransformedBlocksFromPattern(
33
- blocks,
34
- attributes
35
- );
36
- replaceBlock( clientId, newBlocks );
37
- if ( queryClientIds[ 0 ] ) {
38
- selectBlock( queryClientIds[ 0 ] );
39
- }
40
- };
41
- // When we preview Query Loop blocks we should prefer the current
42
- // block's postType, which is passed through block context.
57
+ const blockPatterns = useBlockPatterns( clientId, attributes );
58
+ /*
59
+ * When we preview Query Loop blocks we should prefer the current
60
+ * block's postType, which is passed through block context.
61
+ */
43
62
  const blockPreviewContext = useMemo(
44
63
  () => ( {
45
64
  previewPostType: attributes.query.postType,
46
65
  } ),
47
66
  [ attributes.query.postType ]
48
67
  );
49
- const blockNameForPatterns = useBlockNameForPatterns(
50
- clientId,
51
- attributes
52
- );
53
- const blockPatterns = usePatterns( clientId, blockNameForPatterns );
54
68
  const filteredBlockPatterns = useMemo( () => {
55
69
  return searchPatterns( blockPatterns, searchValue );
56
70
  }, [ blockPatterns, searchValue ] );
57
71
 
72
+ const onBlockPatternSelect = ( pattern, blocks ) => {
73
+ const { newBlocks, queryClientIds } = getTransformedBlocksFromPattern(
74
+ blocks,
75
+ attributes
76
+ );
77
+ replaceBlock( clientId, newBlocks );
78
+ if ( queryClientIds[ 0 ] ) {
79
+ selectBlock( queryClientIds[ 0 ] );
80
+ }
81
+ };
58
82
  return (
59
- <Modal
60
- overlayClassName="block-library-query-pattern__selection-modal"
61
- title={ __( 'Choose a pattern' ) }
62
- onRequestClose={ () => setIsPatternSelectionModalOpen( false ) }
63
- isFullScreen
64
- >
65
- <div className="block-library-query-pattern__selection-content">
83
+ <div className="block-library-query-pattern__selection-content">
84
+ { showSearch && (
66
85
  <div className="block-library-query-pattern__selection-search">
67
86
  <SearchControl
68
87
  __nextHasNoMarginBottom
@@ -72,13 +91,14 @@ export default function PatternSelectionModal( {
72
91
  placeholder={ __( 'Search' ) }
73
92
  />
74
93
  </div>
75
- <BlockContextProvider value={ blockPreviewContext }>
76
- <BlockPatternsList
77
- blockPatterns={ filteredBlockPatterns }
78
- onClickPattern={ onBlockPatternSelect }
79
- />
80
- </BlockContextProvider>
81
- </div>
82
- </Modal>
94
+ ) }
95
+ <BlockContextProvider value={ blockPreviewContext }>
96
+ <BlockPatternsList
97
+ blockPatterns={ filteredBlockPatterns }
98
+ onClickPattern={ onBlockPatternSelect }
99
+ showTitlesAsTooltip={ showTitlesAsTooltip }
100
+ />
101
+ </BlockContextProvider>
102
+ </div>
83
103
  );
84
104
  }
@@ -19,10 +19,10 @@ import { store as coreStore } from '@wordpress/core-data';
19
19
  * Internal dependencies
20
20
  */
21
21
  import EnhancedPaginationControl from './inspector-controls/enhanced-pagination-control';
22
- import QueryToolbar from './query-toolbar';
23
22
  import QueryInspectorControls from './inspector-controls';
24
23
  import EnhancedPaginationModal from './enhanced-pagination-modal';
25
24
  import { getQueryContextFromTemplate } from '../utils';
25
+ import QueryToolbar from './query-toolbar';
26
26
 
27
27
  const DEFAULTS_POSTS_PER_PAGE = 3;
28
28
 
@@ -30,10 +30,9 @@ const TEMPLATE = [ [ 'core/post-template' ] ];
30
30
  export default function QueryContent( {
31
31
  attributes,
32
32
  setAttributes,
33
- openPatternSelectionModal,
34
- name,
35
33
  clientId,
36
34
  context,
35
+ name,
37
36
  } ) {
38
37
  const {
39
38
  queryId,
@@ -154,6 +153,7 @@ export default function QueryContent( {
154
153
  />
155
154
  <InspectorControls>
156
155
  <QueryInspectorControls
156
+ name={ name }
157
157
  attributes={ attributes }
158
158
  setQuery={ updateQuery }
159
159
  setDisplayLayout={ updateDisplayLayout }
@@ -163,13 +163,7 @@ export default function QueryContent( {
163
163
  />
164
164
  </InspectorControls>
165
165
  <BlockControls>
166
- <QueryToolbar
167
- name={ name }
168
- clientId={ clientId }
169
- attributes={ attributes }
170
- setQuery={ updateQuery }
171
- openPatternSelectionModal={ openPatternSelectionModal }
172
- />
166
+ <QueryToolbar attributes={ attributes } clientId={ clientId } />
173
167
  </BlockControls>
174
168
  <InspectorControls group="advanced">
175
169
  <SelectControl
@@ -18,7 +18,8 @@ import { __ } from '@wordpress/i18n';
18
18
  /**
19
19
  * Internal dependencies
20
20
  */
21
- import { useScopedBlockVariations, useBlockNameForPatterns } from '../utils';
21
+ import { useScopedBlockVariations } from '../utils';
22
+ import { useBlockPatterns } from './pattern-selection';
22
23
 
23
24
  export default function QueryPlaceholder( {
24
25
  attributes,
@@ -28,31 +29,21 @@ export default function QueryPlaceholder( {
28
29
  } ) {
29
30
  const [ isStartingBlank, setIsStartingBlank ] = useState( false );
30
31
  const blockProps = useBlockProps();
31
- const blockNameForPatterns = useBlockNameForPatterns(
32
- clientId,
33
- attributes
34
- );
35
- const { blockType, activeBlockVariation, hasPatterns } = useSelect(
32
+ const { blockType, activeBlockVariation } = useSelect(
36
33
  ( select ) => {
37
34
  const { getActiveBlockVariation, getBlockType } =
38
35
  select( blocksStore );
39
- const { getBlockRootClientId, getPatternsByBlockTypes } =
40
- select( blockEditorStore );
41
- const rootClientId = getBlockRootClientId( clientId );
42
36
  return {
43
37
  blockType: getBlockType( name ),
44
38
  activeBlockVariation: getActiveBlockVariation(
45
39
  name,
46
40
  attributes
47
41
  ),
48
- hasPatterns: !! getPatternsByBlockTypes(
49
- blockNameForPatterns,
50
- rootClientId
51
- ).length,
52
42
  };
53
43
  },
54
- [ name, blockNameForPatterns, clientId, attributes ]
44
+ [ name, attributes ]
55
45
  );
46
+ const hasPatterns = !! useBlockPatterns( clientId, attributes ).length;
56
47
  const icon =
57
48
  activeBlockVariation?.icon?.src ||
58
49
  activeBlockVariation?.icon ||
@@ -1,30 +1,51 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
4
+ import {
5
+ ToolbarGroup,
6
+ ToolbarButton,
7
+ Dropdown,
8
+ __experimentalDropdownContentWrapper as DropdownContentWrapper,
9
+ } from '@wordpress/components';
5
10
  import { __ } from '@wordpress/i18n';
6
11
 
7
12
  /**
8
13
  * Internal dependencies
9
14
  */
10
- import { usePatterns } from '../utils';
15
+ import PatternSelection, { useBlockPatterns } from './pattern-selection';
11
16
 
12
- export default function QueryToolbar( {
13
- openPatternSelectionModal,
14
- name,
15
- clientId,
16
- } ) {
17
- const hasPatterns = !! usePatterns( clientId, name ).length;
17
+ export default function QueryToolbar( { clientId, attributes } ) {
18
+ const hasPatterns = useBlockPatterns( clientId, attributes ).length;
19
+ if ( ! hasPatterns ) {
20
+ return null;
21
+ }
18
22
 
19
23
  return (
20
- <>
21
- { hasPatterns && (
22
- <ToolbarGroup className="wp-block-template-part__block-control-group">
23
- <ToolbarButton onClick={ openPatternSelectionModal }>
24
- { __( 'Replace' ) }
25
- </ToolbarButton>
26
- </ToolbarGroup>
27
- ) }
28
- </>
24
+ <ToolbarGroup className="wp-block-template-part__block-control-group">
25
+ <DropdownContentWrapper>
26
+ <Dropdown
27
+ contentClassName="block-editor-block-settings-menu__popover"
28
+ focusOnMount="firstElement"
29
+ expandOnMobile
30
+ renderToggle={ ( { isOpen, onToggle } ) => (
31
+ <ToolbarButton
32
+ aria-haspopup="true"
33
+ aria-expanded={ isOpen }
34
+ onClick={ onToggle }
35
+ >
36
+ { __( 'Change design' ) }
37
+ </ToolbarButton>
38
+ ) }
39
+ renderContent={ () => (
40
+ <PatternSelection
41
+ clientId={ clientId }
42
+ attributes={ attributes }
43
+ showSearch={ false }
44
+ showTitlesAsTooltip
45
+ />
46
+ ) }
47
+ />
48
+ </DropdownContentWrapper>
49
+ </ToolbarGroup>
29
50
  );
30
51
  }
@@ -45,6 +45,12 @@
45
45
  }
46
46
  }
47
47
 
48
+ .block-library-query-toolspanel__design {
49
+ .block-library-query-pattern__selection-content {
50
+ margin-top: $grid-unit-10;
51
+ }
52
+ }
53
+
48
54
  .wp-block-query__enhanced-pagination-modal {
49
55
  @include break-small() {
50
56
  max-width: $break-mobile;
@@ -54,3 +60,27 @@
54
60
  .wp-block-query__enhanced-pagination-notice {
55
61
  margin: 0;
56
62
  }
63
+
64
+ .block-editor-block-settings-menu__popover {
65
+ &.is-expanded {
66
+ overflow-y: scroll;
67
+ }
68
+ .block-library-query-pattern__selection-content {
69
+ height: 100%;
70
+ }
71
+ .block-editor-block-patterns-list {
72
+ display: grid;
73
+ grid-template-columns: 1fr;
74
+ @include break-small() {
75
+ grid-template-columns: 1fr 1fr;
76
+ }
77
+ grid-gap: $grid-unit-15;
78
+ min-width: $break-zoomed-in;
79
+ @include break-small() {
80
+ min-width: $break-mobile;
81
+ }
82
+ }
83
+ .block-editor-block-patterns-list__list-item {
84
+ margin-bottom: 0;
85
+ }
86
+ }
@@ -177,9 +177,9 @@ function render_block_core_search( $attributes ) {
177
177
  )
178
178
  );
179
179
  $form_directives = '
180
- data-wp-interactive="core/search"'
181
- . $form_context .
182
- 'data-wp-class--wp-block-search__searchfield-hidden="!context.isSearchInputVisible"
180
+ data-wp-interactive="core/search"
181
+ ' . $form_context . '
182
+ data-wp-class--wp-block-search__searchfield-hidden="!context.isSearchInputVisible"
183
183
  data-wp-on-async--keydown="actions.handleSearchKeydown"
184
184
  data-wp-on-async--focusout="actions.handleSearchFocusout"
185
185
  ';