@wordpress/block-editor 10.2.0 → 10.3.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 (285) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +41 -0
  3. package/build/components/block-draggable/draggable-chip.js +4 -2
  4. package/build/components/block-draggable/draggable-chip.js.map +1 -1
  5. package/build/components/block-inspector/index.js +4 -4
  6. package/build/components/block-inspector/index.js.map +1 -1
  7. package/build/components/block-list/block-list-compact.native.js +1 -0
  8. package/build/components/block-list/block-list-compact.native.js.map +1 -1
  9. package/build/components/block-list/block.js +72 -14
  10. package/build/components/block-list/block.js.map +1 -1
  11. package/build/components/block-list/block.native.js +79 -12
  12. package/build/components/block-list/block.native.js.map +1 -1
  13. package/build/components/block-list/use-in-between-inserter.js +7 -23
  14. package/build/components/block-list/use-in-between-inserter.js.map +1 -1
  15. package/build/components/block-lock/modal.js +9 -6
  16. package/build/components/block-lock/modal.js.map +1 -1
  17. package/build/components/block-parent-selector/index.js +3 -3
  18. package/build/components/block-parent-selector/index.js.map +1 -1
  19. package/build/components/block-patterns-list/index.js +5 -4
  20. package/build/components/block-patterns-list/index.js.map +1 -1
  21. package/build/components/block-popover/drop-zone.js +85 -0
  22. package/build/components/block-popover/drop-zone.js.map +1 -0
  23. package/build/components/block-popover/index.js +2 -1
  24. package/build/components/block-popover/index.js.map +1 -1
  25. package/build/components/block-preview/auto.js +2 -2
  26. package/build/components/block-preview/auto.js.map +1 -1
  27. package/build/components/block-preview/index.js +6 -9
  28. package/build/components/block-preview/index.js.map +1 -1
  29. package/build/components/block-preview/live.js +3 -7
  30. package/build/components/block-preview/live.js.map +1 -1
  31. package/build/components/block-selection-clearer/index.js +9 -1
  32. package/build/components/block-selection-clearer/index.js.map +1 -1
  33. package/build/components/block-settings-menu/block-settings-dropdown.js +17 -11
  34. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  35. package/build/components/block-styles/index.js +18 -42
  36. package/build/components/block-styles/index.js.map +1 -1
  37. package/build/components/block-toolbar/index.js +4 -4
  38. package/build/components/block-toolbar/index.js.map +1 -1
  39. package/build/components/block-tools/back-compat.js +2 -1
  40. package/build/components/block-tools/back-compat.js.map +1 -1
  41. package/build/components/block-tools/insertion-point.js +50 -20
  42. package/build/components/block-tools/insertion-point.js.map +1 -1
  43. package/build/components/block-tools/selected-block-popover.js +15 -3
  44. package/build/components/block-tools/selected-block-popover.js.map +1 -1
  45. package/build/components/colors-gradients/control.js +1 -1
  46. package/build/components/colors-gradients/control.js.map +1 -1
  47. package/build/components/colors-gradients/panel-color-gradient-settings.js +2 -2
  48. package/build/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  49. package/build/components/font-sizes/fluid-utils.js +256 -0
  50. package/build/components/font-sizes/fluid-utils.js.map +1 -0
  51. package/build/components/font-sizes/index.js +8 -0
  52. package/build/components/font-sizes/index.js.map +1 -1
  53. package/build/components/index.js +0 -9
  54. package/build/components/index.js.map +1 -1
  55. package/build/components/inner-blocks/use-inner-block-template-sync.js +3 -2
  56. package/build/components/inner-blocks/use-inner-block-template-sync.js.map +1 -1
  57. package/build/components/inserter/block-patterns-tab.js +151 -78
  58. package/build/components/inserter/block-patterns-tab.js.map +1 -1
  59. package/build/components/inserter/menu.js +14 -3
  60. package/build/components/inserter/menu.js.map +1 -1
  61. package/build/components/inserter-draggable-blocks/index.js +4 -2
  62. package/build/components/inserter-draggable-blocks/index.js.map +1 -1
  63. package/build/components/list-view/use-list-view-drop-zone.js +1 -14
  64. package/build/components/list-view/use-list-view-drop-zone.js.map +1 -1
  65. package/build/components/preview-options/index.js +2 -3
  66. package/build/components/preview-options/index.js.map +1 -1
  67. package/build/components/spacing-sizes-control/spacing-input-control.js +35 -5
  68. package/build/components/spacing-sizes-control/spacing-input-control.js.map +1 -1
  69. package/build/components/use-block-drop-zone/index.js +98 -57
  70. package/build/components/use-block-drop-zone/index.js.map +1 -1
  71. package/build/components/use-on-block-drop/index.js +12 -12
  72. package/build/components/use-on-block-drop/index.js.map +1 -1
  73. package/build/components/use-on-block-drop/types.js +6 -0
  74. package/build/components/use-on-block-drop/types.js.map +1 -0
  75. package/build/hooks/align.js +1 -3
  76. package/build/hooks/align.js.map +1 -1
  77. package/build/hooks/align.native.js +1 -7
  78. package/build/hooks/align.native.js.map +1 -1
  79. package/build/hooks/font-size.js +60 -0
  80. package/build/hooks/font-size.js.map +1 -1
  81. package/build/hooks/margin.js +6 -5
  82. package/build/hooks/margin.js.map +1 -1
  83. package/build/hooks/padding.js +2 -1
  84. package/build/hooks/padding.js.map +1 -1
  85. package/build/hooks/style.js +126 -4
  86. package/build/hooks/style.js.map +1 -1
  87. package/build/hooks/use-typography-props.js +17 -3
  88. package/build/hooks/use-typography-props.js.map +1 -1
  89. package/build/hooks/utils.js +1 -1
  90. package/build/hooks/utils.js.map +1 -1
  91. package/build/store/actions.js +59 -45
  92. package/build/store/actions.js.map +1 -1
  93. package/build/store/defaults.js +3 -0
  94. package/build/store/defaults.js.map +1 -1
  95. package/build/store/reducer.js +31 -15
  96. package/build/store/reducer.js.map +1 -1
  97. package/build/utils/math.js +14 -0
  98. package/build/utils/math.js.map +1 -1
  99. package/build/utils/pre-parse-patterns.js +19 -2
  100. package/build/utils/pre-parse-patterns.js.map +1 -1
  101. package/build-module/components/block-draggable/draggable-chip.js +7 -3
  102. package/build-module/components/block-draggable/draggable-chip.js.map +1 -1
  103. package/build-module/components/block-inspector/index.js +4 -4
  104. package/build-module/components/block-inspector/index.js.map +1 -1
  105. package/build-module/components/block-list/block-list-compact.native.js +1 -0
  106. package/build-module/components/block-list/block-list-compact.native.js.map +1 -1
  107. package/build-module/components/block-list/block.js +72 -14
  108. package/build-module/components/block-list/block.js.map +1 -1
  109. package/build-module/components/block-list/block.native.js +80 -13
  110. package/build-module/components/block-list/block.native.js.map +1 -1
  111. package/build-module/components/block-list/use-in-between-inserter.js +8 -24
  112. package/build-module/components/block-list/use-in-between-inserter.js.map +1 -1
  113. package/build-module/components/block-lock/modal.js +10 -8
  114. package/build-module/components/block-lock/modal.js.map +1 -1
  115. package/build-module/components/block-parent-selector/index.js +3 -3
  116. package/build-module/components/block-parent-selector/index.js.map +1 -1
  117. package/build-module/components/block-patterns-list/index.js +5 -4
  118. package/build-module/components/block-patterns-list/index.js.map +1 -1
  119. package/build-module/components/block-popover/drop-zone.js +70 -0
  120. package/build-module/components/block-popover/drop-zone.js.map +1 -0
  121. package/build-module/components/block-popover/index.js +2 -1
  122. package/build-module/components/block-popover/index.js.map +1 -1
  123. package/build-module/components/block-preview/auto.js +1 -1
  124. package/build-module/components/block-preview/auto.js.map +1 -1
  125. package/build-module/components/block-preview/index.js +6 -9
  126. package/build-module/components/block-preview/index.js.map +1 -1
  127. package/build-module/components/block-preview/live.js +3 -6
  128. package/build-module/components/block-preview/live.js.map +1 -1
  129. package/build-module/components/block-selection-clearer/index.js +9 -1
  130. package/build-module/components/block-selection-clearer/index.js.map +1 -1
  131. package/build-module/components/block-settings-menu/block-settings-dropdown.js +18 -12
  132. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  133. package/build-module/components/block-styles/index.js +19 -44
  134. package/build-module/components/block-styles/index.js.map +1 -1
  135. package/build-module/components/block-toolbar/index.js +4 -4
  136. package/build-module/components/block-toolbar/index.js.map +1 -1
  137. package/build-module/components/block-tools/back-compat.js +2 -1
  138. package/build-module/components/block-tools/back-compat.js.map +1 -1
  139. package/build-module/components/block-tools/insertion-point.js +48 -20
  140. package/build-module/components/block-tools/insertion-point.js.map +1 -1
  141. package/build-module/components/block-tools/selected-block-popover.js +15 -3
  142. package/build-module/components/block-tools/selected-block-popover.js.map +1 -1
  143. package/build-module/components/colors-gradients/control.js +2 -2
  144. package/build-module/components/colors-gradients/control.js.map +1 -1
  145. package/build-module/components/colors-gradients/panel-color-gradient-settings.js +3 -3
  146. package/build-module/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  147. package/build-module/components/font-sizes/fluid-utils.js +245 -0
  148. package/build-module/components/font-sizes/fluid-utils.js.map +1 -0
  149. package/build-module/components/font-sizes/index.js +1 -0
  150. package/build-module/components/font-sizes/index.js.map +1 -1
  151. package/build-module/components/index.js +0 -1
  152. package/build-module/components/index.js.map +1 -1
  153. package/build-module/components/inner-blocks/use-inner-block-template-sync.js +3 -2
  154. package/build-module/components/inner-blocks/use-inner-block-template-sync.js.map +1 -1
  155. package/build-module/components/inserter/block-patterns-tab.js +148 -81
  156. package/build-module/components/inserter/block-patterns-tab.js.map +1 -1
  157. package/build-module/components/inserter/menu.js +10 -3
  158. package/build-module/components/inserter/menu.js.map +1 -1
  159. package/build-module/components/inserter-draggable-blocks/index.js +4 -2
  160. package/build-module/components/inserter-draggable-blocks/index.js.map +1 -1
  161. package/build-module/components/list-view/use-list-view-drop-zone.js +1 -14
  162. package/build-module/components/list-view/use-list-view-drop-zone.js.map +1 -1
  163. package/build-module/components/preview-options/index.js +2 -3
  164. package/build-module/components/preview-options/index.js.map +1 -1
  165. package/build-module/components/spacing-sizes-control/spacing-input-control.js +34 -5
  166. package/build-module/components/spacing-sizes-control/spacing-input-control.js.map +1 -1
  167. package/build-module/components/use-block-drop-zone/index.js +98 -58
  168. package/build-module/components/use-block-drop-zone/index.js.map +1 -1
  169. package/build-module/components/use-on-block-drop/index.js +12 -12
  170. package/build-module/components/use-on-block-drop/index.js.map +1 -1
  171. package/build-module/components/use-on-block-drop/types.js +2 -0
  172. package/build-module/components/use-on-block-drop/types.js.map +1 -0
  173. package/build-module/hooks/align.js +1 -2
  174. package/build-module/hooks/align.js.map +1 -1
  175. package/build-module/hooks/align.native.js +1 -6
  176. package/build-module/hooks/align.native.js.map +1 -1
  177. package/build-module/hooks/font-size.js +59 -1
  178. package/build-module/hooks/font-size.js.map +1 -1
  179. package/build-module/hooks/margin.js +6 -5
  180. package/build-module/hooks/margin.js.map +1 -1
  181. package/build-module/hooks/padding.js +2 -1
  182. package/build-module/hooks/padding.js.map +1 -1
  183. package/build-module/hooks/style.js +124 -3
  184. package/build-module/hooks/style.js.map +1 -1
  185. package/build-module/hooks/use-typography-props.js +17 -4
  186. package/build-module/hooks/use-typography-props.js.map +1 -1
  187. package/build-module/hooks/utils.js +2 -2
  188. package/build-module/hooks/utils.js.map +1 -1
  189. package/build-module/store/actions.js +55 -42
  190. package/build-module/store/actions.js.map +1 -1
  191. package/build-module/store/defaults.js +3 -0
  192. package/build-module/store/defaults.js.map +1 -1
  193. package/build-module/store/reducer.js +32 -16
  194. package/build-module/store/reducer.js.map +1 -1
  195. package/build-module/utils/math.js +12 -0
  196. package/build-module/utils/math.js.map +1 -1
  197. package/build-module/utils/pre-parse-patterns.js +19 -2
  198. package/build-module/utils/pre-parse-patterns.js.map +1 -1
  199. package/build-style/style-rtl.css +243 -144
  200. package/build-style/style.css +243 -144
  201. package/package.json +28 -28
  202. package/src/components/block-breadcrumb/test/index.js +1 -1
  203. package/src/components/block-draggable/draggable-chip.js +4 -2
  204. package/src/components/block-inspector/index.js +8 -7
  205. package/src/components/block-list/block-list-compact.native.js +1 -0
  206. package/src/components/block-list/block.js +111 -7
  207. package/src/components/block-list/block.native.js +123 -9
  208. package/src/components/block-list/style.scss +93 -126
  209. package/src/components/block-list/use-in-between-inserter.js +8 -19
  210. package/src/components/block-lock/modal.js +12 -7
  211. package/src/components/block-mover/style.scss +0 -1
  212. package/src/components/block-parent-selector/index.js +3 -3
  213. package/src/components/block-patterns-list/index.js +9 -5
  214. package/src/components/block-patterns-list/style.scss +7 -3
  215. package/src/components/block-popover/README.md +8 -0
  216. package/src/components/block-popover/drop-zone.js +63 -0
  217. package/src/components/block-popover/index.js +2 -1
  218. package/src/components/block-popover/style.scss +17 -1
  219. package/src/components/block-preview/auto.js +1 -1
  220. package/src/components/block-preview/index.js +7 -8
  221. package/src/components/block-preview/live.js +2 -7
  222. package/src/components/block-preview/test/index.js +1 -7
  223. package/src/components/block-selection-clearer/index.js +7 -2
  224. package/src/components/block-selection-clearer/test/index.js +118 -0
  225. package/src/components/block-settings-menu/block-settings-dropdown.js +25 -11
  226. package/src/components/block-settings-menu/test/block-mode-toggle.js +17 -17
  227. package/src/components/block-styles/index.js +26 -49
  228. package/src/components/block-switcher/test/index.js +2 -2
  229. package/src/components/block-toolbar/index.js +4 -6
  230. package/src/components/block-toolbar/style.scss +38 -14
  231. package/src/components/block-tools/back-compat.js +1 -0
  232. package/src/components/block-tools/insertion-point.js +42 -17
  233. package/src/components/block-tools/selected-block-popover.js +14 -1
  234. package/src/components/button-block-appender/style.scss +4 -2
  235. package/src/components/color-palette/test/__snapshots__/control.js.snap +32 -52
  236. package/src/components/color-palette/test/control.js +11 -15
  237. package/src/components/colors-gradients/control.js +2 -2
  238. package/src/components/colors-gradients/panel-color-gradient-settings.js +3 -4
  239. package/src/components/colors-gradients/test/control.js +49 -77
  240. package/src/components/font-sizes/fluid-utils.js +296 -0
  241. package/src/components/font-sizes/index.js +1 -0
  242. package/src/components/font-sizes/test/fluid-utils.js +168 -0
  243. package/src/components/image-size-control/test/index.js +47 -60
  244. package/src/components/index.js +0 -1
  245. package/src/components/inner-blocks/use-inner-block-template-sync.js +3 -2
  246. package/src/components/inserter/block-patterns-tab.js +232 -98
  247. package/src/components/inserter/menu.js +15 -2
  248. package/src/components/inserter/style.scss +94 -9
  249. package/src/components/inserter/test/reusable-blocks-tab.js +6 -6
  250. package/src/components/inserter-draggable-blocks/index.js +12 -2
  251. package/src/components/inserter-list-item/style.scss +20 -1
  252. package/src/components/link-control/test/index.js +1 -1
  253. package/src/components/list-view/use-list-view-drop-zone.js +4 -18
  254. package/src/components/panel-color-settings/test/index.js +4 -4
  255. package/src/components/preview-options/index.js +2 -2
  256. package/src/components/preview-options/style.scss +1 -1
  257. package/src/components/provider/test/use-block-sync.js +131 -165
  258. package/src/components/responsive-block-control/test/index.js +4 -4
  259. package/src/components/spacing-sizes-control/spacing-input-control.js +16 -2
  260. package/src/components/spacing-sizes-control/style.scss +26 -19
  261. package/src/components/use-block-drop-zone/index.js +136 -79
  262. package/src/components/use-block-drop-zone/test/index.js +333 -81
  263. package/src/components/use-on-block-drop/index.js +11 -12
  264. package/src/components/use-on-block-drop/types.ts +1 -0
  265. package/src/hooks/align.js +3 -2
  266. package/src/hooks/align.native.js +5 -8
  267. package/src/hooks/font-size.js +75 -0
  268. package/src/hooks/margin.js +5 -4
  269. package/src/hooks/padding.js +1 -0
  270. package/src/hooks/style.js +122 -3
  271. package/src/hooks/test/style.js +206 -1
  272. package/src/hooks/test/use-typography-props.js +22 -0
  273. package/src/hooks/use-typography-props.js +18 -3
  274. package/src/hooks/utils.js +6 -2
  275. package/src/store/actions.js +20 -12
  276. package/src/store/defaults.js +3 -0
  277. package/src/store/reducer.js +31 -24
  278. package/src/store/test/actions.js +0 -9
  279. package/src/utils/math.js +17 -0
  280. package/src/utils/pre-parse-patterns.js +12 -7
  281. package/build/components/inserter/pattern-panel.js +0 -87
  282. package/build/components/inserter/pattern-panel.js.map +0 -1
  283. package/build-module/components/inserter/pattern-panel.js +0 -74
  284. package/build-module/components/inserter/pattern-panel.js.map +0 -1
  285. package/src/components/inserter/pattern-panel.js +0 -93
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { Disabled } from '@wordpress/components';
5
4
  import { useResizeObserver, pure, useRefEffect } from '@wordpress/compose';
6
5
  import { useSelect } from '@wordpress/data';
7
6
  import { useMemo } from '@wordpress/element';
7
+ import { Disabled } from '@wordpress/components';
8
8
 
9
9
  /**
10
10
  * Internal dependencies
@@ -32,11 +32,10 @@ export function BlockPreview( {
32
32
  ( select ) => select( blockEditorStore ).getSettings(),
33
33
  []
34
34
  );
35
- const settings = useMemo( () => {
36
- const _settings = { ...originalSettings };
37
- _settings.__experimentalBlockPatterns = [];
38
- return _settings;
39
- }, [ originalSettings ] );
35
+ const settings = useMemo(
36
+ () => ( { ...originalSettings, __unstableIsPreviewMode: true } ),
37
+ [ originalSettings ]
38
+ );
40
39
  const renderedBlocks = useMemo( () => castArray( blocks ), [ blocks ] );
41
40
  if ( ! blocks || blocks.length === 0 ) {
42
41
  return null;
@@ -94,12 +93,12 @@ export function useBlockPreview( {
94
93
  ( select ) => select( blockEditorStore ).getSettings(),
95
94
  []
96
95
  );
97
- const disabledRef = useDisabled();
98
- const ref = useMergeRefs( [ props.ref, disabledRef ] );
99
96
  const settings = useMemo(
100
- () => ( { ...originalSettings, __experimentalBlockPatterns: [] } ),
97
+ () => ( { ...originalSettings, __unstableIsPreviewMode: true } ),
101
98
  [ originalSettings ]
102
99
  );
100
+ const disabledRef = useDisabled();
101
+ const ref = useMergeRefs( [ props.ref, disabledRef ] );
103
102
  const renderedBlocks = useMemo( () => castArray( blocks ), [ blocks ] );
104
103
 
105
104
  const children = (
@@ -1,8 +1,3 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { Disabled } from '@wordpress/components';
5
-
6
1
  /**
7
2
  * Internal dependencies
8
3
  */
@@ -16,9 +11,9 @@ export default function LiveBlockPreview( { onClick } ) {
16
11
  onClick={ onClick }
17
12
  onKeyPress={ onClick }
18
13
  >
19
- <Disabled>
14
+ <div inert="true">
20
15
  <BlockList />
21
- </Disabled>
16
+ </div>
22
17
  </div>
23
18
  );
24
19
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { render, screen, waitFor } from '@testing-library/react';
4
+ import { render, screen } from '@testing-library/react';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -99,12 +99,6 @@ describe( 'useBlockPreview', () => {
99
99
  );
100
100
  expect( previewedBlockContents ).toBeInTheDocument();
101
101
 
102
- // Test elements within block contents are disabled.
103
- await waitFor( () => {
104
- const button = screen.getByText( 'Button' );
105
- expect( button.hasAttribute( 'disabled' ) ).toBe( true );
106
- } );
107
-
108
102
  // Ensure the block preview class names are merged with the component's class name.
109
103
  expect( container.firstChild.className ).toBe(
110
104
  'test-container-classname block-editor-block-preview__live-content components-disabled'
@@ -17,12 +17,17 @@ import { store as blockEditorStore } from '../../store';
17
17
  * @return {import('react').RefCallback} Ref callback.
18
18
  */
19
19
  export function useBlockSelectionClearer() {
20
- const { hasSelectedBlock, hasMultiSelection } =
20
+ const { getSettings, hasSelectedBlock, hasMultiSelection } =
21
21
  useSelect( blockEditorStore );
22
22
  const { clearSelectedBlock } = useDispatch( blockEditorStore );
23
+ const { __experimentalClearBlockSelection: isEnabled } = getSettings();
23
24
 
24
25
  return useRefEffect(
25
26
  ( node ) => {
27
+ if ( ! isEnabled ) {
28
+ return;
29
+ }
30
+
26
31
  function onMouseDown( event ) {
27
32
  if ( ! hasSelectedBlock() && ! hasMultiSelection() ) {
28
33
  return;
@@ -42,7 +47,7 @@ export function useBlockSelectionClearer() {
42
47
  node.removeEventListener( 'mousedown', onMouseDown );
43
48
  };
44
49
  },
45
- [ hasSelectedBlock, hasMultiSelection, clearSelectedBlock ]
50
+ [ hasSelectedBlock, hasMultiSelection, clearSelectedBlock, isEnabled ]
46
51
  );
47
52
  }
48
53
 
@@ -0,0 +1,118 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { fireEvent, render, screen } from '@testing-library/react';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { useDispatch, useSelect } from '@wordpress/data';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import BlockSelectionClearer from '../';
15
+
16
+ const defaultUseSelectValues = {
17
+ hasSelectedBlock: jest.fn().mockReturnValue( false ),
18
+ hasMultiSelection: jest.fn().mockReturnValue( false ),
19
+ getSettings: jest.fn().mockReturnValue( {
20
+ __experimentalClearBlockSelection: true,
21
+ } ),
22
+ };
23
+
24
+ jest.mock( '@wordpress/data/src/components/use-dispatch', () => ( {
25
+ useDispatch: jest.fn(),
26
+ } ) );
27
+
28
+ jest.mock( '@wordpress/data/src/components/use-select', () => {
29
+ // This allows us to tweak the returned value on each test.
30
+ const mock = jest.fn();
31
+ return mock;
32
+ } );
33
+
34
+ describe( 'BlockSelectionClearer component', () => {
35
+ it( 'should clear the selected block when a selected block exists', () => {
36
+ const mockClearSelectedBlock = jest.fn();
37
+ useSelect.mockImplementation( () => ( {
38
+ ...defaultUseSelectValues,
39
+ hasSelectedBlock: jest.fn().mockReturnValue( true ),
40
+ } ) );
41
+ useDispatch.mockImplementation( () => ( {
42
+ clearSelectedBlock: mockClearSelectedBlock,
43
+ } ) );
44
+
45
+ render(
46
+ <BlockSelectionClearer>
47
+ <button>Not a block</button>
48
+ </BlockSelectionClearer>
49
+ );
50
+ const button = screen.getByRole( 'button' );
51
+ fireEvent.mouseDown( button.parentElement );
52
+
53
+ expect( mockClearSelectedBlock ).toBeCalled();
54
+ } );
55
+
56
+ it( 'should clear the selected block when multiple blocks are selected', () => {
57
+ const mockClearSelectedBlock = jest.fn();
58
+ useSelect.mockImplementation( () => ( {
59
+ ...defaultUseSelectValues,
60
+ hasMultiSelection: jest.fn().mockReturnValue( true ),
61
+ } ) );
62
+ useDispatch.mockImplementation( () => ( {
63
+ clearSelectedBlock: mockClearSelectedBlock,
64
+ } ) );
65
+
66
+ render(
67
+ <BlockSelectionClearer>
68
+ <button>Not a block</button>
69
+ </BlockSelectionClearer>
70
+ );
71
+ const button = screen.getByRole( 'button' );
72
+ fireEvent.mouseDown( button.parentElement );
73
+
74
+ expect( mockClearSelectedBlock ).toBeCalled();
75
+ } );
76
+
77
+ it( 'should not clear the block selection when no blocks are selected', () => {
78
+ const mockClearSelectedBlock = jest.fn();
79
+ useSelect.mockImplementation( () => defaultUseSelectValues );
80
+ useDispatch.mockImplementation( () => ( {
81
+ clearSelectedBlock: mockClearSelectedBlock,
82
+ } ) );
83
+
84
+ render(
85
+ <BlockSelectionClearer>
86
+ <button>Not a block</button>
87
+ </BlockSelectionClearer>
88
+ );
89
+ const button = screen.getByRole( 'button' );
90
+ fireEvent.mouseDown( button.parentElement );
91
+
92
+ expect( mockClearSelectedBlock ).not.toBeCalled();
93
+ } );
94
+
95
+ it( 'should not clear the block selection when the feature is disabled', () => {
96
+ const mockClearSelectedBlock = jest.fn();
97
+ useSelect.mockImplementation( () => ( {
98
+ ...defaultUseSelectValues,
99
+ hasSelectedBlock: jest.fn().mockReturnValue( true ),
100
+ getSettings: jest.fn().mockReturnValue( {
101
+ __experimentalClearBlockSelection: false,
102
+ } ),
103
+ } ) );
104
+ useDispatch.mockImplementation( () => ( {
105
+ clearSelectedBlock: mockClearSelectedBlock,
106
+ } ) );
107
+
108
+ render(
109
+ <BlockSelectionClearer>
110
+ <button>Not a block</button>
111
+ </BlockSelectionClearer>
112
+ );
113
+ const button = screen.getByRole( 'button' );
114
+ fireEvent.mouseDown( button.parentElement );
115
+
116
+ expect( mockClearSelectedBlock ).not.toBeCalled();
117
+ } );
118
+ } );
@@ -6,7 +6,11 @@ import { castArray } from 'lodash';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
- import { getBlockType, serialize } from '@wordpress/blocks';
9
+ import {
10
+ getBlockType,
11
+ serialize,
12
+ store as blocksStore,
13
+ } from '@wordpress/blocks';
10
14
  import { DropdownMenu, MenuGroup, MenuItem } from '@wordpress/components';
11
15
  import { useDispatch, useSelect } from '@wordpress/data';
12
16
  import { moreVertical } from '@wordpress/icons';
@@ -59,7 +63,7 @@ export function BlockSettingsDropdown( {
59
63
  const firstBlockClientId = blockClientIds[ 0 ];
60
64
  const {
61
65
  firstParentClientId,
62
- hasReducedUI,
66
+ isDistractionFree,
63
67
  onlyBlock,
64
68
  parentBlockType,
65
69
  previousBlockClientId,
@@ -70,22 +74,32 @@ export function BlockSettingsDropdown( {
70
74
  const {
71
75
  getBlockCount,
72
76
  getBlockName,
73
- getBlockParents,
77
+ getBlockRootClientId,
74
78
  getPreviousBlockClientId,
75
79
  getNextBlockClientId,
76
80
  getSelectedBlockClientIds,
77
81
  getSettings,
82
+ getBlockAttributes,
78
83
  } = select( blockEditorStore );
79
84
 
80
- const parents = getBlockParents( firstBlockClientId );
81
- const _firstParentClientId = parents[ parents.length - 1 ];
82
- const parentBlockName = getBlockName( _firstParentClientId );
85
+ const { getActiveBlockVariation } = select( blocksStore );
86
+
87
+ const _firstParentClientId =
88
+ getBlockRootClientId( firstBlockClientId );
89
+ const parentBlockName =
90
+ _firstParentClientId && getBlockName( _firstParentClientId );
83
91
 
84
92
  return {
85
93
  firstParentClientId: _firstParentClientId,
86
- hasReducedUI: getSettings().hasReducedUI,
87
- onlyBlock: 1 === getBlockCount(),
88
- parentBlockType: getBlockType( parentBlockName ),
94
+ isDistractionFree: getSettings().isDistractionFree,
95
+ onlyBlock: 1 === getBlockCount( _firstParentClientId ),
96
+ parentBlockType:
97
+ _firstParentClientId &&
98
+ ( getActiveBlockVariation(
99
+ parentBlockName,
100
+ getBlockAttributes( _firstParentClientId )
101
+ ) ||
102
+ getBlockType( parentBlockName ) ),
89
103
  previousBlockClientId:
90
104
  getPreviousBlockClientId( firstBlockClientId ),
91
105
  nextBlockClientId: getNextBlockClientId( firstBlockClientId ),
@@ -171,7 +185,7 @@ export function BlockSettingsDropdown( {
171
185
  const { gestures: showParentOutlineGestures } = useShowMoversGestures( {
172
186
  ref: selectParentButtonRef,
173
187
  onChange( isFocused ) {
174
- if ( isFocused && hasReducedUI ) {
188
+ if ( isFocused && isDistractionFree ) {
175
189
  return;
176
190
  }
177
191
  toggleBlockHighlight( firstParentClientId, isFocused );
@@ -210,7 +224,7 @@ export function BlockSettingsDropdown( {
210
224
  <__unstableBlockSettingsMenuFirstItem.Slot
211
225
  fillProps={ { onClose } }
212
226
  />
213
- { firstParentClientId !== undefined && (
227
+ { !! firstParentClientId && (
214
228
  <MenuItem
215
229
  { ...showParentOutlineGestures }
216
230
  ref={ selectParentButtonRef }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import ShallowRenderer from 'react-test-renderer/shallow';
4
+ import { render, screen } from '@testing-library/react';
5
5
 
6
6
  /**
7
7
  * Internal dependencies
@@ -9,46 +9,44 @@ import ShallowRenderer from 'react-test-renderer/shallow';
9
9
  import { BlockModeToggle } from '../block-mode-toggle';
10
10
 
11
11
  describe( 'BlockModeToggle', () => {
12
- function getShallowRenderOutput( element ) {
13
- const renderer = new ShallowRenderer();
14
- renderer.render( element );
15
- return renderer.getRenderOutput();
16
- }
17
-
18
12
  it( "should not render the HTML mode button if the block doesn't support it", () => {
19
- const wrapper = getShallowRenderOutput(
13
+ render(
20
14
  <BlockModeToggle blockType={ { supports: { html: false } } } />
21
15
  );
22
16
 
23
- expect( wrapper ).toBe( null );
17
+ expect(
18
+ screen.queryByRole( 'menuitem', { name: 'Edit as HTML' } )
19
+ ).not.toBeInTheDocument();
24
20
  } );
25
21
 
26
22
  it( 'should render the HTML mode button', () => {
27
- const wrapper = getShallowRenderOutput(
23
+ render(
28
24
  <BlockModeToggle
29
25
  blockType={ { supports: { html: true } } }
30
26
  mode="visual"
31
27
  />
32
28
  );
33
- const text = wrapper.props.children;
34
29
 
35
- expect( text ).toEqual( 'Edit as HTML' );
30
+ expect(
31
+ screen.getByRole( 'menuitem', { name: 'Edit as HTML' } )
32
+ ).toBeVisible();
36
33
  } );
37
34
 
38
35
  it( 'should render the Visual mode button', () => {
39
- const wrapper = getShallowRenderOutput(
36
+ render(
40
37
  <BlockModeToggle
41
38
  blockType={ { supports: { html: true } } }
42
39
  mode="html"
43
40
  />
44
41
  );
45
- const text = wrapper.props.children;
46
42
 
47
- expect( text ).toEqual( 'Edit visually' );
43
+ expect(
44
+ screen.getByRole( 'menuitem', { name: 'Edit visually' } )
45
+ ).toBeVisible();
48
46
  } );
49
47
 
50
48
  it( 'should not render the Visual mode button if code editing is disabled', () => {
51
- const wrapper = getShallowRenderOutput(
49
+ render(
52
50
  <BlockModeToggle
53
51
  blockType={ { supports: { html: true } } }
54
52
  mode="html"
@@ -56,6 +54,8 @@ describe( 'BlockModeToggle', () => {
56
54
  />
57
55
  );
58
56
 
59
- expect( wrapper ).toBe( null );
57
+ expect(
58
+ screen.queryByRole( 'menuitem', { name: 'Edit visually' } )
59
+ ).not.toBeInTheDocument();
60
60
  } );
61
61
  } );
@@ -6,14 +6,14 @@ import classnames from 'classnames';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
- import { useState, useLayoutEffect } from '@wordpress/element';
9
+ import { useState } from '@wordpress/element';
10
10
  import { debounce, useViewportMatch } from '@wordpress/compose';
11
11
  import {
12
12
  Button,
13
13
  __experimentalTruncate as Truncate,
14
- Slot,
15
- Fill,
14
+ Popover,
16
15
  } from '@wordpress/components';
16
+ import deprecated from '@wordpress/deprecated';
17
17
 
18
18
  /**
19
19
  * Internal dependencies
@@ -21,32 +21,10 @@ import {
21
21
  import BlockStylesPreviewPanel from './preview-panel';
22
22
  import useStylesForBlocks from './use-styles-for-block';
23
23
 
24
- function BlockStylesPreviewPanelSlot( { scope } ) {
25
- return <Slot name={ `BlockStylesPreviewPanel/${ scope }` } />;
26
- }
27
-
28
- function BlockStylesPreviewPanelFill( { children, scope, ...props } ) {
29
- return (
30
- <Fill name={ `BlockStylesPreviewPanel/${ scope }` }>
31
- <div { ...props }>{ children }</div>
32
- </Fill>
33
- );
34
- }
35
-
36
- // Top position (in px) of the Block Styles container
37
- // relative to the editor pane.
38
- // The value is the equivalent of the container's right position.
39
- const DEFAULT_POSITION_TOP = 16;
40
-
41
24
  const noop = () => {};
42
25
 
43
26
  // Block Styles component for the Settings Sidebar.
44
- function BlockStyles( {
45
- clientId,
46
- onSwitch = noop,
47
- onHoverClassName = noop,
48
- scope,
49
- } ) {
27
+ function BlockStyles( { clientId, onSwitch = noop, onHoverClassName = noop } ) {
50
28
  const {
51
29
  onSelect,
52
30
  stylesToRender,
@@ -58,17 +36,8 @@ function BlockStyles( {
58
36
  onSwitch,
59
37
  } );
60
38
  const [ hoveredStyle, setHoveredStyle ] = useState( null );
61
- const [ containerScrollTop, setContainerScrollTop ] = useState( 0 );
62
39
  const isMobileViewport = useViewportMatch( 'medium', '<' );
63
40
 
64
- useLayoutEffect( () => {
65
- const scrollContainer = document.querySelector(
66
- '.interface-interface-skeleton__content'
67
- );
68
- const scrollTop = scrollContainer?.scrollTop || 0;
69
- setContainerScrollTop( scrollTop + DEFAULT_POSITION_TOP );
70
- }, [ hoveredStyle ] );
71
-
72
41
  if ( ! stylesToRender || stylesToRender.length === 0 ) {
73
42
  return null;
74
43
  }
@@ -127,23 +96,31 @@ function BlockStyles( {
127
96
  } ) }
128
97
  </div>
129
98
  { hoveredStyle && ! isMobileViewport && (
130
- <BlockStylesPreviewPanelFill
131
- scope={ scope }
132
- className="block-editor-block-styles__preview-panel"
133
- style={ { top: containerScrollTop } }
134
- onMouseLeave={ () => styleItemHandler( null ) }
135
- >
136
- <BlockStylesPreviewPanel
137
- activeStyle={ activeStyle }
138
- className={ previewClassName }
139
- genericPreviewBlock={ genericPreviewBlock }
140
- style={ hoveredStyle }
141
- />
142
- </BlockStylesPreviewPanelFill>
99
+ <Popover placement="left-start" offset={ 20 }>
100
+ <div
101
+ className="block-editor-block-styles__preview-panel"
102
+ onMouseLeave={ () => styleItemHandler( null ) }
103
+ >
104
+ <BlockStylesPreviewPanel
105
+ activeStyle={ activeStyle }
106
+ className={ previewClassName }
107
+ genericPreviewBlock={ genericPreviewBlock }
108
+ style={ hoveredStyle }
109
+ />
110
+ </div>
111
+ </Popover>
143
112
  ) }
144
113
  </div>
145
114
  );
146
115
  }
147
116
 
148
- BlockStyles.Slot = BlockStylesPreviewPanelSlot;
149
117
  export default BlockStyles;
118
+
119
+ BlockStyles.Slot = () => {
120
+ deprecated( 'BlockStyles.Slot', {
121
+ version: '6.4',
122
+ since: '6.2',
123
+ } );
124
+
125
+ return null;
126
+ };
@@ -288,8 +288,8 @@ describe( 'BlockSwitcherDropdownMenu', () => {
288
288
  screen.getByRole( 'menu', {
289
289
  name: 'Block Name',
290
290
  } )
291
- ).getAllByRole( 'menuitem' )
292
- ).toHaveLength( 1 );
291
+ ).getByRole( 'menuitem' )
292
+ ).toBeInTheDocument();
293
293
  } );
294
294
  } );
295
295
  } );
@@ -34,7 +34,7 @@ const BlockToolbar = ( { hideDragHandle } ) => {
34
34
  blockClientId,
35
35
  blockType,
36
36
  hasFixedToolbar,
37
- hasReducedUI,
37
+ isDistractionFree,
38
38
  isValid,
39
39
  isVisual,
40
40
  isContentLocked,
@@ -60,7 +60,7 @@ const BlockToolbar = ( { hideDragHandle } ) => {
60
60
  selectedBlockClientId &&
61
61
  getBlockType( getBlockName( selectedBlockClientId ) ),
62
62
  hasFixedToolbar: settings.hasFixedToolbar,
63
- hasReducedUI: settings.hasReducedUI,
63
+ isDistractionFree: settings.isDistractionFree,
64
64
  rootClientId: blockRootClientId,
65
65
  isValid: selectedBlockClientIds.every( ( id ) =>
66
66
  isBlockValid( id )
@@ -82,7 +82,7 @@ const BlockToolbar = ( { hideDragHandle } ) => {
82
82
  {
83
83
  ref: nodeRef,
84
84
  onChange( isFocused ) {
85
- if ( isFocused && hasReducedUI ) {
85
+ if ( isFocused && isDistractionFree ) {
86
86
  return;
87
87
  }
88
88
  toggleBlockHighlight( blockClientId, isFocused );
@@ -132,9 +132,7 @@ const BlockToolbar = ( { hideDragHandle } ) => {
132
132
  ) }
133
133
  <BlockMover
134
134
  clientIds={ blockClientIds }
135
- hideDragHandle={
136
- hideDragHandle || hasReducedUI
137
- }
135
+ hideDragHandle={ hideDragHandle }
138
136
  />
139
137
  </ToolbarGroup>
140
138
  ) }
@@ -137,15 +137,6 @@
137
137
  padding-right: 6px;
138
138
  }
139
139
 
140
- // Switcher overrides.
141
- .block-editor-block-switcher {
142
- border-right: 1px solid $gray-900;
143
-
144
- .components-dropdown-menu__toggle {
145
- margin-left: 0;
146
- }
147
- }
148
-
149
140
  .block-editor-block-switcher .components-dropdown-menu__toggle,
150
141
  .block-editor-block-switcher__no-switcher-icon {
151
142
  .block-editor-block-icon {
@@ -162,12 +153,22 @@
162
153
  }
163
154
  }
164
155
 
156
+ .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container {
157
+ width: auto;
158
+ }
159
+
165
160
  // Mover overrides.
166
161
  .block-editor-block-toolbar__block-controls .block-editor-block-mover {
167
- margin-left: 0;
162
+ border-left: 1px solid $gray-900;
163
+ margin-left: 6px;
164
+ margin-right: -6px;
168
165
  white-space: nowrap;
169
166
  }
170
167
 
168
+ .block-editor-block-contextual-toolbar.is-fixed .block-editor-block-toolbar__block-controls .block-editor-block-mover {
169
+ border-left-color: $gray-200;
170
+ }
171
+
171
172
  .block-editor-block-mover-button {
172
173
  // The specificity can be reduced once https://github.com/WordPress/gutenberg/blob/try/block-toolbar-labels/packages/block-editor/src/components/block-mover/style.scss#L34 is also dealt with.
173
174
  padding-left: $grid-unit !important;
@@ -175,17 +176,40 @@
175
176
  }
176
177
 
177
178
  .block-editor-block-mover__drag-handle.has-icon {
178
- padding-left: 6px !important;
179
- padding-right: 6px !important;
180
- border-right: 1px solid $gray-900;
179
+ padding-left: 12px !important;
180
+ padding-right: 12px !important;
181
+ }
182
+
183
+ .block-editor-block-contextual-toolbar.is-fixed .block-editor-block-mover__move-button-container {
184
+ border-width: 0;
181
185
  }
182
186
 
183
187
  @include break-small() {
184
188
  // Specificity override for https://github.com/WordPress/gutenberg/blob/try/block-toolbar-labels/packages/block-editor/src/components/block-mover/style.scss#L69
185
189
  .is-up-button.is-up-button.is-up-button {
186
- border-bottom: 1px solid $gray-900;
187
190
  margin-right: 0;
188
191
  border-radius: 0;
192
+ order: 1;
193
+ }
194
+
195
+ .block-editor-block-mover__move-button-container {
196
+ border-left: 1px solid $gray-900;
197
+
198
+ &::before {
199
+ content: "";
200
+ display: block;
201
+ height: 1px;
202
+ background: $gray-900;
203
+ order: 2;
204
+ }
205
+ }
206
+
207
+ .is-down-button.is-down-button.is-down-button {
208
+ order: 3;
209
+ }
210
+
211
+ .block-editor-block-contextual-toolbar.is-fixed .block-editor-block-mover__move-button-container::before {
212
+ background: $gray-300;
189
213
  }
190
214
  }
191
215
 
@@ -23,6 +23,7 @@ export default function BlockToolsBackCompat( { children } ) {
23
23
  deprecated( 'wp.components.Popover.Slot name="block-toolbar"', {
24
24
  alternative: 'wp.blockEditor.BlockTools',
25
25
  since: '5.8',
26
+ version: '6.3',
26
27
  } );
27
28
 
28
29
  return (