@wordpress/block-editor 15.7.1-next.2f1c7c01b.0 → 15.8.1-next.16d95556a.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 (195) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-card/index.js +76 -34
  3. package/build/components/block-card/index.js.map +2 -2
  4. package/build/components/block-inspector/edit-contents.js +72 -0
  5. package/build/components/block-inspector/edit-contents.js.map +7 -0
  6. package/build/components/block-inspector/index.js +32 -9
  7. package/build/components/block-inspector/index.js.map +3 -3
  8. package/build/components/block-list/index.js +9 -9
  9. package/build/components/block-list/index.js.map +2 -2
  10. package/build/components/block-switcher/index.js +24 -123
  11. package/build/components/block-switcher/index.js.map +3 -3
  12. package/build/components/block-toolbar/block-toolbar-icon.js +175 -0
  13. package/build/components/block-toolbar/block-toolbar-icon.js.map +7 -0
  14. package/build/components/block-toolbar/index.js +51 -53
  15. package/build/components/block-toolbar/index.js.map +3 -3
  16. package/build/components/block-toolbar/pattern-overrides-dropdown.js +93 -0
  17. package/build/components/block-toolbar/pattern-overrides-dropdown.js.map +7 -0
  18. package/build/components/block-tools/index.js +10 -3
  19. package/build/components/block-tools/index.js.map +2 -2
  20. package/build/components/border-radius-control/utils.js +7 -3
  21. package/build/components/border-radius-control/utils.js.map +2 -2
  22. package/build/components/content-lock/modify-content-lock-menu-item.js +3 -3
  23. package/build/components/content-lock/modify-content-lock-menu-item.js.map +2 -2
  24. package/build/components/global-styles/border-panel.js +11 -7
  25. package/build/components/global-styles/border-panel.js.map +2 -2
  26. package/build/components/global-styles/color-panel.js +35 -27
  27. package/build/components/global-styles/color-panel.js.map +2 -2
  28. package/build/components/global-styles/typography-panel.js +19 -12
  29. package/build/components/global-styles/typography-panel.js.map +2 -2
  30. package/build/components/inserter/media-tab/media-tab.js +2 -1
  31. package/build/components/inserter/media-tab/media-tab.js.map +2 -2
  32. package/build/components/inspector-controls-tabs/index.js +2 -1
  33. package/build/components/inspector-controls-tabs/index.js.map +2 -2
  34. package/build/components/inspector-controls-tabs/styles-tab.js +55 -1
  35. package/build/components/inspector-controls-tabs/styles-tab.js.map +3 -3
  36. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.js +1 -1
  37. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.js.map +2 -2
  38. package/build/components/keyboard-shortcuts/index.js +8 -0
  39. package/build/components/keyboard-shortcuts/index.js.map +2 -2
  40. package/build/components/rich-text/format-edit.js +9 -1
  41. package/build/components/rich-text/format-edit.js.map +2 -2
  42. package/build/components/rich-text/index.js +1 -0
  43. package/build/components/rich-text/index.js.map +2 -2
  44. package/build/hooks/border.js +10 -5
  45. package/build/hooks/border.js.map +3 -3
  46. package/build/hooks/color.js +31 -9
  47. package/build/hooks/color.js.map +3 -3
  48. package/build/hooks/content-lock-ui.js +4 -5
  49. package/build/hooks/content-lock-ui.js.map +2 -2
  50. package/build/hooks/dimensions.js +9 -4
  51. package/build/hooks/dimensions.js.map +2 -2
  52. package/build/hooks/fit-text.js +19 -75
  53. package/build/hooks/fit-text.js.map +3 -3
  54. package/build/hooks/font-size.js +5 -2
  55. package/build/hooks/font-size.js.map +2 -2
  56. package/build/hooks/layout.js +4 -1
  57. package/build/hooks/layout.js.map +2 -2
  58. package/build/hooks/spacing-visualizer.js +5 -0
  59. package/build/hooks/spacing-visualizer.js.map +2 -2
  60. package/build/hooks/typography.js +23 -14
  61. package/build/hooks/typography.js.map +3 -3
  62. package/build/store/private-selectors.js +21 -1
  63. package/build/store/private-selectors.js.map +2 -2
  64. package/build/store/reducer.js +4 -0
  65. package/build/store/reducer.js.map +2 -2
  66. package/build/store/selectors.js +12 -3
  67. package/build/store/selectors.js.map +2 -2
  68. package/build/utils/fit-text-frontend.js +1 -0
  69. package/build/utils/fit-text-frontend.js.map +2 -2
  70. package/build/utils/fit-text-utils.js +1 -1
  71. package/build/utils/fit-text-utils.js.map +1 -1
  72. package/build-module/components/block-card/index.js +82 -32
  73. package/build-module/components/block-card/index.js.map +2 -2
  74. package/build-module/components/block-inspector/edit-contents.js +51 -0
  75. package/build-module/components/block-inspector/edit-contents.js.map +7 -0
  76. package/build-module/components/block-inspector/index.js +32 -9
  77. package/build-module/components/block-inspector/index.js.map +2 -2
  78. package/build-module/components/block-list/index.js +11 -11
  79. package/build-module/components/block-list/index.js.map +2 -2
  80. package/build-module/components/block-switcher/index.js +24 -124
  81. package/build-module/components/block-switcher/index.js.map +2 -2
  82. package/build-module/components/block-toolbar/block-toolbar-icon.js +144 -0
  83. package/build-module/components/block-toolbar/block-toolbar-icon.js.map +7 -0
  84. package/build-module/components/block-toolbar/index.js +51 -53
  85. package/build-module/components/block-toolbar/index.js.map +2 -2
  86. package/build-module/components/block-toolbar/pattern-overrides-dropdown.js +76 -0
  87. package/build-module/components/block-toolbar/pattern-overrides-dropdown.js.map +7 -0
  88. package/build-module/components/block-tools/index.js +10 -3
  89. package/build-module/components/block-tools/index.js.map +2 -2
  90. package/build-module/components/border-radius-control/utils.js +7 -3
  91. package/build-module/components/border-radius-control/utils.js.map +2 -2
  92. package/build-module/components/content-lock/modify-content-lock-menu-item.js +3 -3
  93. package/build-module/components/content-lock/modify-content-lock-menu-item.js.map +2 -2
  94. package/build-module/components/global-styles/border-panel.js +11 -7
  95. package/build-module/components/global-styles/border-panel.js.map +2 -2
  96. package/build-module/components/global-styles/color-panel.js +34 -27
  97. package/build-module/components/global-styles/color-panel.js.map +2 -2
  98. package/build-module/components/global-styles/typography-panel.js +21 -13
  99. package/build-module/components/global-styles/typography-panel.js.map +2 -2
  100. package/build-module/components/inserter/media-tab/media-tab.js +2 -1
  101. package/build-module/components/inserter/media-tab/media-tab.js.map +2 -2
  102. package/build-module/components/inspector-controls-tabs/index.js +2 -1
  103. package/build-module/components/inspector-controls-tabs/index.js.map +2 -2
  104. package/build-module/components/inspector-controls-tabs/styles-tab.js +55 -1
  105. package/build-module/components/inspector-controls-tabs/styles-tab.js.map +2 -2
  106. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js +1 -1
  107. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js.map +2 -2
  108. package/build-module/components/keyboard-shortcuts/index.js +8 -0
  109. package/build-module/components/keyboard-shortcuts/index.js.map +2 -2
  110. package/build-module/components/rich-text/format-edit.js +9 -1
  111. package/build-module/components/rich-text/format-edit.js.map +2 -2
  112. package/build-module/components/rich-text/index.js +1 -0
  113. package/build-module/components/rich-text/index.js.map +2 -2
  114. package/build-module/hooks/border.js +10 -5
  115. package/build-module/hooks/border.js.map +3 -3
  116. package/build-module/hooks/color.js +31 -9
  117. package/build-module/hooks/color.js.map +3 -3
  118. package/build-module/hooks/content-lock-ui.js +4 -5
  119. package/build-module/hooks/content-lock-ui.js.map +2 -2
  120. package/build-module/hooks/dimensions.js +9 -4
  121. package/build-module/hooks/dimensions.js.map +2 -2
  122. package/build-module/hooks/fit-text.js +18 -66
  123. package/build-module/hooks/fit-text.js.map +2 -2
  124. package/build-module/hooks/font-size.js +5 -2
  125. package/build-module/hooks/font-size.js.map +2 -2
  126. package/build-module/hooks/layout.js +4 -1
  127. package/build-module/hooks/layout.js.map +2 -2
  128. package/build-module/hooks/spacing-visualizer.js +5 -0
  129. package/build-module/hooks/spacing-visualizer.js.map +2 -2
  130. package/build-module/hooks/typography.js +23 -14
  131. package/build-module/hooks/typography.js.map +3 -3
  132. package/build-module/store/private-selectors.js +20 -1
  133. package/build-module/store/private-selectors.js.map +2 -2
  134. package/build-module/store/reducer.js +4 -0
  135. package/build-module/store/reducer.js.map +2 -2
  136. package/build-module/store/selectors.js +12 -3
  137. package/build-module/store/selectors.js.map +2 -2
  138. package/build-module/utils/fit-text-frontend.js +1 -0
  139. package/build-module/utils/fit-text-frontend.js.map +2 -2
  140. package/build-module/utils/fit-text-utils.js +1 -1
  141. package/build-module/utils/fit-text-utils.js.map +1 -1
  142. package/build-style/style-rtl.css +31 -71
  143. package/build-style/style.css +31 -71
  144. package/package.json +37 -37
  145. package/src/components/block-card/index.js +95 -38
  146. package/src/components/block-card/style.scss +17 -1
  147. package/src/components/block-inspector/edit-contents.js +64 -0
  148. package/src/components/block-inspector/index.js +35 -13
  149. package/src/components/block-inspector/style.scss +6 -3
  150. package/src/components/block-list/index.js +11 -9
  151. package/src/components/block-switcher/block-transformations-menu.native.js +0 -1
  152. package/src/components/block-switcher/index.js +51 -180
  153. package/src/components/block-switcher/style.scss +0 -70
  154. package/src/components/block-switcher/test/index.js +17 -18
  155. package/src/components/block-toolbar/block-toolbar-icon.js +173 -0
  156. package/src/components/block-toolbar/index.js +50 -52
  157. package/src/components/block-toolbar/pattern-overrides-dropdown.js +99 -0
  158. package/src/components/block-toolbar/style.scss +21 -21
  159. package/src/components/block-toolbar/test/__snapshots__/block-toolbar-menu.native.js.snap +6 -4
  160. package/src/components/block-toolbar/test/block-toolbar-icon.js +182 -0
  161. package/src/components/block-toolbar/test/block-toolbar-menu.native.js +2 -2
  162. package/src/components/block-tools/index.js +11 -1
  163. package/src/components/border-radius-control/test/utils.js +90 -0
  164. package/src/components/border-radius-control/utils.js +7 -3
  165. package/src/components/content-lock/modify-content-lock-menu-item.js +9 -3
  166. package/src/components/global-styles/border-panel.js +11 -7
  167. package/src/components/global-styles/color-panel.js +32 -26
  168. package/src/components/global-styles/typography-panel.js +14 -1
  169. package/src/components/inserter/media-tab/media-tab.js +7 -1
  170. package/src/components/inspector-controls-tabs/index.js +1 -0
  171. package/src/components/inspector-controls-tabs/styles-tab.js +58 -0
  172. package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +5 -1
  173. package/src/components/keyboard-shortcuts/index.js +9 -0
  174. package/src/components/rich-text/format-edit.js +9 -1
  175. package/src/components/rich-text/index.js +1 -0
  176. package/src/hooks/border.js +12 -6
  177. package/src/hooks/color.js +40 -13
  178. package/src/hooks/content-lock-ui.js +9 -6
  179. package/src/hooks/dimensions.js +25 -17
  180. package/src/hooks/fit-text.js +23 -84
  181. package/src/hooks/font-size.js +7 -2
  182. package/src/hooks/layout.js +11 -7
  183. package/src/hooks/spacing-visualizer.js +9 -1
  184. package/src/hooks/typography.js +24 -18
  185. package/src/store/private-selectors.js +26 -1
  186. package/src/store/reducer.js +6 -0
  187. package/src/store/selectors.js +24 -3
  188. package/src/utils/fit-text-frontend.js +1 -0
  189. package/src/utils/fit-text-utils.js +1 -1
  190. package/tsconfig.tsbuildinfo +1 -1
  191. package/build/components/block-inspector/edit-contents-button.js +0 -61
  192. package/build/components/block-inspector/edit-contents-button.js.map +0 -7
  193. package/build-module/components/block-inspector/edit-contents-button.js +0 -40
  194. package/build-module/components/block-inspector/edit-contents-button.js.map +0 -7
  195. package/src/components/block-inspector/edit-contents-button.js +0 -46
@@ -94,10 +94,17 @@ describe( 'BlockSwitcher', () => {
94
94
  },
95
95
  ],
96
96
  blocks: [ headingBlock1 ],
97
+ patterns: [],
98
+ isUsingBindings: false,
97
99
  canRemove: true,
98
100
  } ) );
99
101
  const user = userEvent.setup();
100
- render( <BlockSwitcher clientIds={ [ headingBlock1.clientId ] } /> );
102
+ render(
103
+ <BlockSwitcher
104
+ clientIds={ [ headingBlock1.clientId ] }
105
+ label="Block Name"
106
+ />
107
+ );
101
108
  expect(
102
109
  screen.getByRole( 'button', {
103
110
  name: 'Block Name',
@@ -134,29 +141,21 @@ describe( 'BlockSwitcher', () => {
134
141
  expect( items[ 1 ] ).toHaveTextContent( headingBlockType.title );
135
142
  } );
136
143
 
137
- test( 'should render accessibly disabled block switcher when we have a single selected block without styles and we cannot remove it', () => {
138
- useSelect.mockImplementation( () => ( {
139
- blocks: [ headingBlock1 ],
140
- icon: copy,
141
- hasBlockStyles: false,
142
- canRemove: false,
143
- } ) );
144
- render( <BlockSwitcher clientIds={ [ headingBlock1.clientId ] } /> );
145
- const blockSwitcher = screen.getByRole( 'button', {
146
- name: 'Block Name',
147
- } );
148
- expect( blockSwitcher ).toBeEnabled();
149
- expect( blockSwitcher ).toHaveAttribute( 'aria-disabled', 'true' );
150
- } );
151
-
152
144
  test( 'should render message for no available transforms', async () => {
153
145
  useSelect.mockImplementation( () => ( {
154
146
  possibleBlockTransformations: [],
155
147
  blocks: [ headingBlock1 ],
148
+ patterns: [],
149
+ isUsingBindings: false,
150
+ canRemove: false,
156
151
  icon: copy,
157
- canRemove: true,
158
152
  } ) );
159
- render( <BlockSwitcher clientIds={ [ headingBlock1.clientId ] } /> );
153
+ render(
154
+ <BlockSwitcher
155
+ clientIds={ [ headingBlock1.clientId ] }
156
+ label="Block Name"
157
+ />
158
+ );
160
159
  const user = userEvent.setup();
161
160
  await user.type(
162
161
  screen.getByRole( 'button', {
@@ -0,0 +1,173 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { ToolbarButton } from '@wordpress/components';
5
+ import { __ } from '@wordpress/i18n';
6
+ import { useSelect } from '@wordpress/data';
7
+ import { copy } from '@wordpress/icons';
8
+ import { getBlockType, store as blocksStore } from '@wordpress/blocks';
9
+ import { store as preferencesStore } from '@wordpress/preferences';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import BlockSwitcher from '../block-switcher';
15
+ import BlockIcon from '../block-icon';
16
+ import PatternOverridesDropdown from './pattern-overrides-dropdown';
17
+ import useBlockDisplayTitle from '../block-title/use-block-display-title';
18
+ import { store as blockEditorStore } from '../../store';
19
+ import { hasPatternOverridesDefaultBinding } from '../../utils/block-bindings';
20
+ import { unlock } from '../../lock-unlock';
21
+
22
+ function getBlockIconVariant( { select, clientIds } ) {
23
+ const {
24
+ getBlockName,
25
+ getBlockAttributes,
26
+ getBlockParentsByBlockName,
27
+ isSectionBlock,
28
+ canRemoveBlocks,
29
+ getTemplateLock,
30
+ getBlockEditingMode,
31
+ } = unlock( select( blockEditorStore ) );
32
+ const { getBlockStyles } = select( blocksStore );
33
+
34
+ const hasTemplateLock = clientIds.some(
35
+ ( id ) => getTemplateLock( id ) === 'contentOnly'
36
+ );
37
+
38
+ // Calculate props only used in this function
39
+ const isSingleBlock = clientIds.length === 1;
40
+ const blockName = isSingleBlock && getBlockName( clientIds[ 0 ] );
41
+ const hasBlockStyles =
42
+ isSingleBlock && !! getBlockStyles( blockName )?.length;
43
+ const isSectionInSelection = clientIds.some( ( id ) =>
44
+ isSectionBlock( id )
45
+ );
46
+ const hasPatternOverrides = clientIds.every( ( clientId ) =>
47
+ hasPatternOverridesDefaultBinding(
48
+ getBlockAttributes( clientId )?.metadata?.bindings
49
+ )
50
+ );
51
+ const hasParentPattern = clientIds.every(
52
+ ( clientId ) =>
53
+ getBlockParentsByBlockName( clientId, 'core/block', true ).length >
54
+ 0
55
+ );
56
+ const canRemove = canRemoveBlocks( clientIds );
57
+
58
+ const isDefaultEditingMode =
59
+ getBlockEditingMode( clientIds[ 0 ] ) === 'default';
60
+ const _hideTransformsForSections =
61
+ window?.__experimentalContentOnlyPatternInsertion &&
62
+ isSectionInSelection;
63
+ const _showBlockSwitcher =
64
+ ! _hideTransformsForSections &&
65
+ isDefaultEditingMode &&
66
+ ( hasBlockStyles || canRemove ) &&
67
+ ! hasTemplateLock;
68
+
69
+ const _showPatternOverrides = hasPatternOverrides && hasParentPattern;
70
+
71
+ if ( _showBlockSwitcher ) {
72
+ return 'switcher';
73
+ } else if ( _showPatternOverrides ) {
74
+ return 'pattern-overrides';
75
+ }
76
+
77
+ return 'default';
78
+ }
79
+
80
+ function getBlockIcon( { select, clientIds } ) {
81
+ const { getBlockName, getBlockAttributes } = unlock(
82
+ select( blockEditorStore )
83
+ );
84
+ const { getActiveBlockVariation } = select( blocksStore );
85
+
86
+ const _isSingleBlock = clientIds.length === 1;
87
+ const firstClientId = clientIds[ 0 ];
88
+
89
+ const blockName = getBlockName( firstClientId );
90
+ const blockType = getBlockType( blockName );
91
+
92
+ if ( _isSingleBlock ) {
93
+ const match = getActiveBlockVariation(
94
+ blockName,
95
+ getBlockAttributes( firstClientId )
96
+ );
97
+ return match?.icon || blockType?.icon;
98
+ }
99
+
100
+ const blockNames = clientIds.map( ( id ) => getBlockName( id ) );
101
+ const isSelectionOfSameType = new Set( blockNames ).size === 1;
102
+ return isSelectionOfSameType ? blockType?.icon : copy;
103
+ }
104
+
105
+ export default function BlockToolbarIcon( { clientIds, isSynced } ) {
106
+ const { icon, showIconLabels, variant } = useSelect(
107
+ ( select ) => {
108
+ return {
109
+ icon: getBlockIcon( { select, clientIds } ),
110
+ showIconLabels: select( preferencesStore ).get(
111
+ 'core',
112
+ 'showIconLabels'
113
+ ),
114
+ variant: getBlockIconVariant( {
115
+ select,
116
+ clientIds,
117
+ } ),
118
+ };
119
+ },
120
+ [ clientIds ]
121
+ );
122
+
123
+ const blockTitle = useBlockDisplayTitle( {
124
+ clientId: clientIds?.[ 0 ],
125
+ maximumLength: 35,
126
+ } );
127
+
128
+ const isSingleBlock = clientIds.length === 1;
129
+ const showBlockTitle = isSingleBlock && isSynced && ! showIconLabels;
130
+ const label = isSingleBlock ? blockTitle : __( 'Multiple blocks selected' );
131
+ // Used to hide the block icon when the showIconLabels preference is enabled, or to display the template title when it's a template.
132
+ const text = showBlockTitle && blockTitle ? blockTitle : undefined;
133
+
134
+ const BlockIconElement = (
135
+ <BlockIcon
136
+ className="block-editor-block-toolbar__block-icon"
137
+ icon={ icon }
138
+ />
139
+ );
140
+
141
+ if ( variant === 'switcher' ) {
142
+ return (
143
+ <BlockSwitcher
144
+ clientIds={ clientIds }
145
+ label={ label }
146
+ text={ text }
147
+ >
148
+ { BlockIconElement }
149
+ </BlockSwitcher>
150
+ );
151
+ }
152
+
153
+ if ( variant === 'pattern-overrides' ) {
154
+ return (
155
+ <PatternOverridesDropdown
156
+ icon={ BlockIconElement }
157
+ clientIds={ clientIds }
158
+ blockTitle={ blockTitle }
159
+ label={ label }
160
+ />
161
+ );
162
+ }
163
+
164
+ return (
165
+ <ToolbarButton
166
+ disabled
167
+ className="block-editor-block-toolbar__block-icon-button"
168
+ title={ label }
169
+ icon={ BlockIconElement }
170
+ text={ text }
171
+ />
172
+ );
173
+ }
@@ -23,7 +23,6 @@ import { ToolbarGroup } from '@wordpress/components';
23
23
  */
24
24
  import BlockMover from '../block-mover';
25
25
  import BlockParentSelector from '../block-parent-selector';
26
- import BlockSwitcher from '../block-switcher';
27
26
  import BlockControls from '../block-controls';
28
27
  import __unstableBlockToolbarLastItem from './block-toolbar-last-item';
29
28
  import BlockSettingsMenu from '../block-settings-menu';
@@ -39,6 +38,7 @@ import { useHasBlockToolbar } from './use-has-block-toolbar';
39
38
  import ChangeDesign from './change-design';
40
39
  import SwitchSectionStyle from './switch-section-style';
41
40
  import { unlock } from '../../lock-unlock';
41
+ import BlockToolbarIcon from './block-toolbar-icon';
42
42
 
43
43
  /**
44
44
  * Renders the block toolbar.
@@ -68,7 +68,7 @@ export function PrivateBlockToolbar( {
68
68
  shouldShowVisualToolbar,
69
69
  showParentSelector,
70
70
  isUsingBindings,
71
- hasParentPattern,
71
+ isSectionContainer,
72
72
  hasContentOnlyLocking,
73
73
  showShuffleButton,
74
74
  showSlots,
@@ -85,7 +85,6 @@ export function PrivateBlockToolbar( {
85
85
  isBlockValid,
86
86
  getBlockEditingMode,
87
87
  getBlockAttributes,
88
- getBlockParentsByBlockName,
89
88
  getTemplateLock,
90
89
  getParentSectionBlock,
91
90
  isZoomOut,
@@ -112,12 +111,6 @@ export function PrivateBlockToolbar( {
112
111
  !! getBlockAttributes( clientId )?.metadata?.bindings
113
112
  );
114
113
 
115
- const _hasParentPattern = selectedBlockClientIds.every(
116
- ( clientId ) =>
117
- getBlockParentsByBlockName( clientId, 'core/block', true )
118
- .length > 0
119
- );
120
-
121
114
  // If one or more selected blocks are locked, do not show the BlockGroupToolbar.
122
115
  const _hasTemplateLock = selectedBlockClientIds.some(
123
116
  ( id ) => getTemplateLock( id ) === 'contentOnly'
@@ -125,11 +118,13 @@ export function PrivateBlockToolbar( {
125
118
 
126
119
  const _isZoomOut = isZoomOut();
127
120
 
121
+ const _isSectionBlock = isSectionBlock( selectedBlockClientId );
122
+
128
123
  // The switch style button appears more prominently with the
129
124
  // content only pattern experiment.
130
125
  const _showSwitchSectionStyleButton =
131
126
  window?.__experimentalContentOnlyPatternInsertion &&
132
- ( _isZoomOut || isSectionBlock( selectedBlockClientId ) );
127
+ ( _isZoomOut || _isSectionBlock );
133
128
 
134
129
  return {
135
130
  blockClientId: selectedBlockClientId,
@@ -150,7 +145,7 @@ export function PrivateBlockToolbar( {
150
145
  ) &&
151
146
  selectedBlockClientIds.length === 1,
152
147
  isUsingBindings: _isUsingBindings,
153
- hasParentPattern: _hasParentPattern,
148
+ isSectionContainer: _isSectionBlock,
154
149
  hasContentOnlyLocking: _hasTemplateLock,
155
150
  showShuffleButton: _isZoomOut,
156
151
  showSlots: ! _isZoomOut,
@@ -210,34 +205,33 @@ export function PrivateBlockToolbar( {
210
205
  { showParentSelector && ! isMultiToolbar && isLargeViewport && (
211
206
  <BlockParentSelector />
212
207
  ) }
213
- { ( shouldShowVisualToolbar || isMultiToolbar ) &&
214
- ! hasParentPattern && (
215
- <div
216
- ref={ nodeRef }
217
- { ...showHoveredOrFocusedGestures }
218
- >
219
- <ToolbarGroup className="block-editor-block-toolbar__block-controls">
220
- <BlockSwitcher clientIds={ blockClientIds } />
221
- { isDefaultEditingMode &&
222
- showBlockVisibilityButton && (
223
- <BlockVisibilityToolbar
224
- clientIds={ blockClientIds }
225
- />
226
- ) }
227
- { ! isMultiToolbar &&
228
- isDefaultEditingMode &&
229
- showLockButtons && (
230
- <BlockLockToolbar
231
- clientId={ blockClientId }
232
- />
233
- ) }
234
- <BlockMover
235
- clientIds={ blockClientIds }
236
- hideDragHandle={ hideDragHandle }
237
- />
238
- </ToolbarGroup>
239
- </div>
240
- ) }
208
+ { ( shouldShowVisualToolbar || isMultiToolbar ) && (
209
+ <div ref={ nodeRef } { ...showHoveredOrFocusedGestures }>
210
+ <ToolbarGroup className="block-editor-block-toolbar__block-controls">
211
+ <BlockToolbarIcon
212
+ clientIds={ blockClientIds }
213
+ isSynced={ isSynced }
214
+ />
215
+ { isDefaultEditingMode &&
216
+ showBlockVisibilityButton && (
217
+ <BlockVisibilityToolbar
218
+ clientIds={ blockClientIds }
219
+ />
220
+ ) }
221
+ { ! isMultiToolbar &&
222
+ isDefaultEditingMode &&
223
+ showLockButtons && (
224
+ <BlockLockToolbar
225
+ clientId={ blockClientId }
226
+ />
227
+ ) }
228
+ <BlockMover
229
+ clientIds={ blockClientIds }
230
+ hideDragHandle={ hideDragHandle }
231
+ />
232
+ </ToolbarGroup>
233
+ </div>
234
+ ) }
241
235
  { ! hasContentOnlyLocking &&
242
236
  shouldShowVisualToolbar &&
243
237
  isMultiToolbar &&
@@ -250,19 +244,23 @@ export function PrivateBlockToolbar( {
250
244
  ) }
251
245
  { shouldShowVisualToolbar && showSlots && (
252
246
  <>
253
- <BlockControls.Slot
254
- group="parent"
255
- className="block-editor-block-toolbar__slot"
256
- />
257
- <BlockControls.Slot
258
- group="block"
259
- className="block-editor-block-toolbar__slot"
260
- />
261
- <BlockControls.Slot className="block-editor-block-toolbar__slot" />
262
- <BlockControls.Slot
263
- group="inline"
264
- className="block-editor-block-toolbar__slot"
265
- />
247
+ { ! isSectionContainer && (
248
+ <>
249
+ <BlockControls.Slot
250
+ group="parent"
251
+ className="block-editor-block-toolbar__slot"
252
+ />
253
+ <BlockControls.Slot
254
+ group="block"
255
+ className="block-editor-block-toolbar__slot"
256
+ />
257
+ <BlockControls.Slot className="block-editor-block-toolbar__slot" />
258
+ <BlockControls.Slot
259
+ group="inline"
260
+ className="block-editor-block-toolbar__slot"
261
+ />
262
+ </>
263
+ ) }
266
264
  <BlockControls.Slot
267
265
  group="other"
268
266
  className="block-editor-block-toolbar__slot"
@@ -0,0 +1,99 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ Popover,
6
+ ToolbarButton,
7
+ __experimentalText as Text,
8
+ } from '@wordpress/components';
9
+ import { __, sprintf } from '@wordpress/i18n';
10
+ import { useState, useRef } from '@wordpress/element';
11
+ import { useSelect } from '@wordpress/data';
12
+
13
+ /**
14
+ * Internal dependencies
15
+ */
16
+ import { store as blockEditorStore } from '../../store';
17
+
18
+ /**
19
+ * Renders the content of the pattern overrides popover.
20
+ * Only mounts when the popover is opened.
21
+ *
22
+ * @param {Object} props Component props.
23
+ * @param {Array} props.clientIds The client IDs of selected blocks.
24
+ * @param {string} props.blockTitle The display title of the block.
25
+ * @return {JSX.Element} The popover content.
26
+ */
27
+ function PatternOverridesPopoverContent( { clientIds, blockTitle } ) {
28
+ const blockMetaName = useSelect(
29
+ ( select ) => {
30
+ const { getBlockAttributes } = select( blockEditorStore );
31
+ return getBlockAttributes( clientIds?.[ 0 ] )?.metadata?.name;
32
+ },
33
+ [ clientIds ]
34
+ );
35
+
36
+ const isSingleBlock = clientIds.length === 1;
37
+
38
+ // Pattern overrides description
39
+ let description;
40
+ if ( isSingleBlock && blockMetaName ) {
41
+ description = sprintf(
42
+ /* translators: 1: The block type's name. 2: The block's user-provided name (the same as the override name). */
43
+ __( 'This %1$s is editable using the "%2$s" override.' ),
44
+ blockTitle.toLowerCase(),
45
+ blockMetaName
46
+ );
47
+ } else {
48
+ description = __( 'These blocks are editable using overrides.' );
49
+ }
50
+
51
+ return <Text>{ description }</Text>;
52
+ }
53
+
54
+ /**
55
+ * Renders a toolbar button that displays information about pattern overrides in a popover.
56
+ *
57
+ * @param {Object} props Component props.
58
+ * @param {JSX.Element} props.icon The icon element to display.
59
+ * @param {Array} props.clientIds The client IDs of selected blocks.
60
+ * @param {string} props.blockTitle The display title of the block.
61
+ * @param {string} props.label The label for the button.
62
+ * @return {JSX.Element} The pattern overrides button component.
63
+ */
64
+ export default function PatternOverridesDropdown( {
65
+ icon,
66
+ clientIds,
67
+ blockTitle,
68
+ label,
69
+ } ) {
70
+ const [ isOpen, setIsOpen ] = useState( false );
71
+ const anchorRef = useRef();
72
+
73
+ return (
74
+ <>
75
+ <ToolbarButton
76
+ ref={ anchorRef }
77
+ className="block-editor-block-toolbar__pattern-overrides-indicator"
78
+ icon={ icon }
79
+ label={ label }
80
+ onClick={ () => setIsOpen( ! isOpen ) }
81
+ aria-expanded={ isOpen }
82
+ />
83
+ { isOpen && (
84
+ <Popover
85
+ anchor={ anchorRef.current }
86
+ onClose={ () => setIsOpen( false ) }
87
+ placement="bottom-start"
88
+ offset={ 16 }
89
+ className="block-editor-block-toolbar__pattern-overrides-popover"
90
+ >
91
+ <PatternOverridesPopoverContent
92
+ clientIds={ clientIds }
93
+ blockTitle={ blockTitle }
94
+ />
95
+ </Popover>
96
+ ) }
97
+ </>
98
+ );
99
+ }
@@ -50,13 +50,19 @@
50
50
  }
51
51
  }
52
52
 
53
- &.is-synced,
54
- &.is-connected {
55
- .block-editor-block-switcher .components-button .block-editor-block-icon {
56
- color: var(--wp-block-synced-color);
53
+ // Disabled block toolbar icon should have a fixed color.
54
+ .components-button.block-editor-block-toolbar__block-icon-button[aria-disabled="true"] {
55
+ color: $gray-900;
56
+
57
+ // Since it's not clickable, though, don't show a hover state.
58
+ &:hover {
59
+ color: $gray-900;
57
60
  }
61
+ }
58
62
 
59
- .block-editor-block-switcher__no-switcher-icon[aria-disabled="true"] .block-editor-block-icon {
63
+ &.is-synced,
64
+ &.is-connected {
65
+ .block-editor-block-toolbar__block-icon {
60
66
  color: var(--wp-block-synced-color);
61
67
  }
62
68
  }
@@ -145,15 +151,6 @@
145
151
 
146
152
  // Block controls.
147
153
  .block-editor-block-toolbar__block-controls {
148
- // Switcher.
149
- .block-editor-block-switcher .components-dropdown-menu__toggle,
150
- .block-editor-block-switcher__no-switcher-icon {
151
- .block-editor-block-icon {
152
- width: $button-size-small !important;
153
- margin: 0 !important;
154
- }
155
- }
156
-
157
154
  // @todo override toolbar group inherited paddings from components/block-tools/style.scss.
158
155
  // This is best fixed by making the mover control area a proper single toolbar group.
159
156
  .components-toolbar-group {
@@ -161,6 +158,12 @@
161
158
  }
162
159
  }
163
160
 
161
+ // Pattern overrides indicator popover
162
+ .block-editor-block-toolbar__pattern-overrides-popover .components-popover__content {
163
+ min-width: 260px;
164
+ padding: $grid-unit-20;
165
+ }
166
+
164
167
  .block-editor-block-toolbar,
165
168
  .block-editor-rich-text__inline-format-toolbar-group {
166
169
  // Override Toolbar buttons size.
@@ -198,13 +201,10 @@
198
201
  padding-right: 6px;
199
202
  }
200
203
 
201
- .block-editor-block-switcher .components-dropdown-menu__toggle,
202
- .block-editor-block-switcher__no-switcher-icon {
203
- .block-editor-block-icon {
204
- width: 0 !important;
205
- height: 0 !important;
206
- min-width: 0 !important;
207
- }
204
+ .block-editor-block-icon {
205
+ width: 0 !important;
206
+ height: 0 !important;
207
+ min-width: 0 !important;
208
208
  }
209
209
 
210
210
  // Parent selector overrides
@@ -68,10 +68,12 @@ exports[`Block Actions Menu block options duplicates a block 1`] = `
68
68
  <!-- /wp:heading -->"
69
69
  `;
70
70
 
71
- exports[`Block Actions Menu block options transforms a Paragraph block into a Pullquote block 1`] = `
72
- "<!-- wp:pullquote -->
73
- <figure class="wp-block-pullquote"><blockquote><p>Hello!</p></blockquote></figure>
74
- <!-- /wp:pullquote -->
71
+ exports[`Block Actions Menu block options transforms a Paragraph block into a Quote block 1`] = `
72
+ "<!-- wp:quote -->
73
+ <blockquote class="wp-block-quote"><!-- wp:paragraph -->
74
+ <p>Hello!</p>
75
+ <!-- /wp:paragraph --></blockquote>
76
+ <!-- /wp:quote -->
75
77
 
76
78
  <!-- wp:spacer -->
77
79
  <div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>