@wordpress/block-editor 15.7.1-next.2f1c7c01b.0 → 15.8.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 (187) 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 +3 -2
  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/index.js +1 -0
  41. package/build/components/rich-text/index.js.map +2 -2
  42. package/build/hooks/border.js +10 -5
  43. package/build/hooks/border.js.map +3 -3
  44. package/build/hooks/color.js +31 -9
  45. package/build/hooks/color.js.map +3 -3
  46. package/build/hooks/content-lock-ui.js +4 -5
  47. package/build/hooks/content-lock-ui.js.map +2 -2
  48. package/build/hooks/dimensions.js +9 -4
  49. package/build/hooks/dimensions.js.map +2 -2
  50. package/build/hooks/fit-text.js +19 -75
  51. package/build/hooks/fit-text.js.map +3 -3
  52. package/build/hooks/font-size.js +5 -2
  53. package/build/hooks/font-size.js.map +2 -2
  54. package/build/hooks/layout.js +4 -1
  55. package/build/hooks/layout.js.map +2 -2
  56. package/build/hooks/spacing-visualizer.js +5 -0
  57. package/build/hooks/spacing-visualizer.js.map +2 -2
  58. package/build/hooks/typography.js +23 -14
  59. package/build/hooks/typography.js.map +3 -3
  60. package/build/store/private-selectors.js +21 -1
  61. package/build/store/private-selectors.js.map +2 -2
  62. package/build/store/reducer.js +4 -0
  63. package/build/store/reducer.js.map +2 -2
  64. package/build/store/selectors.js +9 -3
  65. package/build/store/selectors.js.map +2 -2
  66. package/build/utils/fit-text-frontend.js +1 -0
  67. package/build/utils/fit-text-frontend.js.map +2 -2
  68. package/build/utils/fit-text-utils.js +1 -1
  69. package/build/utils/fit-text-utils.js.map +1 -1
  70. package/build-module/components/block-card/index.js +82 -32
  71. package/build-module/components/block-card/index.js.map +2 -2
  72. package/build-module/components/block-inspector/edit-contents.js +51 -0
  73. package/build-module/components/block-inspector/edit-contents.js.map +7 -0
  74. package/build-module/components/block-inspector/index.js +32 -9
  75. package/build-module/components/block-inspector/index.js.map +2 -2
  76. package/build-module/components/block-list/index.js +11 -11
  77. package/build-module/components/block-list/index.js.map +2 -2
  78. package/build-module/components/block-switcher/index.js +24 -124
  79. package/build-module/components/block-switcher/index.js.map +2 -2
  80. package/build-module/components/block-toolbar/block-toolbar-icon.js +144 -0
  81. package/build-module/components/block-toolbar/block-toolbar-icon.js.map +7 -0
  82. package/build-module/components/block-toolbar/index.js +51 -53
  83. package/build-module/components/block-toolbar/index.js.map +2 -2
  84. package/build-module/components/block-toolbar/pattern-overrides-dropdown.js +76 -0
  85. package/build-module/components/block-toolbar/pattern-overrides-dropdown.js.map +7 -0
  86. package/build-module/components/block-tools/index.js +10 -3
  87. package/build-module/components/block-tools/index.js.map +2 -2
  88. package/build-module/components/border-radius-control/utils.js +7 -3
  89. package/build-module/components/border-radius-control/utils.js.map +2 -2
  90. package/build-module/components/content-lock/modify-content-lock-menu-item.js +3 -3
  91. package/build-module/components/content-lock/modify-content-lock-menu-item.js.map +2 -2
  92. package/build-module/components/global-styles/border-panel.js +11 -7
  93. package/build-module/components/global-styles/border-panel.js.map +2 -2
  94. package/build-module/components/global-styles/color-panel.js +34 -27
  95. package/build-module/components/global-styles/color-panel.js.map +2 -2
  96. package/build-module/components/global-styles/typography-panel.js +3 -2
  97. package/build-module/components/global-styles/typography-panel.js.map +2 -2
  98. package/build-module/components/inserter/media-tab/media-tab.js +2 -1
  99. package/build-module/components/inserter/media-tab/media-tab.js.map +2 -2
  100. package/build-module/components/inspector-controls-tabs/index.js +2 -1
  101. package/build-module/components/inspector-controls-tabs/index.js.map +2 -2
  102. package/build-module/components/inspector-controls-tabs/styles-tab.js +55 -1
  103. package/build-module/components/inspector-controls-tabs/styles-tab.js.map +2 -2
  104. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js +1 -1
  105. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.js.map +2 -2
  106. package/build-module/components/keyboard-shortcuts/index.js +8 -0
  107. package/build-module/components/keyboard-shortcuts/index.js.map +2 -2
  108. package/build-module/components/rich-text/index.js +1 -0
  109. package/build-module/components/rich-text/index.js.map +2 -2
  110. package/build-module/hooks/border.js +10 -5
  111. package/build-module/hooks/border.js.map +3 -3
  112. package/build-module/hooks/color.js +31 -9
  113. package/build-module/hooks/color.js.map +3 -3
  114. package/build-module/hooks/content-lock-ui.js +4 -5
  115. package/build-module/hooks/content-lock-ui.js.map +2 -2
  116. package/build-module/hooks/dimensions.js +9 -4
  117. package/build-module/hooks/dimensions.js.map +2 -2
  118. package/build-module/hooks/fit-text.js +18 -66
  119. package/build-module/hooks/fit-text.js.map +2 -2
  120. package/build-module/hooks/font-size.js +5 -2
  121. package/build-module/hooks/font-size.js.map +2 -2
  122. package/build-module/hooks/layout.js +4 -1
  123. package/build-module/hooks/layout.js.map +2 -2
  124. package/build-module/hooks/spacing-visualizer.js +5 -0
  125. package/build-module/hooks/spacing-visualizer.js.map +2 -2
  126. package/build-module/hooks/typography.js +23 -14
  127. package/build-module/hooks/typography.js.map +3 -3
  128. package/build-module/store/private-selectors.js +20 -1
  129. package/build-module/store/private-selectors.js.map +2 -2
  130. package/build-module/store/reducer.js +4 -0
  131. package/build-module/store/reducer.js.map +2 -2
  132. package/build-module/store/selectors.js +9 -3
  133. package/build-module/store/selectors.js.map +2 -2
  134. package/build-module/utils/fit-text-frontend.js +1 -0
  135. package/build-module/utils/fit-text-frontend.js.map +2 -2
  136. package/build-module/utils/fit-text-utils.js +1 -1
  137. package/build-module/utils/fit-text-utils.js.map +1 -1
  138. package/build-style/style-rtl.css +31 -71
  139. package/build-style/style.css +31 -71
  140. package/package.json +37 -37
  141. package/src/components/block-card/index.js +95 -38
  142. package/src/components/block-card/style.scss +17 -1
  143. package/src/components/block-inspector/edit-contents.js +64 -0
  144. package/src/components/block-inspector/index.js +35 -13
  145. package/src/components/block-inspector/style.scss +6 -3
  146. package/src/components/block-list/index.js +11 -9
  147. package/src/components/block-switcher/index.js +51 -180
  148. package/src/components/block-switcher/style.scss +0 -70
  149. package/src/components/block-switcher/test/index.js +17 -18
  150. package/src/components/block-toolbar/block-toolbar-icon.js +173 -0
  151. package/src/components/block-toolbar/index.js +50 -52
  152. package/src/components/block-toolbar/pattern-overrides-dropdown.js +99 -0
  153. package/src/components/block-toolbar/style.scss +21 -21
  154. package/src/components/block-toolbar/test/block-toolbar-icon.js +182 -0
  155. package/src/components/block-tools/index.js +11 -1
  156. package/src/components/border-radius-control/test/utils.js +90 -0
  157. package/src/components/border-radius-control/utils.js +7 -3
  158. package/src/components/content-lock/modify-content-lock-menu-item.js +9 -3
  159. package/src/components/global-styles/border-panel.js +11 -7
  160. package/src/components/global-styles/color-panel.js +32 -26
  161. package/src/components/global-styles/typography-panel.js +2 -1
  162. package/src/components/inserter/media-tab/media-tab.js +7 -1
  163. package/src/components/inspector-controls-tabs/index.js +1 -0
  164. package/src/components/inspector-controls-tabs/styles-tab.js +58 -0
  165. package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +5 -1
  166. package/src/components/keyboard-shortcuts/index.js +9 -0
  167. package/src/components/rich-text/index.js +1 -0
  168. package/src/hooks/border.js +12 -6
  169. package/src/hooks/color.js +40 -13
  170. package/src/hooks/content-lock-ui.js +9 -6
  171. package/src/hooks/dimensions.js +25 -17
  172. package/src/hooks/fit-text.js +23 -84
  173. package/src/hooks/font-size.js +7 -2
  174. package/src/hooks/layout.js +11 -7
  175. package/src/hooks/spacing-visualizer.js +9 -1
  176. package/src/hooks/typography.js +24 -18
  177. package/src/store/private-selectors.js +26 -1
  178. package/src/store/reducer.js +6 -0
  179. package/src/store/selectors.js +17 -3
  180. package/src/utils/fit-text-frontend.js +1 -0
  181. package/src/utils/fit-text-utils.js +1 -1
  182. package/tsconfig.tsbuildinfo +1 -1
  183. package/build/components/block-inspector/edit-contents-button.js +0 -61
  184. package/build/components/block-inspector/edit-contents-button.js.map +0 -7
  185. package/build-module/components/block-inspector/edit-contents-button.js +0 -40
  186. package/build-module/components/block-inspector/edit-contents-button.js.map +0 -7
  187. package/src/components/block-inspector/edit-contents-button.js +0 -46
@@ -260,16 +260,37 @@ function ColorInspectorControl( { children, resetAllFilter } ) {
260
260
  );
261
261
  }
262
262
 
263
- export function ColorEdit( { clientId, name, setAttributes, settings } ) {
263
+ export function ColorEdit( {
264
+ clientId,
265
+ name,
266
+ setAttributes,
267
+ settings,
268
+ asWrapper,
269
+ label,
270
+ defaultControls,
271
+ } ) {
264
272
  const isEnabled = useHasColorPanel( settings );
265
- function selector( select ) {
266
- const { style, textColor, backgroundColor, gradient } =
267
- select( blockEditorStore ).getBlockAttributes( clientId ) || {};
268
- return { style, textColor, backgroundColor, gradient };
269
- }
273
+
270
274
  const { style, textColor, backgroundColor, gradient } = useSelect(
271
- selector,
272
- [ clientId ]
275
+ ( select ) => {
276
+ // Early return to avoid subscription when disabled
277
+ if ( ! isEnabled ) {
278
+ return {};
279
+ }
280
+ const {
281
+ style: _style,
282
+ textColor: _textColor,
283
+ backgroundColor: _backgroundColor,
284
+ gradient: _gradient,
285
+ } = select( blockEditorStore ).getBlockAttributes( clientId ) || {};
286
+ return {
287
+ style: _style,
288
+ textColor: _textColor,
289
+ backgroundColor: _backgroundColor,
290
+ gradient: _gradient,
291
+ };
292
+ },
293
+ [ clientId, isEnabled ]
273
294
  );
274
295
  const value = useMemo( () => {
275
296
  return attributesToStyle( {
@@ -288,10 +309,12 @@ export function ColorEdit( { clientId, name, setAttributes, settings } ) {
288
309
  return null;
289
310
  }
290
311
 
291
- const defaultControls = getBlockSupport( name, [
292
- COLOR_SUPPORT_KEY,
293
- '__experimentalDefaultControls',
294
- ] );
312
+ defaultControls = defaultControls
313
+ ? defaultControls
314
+ : getBlockSupport( name, [
315
+ COLOR_SUPPORT_KEY,
316
+ '__experimentalDefaultControls',
317
+ ] );
295
318
 
296
319
  const enableContrastChecking =
297
320
  Platform.OS === 'web' &&
@@ -306,14 +329,18 @@ export function ColorEdit( { clientId, name, setAttributes, settings } ) {
306
329
  'enableContrastChecker',
307
330
  ] );
308
331
 
332
+ // Use provided wrapper or default to ColorInspectorControl
333
+ const Wrapper = asWrapper || ColorInspectorControl;
334
+
309
335
  return (
310
336
  <StylesColorPanel
311
- as={ ColorInspectorControl }
337
+ as={ Wrapper }
312
338
  panelId={ clientId }
313
339
  settings={ settings }
314
340
  value={ value }
315
341
  onChange={ onChange }
316
342
  defaultControls={ defaultControls }
343
+ label={ label }
317
344
  enableContrastChecker={
318
345
  false !==
319
346
  getBlockSupport( name, [
@@ -45,17 +45,20 @@ function ContentLockControlsPure( { clientId } ) {
45
45
  ! isLockedByParent && templateLock === 'contentOnly';
46
46
 
47
47
  const stopEditingAsBlockCallback = useCallback( () => {
48
- stopEditingContentOnlySection( clientId );
49
- }, [ clientId, stopEditingContentOnlySection ] );
48
+ stopEditingContentOnlySection();
49
+ }, [ stopEditingContentOnlySection ] );
50
50
 
51
- if ( ! isContentLocked && ! isEditingContentOnlySection ) {
51
+ // Hide the Done button when the content only pattern insertion experiment is active.
52
+ // This is replaced by an alternative UI in the experiment.
53
+ if (
54
+ window?.__experimentalContentOnlyPatternInsertion ||
55
+ ( ! isContentLocked && ! isEditingContentOnlySection )
56
+ ) {
52
57
  return null;
53
58
  }
54
59
 
55
- const showDoneButton = isEditingContentOnlySection && ! isContentLocked;
56
-
57
60
  return (
58
- showDoneButton && (
61
+ isEditingContentOnlySection && (
59
62
  <BlockControls group="other">
60
63
  <ToolbarButton onClick={ stopEditingAsBlockCallback }>
61
64
  { __( 'Done' ) }
@@ -71,9 +71,15 @@ function DimensionsInspectorControl( { children, resetAllFilter } ) {
71
71
  export function DimensionsPanel( { clientId, name, setAttributes, settings } ) {
72
72
  const isEnabled = useHasDimensionsPanel( settings );
73
73
  const value = useSelect(
74
- ( select ) =>
75
- select( blockEditorStore ).getBlockAttributes( clientId )?.style,
76
- [ clientId ]
74
+ ( select ) => {
75
+ // Early return to avoid subscription when disabled
76
+ if ( ! isEnabled ) {
77
+ return undefined;
78
+ }
79
+ return select( blockEditorStore ).getBlockAttributes( clientId )
80
+ ?.style;
81
+ },
82
+ [ clientId, isEnabled ]
77
83
  );
78
84
  const [ visualizedProperty, setVisualizedProperty ] = useVisualizer();
79
85
  const onChange = ( newStyle ) => {
@@ -110,20 +116,22 @@ export function DimensionsPanel( { clientId, name, setAttributes, settings } ) {
110
116
  defaultControls={ defaultControls }
111
117
  onVisualize={ setVisualizedProperty }
112
118
  />
113
- { !! settings?.spacing?.padding && (
114
- <PaddingVisualizer
115
- forceShow={ visualizedProperty === 'padding' }
116
- clientId={ clientId }
117
- value={ value }
118
- />
119
- ) }
120
- { !! settings?.spacing?.margin && (
121
- <MarginVisualizer
122
- forceShow={ visualizedProperty === 'margin' }
123
- clientId={ clientId }
124
- value={ value }
125
- />
126
- ) }
119
+ { !! settings?.spacing?.padding &&
120
+ visualizedProperty === 'padding' && (
121
+ <PaddingVisualizer
122
+ forceShow={ visualizedProperty === 'padding' }
123
+ clientId={ clientId }
124
+ value={ value }
125
+ />
126
+ ) }
127
+ { !! settings?.spacing?.margin &&
128
+ visualizedProperty === 'margin' && (
129
+ <MarginVisualizer
130
+ forceShow={ visualizedProperty === 'margin' }
131
+ clientId={ clientId }
132
+ value={ value }
133
+ />
134
+ ) }
127
135
  </>
128
136
  );
129
137
  }
@@ -5,11 +5,8 @@ import { addFilter } from '@wordpress/hooks';
5
5
  import { hasBlockSupport } from '@wordpress/blocks';
6
6
  import { useEffect, useCallback } from '@wordpress/element';
7
7
  import { useSelect } from '@wordpress/data';
8
- import { __ } from '@wordpress/i18n';
9
- import {
10
- ToggleControl,
11
- __experimentalToolsPanelItem as ToolsPanelItem,
12
- } from '@wordpress/components';
8
+
9
+ const EMPTY_OBJECT = {};
13
10
 
14
11
  /**
15
12
  * Internal dependencies
@@ -17,7 +14,6 @@ import {
17
14
  import { optimizeFitText } from '../utils/fit-text-utils';
18
15
  import { store as blockEditorStore } from '../store';
19
16
  import { useBlockElement } from '../components/block-list/use-block-props/use-block-refs';
20
- import InspectorControls from '../components/inspector-controls';
21
17
 
22
18
  export const FIT_TEXT_SUPPORT_KEY = 'typography.fitText';
23
19
 
@@ -62,14 +58,19 @@ function useFitText( { fitText, name, clientId } ) {
62
58
  const hasFitTextSupport = hasBlockSupport( name, FIT_TEXT_SUPPORT_KEY );
63
59
  const blockElement = useBlockElement( clientId );
64
60
 
65
- // Monitor block attribute changes
66
- // Any attribute may change the available space.
67
- const blockAttributes = useSelect(
61
+ // Monitor block attribute changes, and parent changes.
62
+ // Any attribute or parent change may change the available space.
63
+ const { blockAttributes, parentId } = useSelect(
68
64
  ( select ) => {
69
65
  if ( ! clientId || ! hasFitTextSupport || ! fitText ) {
70
- return;
66
+ return EMPTY_OBJECT;
71
67
  }
72
- return select( blockEditorStore ).getBlockAttributes( clientId );
68
+ return {
69
+ blockAttributes:
70
+ select( blockEditorStore ).getBlockAttributes( clientId ),
71
+ parentId:
72
+ select( blockEditorStore ).getBlockRootClientId( clientId ),
73
+ };
73
74
  },
74
75
  [ clientId, hasFitTextSupport, fitText ]
75
76
  );
@@ -143,6 +144,7 @@ function useFitText( { fitText, name, clientId } ) {
143
144
  if ( window.ResizeObserver && currentElement.parentElement ) {
144
145
  resizeObserver = new window.ResizeObserver( applyFitText );
145
146
  resizeObserver.observe( currentElement.parentElement );
147
+ resizeObserver.observe( currentElement );
146
148
  }
147
149
 
148
150
  // Cleanup function
@@ -169,7 +171,14 @@ function useFitText( { fitText, name, clientId } ) {
169
171
  styleElement.remove();
170
172
  }
171
173
  };
172
- }, [ fitText, clientId, applyFitText, blockElement, hasFitTextSupport ] );
174
+ }, [
175
+ fitText,
176
+ clientId,
177
+ parentId,
178
+ applyFitText,
179
+ blockElement,
180
+ hasFitTextSupport,
181
+ ] );
173
182
 
174
183
  // Trigger fit text recalculation when content changes
175
184
  useEffect( () => {
@@ -192,76 +201,6 @@ function useFitText( { fitText, name, clientId } ) {
192
201
  ] );
193
202
  }
194
203
 
195
- /**
196
- * Fit text control component for the typography panel.
197
- *
198
- * @param {Object} props Component props.
199
- * @param {string} props.clientId Block client ID.
200
- * @param {Function} props.setAttributes Function to set block attributes.
201
- * @param {string} props.name Block name.
202
- * @param {boolean} props.fitText Whether fit text is enabled.
203
- * @param {string} props.fontSize Font size slug.
204
- * @param {Object} props.style Block style object.
205
- */
206
- export function FitTextControl( {
207
- clientId,
208
- fitText = false,
209
- setAttributes,
210
- name,
211
- fontSize,
212
- style,
213
- } ) {
214
- if ( ! hasBlockSupport( name, FIT_TEXT_SUPPORT_KEY ) ) {
215
- return null;
216
- }
217
- return (
218
- <InspectorControls group="typography">
219
- <ToolsPanelItem
220
- hasValue={ () => fitText }
221
- label={ __( 'Fit text' ) }
222
- onDeselect={ () => setAttributes( { fitText: undefined } ) }
223
- resetAllFilter={ () => ( { fitText: undefined } ) }
224
- panelId={ clientId }
225
- >
226
- <ToggleControl
227
- __nextHasNoMarginBottom
228
- label={ __( 'Fit text' ) }
229
- checked={ fitText }
230
- onChange={ () => {
231
- const newFitText = ! fitText || undefined;
232
- const updates = { fitText: newFitText };
233
-
234
- // When enabling fit text, clear font size if it has a value
235
- if ( newFitText ) {
236
- if ( fontSize ) {
237
- updates.fontSize = undefined;
238
- }
239
- if ( style?.typography?.fontSize ) {
240
- updates.style = {
241
- ...style,
242
- typography: {
243
- ...style?.typography,
244
- fontSize: undefined,
245
- },
246
- };
247
- }
248
- }
249
-
250
- setAttributes( updates );
251
- } }
252
- help={
253
- fitText
254
- ? __( 'Text will resize to fit its container.' )
255
- : __(
256
- 'The text will resize to fit its container, resetting other font size settings.'
257
- )
258
- }
259
- />
260
- </ToolsPanelItem>
261
- </InspectorControls>
262
- );
263
- }
264
-
265
204
  /**
266
205
  * Override props applied to the block element on save.
267
206
  *
@@ -323,7 +262,7 @@ const hasFitTextSupport = ( blockNameOrType ) => {
323
262
  export default {
324
263
  useBlockProps,
325
264
  addSaveProps,
326
- attributeKeys: [ 'fitText', 'fontSize', 'style' ],
265
+ attributeKeys: [ 'fitText' ],
327
266
  hasSupport: hasFitTextSupport,
328
- edit: FitTextControl,
267
+ edit: () => null,
329
268
  };
@@ -92,11 +92,16 @@ function addSaveProps( props, blockNameOrType, attributes ) {
92
92
  */
93
93
  export function FontSizeEdit( props ) {
94
94
  const {
95
- attributes: { fontSize, style },
95
+ attributes: { fontSize, style, fitText },
96
96
  setAttributes,
97
97
  } = props;
98
+
98
99
  const [ fontSizes ] = useSettings( 'typography.fontSizes' );
99
100
 
101
+ // Hide font size UI when fitText is enabled
102
+ if ( fitText ) {
103
+ return null;
104
+ }
100
105
  const onChange = ( value, selectedItem ) => {
101
106
  // Use the selectedItem's slug if available, otherwise fall back to finding by value
102
107
  const fontSizeSlug =
@@ -211,7 +216,7 @@ function useBlockProps( { name, fontSize, style } ) {
211
216
  export default {
212
217
  useBlockProps,
213
218
  addSaveProps,
214
- attributeKeys: [ 'fontSize', 'style' ],
219
+ attributeKeys: [ 'fontSize', 'style', 'fitText' ],
215
220
  hasSupport( name ) {
216
221
  return hasBlockSupport( name, FONT_SIZE_SUPPORT_KEY );
217
222
  },
@@ -74,13 +74,17 @@ export function useLayoutClasses( blockAttributes = {}, blockName = '' ) {
74
74
 
75
75
  const hasGlobalPadding = useSelect(
76
76
  ( select ) => {
77
- return (
78
- ( usedLayout?.inherit ||
79
- usedLayout?.contentSize ||
80
- usedLayout?.type === 'constrained' ) &&
81
- select( blockEditorStore ).getSettings().__experimentalFeatures
82
- ?.useRootPaddingAwareAlignments
83
- );
77
+ // Early return to avoid subscription when layout doesn't use global padding
78
+ if (
79
+ ! usedLayout?.inherit &&
80
+ ! usedLayout?.contentSize &&
81
+ usedLayout?.type !== 'constrained'
82
+ ) {
83
+ return false;
84
+ }
85
+
86
+ return select( blockEditorStore ).getSettings()
87
+ .__experimentalFeatures?.useRootPaddingAwareAlignments;
84
88
  },
85
89
  [ usedLayout?.contentSize, usedLayout?.inherit, usedLayout?.type ]
86
90
  );
@@ -16,7 +16,15 @@ function SpacingVisualizer( { clientId, value, computeStyle, forceShow } ) {
16
16
  computeStyle( blockElement )
17
17
  );
18
18
 
19
- // It's not sufficient to read the block’s computed style when `value` changes because
19
+ // Force style computation when forceShow becomes true (e.g., when hovering control)
20
+ // to ensure visualizer displays correct dimensions on first render.
21
+ useEffect( () => {
22
+ if ( blockElement && forceShow ) {
23
+ updateStyle();
24
+ }
25
+ }, [ blockElement, forceShow ] );
26
+
27
+ // It's not sufficient to read the block's computed style when `value` changes because
20
28
  // the effect would run before the block’s style has updated. Thus observing mutations
21
29
  // to the block’s attributes is used to trigger updates to the visualizer’s styles.
22
30
  useEffect( () => {
@@ -115,31 +115,36 @@ function TypographyInspectorControl( { children, resetAllFilter } ) {
115
115
  }
116
116
 
117
117
  export function TypographyPanel( { clientId, name, setAttributes, settings } ) {
118
- function selector( select ) {
119
- const { style, fontFamily, fontSize, fitText } =
120
- select( blockEditorStore ).getBlockAttributes( clientId ) || {};
121
- return { style, fontFamily, fontSize, fitText };
122
- }
123
- const { style, fontFamily, fontSize, fitText } = useSelect( selector, [
124
- clientId,
125
- ] );
126
118
  const isEnabled = useHasTypographyPanel( settings );
119
+
120
+ const { style, fontFamily, fontSize, fitText } = useSelect(
121
+ ( select ) => {
122
+ // Early return to avoid subscription when disabled.
123
+ if ( ! isEnabled ) {
124
+ return {};
125
+ }
126
+ const {
127
+ style: _style,
128
+ fontFamily: _fontFamily,
129
+ fontSize: _fontSize,
130
+ fitText: _fitText,
131
+ } = select( blockEditorStore ).getBlockAttributes( clientId ) || {};
132
+ return {
133
+ style: _style,
134
+ fontFamily: _fontFamily,
135
+ fontSize: _fontSize,
136
+ fitText: _fitText,
137
+ };
138
+ },
139
+ [ clientId, isEnabled ]
140
+ );
127
141
  const value = useMemo(
128
142
  () => attributesToStyle( { style, fontFamily, fontSize } ),
129
143
  [ style, fontSize, fontFamily ]
130
144
  );
131
145
 
132
146
  const onChange = ( newStyle ) => {
133
- const newAttributes = styleToAttributes( newStyle );
134
-
135
- // If setting a font size and fitText is currently enabled, disable it
136
- const hasFontSize =
137
- newAttributes.fontSize || newAttributes.style?.typography?.fontSize;
138
- if ( hasFontSize && fitText ) {
139
- newAttributes.fitText = undefined;
140
- }
141
-
142
- setAttributes( newAttributes );
147
+ setAttributes( styleToAttributes( newStyle ) );
143
148
  };
144
149
 
145
150
  if ( ! isEnabled ) {
@@ -159,6 +164,7 @@ export function TypographyPanel( { clientId, name, setAttributes, settings } ) {
159
164
  value={ value }
160
165
  onChange={ onChange }
161
166
  defaultControls={ defaultControls }
167
+ fitText={ fitText }
162
168
  />
163
169
  );
164
170
  }
@@ -493,7 +493,10 @@ export const getContentLockingParent = ( state, clientId ) => {
493
493
  export const getParentSectionBlock = ( state, clientId ) => {
494
494
  let current = clientId;
495
495
  let result;
496
- while ( ! result && ( current = state.blocks.parents.get( current ) ) ) {
496
+
497
+ // If sections are nested, return the top level section block.
498
+ // Don't return early.
499
+ while ( ( current = state.blocks.parents.get( current ) ) ) {
497
500
  if ( isSectionBlock( state, current ) ) {
498
501
  result = current;
499
502
  }
@@ -510,6 +513,10 @@ export const getParentSectionBlock = ( state, clientId ) => {
510
513
  * @return {boolean} Whether the block is a contentOnly section.
511
514
  */
512
515
  export function isSectionBlock( state, clientId ) {
516
+ if ( clientId === state.editedContentOnlySection ) {
517
+ return false;
518
+ }
519
+
513
520
  const blockName = getBlockName( state, clientId );
514
521
  if (
515
522
  blockName === 'core/block' ||
@@ -541,6 +548,24 @@ export function getEditedContentOnlySection( state ) {
541
548
  return state.editedContentOnlySection;
542
549
  }
543
550
 
551
+ export function isWithinEditedContentOnlySection( state, clientId ) {
552
+ if ( ! state.editedContentOnlySection ) {
553
+ return false;
554
+ }
555
+
556
+ if ( state.editedContentOnlySection === clientId ) {
557
+ return true;
558
+ }
559
+
560
+ let current = clientId;
561
+ while ( ( current = state.blocks.parents.get( current ) ) ) {
562
+ if ( state.editedContentOnlySection === current ) {
563
+ return true;
564
+ }
565
+ }
566
+ return false;
567
+ }
568
+
544
569
  /**
545
570
  * Returns the style attributes of multiple blocks.
546
571
  *
@@ -2331,6 +2331,12 @@ function getDerivedBlockEditingModesForTree( state, treeClientId = '' ) {
2331
2331
  derivedBlockEditingModes.set( clientId, 'default' );
2332
2332
  return;
2333
2333
  }
2334
+
2335
+ // For the content only pattern experiment, disable blocks that are outside of the edited section.
2336
+ if ( window?.__experimentalContentOnlyPatternInsertion ) {
2337
+ derivedBlockEditingModes.set( clientId, 'disabled' );
2338
+ return;
2339
+ }
2334
2340
  }
2335
2341
 
2336
2342
  // If the block already has an explicit block editing mode set,
@@ -2274,6 +2274,8 @@ export const getInserterItems = createRegistrySelector( ( select ) =>
2274
2274
  } ) );
2275
2275
  }
2276
2276
 
2277
+ // Hardcode: Collect stretch variations separately to add at the end
2278
+ const stretchVariations = [];
2277
2279
  const items = blockTypeInserterItems.reduce(
2278
2280
  ( accumulator, item ) => {
2279
2281
  const { variations = [] } = item;
@@ -2286,14 +2288,26 @@ export const getInserterItems = createRegistrySelector( ( select ) =>
2286
2288
  state,
2287
2289
  item
2288
2290
  );
2289
- accumulator.push(
2290
- ...variations.map( variationMapper )
2291
- );
2291
+ variations
2292
+ .map( variationMapper )
2293
+ .forEach( ( variation ) => {
2294
+ if (
2295
+ variation.id ===
2296
+ 'core/paragraph/stretchy-paragraph' ||
2297
+ variation.id ===
2298
+ 'core/heading/stretchy-heading'
2299
+ ) {
2300
+ stretchVariations.push( variation );
2301
+ } else {
2302
+ accumulator.push( variation );
2303
+ }
2304
+ } );
2292
2305
  }
2293
2306
  return accumulator;
2294
2307
  },
2295
2308
  []
2296
2309
  );
2310
+ items.push( ...stretchVariations );
2297
2311
 
2298
2312
  // Ensure core blocks are prioritized in the returned results,
2299
2313
  // because third party blocks can be registered earlier than
@@ -38,6 +38,7 @@ store( 'core/fit-text', {
38
38
  context.fontSize = optimizeFitText( ref, applyFontSize );
39
39
  } );
40
40
  resizeObserver.observe( ref.parentElement );
41
+ resizeObserver.observe( ref );
41
42
 
42
43
  // Return cleanup function to be called when element is removed.
43
44
  return () => {
@@ -14,7 +14,7 @@ function findOptimalFontSize( textElement, applyFontSize ) {
14
14
  const alreadyHasScrollableHeight =
15
15
  textElement.scrollHeight > textElement.clientHeight;
16
16
  let minSize = 5;
17
- let maxSize = 600;
17
+ let maxSize = 2400;
18
18
  let bestSize = minSize;
19
19
 
20
20
  while ( minSize <= maxSize ) {