@wordpress/block-editor 12.6.0 → 12.7.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 (199) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +2 -2
  3. package/build/autocompleters/block.js +6 -2
  4. package/build/autocompleters/block.js.map +1 -1
  5. package/build/components/block-editing-mode/index.js +1 -1
  6. package/build/components/block-editing-mode/index.js.map +1 -1
  7. package/build/components/block-list/block.js +4 -2
  8. package/build/components/block-list/block.js.map +1 -1
  9. package/build/components/block-list/index.js +2 -4
  10. package/build/components/block-list/index.js.map +1 -1
  11. package/build/components/block-parent-selector/index.js +6 -21
  12. package/build/components/block-parent-selector/index.js.map +1 -1
  13. package/build/components/block-preview/auto.js +6 -1
  14. package/build/components/block-preview/auto.js.map +1 -1
  15. package/build/components/block-settings-menu/block-settings-dropdown.js +3 -17
  16. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  17. package/build/components/block-toolbar/index.js +4 -34
  18. package/build/components/block-toolbar/index.js.map +1 -1
  19. package/build/components/block-toolbar/utils.js +56 -51
  20. package/build/components/block-toolbar/utils.js.map +1 -1
  21. package/build/components/block-tools/block-contextual-toolbar.js +4 -2
  22. package/build/components/block-tools/block-contextual-toolbar.js.map +1 -1
  23. package/build/components/block-variation-picker/index.native.js +10 -20
  24. package/build/components/block-variation-picker/index.native.js.map +1 -1
  25. package/build/components/editor-styles/index.js +2 -2
  26. package/build/components/editor-styles/index.js.map +1 -1
  27. package/build/components/font-sizes/fluid-utils.js +11 -11
  28. package/build/components/font-sizes/fluid-utils.js.map +1 -1
  29. package/build/components/global-styles/behaviors-panel.js +66 -0
  30. package/build/components/global-styles/behaviors-panel.js.map +1 -0
  31. package/build/components/global-styles/hooks.js +118 -4
  32. package/build/components/global-styles/hooks.js.map +1 -1
  33. package/build/components/global-styles/index.js +20 -0
  34. package/build/components/global-styles/index.js.map +1 -1
  35. package/build/components/global-styles/typography-utils.js +4 -4
  36. package/build/components/global-styles/typography-utils.js.map +1 -1
  37. package/build/components/global-styles/utils.js +1 -1
  38. package/build/components/global-styles/utils.js.map +1 -1
  39. package/build/components/inserter/hooks/use-block-types-state.js +6 -2
  40. package/build/components/inserter/hooks/use-block-types-state.js.map +1 -1
  41. package/build/components/inserter/hooks/use-debounced-input.js +5 -7
  42. package/build/components/inserter/hooks/use-debounced-input.js.map +1 -1
  43. package/build/components/inserter/hooks/use-patterns-state.js +3 -2
  44. package/build/components/inserter/hooks/use-patterns-state.js.map +1 -1
  45. package/build/components/inserter/reusable-blocks-tab.js +3 -2
  46. package/build/components/inserter/reusable-blocks-tab.js.map +1 -1
  47. package/build/components/inserter-list-item/index.js +1 -1
  48. package/build/components/inserter-list-item/index.js.map +1 -1
  49. package/build/components/link-control/index.js +47 -6
  50. package/build/components/link-control/index.js.map +1 -1
  51. package/build/components/link-control/link-preview.js +3 -3
  52. package/build/components/link-control/link-preview.js.map +1 -1
  53. package/build/components/list-view/use-list-view-drop-zone.js +6 -1
  54. package/build/components/list-view/use-list-view-drop-zone.js.map +1 -1
  55. package/build/components/media-replace-flow/index.native.js +15 -3
  56. package/build/components/media-replace-flow/index.native.js.map +1 -1
  57. package/build/components/rich-text/format-edit.js +57 -28
  58. package/build/components/rich-text/format-edit.js.map +1 -1
  59. package/build/components/rich-text/get-rich-text-values.js +11 -18
  60. package/build/components/rich-text/get-rich-text-values.js.map +1 -1
  61. package/build/components/spacing-sizes-control/utils.js +2 -2
  62. package/build/components/spacing-sizes-control/utils.js.map +1 -1
  63. package/build/hooks/behaviors.js +5 -12
  64. package/build/hooks/behaviors.js.map +1 -1
  65. package/build/hooks/border.js +2 -1
  66. package/build/hooks/border.js.map +1 -1
  67. package/build/hooks/style.js +11 -2
  68. package/build/hooks/style.js.map +1 -1
  69. package/build/private-apis.js +4 -1
  70. package/build/private-apis.js.map +1 -1
  71. package/build/store/actions.js +2 -3
  72. package/build/store/actions.js.map +1 -1
  73. package/build/store/selectors.js +4 -71
  74. package/build/store/selectors.js.map +1 -1
  75. package/build-module/autocompleters/block.js +7 -3
  76. package/build-module/autocompleters/block.js.map +1 -1
  77. package/build-module/components/block-editing-mode/index.js +1 -1
  78. package/build-module/components/block-editing-mode/index.js.map +1 -1
  79. package/build-module/components/block-list/block.js +4 -2
  80. package/build-module/components/block-list/block.js.map +1 -1
  81. package/build-module/components/block-list/index.js +2 -3
  82. package/build-module/components/block-list/index.js.map +1 -1
  83. package/build-module/components/block-parent-selector/index.js +7 -22
  84. package/build-module/components/block-parent-selector/index.js.map +1 -1
  85. package/build-module/components/block-preview/auto.js +6 -1
  86. package/build-module/components/block-preview/auto.js.map +1 -1
  87. package/build-module/components/block-settings-menu/block-settings-dropdown.js +4 -18
  88. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  89. package/build-module/components/block-toolbar/index.js +6 -36
  90. package/build-module/components/block-toolbar/index.js.map +1 -1
  91. package/build-module/components/block-toolbar/utils.js +54 -49
  92. package/build-module/components/block-toolbar/utils.js.map +1 -1
  93. package/build-module/components/block-tools/block-contextual-toolbar.js +4 -2
  94. package/build-module/components/block-tools/block-contextual-toolbar.js.map +1 -1
  95. package/build-module/components/block-variation-picker/index.native.js +13 -23
  96. package/build-module/components/block-variation-picker/index.native.js.map +1 -1
  97. package/build-module/components/editor-styles/index.js +2 -2
  98. package/build-module/components/editor-styles/index.js.map +1 -1
  99. package/build-module/components/font-sizes/fluid-utils.js +11 -11
  100. package/build-module/components/font-sizes/fluid-utils.js.map +1 -1
  101. package/build-module/components/global-styles/behaviors-panel.js +57 -0
  102. package/build-module/components/global-styles/behaviors-panel.js.map +1 -0
  103. package/build-module/components/global-styles/hooks.js +115 -5
  104. package/build-module/components/global-styles/hooks.js.map +1 -1
  105. package/build-module/components/global-styles/index.js +2 -1
  106. package/build-module/components/global-styles/index.js.map +1 -1
  107. package/build-module/components/global-styles/typography-utils.js +4 -4
  108. package/build-module/components/global-styles/typography-utils.js.map +1 -1
  109. package/build-module/components/global-styles/utils.js +1 -1
  110. package/build-module/components/global-styles/utils.js.map +1 -1
  111. package/build-module/components/inserter/hooks/use-block-types-state.js +7 -3
  112. package/build-module/components/inserter/hooks/use-block-types-state.js.map +1 -1
  113. package/build-module/components/inserter/hooks/use-debounced-input.js +5 -7
  114. package/build-module/components/inserter/hooks/use-debounced-input.js.map +1 -1
  115. package/build-module/components/inserter/hooks/use-patterns-state.js +3 -2
  116. package/build-module/components/inserter/hooks/use-patterns-state.js.map +1 -1
  117. package/build-module/components/inserter/reusable-blocks-tab.js +3 -2
  118. package/build-module/components/inserter/reusable-blocks-tab.js.map +1 -1
  119. package/build-module/components/inserter-list-item/index.js +1 -1
  120. package/build-module/components/inserter-list-item/index.js.map +1 -1
  121. package/build-module/components/link-control/index.js +45 -6
  122. package/build-module/components/link-control/index.js.map +1 -1
  123. package/build-module/components/link-control/link-preview.js +3 -3
  124. package/build-module/components/link-control/link-preview.js.map +1 -1
  125. package/build-module/components/list-view/use-list-view-drop-zone.js +6 -1
  126. package/build-module/components/list-view/use-list-view-drop-zone.js.map +1 -1
  127. package/build-module/components/media-replace-flow/index.native.js +15 -3
  128. package/build-module/components/media-replace-flow/index.native.js.map +1 -1
  129. package/build-module/components/rich-text/format-edit.js +51 -26
  130. package/build-module/components/rich-text/format-edit.js.map +1 -1
  131. package/build-module/components/rich-text/get-rich-text-values.js +13 -18
  132. package/build-module/components/rich-text/get-rich-text-values.js.map +1 -1
  133. package/build-module/components/spacing-sizes-control/utils.js +2 -2
  134. package/build-module/components/spacing-sizes-control/utils.js.map +1 -1
  135. package/build-module/hooks/behaviors.js +5 -12
  136. package/build-module/hooks/behaviors.js.map +1 -1
  137. package/build-module/hooks/border.js +2 -1
  138. package/build-module/hooks/border.js.map +1 -1
  139. package/build-module/hooks/style.js +11 -2
  140. package/build-module/hooks/style.js.map +1 -1
  141. package/build-module/private-apis.js +3 -1
  142. package/build-module/private-apis.js.map +1 -1
  143. package/build-module/store/actions.js +2 -3
  144. package/build-module/store/actions.js.map +1 -1
  145. package/build-module/store/selectors.js +4 -69
  146. package/build-module/store/selectors.js.map +1 -1
  147. package/build-style/style-rtl.css +18 -5
  148. package/build-style/style.css +18 -5
  149. package/package.json +31 -31
  150. package/src/autocompleters/block.js +21 -6
  151. package/src/components/block-draggable/test/index.native.js +2 -3
  152. package/src/components/block-editing-mode/index.js +1 -1
  153. package/src/components/block-list/block.js +6 -1
  154. package/src/components/block-list/index.js +3 -6
  155. package/src/components/block-list/test/block-invalid-warning.native.js +8 -1
  156. package/src/components/block-mover/test/__snapshots__/index.native.js.snap +24 -0
  157. package/src/components/block-parent-selector/index.js +30 -42
  158. package/src/components/block-preview/auto.js +8 -1
  159. package/src/components/block-preview/style.scss +2 -1
  160. package/src/components/block-settings-menu/block-settings-dropdown.js +4 -13
  161. package/src/components/block-toolbar/index.js +36 -63
  162. package/src/components/block-toolbar/utils.js +57 -45
  163. package/src/components/block-tools/block-contextual-toolbar.js +43 -35
  164. package/src/components/block-tools/style.scss +17 -5
  165. package/src/components/block-variation-picker/index.native.js +52 -72
  166. package/src/components/color-palette/test/__snapshots__/control.js.snap +1 -1
  167. package/src/components/editor-styles/index.js +2 -2
  168. package/src/components/font-sizes/fluid-utils.js +17 -17
  169. package/src/components/font-sizes/test/fluid-utils.js +6 -6
  170. package/src/components/global-styles/behaviors-panel.js +71 -0
  171. package/src/components/global-styles/hooks.js +114 -5
  172. package/src/components/global-styles/index.js +3 -0
  173. package/src/components/global-styles/test/typography-utils.js +6 -6
  174. package/src/components/global-styles/typography-utils.js +4 -4
  175. package/src/components/global-styles/utils.js +2 -1
  176. package/src/components/inserter/hooks/use-block-types-state.js +15 -6
  177. package/src/components/inserter/hooks/use-debounced-input.js +8 -7
  178. package/src/components/inserter/hooks/use-patterns-state.js +2 -1
  179. package/src/components/inserter/reusable-blocks-tab.js +4 -1
  180. package/src/components/inserter-list-item/index.js +3 -1
  181. package/src/components/link-control/README.md +12 -3
  182. package/src/components/link-control/index.js +43 -6
  183. package/src/components/link-control/link-preview.js +6 -4
  184. package/src/components/link-control/style.scss +3 -2
  185. package/src/components/link-control/test/index.js +2 -1
  186. package/src/components/list-view/use-list-view-drop-zone.js +5 -1
  187. package/src/components/media-replace-flow/index.native.js +12 -3
  188. package/src/components/media-upload/test/index.native.js +1 -0
  189. package/src/components/rich-text/format-edit.js +62 -38
  190. package/src/components/rich-text/get-rich-text-values.js +22 -28
  191. package/src/components/spacing-sizes-control/test/utils.js +9 -1
  192. package/src/components/spacing-sizes-control/utils.js +2 -2
  193. package/src/hooks/behaviors.js +10 -16
  194. package/src/hooks/border.js +2 -1
  195. package/src/hooks/style.js +7 -3
  196. package/src/private-apis.js +2 -0
  197. package/src/store/actions.js +22 -28
  198. package/src/store/selectors.js +3 -80
  199. package/src/store/test/selectors.js +7 -6
@@ -42,11 +42,13 @@ export default function LinkPreview( {
42
42
  ( value && filterURLForDisplay( safeDecodeURI( value.url ), 16 ) ) ||
43
43
  '';
44
44
 
45
- const displayTitle = richData?.title || value?.title || displayURL;
46
-
47
45
  // url can be undefined if the href attribute is unset
48
46
  const isEmptyURL = ! value?.url?.length;
49
47
 
48
+ const displayTitle =
49
+ ! isEmptyURL &&
50
+ stripHTML( richData?.title || value?.title || displayURL );
51
+
50
52
  let icon;
51
53
 
52
54
  if ( richData?.icon ) {
@@ -87,10 +89,10 @@ export default function LinkPreview( {
87
89
  className="block-editor-link-control__search-item-title"
88
90
  href={ value.url }
89
91
  >
90
- { stripHTML( displayTitle ) }
92
+ { displayTitle }
91
93
  </ExternalLink>
92
94
 
93
- { value?.url && (
95
+ { value?.url && displayTitle !== displayURL && (
94
96
  <span className="block-editor-link-control__search-item-info">
95
97
  { displayURL }
96
98
  </span>
@@ -84,7 +84,7 @@ $preview-image-height: 140px;
84
84
  flex-direction: row-reverse; // put "Cancel" on the left but retain DOM order.
85
85
  justify-content: flex-start;
86
86
  gap: $grid-unit-10;
87
- padding: $grid-unit-10;
87
+ padding: $grid-unit-10 $grid-unit-20 $grid-unit-20;
88
88
  order: 20;
89
89
  }
90
90
 
@@ -215,9 +215,9 @@ $preview-image-height: 140px;
215
215
 
216
216
  .block-editor-link-control__search-item-title {
217
217
  display: block;
218
- margin-bottom: 0.2em;
219
218
  font-weight: 500;
220
219
  position: relative;
220
+ line-height: $grid-unit-30;
221
221
 
222
222
  mark {
223
223
  font-weight: 600;
@@ -291,6 +291,7 @@ $preview-image-height: 140px;
291
291
  display: flex;
292
292
  flex-direction: row;
293
293
  width: 100%; // clip.
294
+ align-items: center;
294
295
  }
295
296
 
296
297
  .block-editor-link-control__search-item-bottom {
@@ -1734,7 +1734,7 @@ describe( 'Selecting links', () => {
1734
1734
  } );
1735
1735
 
1736
1736
  describe( 'Addition Settings UI', () => {
1737
- it( 'should not show a means to toggle the link settings when not editing a link', async () => {
1737
+ it( 'should hide advanced link settings when not editing a link', async () => {
1738
1738
  const selectedLink = fauxEntitySuggestions[ 0 ];
1739
1739
 
1740
1740
  const LinkControlConsumer = () => {
@@ -1749,6 +1749,7 @@ describe( 'Addition Settings UI', () => {
1749
1749
 
1750
1750
  expect( settingsToggle ).not.toBeInTheDocument();
1751
1751
  } );
1752
+
1752
1753
  it( 'should provides a means to toggle the link settings', async () => {
1753
1754
  const selectedLink = fauxEntitySuggestions[ 0 ];
1754
1755
 
@@ -489,7 +489,11 @@ export default function useListViewDropZone( { dropZoneElement } ) {
489
489
 
490
490
  const ref = useDropZone( {
491
491
  dropZoneElement,
492
- onDrop: onBlockDrop,
492
+ onDrop( event ) {
493
+ if ( target ) {
494
+ onBlockDrop( event );
495
+ }
496
+ },
493
497
  onDragLeave() {
494
498
  throttled.cancel();
495
499
  setTarget( null );
@@ -1,3 +1,12 @@
1
- // MediaReplaceFlow component is not yet implemented in the native version,
2
- // so we return an empty component instead.
3
- export default () => null;
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { View } from 'react-native';
5
+
6
+ // MediaReplaceFlow component is not yet implemented in the native version.
7
+ // For testing purposes, we are using an empty View component with a testID prop.
8
+ const MediaReplaceFlow = () => {
9
+ return <View testID="media-replace-flow" />;
10
+ };
11
+
12
+ export default MediaReplaceFlow;
@@ -44,6 +44,7 @@ describe( 'MediaUpload component', () => {
44
44
  const wrapper = render(
45
45
  <MediaUpload
46
46
  allowedTypes={ [ mediaType ] }
47
+ onSelectURL={ jest.fn() }
47
48
  render={ ( { open, getMediaOptions } ) => {
48
49
  return (
49
50
  <>
@@ -2,43 +2,67 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { getActiveFormat, getActiveObject } from '@wordpress/rich-text';
5
+ import { useContext, useMemo } from '@wordpress/element';
5
6
 
6
- export default function FormatEdit( {
7
- formatTypes,
8
- onChange,
9
- onFocus,
10
- value,
11
- forwardedRef,
12
- } ) {
13
- return formatTypes.map( ( settings ) => {
14
- const { name, edit: Edit } = settings;
15
-
16
- if ( ! Edit ) {
17
- return null;
18
- }
19
-
20
- const activeFormat = getActiveFormat( value, name );
21
- const isActive = activeFormat !== undefined;
22
- const activeObject = getActiveObject( value );
23
- const isObjectActive =
24
- activeObject !== undefined && activeObject.type === name;
25
-
26
- return (
27
- <Edit
28
- key={ name }
29
- isActive={ isActive }
30
- activeAttributes={
31
- isActive ? activeFormat.attributes || {} : {}
32
- }
33
- isObjectActive={ isObjectActive }
34
- activeObjectAttributes={
35
- isObjectActive ? activeObject.attributes || {} : {}
36
- }
37
- value={ value }
38
- onChange={ onChange }
39
- onFocus={ onFocus }
40
- contentRef={ forwardedRef }
41
- />
42
- );
43
- } );
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import BlockContext from '../block-context';
11
+
12
+ const DEFAULT_BLOCK_CONTEXT = {};
13
+
14
+ export const usesContextKey = Symbol( 'usesContext' );
15
+
16
+ function Edit( { onChange, onFocus, value, forwardedRef, settings } ) {
17
+ const {
18
+ name,
19
+ edit: EditFunction,
20
+ [ usesContextKey ]: usesContext,
21
+ } = settings;
22
+
23
+ const blockContext = useContext( BlockContext );
24
+
25
+ // Assign context values using the block type's declared context needs.
26
+ const context = useMemo( () => {
27
+ return usesContext
28
+ ? Object.fromEntries(
29
+ Object.entries( blockContext ).filter( ( [ key ] ) =>
30
+ usesContext.includes( key )
31
+ )
32
+ )
33
+ : DEFAULT_BLOCK_CONTEXT;
34
+ }, [ usesContext, blockContext ] );
35
+
36
+ if ( ! EditFunction ) {
37
+ return null;
38
+ }
39
+
40
+ const activeFormat = getActiveFormat( value, name );
41
+ const isActive = activeFormat !== undefined;
42
+ const activeObject = getActiveObject( value );
43
+ const isObjectActive =
44
+ activeObject !== undefined && activeObject.type === name;
45
+
46
+ return (
47
+ <EditFunction
48
+ key={ name }
49
+ isActive={ isActive }
50
+ activeAttributes={ isActive ? activeFormat.attributes || {} : {} }
51
+ isObjectActive={ isObjectActive }
52
+ activeObjectAttributes={
53
+ isObjectActive ? activeObject.attributes || {} : {}
54
+ }
55
+ value={ value }
56
+ onChange={ onChange }
57
+ onFocus={ onFocus }
58
+ contentRef={ forwardedRef }
59
+ context={ context }
60
+ />
61
+ );
62
+ }
63
+
64
+ export default function FormatEdit( { formatTypes, ...props } ) {
65
+ return formatTypes.map( ( settings ) => (
66
+ <Edit settings={ settings } { ...props } key={ settings.name } />
67
+ ) );
44
68
  }
@@ -18,13 +18,13 @@ import { Content } from './content';
18
18
  * except that it does not render the elements to a string, but instead collects
19
19
  * the values of all rich text `Content` elements.
20
20
  */
21
- function addValuesForElement( element, ...args ) {
21
+ function addValuesForElement( element, values, innerBlocks ) {
22
22
  if ( null === element || undefined === element || false === element ) {
23
23
  return;
24
24
  }
25
25
 
26
26
  if ( Array.isArray( element ) ) {
27
- return addValuesForElements( element, ...args );
27
+ return addValuesForElements( element, values, innerBlocks );
28
28
  }
29
29
 
30
30
  switch ( typeof element ) {
@@ -38,13 +38,12 @@ function addValuesForElement( element, ...args ) {
38
38
  switch ( type ) {
39
39
  case StrictMode:
40
40
  case Fragment:
41
- return addValuesForElements( props.children, ...args );
41
+ return addValuesForElements( props.children, values, innerBlocks );
42
42
  case RawHTML:
43
43
  return;
44
44
  case InnerBlocks.Content:
45
- return addValuesForBlocks( ...args );
45
+ return addValuesForBlocks( values, innerBlocks );
46
46
  case Content:
47
- const [ values ] = args;
48
47
  values.push( props.value );
49
48
  return;
50
49
  }
@@ -52,21 +51,19 @@ function addValuesForElement( element, ...args ) {
52
51
  switch ( typeof type ) {
53
52
  case 'string':
54
53
  if ( typeof props.children !== 'undefined' ) {
55
- return addValuesForElements( props.children, ...args );
54
+ return addValuesForElements(
55
+ props.children,
56
+ values,
57
+ innerBlocks
58
+ );
56
59
  }
57
60
  return;
58
61
  case 'function':
59
- if (
60
- type.prototype &&
61
- typeof type.prototype.render === 'function'
62
- ) {
63
- return addValuesForElement(
64
- new type( props ).render(),
65
- ...args
66
- );
67
- }
68
-
69
- return addValuesForElement( type( props ), ...args );
62
+ const el =
63
+ type.prototype && typeof type.prototype.render === 'function'
64
+ ? new type( props ).render()
65
+ : type( props );
66
+ return addValuesForElement( el, values, innerBlocks );
70
67
  }
71
68
  }
72
69
 
@@ -78,20 +75,17 @@ function addValuesForElements( children, ...args ) {
78
75
  }
79
76
  }
80
77
 
81
- function _getSaveElement( name, attributes, innerBlocks ) {
82
- return getSaveElement(
83
- name,
84
- attributes,
85
- innerBlocks.map( ( block ) =>
86
- _getSaveElement( block.name, block.attributes, block.innerBlocks )
87
- )
88
- );
89
- }
90
-
91
78
  function addValuesForBlocks( values, blocks ) {
92
79
  for ( let i = 0; i < blocks.length; i++ ) {
93
80
  const { name, attributes, innerBlocks } = blocks[ i ];
94
- const saveElement = _getSaveElement( name, attributes, innerBlocks );
81
+ const saveElement = getSaveElement(
82
+ name,
83
+ attributes,
84
+ // Instead of letting save elements use `useInnerBlocksProps.save`,
85
+ // force them to use InnerBlocks.Content instead so we can intercept
86
+ // a single component.
87
+ <InnerBlocks.Content />
88
+ );
95
89
  addValuesForElement( saveElement, values, innerBlocks );
96
90
  }
97
91
  }
@@ -49,7 +49,15 @@ describe( 'getCustomValueFromPreset', () => {
49
49
  } );
50
50
 
51
51
  describe( 'getPresetValueFromCustomValue', () => {
52
- const spacingSizes = [ { name: 'Small', slug: 20, size: '8px' } ];
52
+ const spacingSizes = [
53
+ { name: 'Default', slug: 'default', size: undefined },
54
+ { name: 'Small', slug: 20, size: '8px' },
55
+ ];
56
+ it( 'should return undefined even if an undefined value exist in spacing sizes as occurs if spacingSizes has > 7 entries', () => {
57
+ expect( getPresetValueFromCustomValue( undefined, spacingSizes ) ).toBe(
58
+ undefined
59
+ );
60
+ } );
53
61
  it( 'should return original value if a string in spacing presets var format', () => {
54
62
  expect(
55
63
  getPresetValueFromCustomValue(
@@ -101,8 +101,8 @@ export function getCustomValueFromPreset( value, spacingSizes ) {
101
101
  * @return {string} The preset value if it can be found.
102
102
  */
103
103
  export function getPresetValueFromCustomValue( value, spacingSizes ) {
104
- // Return value as-is if it is already a preset;
105
- if ( isValueSpacingPreset( value ) || value === '0' ) {
104
+ // Return value as-is if it is undefined or is already a preset, or '0';
105
+ if ( ! value || isValueSpacingPreset( value ) || value === '0' ) {
106
106
  return value;
107
107
  }
108
108
 
@@ -22,15 +22,13 @@ function BehaviorsControl( {
22
22
  onChangeAnimation,
23
23
  disabled = false,
24
24
  } ) {
25
- const { settings, themeBehaviors } = useSelect(
25
+ const { settings } = useSelect(
26
26
  ( select ) => {
27
- const { getBehaviors, getSettings } = select( blockEditorStore );
28
-
27
+ const { getSettings } = select( blockEditorStore );
29
28
  return {
30
29
  settings:
31
30
  getSettings()?.__experimentalFeatures?.blocks?.[ blockName ]
32
- ?.behaviors,
33
- themeBehaviors: getBehaviors()?.blocks?.[ blockName ],
31
+ ?.behaviors || {},
34
32
  };
35
33
  },
36
34
  [ blockName ]
@@ -46,7 +44,6 @@ function BehaviorsControl( {
46
44
  label: __( 'No behaviors' ),
47
45
  },
48
46
  };
49
-
50
47
  const behaviorsOptions = Object.entries( settings )
51
48
  .filter(
52
49
  ( [ behaviorName, behaviorValue ] ) =>
@@ -60,7 +57,6 @@ function BehaviorsControl( {
60
57
  .slice( 1 )
61
58
  .toLowerCase() }`,
62
59
  } ) );
63
-
64
60
  const options = [
65
61
  ...Object.values( defaultBehaviors ),
66
62
  ...behaviorsOptions,
@@ -68,7 +64,6 @@ function BehaviorsControl( {
68
64
 
69
65
  const { behaviors, behaviorsValue } = useMemo( () => {
70
66
  const mergedBehaviors = {
71
- ...themeBehaviors,
72
67
  ...( blockBehaviors || {} ),
73
68
  };
74
69
 
@@ -83,7 +78,8 @@ function BehaviorsControl( {
83
78
  behaviors: mergedBehaviors,
84
79
  behaviorsValue: value,
85
80
  };
86
- }, [ blockBehaviors, themeBehaviors ] );
81
+ }, [ blockBehaviors ] );
82
+
87
83
  // If every behavior is disabled, do not show the behaviors inspector control.
88
84
  if ( behaviorsOptions.length === 0 ) {
89
85
  return null;
@@ -203,10 +199,8 @@ export const withBehaviors = createHigherOrderComponent( ( BlockEdit ) => {
203
199
  };
204
200
  }, 'withBehaviors' );
205
201
 
206
- if ( window?.__experimentalInteractivityAPI ) {
207
- addFilter(
208
- 'editor.BlockEdit',
209
- 'core/behaviors/with-inspector-control',
210
- withBehaviors
211
- );
212
- }
202
+ addFilter(
203
+ 'editor.BlockEdit',
204
+ 'core/behaviors/with-inspector-control',
205
+ withBehaviors
206
+ );
@@ -377,13 +377,14 @@ export const withBorderColorPaletteStyles = createHigherOrderComponent(
377
377
  borderBottomColor: borderBottomColor || borderColorValue,
378
378
  borderLeftColor: borderLeftColor || borderColorValue,
379
379
  };
380
+ const cleanedExtraStyles = cleanEmptyObject( extraStyles ) || {};
380
381
 
381
382
  let wrapperProps = props.wrapperProps;
382
383
  wrapperProps = {
383
384
  ...props.wrapperProps,
384
385
  style: {
385
386
  ...props.wrapperProps?.style,
386
- ...extraStyles,
387
+ ...cleanedExtraStyles,
387
388
  },
388
389
  };
389
390
 
@@ -44,8 +44,8 @@ const styleSupportKeys = [
44
44
  SPACING_SUPPORT_KEY,
45
45
  ];
46
46
 
47
- const hasStyleSupport = ( blockType ) =>
48
- styleSupportKeys.some( ( key ) => hasBlockSupport( blockType, key ) );
47
+ const hasStyleSupport = ( nameOrType ) =>
48
+ styleSupportKeys.some( ( key ) => hasBlockSupport( nameOrType, key ) );
49
49
 
50
50
  /**
51
51
  * Returns the inline styles to add depending on the style object
@@ -347,6 +347,10 @@ export function addEditProps( settings ) {
347
347
  */
348
348
  export const withBlockControls = createHigherOrderComponent(
349
349
  ( BlockEdit ) => ( props ) => {
350
+ if ( ! hasStyleSupport( props.name ) ) {
351
+ return <BlockEdit key="edit" { ...props } />;
352
+ }
353
+
350
354
  const shouldDisplayControls = useDisplayBlockControls();
351
355
  const blockEditingMode = useBlockEditingMode();
352
356
 
@@ -360,7 +364,7 @@ export const withBlockControls = createHigherOrderComponent(
360
364
  <DimensionsPanel { ...props } />
361
365
  </>
362
366
  ) }
363
- <BlockEdit { ...props } />
367
+ <BlockEdit key="edit" { ...props } />
364
368
  </>
365
369
  );
366
370
  },
@@ -23,6 +23,7 @@ import {
23
23
  default as ReusableBlocksRenameHint,
24
24
  useReusableBlocksRenameHint,
25
25
  } from './components/inserter/reusable-block-rename-hint';
26
+ import { usesContextKey } from './components/rich-text/format-edit';
26
27
 
27
28
  /**
28
29
  * Private @wordpress/block-editor APIs.
@@ -49,4 +50,5 @@ lock( privateApis, {
49
50
  ResolutionTool,
50
51
  ReusableBlocksRenameHint,
51
52
  useReusableBlocksRenameHint,
53
+ usesContextKey,
52
54
  } );
@@ -948,36 +948,30 @@ export const __unstableSplitSelection =
948
948
  valueA = remove( valueA, selectionA.offset, valueA.text.length );
949
949
  valueB = remove( valueB, 0, selectionB.offset );
950
950
 
951
- dispatch.replaceBlocks(
952
- select.getSelectedBlockClientIds(),
953
- [
954
- {
955
- // Preserve the original client ID.
956
- ...blockA,
957
- attributes: {
958
- ...blockA.attributes,
959
- [ selectionA.attributeKey ]: toHTMLString( {
960
- value: valueA,
961
- ...mapRichTextSettings( attributeDefinitionA ),
962
- } ),
963
- },
951
+ dispatch.replaceBlocks( select.getSelectedBlockClientIds(), [
952
+ {
953
+ // Preserve the original client ID.
954
+ ...blockA,
955
+ attributes: {
956
+ ...blockA.attributes,
957
+ [ selectionA.attributeKey ]: toHTMLString( {
958
+ value: valueA,
959
+ ...mapRichTextSettings( attributeDefinitionA ),
960
+ } ),
964
961
  },
965
- createBlock( getDefaultBlockName() ),
966
- {
967
- // Preserve the original client ID.
968
- ...blockB,
969
- attributes: {
970
- ...blockB.attributes,
971
- [ selectionB.attributeKey ]: toHTMLString( {
972
- value: valueB,
973
- ...mapRichTextSettings( attributeDefinitionB ),
974
- } ),
975
- },
962
+ },
963
+ {
964
+ // Preserve the original client ID.
965
+ ...blockB,
966
+ attributes: {
967
+ ...blockB.attributes,
968
+ [ selectionB.attributeKey ]: toHTMLString( {
969
+ value: valueB,
970
+ ...mapRichTextSettings( attributeDefinitionB ),
971
+ } ),
976
972
  },
977
- ],
978
- 1, // If we don't pass the `indexToSelect` it will default to the last block.
979
- select.getSelectedBlocksInitialCaretPosition()
980
- );
973
+ },
974
+ ] );
981
975
  };
982
976
 
983
977
  /**
@@ -1962,51 +1962,8 @@ const buildBlockTypeItem =
1962
1962
  */
1963
1963
  export const getInserterItems = createSelector(
1964
1964
  ( state, rootClientId = null ) => {
1965
- /*
1966
- * Matches block comment delimiters amid serialized content.
1967
- *
1968
- * @see `tokenizer` in `@wordpress/block-serialization-default-parser`
1969
- * package
1970
- *
1971
- * blockParserTokenizer differs from the original tokenizer in the
1972
- * following ways:
1973
- *
1974
- * - removed global flag (/g)
1975
- * - prepended ^\s*
1976
- *
1977
- */
1978
- const blockParserTokenizer =
1979
- /^\s*<!--\s+(\/)?wp:([a-z][a-z0-9_-]*\/)?([a-z][a-z0-9_-]*)\s+({(?:(?=([^}]+|}+(?=})|(?!}\s+\/?-->)[^])*)\5|[^]*?)}\s+)?(\/)?-->/;
1980
-
1981
1965
  const buildReusableBlockInserterItem = ( reusableBlock ) => {
1982
- let icon = symbol;
1983
-
1984
- /*
1985
- * Instead of always displaying a generic "symbol" icon for every
1986
- * reusable block, try to use an icon that represents the first
1987
- * outermost block contained in the reusable block. This requires
1988
- * scanning the serialized form of the reusable block to find its
1989
- * first block delimiter, then looking up the corresponding block
1990
- * type, if available.
1991
- */
1992
- if ( Platform.OS === 'web' ) {
1993
- const content =
1994
- typeof reusableBlock.content.raw === 'string'
1995
- ? reusableBlock.content.raw
1996
- : reusableBlock.content;
1997
- const rawBlockMatch = content.match( blockParserTokenizer );
1998
- if ( rawBlockMatch ) {
1999
- const [ , , namespace = 'core/', blockName ] =
2000
- rawBlockMatch;
2001
- const referencedBlockType = getBlockType(
2002
- namespace + blockName
2003
- );
2004
- if ( referencedBlockType ) {
2005
- icon = referencedBlockType.icon;
2006
- }
2007
- }
2008
- }
2009
-
1966
+ const icon = symbol;
2010
1967
  const id = `core/block/${ reusableBlock.id }`;
2011
1968
  const { time, count = 0 } = getInsertUsage( state, id ) || {};
2012
1969
  const frecency = calculateFrecency( time, count );
@@ -2023,6 +1980,7 @@ export const getInserterItems = createSelector(
2023
1980
  utility: 1, // Deprecated.
2024
1981
  frecency,
2025
1982
  content: reusableBlock.content.raw,
1983
+ syncStatus: reusableBlock.wp_pattern_sync_status,
2026
1984
  };
2027
1985
  };
2028
1986
 
@@ -2031,18 +1989,7 @@ export const getInserterItems = createSelector(
2031
1989
  'core/block',
2032
1990
  rootClientId
2033
1991
  )
2034
- ? getReusableBlocks( state )
2035
- .filter(
2036
- ( reusableBlock ) =>
2037
- // Reusable blocks that are fully synced should have no sync status set
2038
- // for backwards compat between patterns and old reusable blocks, but
2039
- // some in release 16.1 may have had sync status inadvertantly set to
2040
- // 'fully' if created in the site editor.
2041
- reusableBlock.wp_pattern_sync_status === 'fully' ||
2042
- reusableBlock.wp_pattern_sync_status === '' ||
2043
- ! reusableBlock.wp_pattern_sync_status
2044
- )
2045
- .map( buildReusableBlockInserterItem )
1992
+ ? getReusableBlocks( state ).map( buildReusableBlockInserterItem )
2046
1993
  : [];
2047
1994
 
2048
1995
  const buildBlockTypeInserterItem = buildBlockTypeItem( state, {
@@ -2577,30 +2524,6 @@ export function getSettings( state ) {
2577
2524
  return state.settings;
2578
2525
  }
2579
2526
 
2580
- /**
2581
- * Returns the behaviors registered with the editor.
2582
- *
2583
- * Behaviors are named, reusable pieces of functionality that can be
2584
- * attached to blocks. They are registered with the editor using the
2585
- * `theme.json` file.
2586
- *
2587
- * @example
2588
- *
2589
- * ```js
2590
- * const behaviors = select( blockEditorStore ).getBehaviors();
2591
- * if ( behaviors?.lightbox ) {
2592
- * // Do something with the lightbox.
2593
- * }
2594
- *```
2595
- *
2596
- * @param {Object} state Editor state.
2597
- *
2598
- * @return {Object} The editor behaviors object.
2599
- */
2600
- export function getBehaviors( state ) {
2601
- return state.settings.behaviors;
2602
- }
2603
-
2604
2527
  /**
2605
2528
  * Returns true if the most recent block change is be considered persistent, or
2606
2529
  * false otherwise. A persistent change is one committed by BlockEditorProvider