@wordpress/block-editor 15.11.1-next.v.0 → 15.12.1-next.v.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 (201) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-breadcrumb/index.cjs +10 -2
  3. package/build/components/block-breadcrumb/index.cjs.map +2 -2
  4. package/build/components/block-inspector/index.cjs +11 -11
  5. package/build/components/block-inspector/index.cjs.map +3 -3
  6. package/build/components/block-list/block.cjs +6 -3
  7. package/build/components/block-list/block.cjs.map +3 -3
  8. package/build/components/block-list/index.cjs +26 -18
  9. package/build/components/block-list/index.cjs.map +2 -2
  10. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs +2 -6
  11. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs.map +2 -2
  12. package/build/components/block-list/use-in-between-inserter.cjs +4 -4
  13. package/build/components/block-list/use-in-between-inserter.cjs.map +2 -2
  14. package/build/components/block-settings-menu/block-settings-dropdown.cjs +10 -7
  15. package/build/components/block-settings-menu/block-settings-dropdown.cjs.map +2 -2
  16. package/build/components/block-settings-menu-controls/edit-section-menu-item.cjs +1 -1
  17. package/build/components/block-settings-menu-controls/edit-section-menu-item.cjs.map +2 -2
  18. package/build/components/block-settings-menu-controls/index.cjs +10 -15
  19. package/build/components/block-settings-menu-controls/index.cjs.map +2 -2
  20. package/build/components/block-toolbar/block-toolbar-icon.cjs +6 -4
  21. package/build/components/block-toolbar/block-toolbar-icon.cjs.map +2 -2
  22. package/build/components/block-toolbar/index.cjs +1 -1
  23. package/build/components/block-toolbar/index.cjs.map +2 -2
  24. package/build/components/block-variation-transforms/index.cjs +1 -2
  25. package/build/components/block-variation-transforms/index.cjs.map +2 -2
  26. package/build/components/block-visibility/modal.cjs +5 -92
  27. package/build/components/block-visibility/modal.cjs.map +2 -2
  28. package/build/components/inserter/index.cjs +1 -0
  29. package/build/components/inserter/index.cjs.map +2 -2
  30. package/build/components/inspector-controls/last-item.cjs +41 -0
  31. package/build/components/inspector-controls/last-item.cjs.map +7 -0
  32. package/build/components/inspector-controls-tabs/index.cjs +2 -2
  33. package/build/components/inspector-controls-tabs/index.cjs.map +3 -3
  34. package/build/components/inspector-controls-tabs/styles-tab.cjs +4 -4
  35. package/build/components/inspector-controls-tabs/styles-tab.cjs.map +2 -2
  36. package/build/components/media-replace-flow/index.cjs +2 -2
  37. package/build/components/media-replace-flow/index.cjs.map +2 -2
  38. package/build/components/rich-text/index.cjs +1 -1
  39. package/build/components/rich-text/index.cjs.map +2 -2
  40. package/build/components/use-block-display-information/index.cjs +1 -1
  41. package/build/components/use-block-display-information/index.cjs.map +2 -2
  42. package/build/components/writing-flow/index.cjs +2 -0
  43. package/build/components/writing-flow/index.cjs.map +2 -2
  44. package/build/components/writing-flow/use-arrow-nav.cjs +3 -0
  45. package/build/components/writing-flow/use-arrow-nav.cjs.map +2 -2
  46. package/build/components/writing-flow/use-drag-selection.cjs +2 -1
  47. package/build/components/writing-flow/use-drag-selection.cjs.map +2 -2
  48. package/build/components/writing-flow/use-preview-mode-nav.cjs +92 -0
  49. package/build/components/writing-flow/use-preview-mode-nav.cjs.map +7 -0
  50. package/build/hooks/anchor.cjs +1 -1
  51. package/build/hooks/anchor.cjs.map +1 -1
  52. package/build/hooks/block-renaming.cjs +1 -1
  53. package/build/hooks/block-renaming.cjs.map +2 -2
  54. package/build/hooks/custom-css.cjs +1 -1
  55. package/build/hooks/custom-css.cjs.map +2 -2
  56. package/build/hooks/grid-visualizer.cjs +42 -5
  57. package/build/hooks/grid-visualizer.cjs.map +3 -3
  58. package/build/hooks/index.cjs +0 -2
  59. package/build/hooks/index.cjs.map +3 -3
  60. package/build/hooks/layout-child.cjs +41 -5
  61. package/build/hooks/layout-child.cjs.map +3 -3
  62. package/build/private-apis.cjs +2 -0
  63. package/build/private-apis.cjs.map +3 -3
  64. package/build/store/actions.cjs +5 -0
  65. package/build/store/actions.cjs.map +2 -2
  66. package/build/store/private-selectors.cjs +1 -1
  67. package/build/store/private-selectors.cjs.map +2 -2
  68. package/build/store/reducer.cjs +5 -7
  69. package/build/store/reducer.cjs.map +2 -2
  70. package/build/store/selectors.cjs +15 -0
  71. package/build/store/selectors.cjs.map +2 -2
  72. package/build/utils/fit-text-utils.cjs +17 -7
  73. package/build/utils/fit-text-utils.cjs.map +2 -2
  74. package/build-module/components/block-breadcrumb/index.mjs +10 -2
  75. package/build-module/components/block-breadcrumb/index.mjs.map +2 -2
  76. package/build-module/components/block-inspector/index.mjs +12 -11
  77. package/build-module/components/block-inspector/index.mjs.map +2 -2
  78. package/build-module/components/block-list/block.mjs +6 -3
  79. package/build-module/components/block-list/block.mjs.map +3 -3
  80. package/build-module/components/block-list/index.mjs +26 -18
  81. package/build-module/components/block-list/index.mjs.map +2 -2
  82. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs +2 -6
  83. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs.map +2 -2
  84. package/build-module/components/block-list/use-in-between-inserter.mjs +4 -4
  85. package/build-module/components/block-list/use-in-between-inserter.mjs.map +2 -2
  86. package/build-module/components/block-settings-menu/block-settings-dropdown.mjs +10 -7
  87. package/build-module/components/block-settings-menu/block-settings-dropdown.mjs.map +2 -2
  88. package/build-module/components/block-settings-menu-controls/edit-section-menu-item.mjs +1 -1
  89. package/build-module/components/block-settings-menu-controls/edit-section-menu-item.mjs.map +2 -2
  90. package/build-module/components/block-settings-menu-controls/index.mjs +10 -15
  91. package/build-module/components/block-settings-menu-controls/index.mjs.map +2 -2
  92. package/build-module/components/block-toolbar/block-toolbar-icon.mjs +6 -4
  93. package/build-module/components/block-toolbar/block-toolbar-icon.mjs.map +2 -2
  94. package/build-module/components/block-toolbar/index.mjs +1 -1
  95. package/build-module/components/block-toolbar/index.mjs.map +2 -2
  96. package/build-module/components/block-variation-transforms/index.mjs +1 -2
  97. package/build-module/components/block-variation-transforms/index.mjs.map +2 -2
  98. package/build-module/components/block-visibility/modal.mjs +5 -92
  99. package/build-module/components/block-visibility/modal.mjs.map +2 -2
  100. package/build-module/components/inserter/index.mjs +1 -0
  101. package/build-module/components/inserter/index.mjs.map +2 -2
  102. package/build-module/components/inspector-controls/last-item.mjs +23 -0
  103. package/build-module/components/inspector-controls/last-item.mjs.map +7 -0
  104. package/build-module/components/inspector-controls-tabs/index.mjs +2 -2
  105. package/build-module/components/inspector-controls-tabs/index.mjs.map +2 -2
  106. package/build-module/components/inspector-controls-tabs/styles-tab.mjs +4 -4
  107. package/build-module/components/inspector-controls-tabs/styles-tab.mjs.map +2 -2
  108. package/build-module/components/media-replace-flow/index.mjs +2 -2
  109. package/build-module/components/media-replace-flow/index.mjs.map +2 -2
  110. package/build-module/components/rich-text/index.mjs +1 -1
  111. package/build-module/components/rich-text/index.mjs.map +2 -2
  112. package/build-module/components/use-block-display-information/index.mjs +1 -1
  113. package/build-module/components/use-block-display-information/index.mjs.map +2 -2
  114. package/build-module/components/writing-flow/index.mjs +2 -0
  115. package/build-module/components/writing-flow/index.mjs.map +2 -2
  116. package/build-module/components/writing-flow/use-arrow-nav.mjs +3 -0
  117. package/build-module/components/writing-flow/use-arrow-nav.mjs.map +2 -2
  118. package/build-module/components/writing-flow/use-drag-selection.mjs +2 -1
  119. package/build-module/components/writing-flow/use-drag-selection.mjs.map +2 -2
  120. package/build-module/components/writing-flow/use-preview-mode-nav.mjs +67 -0
  121. package/build-module/components/writing-flow/use-preview-mode-nav.mjs.map +7 -0
  122. package/build-module/hooks/anchor.mjs +1 -1
  123. package/build-module/hooks/anchor.mjs.map +1 -1
  124. package/build-module/hooks/block-renaming.mjs +1 -1
  125. package/build-module/hooks/block-renaming.mjs.map +2 -2
  126. package/build-module/hooks/custom-css.mjs +1 -1
  127. package/build-module/hooks/custom-css.mjs.map +2 -2
  128. package/build-module/hooks/grid-visualizer.mjs +20 -5
  129. package/build-module/hooks/grid-visualizer.mjs.map +2 -2
  130. package/build-module/hooks/index.mjs +0 -2
  131. package/build-module/hooks/index.mjs.map +2 -2
  132. package/build-module/hooks/layout-child.mjs +31 -5
  133. package/build-module/hooks/layout-child.mjs.map +2 -2
  134. package/build-module/private-apis.mjs +2 -0
  135. package/build-module/private-apis.mjs.map +2 -2
  136. package/build-module/store/actions.mjs +5 -0
  137. package/build-module/store/actions.mjs.map +2 -2
  138. package/build-module/store/private-selectors.mjs +1 -1
  139. package/build-module/store/private-selectors.mjs.map +2 -2
  140. package/build-module/store/reducer.mjs +5 -7
  141. package/build-module/store/reducer.mjs.map +2 -2
  142. package/build-module/store/selectors.mjs +15 -0
  143. package/build-module/store/selectors.mjs.map +2 -2
  144. package/build-module/utils/fit-text-utils.mjs +17 -7
  145. package/build-module/utils/fit-text-utils.mjs.map +2 -2
  146. package/build-style/content-rtl.css +10 -0
  147. package/build-style/content.css +10 -0
  148. package/package.json +39 -39
  149. package/src/components/block-breadcrumb/index.js +6 -1
  150. package/src/components/block-inspector/index.js +20 -21
  151. package/src/components/block-list/block.js +5 -2
  152. package/src/components/block-list/content.scss +11 -0
  153. package/src/components/block-list/index.js +25 -17
  154. package/src/components/block-list/use-block-props/use-selected-block-event-handlers.js +2 -7
  155. package/src/components/block-list/use-in-between-inserter.js +8 -6
  156. package/src/components/block-settings-menu/block-settings-dropdown.js +11 -6
  157. package/src/components/block-settings-menu-controls/edit-section-menu-item.js +1 -7
  158. package/src/components/block-settings-menu-controls/index.js +14 -16
  159. package/src/components/block-toolbar/block-toolbar-icon.js +6 -10
  160. package/src/components/block-toolbar/index.js +1 -7
  161. package/src/components/block-variation-transforms/index.js +1 -4
  162. package/src/components/inserter/index.js +1 -0
  163. package/src/components/inserter/stories/index.story.jsx +31 -24
  164. package/src/components/inspector-controls/last-item.js +29 -0
  165. package/src/components/inspector-controls-tabs/index.js +1 -1
  166. package/src/components/inspector-controls-tabs/styles-tab.js +10 -11
  167. package/src/components/media-replace-flow/index.js +3 -3
  168. package/src/components/rich-text/index.js +1 -1
  169. package/src/components/use-block-display-information/index.js +1 -5
  170. package/src/components/writing-flow/index.js +2 -0
  171. package/src/components/writing-flow/use-arrow-nav.js +5 -0
  172. package/src/components/writing-flow/use-drag-selection.js +7 -1
  173. package/src/components/writing-flow/use-preview-mode-nav.js +102 -0
  174. package/src/hooks/anchor.js +1 -1
  175. package/src/hooks/block-renaming.js +5 -2
  176. package/src/hooks/custom-css.js +1 -1
  177. package/src/hooks/grid-visualizer.js +23 -4
  178. package/src/hooks/index.js +0 -2
  179. package/src/hooks/layout-child.js +39 -3
  180. package/src/private-apis.js +2 -0
  181. package/src/store/actions.js +7 -0
  182. package/src/store/private-selectors.js +0 -1
  183. package/src/store/reducer.js +11 -18
  184. package/src/store/selectors.js +25 -0
  185. package/src/store/test/reducer.js +258 -266
  186. package/src/utils/fit-text-utils.js +24 -8
  187. package/build/components/content-lock/index.cjs +0 -31
  188. package/build/components/content-lock/index.cjs.map +0 -7
  189. package/build/components/content-lock/modify-content-lock-menu-item.cjs +0 -70
  190. package/build/components/content-lock/modify-content-lock-menu-item.cjs.map +0 -7
  191. package/build/hooks/content-lock-ui.cjs +0 -68
  192. package/build/hooks/content-lock-ui.cjs.map +0 -7
  193. package/build-module/components/content-lock/index.mjs +0 -6
  194. package/build-module/components/content-lock/index.mjs.map +0 -7
  195. package/build-module/components/content-lock/modify-content-lock-menu-item.mjs +0 -45
  196. package/build-module/components/content-lock/modify-content-lock-menu-item.mjs.map +0 -7
  197. package/build-module/hooks/content-lock-ui.mjs +0 -47
  198. package/build-module/hooks/content-lock-ui.mjs.map +0 -7
  199. package/src/components/content-lock/index.js +0 -1
  200. package/src/components/content-lock/modify-content-lock-menu-item.js +0 -67
  201. package/src/hooks/content-lock-ui.js +0 -76
@@ -27,6 +27,7 @@ function getBlockIconVariant( { select, clientIds } ) {
27
27
  canRemoveBlocks,
28
28
  getTemplateLock,
29
29
  getBlockEditingMode,
30
+ canEditBlock,
30
31
  } = unlock( select( blockEditorStore ) );
31
32
  const { getBlockStyles } = select( blocksStore );
32
33
 
@@ -53,17 +54,16 @@ function getBlockIconVariant( { select, clientIds } ) {
53
54
  0
54
55
  );
55
56
  const canRemove = canRemoveBlocks( clientIds );
56
-
57
+ const canEdit = clientIds.every( ( clientId ) => canEditBlock( clientId ) );
57
58
  const isDefaultEditingMode =
58
59
  getBlockEditingMode( clientIds[ 0 ] ) === 'default';
59
- const _hideTransformsForSections =
60
- window?.__experimentalContentOnlyPatternInsertion &&
61
- hasPatternNameInSelection;
60
+ const _hideTransformsForSections = hasPatternNameInSelection;
62
61
  const _showBlockSwitcher =
63
62
  ! _hideTransformsForSections &&
64
63
  isDefaultEditingMode &&
65
64
  ( hasBlockStyles || canRemove ) &&
66
- ! hasTemplateLock;
65
+ ! hasTemplateLock &&
66
+ canEdit;
67
67
 
68
68
  const _showPatternOverrides = hasPatternOverrides && hasParentPattern;
69
69
 
@@ -84,11 +84,7 @@ function getBlockIcon( { select, clientIds } ) {
84
84
  const _isSingleBlock = clientIds.length === 1;
85
85
  const firstClientId = clientIds[ 0 ];
86
86
  const blockAttributes = getBlockAttributes( firstClientId );
87
- if (
88
- _isSingleBlock &&
89
- blockAttributes?.metadata?.patternName &&
90
- window?.__experimentalContentOnlyPatternInsertion
91
- ) {
87
+ if ( _isSingleBlock && blockAttributes?.metadata?.patternName ) {
92
88
  return symbol;
93
89
  }
94
90
 
@@ -116,14 +116,8 @@ export function PrivateBlockToolbar( {
116
116
  );
117
117
 
118
118
  const _isZoomOut = isZoomOut();
119
-
120
119
  const _isSectionBlock = isSectionBlock( selectedBlockClientId );
121
-
122
- // The switch style button appears more prominently with the
123
- // content only pattern experiment.
124
- const _showSwitchSectionStyleButton =
125
- window?.__experimentalContentOnlyPatternInsertion &&
126
- ( _isZoomOut || _isSectionBlock );
120
+ const _showSwitchSectionStyleButton = _isZoomOut || _isSectionBlock;
127
121
 
128
122
  return {
129
123
  blockClientId: selectedBlockClientId,
@@ -205,10 +205,7 @@ function __experimentalBlockVariationTransforms( { blockClientId } ) {
205
205
  } );
206
206
  };
207
207
 
208
- const hideVariationsForSections =
209
- window?.__experimentalContentOnlyPatternInsertion && isSection;
210
-
211
- if ( ! variations?.length || isContentOnly || hideVariationsForSections ) {
208
+ if ( ! variations?.length || isContentOnly || isSection ) {
212
209
  return null;
213
210
  }
214
211
 
@@ -176,6 +176,7 @@ class Inserter extends Component {
176
176
  onSelect={ () => {
177
177
  onClose();
178
178
  } }
179
+ onClose={ onClose }
179
180
  rootClientId={ rootClientId }
180
181
  clientId={ clientId }
181
182
  isAppender={ isAppender }
@@ -1,3 +1,8 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { registerCoreBlocks } from '@wordpress/block-library';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
@@ -8,13 +13,17 @@ import Inserter from '../';
8
13
 
9
14
  export default { title: 'BlockEditor/Inserter' };
10
15
 
16
+ // For the purpose of this story, we need to register the core blocks samples.
17
+ registerCoreBlocks();
18
+
19
+ const wrapperStyle = {
20
+ margin: '24px',
21
+ height: 400,
22
+ border: '1px solid #f3f3f3',
23
+ display: 'inline-block',
24
+ };
25
+
11
26
  export const LibraryWithoutPatterns = () => {
12
- const wrapperStyle = {
13
- margin: '24px',
14
- height: 400,
15
- border: '1px solid #f3f3f3',
16
- display: 'inline-block',
17
- };
18
27
  return (
19
28
  <ExperimentalBlockEditorProvider>
20
29
  <div style={ wrapperStyle }>
@@ -25,12 +34,6 @@ export const LibraryWithoutPatterns = () => {
25
34
  };
26
35
 
27
36
  export const LibraryWithPatterns = () => {
28
- const wrapperStyle = {
29
- margin: '24px',
30
- height: 400,
31
- border: '1px solid #f3f3f3',
32
- display: 'inline-block',
33
- };
34
37
  return (
35
38
  <ExperimentalBlockEditorProvider
36
39
  settings={ {
@@ -46,12 +49,6 @@ export const LibraryWithPatterns = () => {
46
49
  };
47
50
 
48
51
  export const LibraryWithPatternsAndReusableBlocks = () => {
49
- const wrapperStyle = {
50
- margin: '24px',
51
- height: 400,
52
- border: '1px solid #f3f3f3',
53
- display: 'inline-block',
54
- };
55
52
  return (
56
53
  <ExperimentalBlockEditorProvider
57
54
  settings={ {
@@ -67,13 +64,23 @@ export const LibraryWithPatternsAndReusableBlocks = () => {
67
64
  );
68
65
  };
69
66
 
67
+ export const FullInserter = () => {
68
+ return (
69
+ <ExperimentalBlockEditorProvider
70
+ settings={ {
71
+ __experimentalBlockPatternCategories: patternCategories,
72
+ __experimentalBlockPatterns: patterns,
73
+ __experimentalReusableBlocks: reusableBlocks,
74
+ } }
75
+ >
76
+ <div style={ wrapperStyle }>
77
+ <Inserter />
78
+ </div>
79
+ </ExperimentalBlockEditorProvider>
80
+ );
81
+ };
82
+
70
83
  export const QuickInserter = () => {
71
- const wrapperStyle = {
72
- margin: '24px',
73
- height: 400,
74
- border: '1px solid #f3f3f3',
75
- display: 'inline-block',
76
- };
77
84
  return (
78
85
  <ExperimentalBlockEditorProvider
79
86
  settings={ {
@@ -0,0 +1,29 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { createSlotFill } from '@wordpress/components';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import {
10
+ useBlockEditContext,
11
+ mayDisplayControlsKey,
12
+ } from '../block-edit/context';
13
+
14
+ const { Fill, Slot } = createSlotFill( Symbol( 'InspectorControlsLastItem' ) );
15
+
16
+ const InspectorControlsLastItem = ( props ) => {
17
+ const context = useBlockEditContext();
18
+ if ( ! context[ mayDisplayControlsKey ] ) {
19
+ return null;
20
+ }
21
+ return <Fill { ...props } />;
22
+ };
23
+ InspectorControlsLastItem.Slot = function InspectorControlsLastItemSlot(
24
+ props
25
+ ) {
26
+ return <Slot { ...props } />;
27
+ };
28
+
29
+ export default InspectorControlsLastItem;
@@ -101,8 +101,8 @@ export default function InspectorControlsTabs( {
101
101
  />
102
102
  </Tabs.TabPanel>
103
103
  <Tabs.TabPanel tabId={ TAB_CONTENT.name } focusable={ false }>
104
- <InspectorControls.Slot group="content" />
105
104
  <ContentTab contentClientIds={ contentClientIds } />
105
+ <InspectorControls.Slot group="content" />
106
106
  </Tabs.TabPanel>
107
107
  <Tabs.TabPanel tabId={ TAB_LIST_VIEW.name } focusable={ false }>
108
108
  <InspectorControls.Slot group="list" />
@@ -23,14 +23,14 @@ function SectionBlockColorControls( {
23
23
  const settings = useBlockSettings( blockName );
24
24
  const { updateBlockAttributes } = useDispatch( blockEditorStore );
25
25
 
26
- const { hasButton, hasHeading } = useSelect(
26
+ const { hasButtons, hasHeading } = useSelect(
27
27
  ( select ) => {
28
28
  const blockNames =
29
29
  select( blockEditorStore ).getBlockNamesByClientId(
30
30
  contentClientIds
31
31
  );
32
32
  return {
33
- hasButton: blockNames.includes( 'core/button' ),
33
+ hasButtons: blockNames.includes( 'core/buttons' ),
34
34
  hasHeading: blockNames.includes( 'core/heading' ),
35
35
  };
36
36
  },
@@ -52,7 +52,7 @@ function SectionBlockColorControls( {
52
52
  defaultControls={ {
53
53
  text: true,
54
54
  background: true,
55
- button: hasButton,
55
+ button: hasButtons,
56
56
  heading: hasHeading,
57
57
  } }
58
58
  />
@@ -71,14 +71,13 @@ const StylesTab = ( {
71
71
  return (
72
72
  <>
73
73
  { hasBlockStyles && <BlockStyles clientId={ clientId } /> }
74
- { isSectionBlock &&
75
- window?.__experimentalContentOnlyPatternInsertion && (
76
- <SectionBlockColorControls
77
- blockName={ blockName }
78
- clientId={ clientId }
79
- contentClientIds={ contentClientIds }
80
- />
81
- ) }
74
+ { isSectionBlock && (
75
+ <SectionBlockColorControls
76
+ blockName={ blockName }
77
+ clientId={ clientId }
78
+ contentClientIds={ contentClientIds }
79
+ />
80
+ ) }
82
81
  { ! isSectionBlock && (
83
82
  <>
84
83
  <InspectorControls.Slot
@@ -239,6 +239,9 @@ const MediaReplaceFlow = ( {
239
239
  { __( 'Use featured image' ) }
240
240
  </MenuItem>
241
241
  ) }
242
+ { typeof children === 'function'
243
+ ? children( { onClose } )
244
+ : children }
242
245
  { mediaURL && onReset && (
243
246
  <MenuItem
244
247
  onClick={ () => {
@@ -249,9 +252,6 @@ const MediaReplaceFlow = ( {
249
252
  { __( 'Reset' ) }
250
253
  </MenuItem>
251
254
  ) }
252
- { typeof children === 'function'
253
- ? children( { onClose } )
254
- : children }
255
255
  </NavigableMenu>
256
256
  { onSelectURL && (
257
257
  <form className="block-editor-media-flow__url-input">
@@ -583,7 +583,7 @@ const PublicForwardedRichTextContainer = forwardRef( ( props, ref ) => {
583
583
  ref={ ref }
584
584
  { ...contentProps }
585
585
  dangerouslySetInnerHTML={ {
586
- __html: valueToHTMLString( value, multiline ),
586
+ __html: valueToHTMLString( value, multiline ) || '<br>',
587
587
  } }
588
588
  />
589
589
  );
@@ -89,12 +89,8 @@ export default function useBlockDisplayInformation( clientId ) {
89
89
  // Check if this block is a pattern
90
90
  const patternName = attributes?.metadata?.patternName;
91
91
 
92
- if (
93
- patternName &&
94
- window?.__experimentalContentOnlyPatternInsertion
95
- ) {
92
+ if ( patternName ) {
96
93
  const pattern = __experimentalGetParsedPattern( patternName );
97
-
98
94
  const positionLabel = getPositionTypeLabel( attributes );
99
95
  return {
100
96
  isSynced: false,
@@ -17,6 +17,7 @@ import { forwardRef } from '@wordpress/element';
17
17
  import useMultiSelection from './use-multi-selection';
18
18
  import useTabNav from './use-tab-nav';
19
19
  import useArrowNav from './use-arrow-nav';
20
+ import { usePreviewModeNav } from './use-preview-mode-nav';
20
21
  import useSelectAll from './use-select-all';
21
22
  import useDragSelection from './use-drag-selection';
22
23
  import useSelectionObserver from './use-selection-observer';
@@ -44,6 +45,7 @@ export function useWritingFlow() {
44
45
  useMultiSelection(),
45
46
  useSelectAll(),
46
47
  useArrowNav(),
48
+ usePreviewModeNav(),
47
49
  useRefEffect(
48
50
  ( node ) => {
49
51
  node.tabIndex = 0;
@@ -209,6 +209,11 @@ export default function useArrowNav() {
209
209
  return;
210
210
  }
211
211
 
212
+ // In preview mode, navigation is handled by useSelectableBlocksNav.
213
+ if ( getSettings().isPreviewMode ) {
214
+ return;
215
+ }
216
+
212
217
  // If there is a multi-selection, the arrow keys should collapse the
213
218
  // selection to the start or end of the selection.
214
219
  if ( hasMultiSelection() ) {
@@ -30,6 +30,7 @@ export default function useDragSelection() {
30
30
  const { startMultiSelect, stopMultiSelect } =
31
31
  useDispatch( blockEditorStore );
32
32
  const {
33
+ getSettings,
33
34
  isSelectionEnabled,
34
35
  hasSelectedBlock,
35
36
  isDraggingBlocks,
@@ -123,7 +124,12 @@ export default function useDragSelection() {
123
124
  // child elements of the content editable wrapper are editable
124
125
  // and return true for this property. We only want to start
125
126
  // multi selecting when the mouse leaves the wrapper.
126
- if ( target.getAttribute( 'contenteditable' ) !== 'true' ) {
127
+ // In preview mode, allow drag selection from blocks since they
128
+ // are not contenteditable.
129
+ if (
130
+ target.getAttribute( 'contenteditable' ) !== 'true' &&
131
+ ! getSettings().isPreviewMode
132
+ ) {
127
133
  return;
128
134
  }
129
135
 
@@ -0,0 +1,102 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useRefEffect } from '@wordpress/compose';
5
+ import { useSelect } from '@wordpress/data';
6
+ import { TAB, UP, DOWN, LEFT, RIGHT } from '@wordpress/keycodes';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { store as blockEditorStore } from '../../store';
12
+
13
+ /**
14
+ * In preview mode, handles Tab and arrow key navigation to move only between
15
+ * block elements, skipping all other focusable content.
16
+ *
17
+ * @return {Function} Ref callback.
18
+ */
19
+ export function usePreviewModeNav() {
20
+ const isPreviewMode = useSelect(
21
+ ( select ) => select( blockEditorStore ).getSettings().isPreviewMode,
22
+ []
23
+ );
24
+
25
+ return useRefEffect(
26
+ ( node ) => {
27
+ if ( ! isPreviewMode ) {
28
+ return;
29
+ }
30
+
31
+ function onKeyDown( event ) {
32
+ const { keyCode, shiftKey, target } = event;
33
+
34
+ const isTab = keyCode === TAB;
35
+ const isUp = keyCode === UP;
36
+ const isDown = keyCode === DOWN;
37
+ const isLeft = keyCode === LEFT;
38
+ const isRight = keyCode === RIGHT;
39
+ const isArrow = isUp || isDown || isLeft || isRight;
40
+
41
+ if ( ! isTab && ! isArrow ) {
42
+ return;
43
+ }
44
+
45
+ const isReverse = isTab ? shiftKey : isUp || isLeft;
46
+
47
+ const blocks = Array.from(
48
+ node.querySelectorAll( '[data-block]' )
49
+ );
50
+
51
+ if ( ! blocks.length ) {
52
+ return;
53
+ }
54
+
55
+ const currentBlock = target.closest( '[data-block]' );
56
+ const currentIndex = currentBlock
57
+ ? blocks.indexOf( currentBlock )
58
+ : -1;
59
+
60
+ // If focus is not on a block, don't intercept navigation.
61
+ if ( currentIndex === -1 ) {
62
+ return;
63
+ }
64
+
65
+ // For Tab navigation, allow escaping the block list at boundaries.
66
+ // For arrow keys, wrap around.
67
+ if ( isTab ) {
68
+ if ( isReverse && currentIndex === 0 ) {
69
+ // At first block, Shift+Tab should exit the block list.
70
+ return;
71
+ }
72
+ if ( ! isReverse && currentIndex === blocks.length - 1 ) {
73
+ // At last block, Tab should exit the block list.
74
+ return;
75
+ }
76
+ }
77
+
78
+ let nextIndex;
79
+ if ( isReverse ) {
80
+ nextIndex =
81
+ currentIndex <= 0
82
+ ? blocks.length - 1
83
+ : currentIndex - 1;
84
+ } else {
85
+ nextIndex =
86
+ currentIndex === -1 || currentIndex >= blocks.length - 1
87
+ ? 0
88
+ : currentIndex + 1;
89
+ }
90
+
91
+ event.preventDefault();
92
+ blocks[ nextIndex ].focus();
93
+ }
94
+
95
+ node.addEventListener( 'keydown', onKeyDown );
96
+ return () => {
97
+ node.removeEventListener( 'keydown', onKeyDown );
98
+ };
99
+ },
100
+ [ isPreviewMode ]
101
+ );
102
+ }
@@ -64,7 +64,7 @@ function BlockEditAnchorControlPure( { anchor, setAttributes } ) {
64
64
  help={
65
65
  <>
66
66
  { __(
67
- 'Enter a word or two without spaces to make a unique web address just for this block, called an “anchor”. Then, you’ll be able to link directly to this section of your page.'
67
+ 'Enter a word or two—without spaces—to make a unique web address just for this block, called an “anchor”. Then, you’ll be able to link directly to this section of your page.'
68
68
  ) }
69
69
  { isWeb && (
70
70
  <>
@@ -28,8 +28,11 @@ export function addLabelCallback( settings ) {
28
28
  settings.__experimentalLabel = ( attributes, { context } ) => {
29
29
  const { metadata } = attributes;
30
30
 
31
- // In the list view, use the block's name attribute as the label.
32
- if ( context === 'list-view' && metadata?.name ) {
31
+ // In the list view and breadcrumb, use the block's name attribute as the label.
32
+ if (
33
+ ( context === 'list-view' || context === 'breadcrumb' ) &&
34
+ metadata?.name
35
+ ) {
33
36
  return metadata.name;
34
37
  }
35
38
  };
@@ -132,7 +132,7 @@ function useBlockProps( { style } ) {
132
132
  }
133
133
 
134
134
  return {
135
- className: customCSSIdentifier,
135
+ className: `has-custom-css ${ customCSSIdentifier }`,
136
136
  };
137
137
  }
138
138
 
@@ -10,19 +10,24 @@ import { useSelect } from '@wordpress/data';
10
10
  */
11
11
  import { GridVisualizer, useGridLayoutSync } from '../components/grid';
12
12
  import { store as blockEditorStore } from '../store';
13
+ import useBlockVisibility from '../components/block-visibility/use-block-visibility';
14
+ import { deviceTypeKey } from '../store/private-keys';
15
+ import { BLOCK_VISIBILITY_VIEWPORTS } from '../components/block-visibility/constants';
13
16
 
14
17
  function GridLayoutSync( props ) {
15
18
  useGridLayoutSync( props );
16
19
  }
17
20
 
18
21
  function GridTools( { clientId, layout } ) {
19
- const isVisible = useSelect(
22
+ const { isVisible, blockVisibility, deviceType } = useSelect(
20
23
  ( select ) => {
21
24
  const {
22
25
  isBlockSelected,
23
26
  isDraggingBlocks,
24
27
  getTemplateLock,
25
28
  getBlockEditingMode,
29
+ getBlockAttributes,
30
+ getSettings,
26
31
  } = select( blockEditorStore );
27
32
 
28
33
  // These calls are purposely ordered from least expensive to most expensive.
@@ -32,18 +37,32 @@ function GridTools( { clientId, layout } ) {
32
37
  getTemplateLock( clientId ) ||
33
38
  getBlockEditingMode( clientId ) !== 'default'
34
39
  ) {
35
- return false;
40
+ return { isVisible: false };
36
41
  }
37
42
 
38
- return true;
43
+ const attributes = getBlockAttributes( clientId );
44
+ const settings = getSettings();
45
+
46
+ return {
47
+ isVisible: true,
48
+ blockVisibility: attributes?.metadata?.blockVisibility,
49
+ deviceType:
50
+ settings?.[ deviceTypeKey ]?.toLowerCase() ||
51
+ BLOCK_VISIBILITY_VIEWPORTS.desktop.value,
52
+ };
39
53
  },
40
54
  [ clientId ]
41
55
  );
42
56
 
57
+ const { isBlockCurrentlyHidden } = useBlockVisibility( {
58
+ blockVisibility,
59
+ deviceType,
60
+ } );
61
+
43
62
  return (
44
63
  <>
45
64
  <GridLayoutSync clientId={ clientId } />
46
- { isVisible && (
65
+ { isVisible && ! isBlockCurrentlyHidden && (
47
66
  <GridVisualizer clientId={ clientId } parentLayout={ layout } />
48
67
  ) }
49
68
  </>
@@ -32,7 +32,6 @@ import position from './position';
32
32
  import blockStyleVariation from './block-style-variation';
33
33
  import layout from './layout';
34
34
  import childLayout from './layout-child';
35
- import contentLockUI from './content-lock-ui';
36
35
  import './metadata';
37
36
  import blockHooks from './block-hooks';
38
37
  import blockBindingsPanel from './block-bindings';
@@ -53,7 +52,6 @@ createBlockEditFilter(
53
52
  fitText,
54
53
  position,
55
54
  layout,
56
- contentLockUI,
57
55
  blockHooks,
58
56
  blockBindingsPanel,
59
57
  childLayout,
@@ -16,6 +16,9 @@ import {
16
16
  GridItemResizer,
17
17
  GridItemMovers,
18
18
  } from '../components/grid';
19
+ import useBlockVisibility from '../components/block-visibility/use-block-visibility';
20
+ import { deviceTypeKey } from '../store/private-keys';
21
+ import { BLOCK_VISIBILITY_VIEWPORTS } from '../components/block-visibility/constants';
19
22
 
20
23
  // Used for generating the instance ID
21
24
  const LAYOUT_CHILD_BLOCK_PROPS_REFERENCE = {};
@@ -199,12 +202,20 @@ function GridTools( {
199
202
  isManualPlacement,
200
203
  parentLayout,
201
204
  } ) {
202
- const { rootClientId, isVisible } = useSelect(
205
+ const {
206
+ rootClientId,
207
+ isVisible,
208
+ parentBlockVisibility,
209
+ blockBlockVisibility,
210
+ deviceType,
211
+ } = useSelect(
203
212
  ( select ) => {
204
213
  const {
205
214
  getBlockRootClientId,
206
215
  getBlockEditingMode,
207
216
  getTemplateLock,
217
+ getBlockAttributes,
218
+ getSettings,
208
219
  } = select( blockEditorStore );
209
220
 
210
221
  const _rootClientId = getBlockRootClientId( clientId );
@@ -219,21 +230,46 @@ function GridTools( {
219
230
  };
220
231
  }
221
232
 
233
+ const parentAttributes = getBlockAttributes( _rootClientId );
234
+ const blockAttributes = getBlockAttributes( clientId );
235
+ const settings = getSettings();
236
+
222
237
  return {
223
238
  rootClientId: _rootClientId,
224
239
  isVisible: true,
240
+ parentBlockVisibility:
241
+ parentAttributes?.metadata?.blockVisibility,
242
+ blockBlockVisibility:
243
+ blockAttributes?.metadata?.blockVisibility,
244
+ deviceType:
245
+ settings?.[ deviceTypeKey ]?.toLowerCase() ||
246
+ BLOCK_VISIBILITY_VIEWPORTS.desktop.value,
225
247
  };
226
248
  },
227
249
  [ clientId ]
228
250
  );
229
251
 
252
+ const { isBlockCurrentlyHidden: isParentBlockCurrentlyHidden } =
253
+ useBlockVisibility( {
254
+ blockVisibility: parentBlockVisibility,
255
+ deviceType,
256
+ } );
257
+
258
+ const { isBlockCurrentlyHidden: isBlockItselfCurrentlyHidden } =
259
+ useBlockVisibility( {
260
+ blockVisibility: blockBlockVisibility,
261
+ deviceType,
262
+ } );
263
+
230
264
  // Use useState() instead of useRef() so that GridItemResizer updates when ref is set.
231
265
  const [ resizerBounds, setResizerBounds ] = useState();
232
266
 
233
- if ( ! isVisible ) {
267
+ if ( ! isVisible || isParentBlockCurrentlyHidden ) {
234
268
  return null;
235
269
  }
236
270
 
271
+ const showResizer = allowSizingOnChildren && ! isBlockItselfCurrentlyHidden;
272
+
237
273
  function updateLayout( layout ) {
238
274
  setAttributes( {
239
275
  style: {
@@ -253,7 +289,7 @@ function GridTools( {
253
289
  contentRef={ setResizerBounds }
254
290
  parentLayout={ parentLayout }
255
291
  />
256
- { allowSizingOnChildren && (
292
+ { showResizer && (
257
293
  <GridItemResizer
258
294
  clientId={ clientId }
259
295
  // Don't allow resizing beyond the grid visualizer.
@@ -13,6 +13,7 @@ import {
13
13
  normalizeString,
14
14
  } from './components/inserter/search-items';
15
15
  import { PrivateListView } from './components/list-view';
16
+ import InspectorControlsLastItem from './components/inspector-controls/last-item';
16
17
  import { useHasBlockToolbar } from './components/block-toolbar/use-has-block-toolbar';
17
18
  import { cleanEmptyObject } from './hooks/utils';
18
19
  import BlockQuickNavigation from './components/block-quick-navigation';
@@ -79,6 +80,7 @@ lock( privateApis, {
79
80
  normalizeString,
80
81
  PrivateListView,
81
82
  ResizableBoxPopover,
83
+ InspectorControlsLastItem,
82
84
  useHasBlockToolbar,
83
85
  cleanEmptyObject,
84
86
  BlockQuickNavigation,