@wordpress/block-editor 15.6.1-next.36001005c.0 → 15.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-list/block.js +3 -3
  3. package/build/components/block-list/block.js.map +2 -2
  4. package/build/components/block-list/index.js +2 -2
  5. package/build/components/block-list/index.js.map +1 -1
  6. package/build/components/block-toolbar/switch-section-style.js +2 -5
  7. package/build/components/block-toolbar/switch-section-style.js.map +2 -2
  8. package/build/components/global-styles/hooks.js +0 -107
  9. package/build/components/global-styles/hooks.js.map +3 -3
  10. package/build/components/global-styles/index.js +0 -15
  11. package/build/components/global-styles/index.js.map +2 -2
  12. package/build/components/global-styles/typography-panel.js +18 -1
  13. package/build/components/global-styles/typography-panel.js.map +2 -2
  14. package/build/components/global-styles/utils.js +0 -19
  15. package/build/components/global-styles/utils.js.map +3 -3
  16. package/build/components/inserter/media-tab/media-tab.js +33 -1
  17. package/build/components/inserter/media-tab/media-tab.js.map +3 -3
  18. package/build/components/inserter/tips.js +0 -2
  19. package/build/components/inserter/tips.js.map +2 -2
  20. package/build/components/media-placeholder/index.js +31 -1
  21. package/build/components/media-placeholder/index.js.map +3 -3
  22. package/build/components/media-replace-flow/index.js +29 -1
  23. package/build/components/media-replace-flow/index.js.map +3 -3
  24. package/build/components/{global-styles/context.js → media-upload-modal/index.js} +8 -23
  25. package/build/components/media-upload-modal/index.js.map +7 -0
  26. package/build/components/rich-text/index.js +8 -7
  27. package/build/components/rich-text/index.js.map +2 -2
  28. package/build/hooks/allowed-blocks.js +3 -8
  29. package/build/hooks/allowed-blocks.js.map +3 -3
  30. package/build/hooks/block-bindings.js +111 -170
  31. package/build/hooks/block-bindings.js.map +2 -2
  32. package/build/hooks/block-style-variation.js +4 -13
  33. package/build/hooks/block-style-variation.js.map +2 -2
  34. package/build/hooks/custom-class-name.js +1 -1
  35. package/build/hooks/custom-class-name.js.map +1 -1
  36. package/build/hooks/fit-text.js +33 -20
  37. package/build/hooks/fit-text.js.map +2 -2
  38. package/build/hooks/font-size.js +4 -3
  39. package/build/hooks/font-size.js.map +2 -2
  40. package/build/hooks/metadata.js +48 -2
  41. package/build/hooks/metadata.js.map +2 -2
  42. package/build/hooks/typography.js +11 -4
  43. package/build/hooks/typography.js.map +3 -3
  44. package/build/private-apis.js +3 -1
  45. package/build/private-apis.js.map +3 -3
  46. package/build/store/private-selectors.js +3 -3
  47. package/build/store/private-selectors.js.map +2 -2
  48. package/build/store/selectors.js +38 -13
  49. package/build/store/selectors.js.map +2 -2
  50. package/build/store/utils.js +2 -1
  51. package/build/store/utils.js.map +2 -2
  52. package/build/utils/fit-text-utils.js +4 -4
  53. package/build/utils/fit-text-utils.js.map +2 -2
  54. package/build-module/components/block-list/block.js +3 -3
  55. package/build-module/components/block-list/block.js.map +2 -2
  56. package/build-module/components/block-list/index.js +2 -2
  57. package/build-module/components/block-list/index.js.map +1 -1
  58. package/build-module/components/block-toolbar/switch-section-style.js +2 -5
  59. package/build-module/components/block-toolbar/switch-section-style.js.map +2 -2
  60. package/build-module/components/global-styles/hooks.js +1 -99
  61. package/build-module/components/global-styles/hooks.js.map +2 -2
  62. package/build-module/components/global-styles/index.js +1 -15
  63. package/build-module/components/global-styles/index.js.map +2 -2
  64. package/build-module/components/global-styles/typography-panel.js +18 -1
  65. package/build-module/components/global-styles/typography-panel.js.map +2 -2
  66. package/build-module/components/global-styles/utils.js +0 -8
  67. package/build-module/components/global-styles/utils.js.map +2 -2
  68. package/build-module/components/inserter/media-tab/media-tab.js +34 -2
  69. package/build-module/components/inserter/media-tab/media-tab.js.map +2 -2
  70. package/build-module/components/inserter/tips.js +0 -2
  71. package/build-module/components/inserter/tips.js.map +2 -2
  72. package/build-module/components/media-placeholder/index.js +31 -1
  73. package/build-module/components/media-placeholder/index.js.map +2 -2
  74. package/build-module/components/media-replace-flow/index.js +29 -1
  75. package/build-module/components/media-replace-flow/index.js.map +2 -2
  76. package/build-module/components/media-upload-modal/index.js +7 -0
  77. package/build-module/components/media-upload-modal/index.js.map +7 -0
  78. package/build-module/components/rich-text/index.js +8 -7
  79. package/build-module/components/rich-text/index.js.map +2 -2
  80. package/build-module/hooks/allowed-blocks.js +3 -8
  81. package/build-module/hooks/allowed-blocks.js.map +2 -2
  82. package/build-module/hooks/block-bindings.js +112 -172
  83. package/build-module/hooks/block-bindings.js.map +2 -2
  84. package/build-module/hooks/block-style-variation.js +5 -14
  85. package/build-module/hooks/block-style-variation.js.map +2 -2
  86. package/build-module/hooks/custom-class-name.js +1 -1
  87. package/build-module/hooks/custom-class-name.js.map +1 -1
  88. package/build-module/hooks/fit-text.js +34 -21
  89. package/build-module/hooks/fit-text.js.map +2 -2
  90. package/build-module/hooks/font-size.js +4 -3
  91. package/build-module/hooks/font-size.js.map +2 -2
  92. package/build-module/hooks/metadata.js +46 -1
  93. package/build-module/hooks/metadata.js.map +2 -2
  94. package/build-module/hooks/typography.js +11 -4
  95. package/build-module/hooks/typography.js.map +3 -3
  96. package/build-module/private-apis.js +3 -1
  97. package/build-module/private-apis.js.map +2 -2
  98. package/build-module/store/private-selectors.js +2 -2
  99. package/build-module/store/private-selectors.js.map +2 -2
  100. package/build-module/store/selectors.js +39 -14
  101. package/build-module/store/selectors.js.map +2 -2
  102. package/build-module/store/utils.js +3 -2
  103. package/build-module/store/utils.js.map +2 -2
  104. package/build-module/utils/fit-text-utils.js +4 -4
  105. package/build-module/utils/fit-text-utils.js.map +2 -2
  106. package/package.json +36 -36
  107. package/src/components/block-list/block.js +1 -1
  108. package/src/components/block-list/index.js +2 -2
  109. package/src/components/block-toolbar/switch-section-style.js +2 -5
  110. package/src/components/global-styles/hooks.js +1 -121
  111. package/src/components/global-styles/index.js +1 -9
  112. package/src/components/global-styles/typography-panel.js +26 -1
  113. package/src/components/global-styles/utils.js +0 -31
  114. package/src/components/inserter/media-tab/media-tab.js +44 -2
  115. package/src/components/inserter/tips.js +0 -2
  116. package/src/components/media-placeholder/index.js +41 -1
  117. package/src/components/media-replace-flow/index.js +39 -1
  118. package/src/components/media-upload-modal/index.js +18 -0
  119. package/src/components/rich-text/index.js +8 -14
  120. package/src/hooks/allowed-blocks.js +3 -11
  121. package/src/hooks/block-bindings.js +79 -153
  122. package/src/hooks/block-style-variation.js +5 -17
  123. package/src/hooks/custom-class-name.js +1 -1
  124. package/src/hooks/fit-text.js +39 -30
  125. package/src/hooks/font-size.js +7 -3
  126. package/src/hooks/metadata.js +89 -0
  127. package/src/hooks/test/metadata.js +316 -0
  128. package/src/hooks/typography.js +15 -4
  129. package/src/private-apis.js +2 -0
  130. package/src/store/private-selectors.js +2 -2
  131. package/src/store/selectors.js +59 -21
  132. package/src/store/test/selectors.js +1 -1
  133. package/src/store/utils.js +2 -1
  134. package/src/utils/fit-text-utils.js +4 -16
  135. package/tsconfig.json +1 -0
  136. package/build/components/global-styles/context.js.map +0 -7
  137. package/build/components/global-styles/get-global-styles-changes.js +0 -216
  138. package/build/components/global-styles/get-global-styles-changes.js.map +0 -7
  139. package/build-module/components/global-styles/context.js +0 -17
  140. package/build-module/components/global-styles/context.js.map +0 -7
  141. package/build-module/components/global-styles/get-global-styles-changes.js +0 -182
  142. package/build-module/components/global-styles/get-global-styles-changes.js.map +0 -7
  143. package/src/components/global-styles/README.md +0 -190
  144. package/src/components/global-styles/context.js +0 -16
  145. package/src/components/global-styles/get-global-styles-changes.js +0 -252
  146. package/src/components/global-styles/test/get-global-styles-changes.js +0 -290
  147. package/src/components/global-styles/test/utils.js +0 -58
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { addFilter } from '@wordpress/hooks';
5
5
  import { hasBlockSupport } from '@wordpress/blocks';
6
- import { useEffect, useCallback, useRef } from '@wordpress/element';
6
+ import { useEffect, useCallback } from '@wordpress/element';
7
7
  import { useSelect } from '@wordpress/data';
8
8
  import { __ } from '@wordpress/i18n';
9
9
  import {
@@ -62,28 +62,18 @@ function useFitText( { fitText, name, clientId } ) {
62
62
  const hasFitTextSupport = hasBlockSupport( name, FIT_TEXT_SUPPORT_KEY );
63
63
  const blockElement = useBlockElement( clientId );
64
64
 
65
- // Monitor block attribute changes and selection state
65
+ // Monitor block attribute changes
66
66
  // Any attribute may change the available space.
67
- const { blockAttributes, isSelected } = useSelect(
67
+ const blockAttributes = useSelect(
68
68
  ( select ) => {
69
- if ( ! clientId ) {
70
- return { blockAttributes: undefined, isSelected: false };
69
+ if ( ! clientId || ! hasFitTextSupport || ! fitText ) {
70
+ return;
71
71
  }
72
- return {
73
- blockAttributes:
74
- select( blockEditorStore ).getBlockAttributes( clientId ),
75
- isSelected:
76
- select( blockEditorStore ).isBlockSelected( clientId ),
77
- };
72
+ return select( blockEditorStore ).getBlockAttributes( clientId );
78
73
  },
79
- [ clientId ]
74
+ [ clientId, hasFitTextSupport, fitText ]
80
75
  );
81
76
 
82
- const isSelectedRef = useRef();
83
- useEffect( () => {
84
- isSelectedRef.current = isSelected;
85
- }, [ isSelected ] );
86
-
87
77
  const applyFitText = useCallback( () => {
88
78
  if ( ! blockElement || ! hasFitTextSupport || ! fitText ) {
89
79
  return;
@@ -104,13 +94,8 @@ function useFitText( { fitText, name, clientId } ) {
104
94
  styleElement.textContent = css;
105
95
  };
106
96
 
107
- // Avoid very jarring resizes when a user is actively editing the
108
- // block. Placing a ceiling on how much the block can grow curbs the
109
- // effect of the first few keypresses.
110
- const maxSize = isSelectedRef.current ? 200 : undefined;
111
-
112
- optimizeFitText( blockElement, blockSelector, applyStylesFn, maxSize );
113
- }, [ blockElement, clientId, hasFitTextSupport, fitText, isSelectedRef ] );
97
+ optimizeFitText( blockElement, blockSelector, applyStylesFn );
98
+ }, [ blockElement, clientId, hasFitTextSupport, fitText ] );
114
99
 
115
100
  useEffect( () => {
116
101
  if (
@@ -164,7 +149,6 @@ function useFitText( { fitText, name, clientId } ) {
164
149
  }
165
150
  }, [
166
151
  blockAttributes,
167
- isSelected,
168
152
  fitText,
169
153
  applyFitText,
170
154
  blockElement,
@@ -180,12 +164,16 @@ function useFitText( { fitText, name, clientId } ) {
180
164
  * @param {Function} props.setAttributes Function to set block attributes.
181
165
  * @param {string} props.name Block name.
182
166
  * @param {boolean} props.fitText Whether fit text is enabled.
167
+ * @param {string} props.fontSize Font size slug.
168
+ * @param {Object} props.style Block style object.
183
169
  */
184
170
  export function FitTextControl( {
185
171
  clientId,
186
172
  fitText = false,
187
173
  setAttributes,
188
174
  name,
175
+ fontSize,
176
+ style,
189
177
  } ) {
190
178
  if ( ! hasBlockSupport( name, FIT_TEXT_SUPPORT_KEY ) ) {
191
179
  return null;
@@ -203,13 +191,34 @@ export function FitTextControl( {
203
191
  __nextHasNoMarginBottom
204
192
  label={ __( 'Fit text' ) }
205
193
  checked={ fitText }
206
- onChange={ () =>
207
- setAttributes( { fitText: ! fitText || undefined } )
208
- }
194
+ onChange={ () => {
195
+ const newFitText = ! fitText || undefined;
196
+ const updates = { fitText: newFitText };
197
+
198
+ // When enabling fit text, clear font size if it has a value
199
+ if ( newFitText ) {
200
+ if ( fontSize ) {
201
+ updates.fontSize = undefined;
202
+ }
203
+ if ( style?.typography?.fontSize ) {
204
+ updates.style = {
205
+ ...style,
206
+ typography: {
207
+ ...style?.typography,
208
+ fontSize: undefined,
209
+ },
210
+ };
211
+ }
212
+ }
213
+
214
+ setAttributes( updates );
215
+ } }
209
216
  help={
210
217
  fitText
211
218
  ? __( 'Text will resize to fit its container.' )
212
- : __( 'Resize text to fit its container.' )
219
+ : __(
220
+ 'The text will resize to fit its container, resetting other font size settings.'
221
+ )
213
222
  }
214
223
  />
215
224
  </ToolsPanelItem>
@@ -278,7 +287,7 @@ const hasFitTextSupport = ( blockNameOrType ) => {
278
287
  export default {
279
288
  useBlockProps,
280
289
  addSaveProps,
281
- attributeKeys: [ 'fitText' ],
290
+ attributeKeys: [ 'fitText', 'fontSize', 'style' ],
282
291
  hasSupport: hasFitTextSupport,
283
292
  edit: FitTextControl,
284
293
  };
@@ -97,8 +97,11 @@ export function FontSizeEdit( props ) {
97
97
  } = props;
98
98
  const [ fontSizes ] = useSettings( 'typography.fontSizes' );
99
99
 
100
- const onChange = ( value ) => {
101
- const fontSizeSlug = getFontSizeObjectByValue( fontSizes, value ).slug;
100
+ const onChange = ( value, selectedItem ) => {
101
+ // Use the selectedItem's slug if available, otherwise fall back to finding by value
102
+ const fontSizeSlug =
103
+ selectedItem?.slug ||
104
+ getFontSizeObjectByValue( fontSizes, value ).slug;
102
105
 
103
106
  setAttributes( {
104
107
  style: cleanEmptyObject( {
@@ -124,7 +127,8 @@ export function FontSizeEdit( props ) {
124
127
  return (
125
128
  <FontSizePicker
126
129
  onChange={ onChange }
127
- value={ fontSizeValue }
130
+ value={ fontSize || fontSizeValue }
131
+ valueMode={ fontSize ? 'slug' : 'literal' }
128
132
  withReset={ false }
129
133
  withSlider
130
134
  size="__unstable-large"
@@ -2,6 +2,8 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { addFilter } from '@wordpress/hooks';
5
+ import { hasBlockSupport } from '@wordpress/blocks';
6
+
5
7
  const META_ATTRIBUTE_NAME = 'metadata';
6
8
 
7
9
  /**
@@ -28,8 +30,95 @@ export function addMetaAttribute( blockTypeSettings ) {
28
30
  return blockTypeSettings;
29
31
  }
30
32
 
33
+ /**
34
+ * Add metadata transforms.
35
+ *
36
+ * @param {Object} result The transformed block.
37
+ * @param {Array} source Original blocks transformed.
38
+ * @param {number} index Index of the transformed block.
39
+ * @param {Array} results All blocks that resulted from the transformation.
40
+ * @return {Object} Modified transformed block.
41
+ */
42
+ export function addTransforms( result, source, index, results ) {
43
+ // If the condition verifies we are probably in the presence of a wrapping transform
44
+ // e.g: nesting paragraphs in a group or columns and in that case the metadata should not be kept.
45
+ if ( results.length === 1 && result.innerBlocks.length === source.length ) {
46
+ return result;
47
+ }
48
+
49
+ // If we are transforming one block to multiple blocks or multiple blocks to one block,
50
+ // we ignore the metadata during the transform.
51
+ if (
52
+ ( results.length === 1 && source.length > 1 ) ||
53
+ ( results.length > 1 && source.length === 1 )
54
+ ) {
55
+ return result;
56
+ }
57
+
58
+ // If we are transforming multiple blocks to multiple blocks with different counts,
59
+ // we ignore the metadata during the transform.
60
+ if (
61
+ results.length > 1 &&
62
+ source.length > 1 &&
63
+ results.length !== source.length
64
+ ) {
65
+ return result;
66
+ }
67
+
68
+ const sourceMetadata = source[ index ]?.attributes?.metadata;
69
+
70
+ if ( ! sourceMetadata ) {
71
+ return result;
72
+ }
73
+
74
+ const preservedMetadata = {};
75
+
76
+ // Notes
77
+ if ( sourceMetadata.noteId && ! result.attributes?.metadata?.noteId ) {
78
+ preservedMetadata.noteId = sourceMetadata.noteId;
79
+ }
80
+
81
+ // Custom name
82
+ if (
83
+ sourceMetadata.name &&
84
+ ! result.attributes?.metadata?.name &&
85
+ hasBlockSupport( result.name, 'renaming', true )
86
+ ) {
87
+ preservedMetadata.name = sourceMetadata.name;
88
+ }
89
+
90
+ // Block visibility
91
+ if (
92
+ sourceMetadata.blockVisibility !== undefined &&
93
+ ! result.attributes?.metadata?.blockVisibility &&
94
+ hasBlockSupport( result.name, 'blockVisibility', true )
95
+ ) {
96
+ preservedMetadata.blockVisibility = sourceMetadata.blockVisibility;
97
+ }
98
+
99
+ if ( Object.keys( preservedMetadata ).length > 0 ) {
100
+ return {
101
+ ...result,
102
+ attributes: {
103
+ ...result.attributes,
104
+ metadata: {
105
+ ...result.attributes.metadata,
106
+ ...preservedMetadata,
107
+ },
108
+ },
109
+ };
110
+ }
111
+ return result;
112
+ }
113
+
31
114
  addFilter(
32
115
  'blocks.registerBlockType',
33
116
  'core/metadata/addMetaAttribute',
34
117
  addMetaAttribute
35
118
  );
119
+
120
+ addFilter(
121
+ 'blocks.switchToBlockType.transformedBlock',
122
+ 'core/metadata/addTransforms',
123
+ addTransforms
124
+ );
@@ -0,0 +1,316 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ getBlockTypes,
6
+ registerBlockType,
7
+ unregisterBlockType,
8
+ } from '@wordpress/blocks';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { addTransforms } from '../metadata';
14
+
15
+ describe( 'metadata', () => {
16
+ afterEach( () => {
17
+ getBlockTypes().forEach( ( block ) => {
18
+ unregisterBlockType( block.name );
19
+ } );
20
+ } );
21
+
22
+ describe( 'addTransforms()', () => {
23
+ it( 'should not preserve metadata in wrapping transforms', () => {
24
+ const source = [
25
+ {
26
+ name: 'core/foo',
27
+ attributes: { metadata: { noteId: 1 } },
28
+ innerBlocks: [],
29
+ },
30
+ {
31
+ name: 'core/foo',
32
+ attributes: { metadata: { noteId: 2 } },
33
+ innerBlocks: [],
34
+ },
35
+ ];
36
+ const result = {
37
+ name: 'core/bar',
38
+ attributes: {},
39
+ innerBlocks: source,
40
+ };
41
+ const transformed = addTransforms( result, source, 0, [ result ] );
42
+
43
+ expect( transformed.attributes.metadata ).toBeUndefined();
44
+ } );
45
+
46
+ it( 'should not preserve metadata in one-to-many transforms', () => {
47
+ const source = [
48
+ {
49
+ name: 'core/foo',
50
+ attributes: { metadata: { noteId: 1 } },
51
+ innerBlocks: [],
52
+ },
53
+ ];
54
+ const results = [
55
+ {
56
+ name: 'core/bar',
57
+ attributes: {},
58
+ innerBlocks: [],
59
+ },
60
+ {
61
+ name: 'core/bar',
62
+ attributes: {},
63
+ innerBlocks: [],
64
+ },
65
+ ];
66
+ const transformed = addTransforms(
67
+ results[ 0 ],
68
+ source,
69
+ 0,
70
+ results
71
+ );
72
+
73
+ expect( transformed.attributes.metadata ).toBeUndefined();
74
+ } );
75
+
76
+ it( 'should not preserve metadata in many-to-one transforms', () => {
77
+ const source = [
78
+ {
79
+ name: 'core/foo',
80
+ attributes: { metadata: { noteId: 1 } },
81
+ innerBlocks: [],
82
+ },
83
+ {
84
+ name: 'core/foo',
85
+ attributes: { metadata: { noteId: 2 } },
86
+ innerBlocks: [],
87
+ },
88
+ ];
89
+ const result = {
90
+ name: 'core/bar',
91
+ attributes: {},
92
+ innerBlocks: [],
93
+ };
94
+ const transformed = addTransforms( result, source, 0, [ result ] );
95
+
96
+ expect( transformed.attributes.metadata ).toBeUndefined();
97
+ } );
98
+
99
+ it( 'should not preserve metadata in many-to-many transforms with different counts', () => {
100
+ const source = [
101
+ {
102
+ name: 'core/foo',
103
+ attributes: { metadata: { noteId: 1 } },
104
+ innerBlocks: [],
105
+ },
106
+ {
107
+ name: 'core/foo',
108
+ attributes: { metadata: { noteId: 2 } },
109
+ innerBlocks: [],
110
+ },
111
+ {
112
+ name: 'core/foo',
113
+ attributes: { metadata: { noteId: 3 } },
114
+ innerBlocks: [],
115
+ },
116
+ ];
117
+ const results = [
118
+ {
119
+ name: 'core/bar',
120
+ attributes: {},
121
+ innerBlocks: [],
122
+ },
123
+ {
124
+ name: 'core/bar',
125
+ attributes: {},
126
+ innerBlocks: [],
127
+ },
128
+ ];
129
+ const [ firstTransformed, secondTransformed ] = results.map(
130
+ ( result, index ) =>
131
+ addTransforms( result, source, index, results )
132
+ );
133
+
134
+ expect( firstTransformed.attributes.metadata ).toBeUndefined();
135
+ expect( secondTransformed.attributes.metadata ).toBeUndefined();
136
+ } );
137
+
138
+ it( 'should preserve metadata in many-to-many transforms with same counts', () => {
139
+ const source = [
140
+ {
141
+ name: 'core/foo',
142
+ attributes: { metadata: { noteId: 1 } },
143
+ innerBlocks: [],
144
+ },
145
+ {
146
+ name: 'core/foo',
147
+ attributes: { metadata: { noteId: 2 } },
148
+ innerBlocks: [],
149
+ },
150
+ ];
151
+ const results = [
152
+ {
153
+ name: 'core/bar',
154
+ attributes: { metadata: { noteId: 1 } },
155
+ },
156
+ {
157
+ name: 'core/bar',
158
+ attributes: { metadata: { noteId: 2 } },
159
+ },
160
+ ];
161
+
162
+ const [ firstTransformed, secondTransformed ] = results.map(
163
+ ( result, index ) =>
164
+ addTransforms( result, source, index, results )
165
+ );
166
+
167
+ expect( firstTransformed.attributes.metadata ).toEqual( {
168
+ noteId: 1,
169
+ } );
170
+ expect( secondTransformed.attributes.metadata ).toEqual( {
171
+ noteId: 2,
172
+ } );
173
+ } );
174
+
175
+ it( 'should preserve custom name metadata', () => {
176
+ registerBlockType( 'core/bar', {
177
+ title: 'Bar',
178
+ } );
179
+ const source = [
180
+ {
181
+ name: 'core/foo',
182
+ attributes: {
183
+ metadata: { name: 'Custom Name' },
184
+ },
185
+ innerBlocks: [],
186
+ },
187
+ ];
188
+ const result = {
189
+ name: 'core/bar',
190
+ attributes: {},
191
+ innerBlocks: [],
192
+ };
193
+ const transformed = addTransforms( result, source, 0, [ result ] );
194
+
195
+ expect( transformed.attributes.metadata.name ).toBe(
196
+ 'Custom Name'
197
+ );
198
+ } );
199
+
200
+ it( 'should not preserve custom name metadata when target block does not support renaming', () => {
201
+ registerBlockType( 'core/bar', {
202
+ title: 'Bar',
203
+ supports: {
204
+ renaming: false,
205
+ },
206
+ } );
207
+
208
+ const source = [
209
+ {
210
+ name: 'core/foo',
211
+ attributes: {
212
+ metadata: { name: 'Custom Name' },
213
+ },
214
+ innerBlocks: [],
215
+ },
216
+ ];
217
+ const result = {
218
+ name: 'core/bar',
219
+ attributes: {},
220
+ innerBlocks: [],
221
+ };
222
+ const transformed = addTransforms( result, source, 0, [ result ] );
223
+
224
+ expect( transformed.attributes.metadata?.name ).toBeUndefined();
225
+ } );
226
+
227
+ it( 'should preserve block visibility metadata', () => {
228
+ registerBlockType( 'core/bar', {
229
+ title: 'Bar',
230
+ } );
231
+
232
+ const source = [
233
+ {
234
+ name: 'core/foo',
235
+ attributes: {
236
+ metadata: { blockVisibility: false },
237
+ },
238
+ innerBlocks: [],
239
+ },
240
+ ];
241
+ const result = {
242
+ name: 'core/bar',
243
+ attributes: {},
244
+ innerBlocks: [],
245
+ };
246
+ const transformed = addTransforms( result, source, 0, [ result ] );
247
+
248
+ expect( transformed.attributes.metadata?.blockVisibility ).toBe(
249
+ false
250
+ );
251
+ } );
252
+
253
+ it( 'should not preserve block visibility metadata when target block does not support it', () => {
254
+ registerBlockType( 'core/bar', {
255
+ title: 'Bar',
256
+ supports: {
257
+ blockVisibility: false,
258
+ },
259
+ } );
260
+
261
+ const source = [
262
+ {
263
+ name: 'core/foo',
264
+ attributes: {
265
+ metadata: { blockVisibility: false },
266
+ },
267
+ innerBlocks: [],
268
+ },
269
+ ];
270
+ const result = {
271
+ name: 'core/bar',
272
+ attributes: {},
273
+ innerBlocks: [],
274
+ };
275
+ const transformed = addTransforms( result, source, 0, [ result ] );
276
+
277
+ expect(
278
+ transformed.attributes.metadata?.blockVisibility
279
+ ).toBeUndefined();
280
+ } );
281
+
282
+ it( 'should not override existing metadata in target block', () => {
283
+ const source = [
284
+ {
285
+ name: 'core/foo',
286
+ attributes: {
287
+ metadata: {
288
+ noteId: 1,
289
+ name: 'Custom Name',
290
+ blockVisibility: false,
291
+ },
292
+ },
293
+ innerBlocks: [],
294
+ },
295
+ ];
296
+ const result = {
297
+ name: 'core/bar',
298
+ attributes: {
299
+ metadata: {
300
+ noteId: 2,
301
+ name: 'Existing Name',
302
+ blockVisibility: true,
303
+ },
304
+ },
305
+ innerBlocks: [],
306
+ };
307
+ const transformed = addTransforms( result, source, 0, [ result ] );
308
+
309
+ expect( transformed.attributes.metadata ).toEqual( {
310
+ noteId: 2,
311
+ name: 'Existing Name',
312
+ blockVisibility: true,
313
+ } );
314
+ } );
315
+ } );
316
+ } );
@@ -116,11 +116,13 @@ function TypographyInspectorControl( { children, resetAllFilter } ) {
116
116
 
117
117
  export function TypographyPanel( { clientId, name, setAttributes, settings } ) {
118
118
  function selector( select ) {
119
- const { style, fontFamily, fontSize } =
119
+ const { style, fontFamily, fontSize, fitText } =
120
120
  select( blockEditorStore ).getBlockAttributes( clientId ) || {};
121
- return { style, fontFamily, fontSize };
121
+ return { style, fontFamily, fontSize, fitText };
122
122
  }
123
- const { style, fontFamily, fontSize } = useSelect( selector, [ clientId ] );
123
+ const { style, fontFamily, fontSize, fitText } = useSelect( selector, [
124
+ clientId,
125
+ ] );
124
126
  const isEnabled = useHasTypographyPanel( settings );
125
127
  const value = useMemo(
126
128
  () => attributesToStyle( { style, fontFamily, fontSize } ),
@@ -128,7 +130,16 @@ export function TypographyPanel( { clientId, name, setAttributes, settings } ) {
128
130
  );
129
131
 
130
132
  const onChange = ( newStyle ) => {
131
- setAttributes( styleToAttributes( 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 );
132
143
  };
133
144
 
134
145
  if ( ! isEnabled ) {
@@ -57,6 +57,7 @@ import {
57
57
  useBlockElementRef,
58
58
  useBlockElement,
59
59
  } from './components/block-list/use-block-props/use-block-refs';
60
+ import { default as MediaUploadModal } from './components/media-upload-modal';
60
61
 
61
62
  /**
62
63
  * Private @wordpress/block-editor APIs.
@@ -110,4 +111,5 @@ lock( privateApis, {
110
111
  essentialFormatKey,
111
112
  useBlockElement,
112
113
  useBlockElementRef,
114
+ MediaUploadModal,
113
115
  } );
@@ -95,7 +95,7 @@ export const isBlockSubtreeDisabled = ( state, clientId ) => {
95
95
  * @param {string} rootClientId The client ID of the root container block.
96
96
  * @return {boolean} Whether the container allows insertion.
97
97
  */
98
- export function isContainerInsertableToInWriteMode(
98
+ export function isContainerInsertableToInContentOnlyMode(
99
99
  state,
100
100
  blockName,
101
101
  rootClientId
@@ -105,7 +105,7 @@ export function isContainerInsertableToInWriteMode(
105
105
  const isContainerContentBlock = isContentBlock( rootBlockName );
106
106
  const isRootBlockMain = getSectionRootClientId( state ) === rootClientId;
107
107
 
108
- // In write mode, containers shouldn't be inserted into unless:
108
+ // In contentOnly mode, containers shouldn't be inserted into unless:
109
109
  // 1. they are a section root;
110
110
  // 2. they are a content block and the block to be inserted is also content.
111
111
  return (