@wordpress/block-editor 15.11.0 → 15.11.1-next.v.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/build/components/block-controls/index.cjs +1 -1
  2. package/build/components/block-controls/index.cjs.map +2 -2
  3. package/build/components/block-inspector/index.cjs +6 -19
  4. package/build/components/block-inspector/index.cjs.map +3 -3
  5. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs +37 -13
  6. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.cjs.map +2 -2
  7. package/build/components/block-settings-menu-controls/index.cjs +1 -1
  8. package/build/components/block-settings-menu-controls/index.cjs.map +2 -2
  9. package/build/components/block-toolbar/index.cjs +1 -1
  10. package/build/components/block-toolbar/index.cjs.map +2 -2
  11. package/build/components/block-tools/index.cjs +2 -26
  12. package/build/components/block-tools/index.cjs.map +2 -2
  13. package/build/components/block-visibility/index.cjs +7 -9
  14. package/build/components/block-visibility/index.cjs.map +3 -3
  15. package/build/components/block-visibility/modal.cjs +13 -11
  16. package/build/components/block-visibility/modal.cjs.map +2 -2
  17. package/build/components/block-visibility/use-block-visibility.cjs +1 -1
  18. package/build/components/block-visibility/use-block-visibility.cjs.map +2 -2
  19. package/build/components/block-visibility/utils.cjs +5 -1
  20. package/build/components/block-visibility/utils.cjs.map +2 -2
  21. package/build/components/block-visibility/viewport-menu-item.cjs +11 -4
  22. package/build/components/block-visibility/viewport-menu-item.cjs.map +2 -2
  23. package/build/components/block-visibility/viewport-toolbar.cjs +4 -6
  24. package/build/components/block-visibility/viewport-toolbar.cjs.map +2 -2
  25. package/build/components/block-visibility/viewport-visibility-info.cjs +121 -0
  26. package/build/components/block-visibility/viewport-visibility-info.cjs.map +7 -0
  27. package/build/components/color-palette/with-color-context.cjs +1 -1
  28. package/build/components/color-palette/with-color-context.cjs.map +2 -2
  29. package/build/components/color-style-selector/index.cjs +1 -1
  30. package/build/components/color-style-selector/index.cjs.map +2 -2
  31. package/build/components/colors/with-colors.cjs +5 -3
  32. package/build/components/colors/with-colors.cjs.map +2 -2
  33. package/build/components/colors-gradients/dropdown.cjs +1 -1
  34. package/build/components/colors-gradients/dropdown.cjs.map +2 -2
  35. package/build/components/editable-text/index.cjs +5 -1
  36. package/build/components/editable-text/index.cjs.map +2 -2
  37. package/build/components/font-sizes/with-font-sizes.cjs +5 -3
  38. package/build/components/font-sizes/with-font-sizes.cjs.map +2 -2
  39. package/build/components/global-styles/advanced-panel.cjs +26 -13
  40. package/build/components/global-styles/advanced-panel.cjs.map +2 -2
  41. package/build/components/global-styles/filters-panel.cjs +1 -1
  42. package/build/components/global-styles/filters-panel.cjs.map +2 -2
  43. package/build/components/global-styles/shadow-panel-components.cjs +1 -1
  44. package/build/components/global-styles/shadow-panel-components.cjs.map +2 -2
  45. package/build/components/gradients/with-gradient.cjs +1 -1
  46. package/build/components/gradients/with-gradient.cjs.map +2 -2
  47. package/build/components/inspector-controls/fill.cjs +12 -2
  48. package/build/components/inspector-controls/fill.cjs.map +2 -2
  49. package/build/components/inspector-controls/index.cjs +1 -1
  50. package/build/components/inspector-controls/index.cjs.map +2 -2
  51. package/build/components/inspector-controls-tabs/index.cjs +1 -1
  52. package/build/components/inspector-controls-tabs/index.cjs.map +2 -2
  53. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs +2 -2
  54. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs.map +2 -2
  55. package/build/components/list-view/block-select-button.cjs +8 -16
  56. package/build/components/list-view/block-select-button.cjs.map +2 -2
  57. package/build/components/list-view/block.cjs +29 -34
  58. package/build/components/list-view/block.cjs.map +3 -3
  59. package/build/components/list-view/utils.cjs +3 -1
  60. package/build/components/list-view/utils.cjs.map +2 -2
  61. package/build/components/provider/index.cjs +7 -8
  62. package/build/components/provider/index.cjs.map +2 -2
  63. package/build/components/provider/with-registry-provider.cjs +1 -1
  64. package/build/components/provider/with-registry-provider.cjs.map +2 -2
  65. package/build/components/use-block-commands/index.cjs +2 -34
  66. package/build/components/use-block-commands/index.cjs.map +2 -2
  67. package/build/hooks/cross-origin-isolation.cjs +1 -1
  68. package/build/hooks/cross-origin-isolation.cjs.map +2 -2
  69. package/build/hooks/custom-css.cjs +141 -0
  70. package/build/hooks/custom-css.cjs.map +7 -0
  71. package/build/hooks/fit-text.cjs +14 -7
  72. package/build/hooks/fit-text.cjs.map +2 -2
  73. package/build/hooks/grid-visualizer.cjs +1 -1
  74. package/build/hooks/grid-visualizer.cjs.map +2 -2
  75. package/build/hooks/index.cjs +4 -0
  76. package/build/hooks/index.cjs.map +3 -3
  77. package/build/hooks/layout.cjs +10 -4
  78. package/build/hooks/layout.cjs.map +2 -2
  79. package/build/hooks/list-view.cjs +9 -5
  80. package/build/hooks/list-view.cjs.map +3 -3
  81. package/build/hooks/utils.cjs +2 -2
  82. package/build/hooks/utils.cjs.map +2 -2
  83. package/build/layouts/grid.cjs +12 -1
  84. package/build/layouts/grid.cjs.map +2 -2
  85. package/build/store/defaults.cjs +3 -0
  86. package/build/store/defaults.cjs.map +2 -2
  87. package/build/store/private-selectors.cjs +45 -37
  88. package/build/store/private-selectors.cjs.map +2 -2
  89. package/build/utils/fit-text-utils.cjs +5 -1
  90. package/build/utils/fit-text-utils.cjs.map +2 -2
  91. package/build-module/components/block-controls/index.mjs +1 -1
  92. package/build-module/components/block-controls/index.mjs.map +2 -2
  93. package/build-module/components/block-inspector/index.mjs +6 -19
  94. package/build-module/components/block-inspector/index.mjs.map +2 -2
  95. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs +37 -13
  96. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.mjs.map +2 -2
  97. package/build-module/components/block-settings-menu-controls/index.mjs +2 -2
  98. package/build-module/components/block-settings-menu-controls/index.mjs.map +2 -2
  99. package/build-module/components/block-toolbar/index.mjs +2 -2
  100. package/build-module/components/block-toolbar/index.mjs.map +2 -2
  101. package/build-module/components/block-tools/index.mjs +2 -26
  102. package/build-module/components/block-tools/index.mjs.map +2 -2
  103. package/build-module/components/block-visibility/index.mjs +6 -9
  104. package/build-module/components/block-visibility/index.mjs.map +2 -2
  105. package/build-module/components/block-visibility/modal.mjs +13 -11
  106. package/build-module/components/block-visibility/modal.mjs.map +2 -2
  107. package/build-module/components/block-visibility/use-block-visibility.mjs +1 -1
  108. package/build-module/components/block-visibility/use-block-visibility.mjs.map +2 -2
  109. package/build-module/components/block-visibility/utils.mjs +5 -1
  110. package/build-module/components/block-visibility/utils.mjs.map +2 -2
  111. package/build-module/components/block-visibility/viewport-menu-item.mjs +11 -4
  112. package/build-module/components/block-visibility/viewport-menu-item.mjs.map +2 -2
  113. package/build-module/components/block-visibility/viewport-toolbar.mjs +4 -6
  114. package/build-module/components/block-visibility/viewport-toolbar.mjs.map +2 -2
  115. package/build-module/components/block-visibility/viewport-visibility-info.mjs +95 -0
  116. package/build-module/components/block-visibility/viewport-visibility-info.mjs.map +7 -0
  117. package/build-module/components/color-palette/with-color-context.mjs +1 -1
  118. package/build-module/components/color-palette/with-color-context.mjs.map +2 -2
  119. package/build-module/components/color-style-selector/index.mjs +1 -1
  120. package/build-module/components/color-style-selector/index.mjs.map +2 -2
  121. package/build-module/components/colors/with-colors.mjs +5 -3
  122. package/build-module/components/colors/with-colors.mjs.map +2 -2
  123. package/build-module/components/colors-gradients/dropdown.mjs +1 -1
  124. package/build-module/components/colors-gradients/dropdown.mjs.map +2 -2
  125. package/build-module/components/editable-text/index.mjs +5 -1
  126. package/build-module/components/editable-text/index.mjs.map +2 -2
  127. package/build-module/components/font-sizes/with-font-sizes.mjs +5 -3
  128. package/build-module/components/font-sizes/with-font-sizes.mjs.map +2 -2
  129. package/build-module/components/global-styles/advanced-panel.mjs +22 -13
  130. package/build-module/components/global-styles/advanced-panel.mjs.map +2 -2
  131. package/build-module/components/global-styles/filters-panel.mjs +1 -1
  132. package/build-module/components/global-styles/filters-panel.mjs.map +2 -2
  133. package/build-module/components/global-styles/shadow-panel-components.mjs +1 -1
  134. package/build-module/components/global-styles/shadow-panel-components.mjs.map +2 -2
  135. package/build-module/components/gradients/with-gradient.mjs +1 -1
  136. package/build-module/components/gradients/with-gradient.mjs.map +2 -2
  137. package/build-module/components/inspector-controls/fill.mjs +12 -2
  138. package/build-module/components/inspector-controls/fill.mjs.map +2 -2
  139. package/build-module/components/inspector-controls/index.mjs +1 -1
  140. package/build-module/components/inspector-controls/index.mjs.map +2 -2
  141. package/build-module/components/inspector-controls-tabs/index.mjs +1 -1
  142. package/build-module/components/inspector-controls-tabs/index.mjs.map +2 -2
  143. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs +2 -2
  144. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs.map +2 -2
  145. package/build-module/components/list-view/block-select-button.mjs +8 -16
  146. package/build-module/components/list-view/block-select-button.mjs.map +2 -2
  147. package/build-module/components/list-view/block.mjs +31 -36
  148. package/build-module/components/list-view/block.mjs.map +2 -2
  149. package/build-module/components/list-view/utils.mjs +3 -1
  150. package/build-module/components/list-view/utils.mjs.map +2 -2
  151. package/build-module/components/provider/index.mjs +7 -8
  152. package/build-module/components/provider/index.mjs.map +2 -2
  153. package/build-module/components/provider/with-registry-provider.mjs +1 -1
  154. package/build-module/components/provider/with-registry-provider.mjs.map +2 -2
  155. package/build-module/components/use-block-commands/index.mjs +3 -37
  156. package/build-module/components/use-block-commands/index.mjs.map +2 -2
  157. package/build-module/hooks/cross-origin-isolation.mjs +1 -1
  158. package/build-module/hooks/cross-origin-isolation.mjs.map +2 -2
  159. package/build-module/hooks/custom-css.mjs +112 -0
  160. package/build-module/hooks/custom-css.mjs.map +7 -0
  161. package/build-module/hooks/fit-text.mjs +14 -7
  162. package/build-module/hooks/fit-text.mjs.map +2 -2
  163. package/build-module/hooks/grid-visualizer.mjs +1 -1
  164. package/build-module/hooks/grid-visualizer.mjs.map +2 -2
  165. package/build-module/hooks/index.mjs +4 -0
  166. package/build-module/hooks/index.mjs.map +2 -2
  167. package/build-module/hooks/layout.mjs +10 -4
  168. package/build-module/hooks/layout.mjs.map +2 -2
  169. package/build-module/hooks/list-view.mjs +10 -6
  170. package/build-module/hooks/list-view.mjs.map +2 -2
  171. package/build-module/hooks/utils.mjs +2 -2
  172. package/build-module/hooks/utils.mjs.map +2 -2
  173. package/build-module/layouts/grid.mjs +12 -1
  174. package/build-module/layouts/grid.mjs.map +2 -2
  175. package/build-module/store/defaults.mjs +3 -0
  176. package/build-module/store/defaults.mjs.map +2 -2
  177. package/build-module/store/private-selectors.mjs +42 -40
  178. package/build-module/store/private-selectors.mjs.map +2 -2
  179. package/build-module/utils/fit-text-utils.mjs +5 -1
  180. package/build-module/utils/fit-text-utils.mjs.map +2 -2
  181. package/build-style/style-rtl.css +3 -0
  182. package/build-style/style.css +3 -0
  183. package/package.json +39 -39
  184. package/src/components/block-controls/index.js +1 -1
  185. package/src/components/block-controls/test/index.js +1 -0
  186. package/src/components/block-edit/test/edit.js +10 -0
  187. package/src/components/block-inspector/index.js +14 -32
  188. package/src/components/block-list/use-block-props/use-selected-block-event-handlers.js +49 -29
  189. package/src/components/block-preview/test/index.js +11 -7
  190. package/src/components/block-settings-menu-controls/index.js +2 -2
  191. package/src/components/block-switcher/test/index.js +2 -0
  192. package/src/components/block-switcher/test/use-transformed.patterns.js +2 -0
  193. package/src/components/block-switcher/test/utils.js +2 -0
  194. package/src/components/block-toolbar/index.js +2 -2
  195. package/src/components/block-tools/index.js +2 -29
  196. package/src/components/block-visibility/index.js +3 -19
  197. package/src/components/block-visibility/modal.js +16 -14
  198. package/src/components/block-visibility/test/use-block-visibility.js +27 -25
  199. package/src/components/block-visibility/test/utils.js +24 -8
  200. package/src/components/block-visibility/use-block-visibility.js +1 -4
  201. package/src/components/block-visibility/utils.js +9 -1
  202. package/src/components/block-visibility/viewport-menu-item.js +11 -5
  203. package/src/components/block-visibility/viewport-toolbar.js +5 -6
  204. package/src/components/block-visibility/viewport-visibility-info.js +131 -0
  205. package/src/components/color-palette/with-color-context.js +1 -1
  206. package/src/components/color-style-selector/index.js +2 -3
  207. package/src/components/colors/with-colors.js +23 -20
  208. package/src/components/colors-gradients/dropdown.js +2 -3
  209. package/src/components/editable-text/index.js +5 -1
  210. package/src/components/font-sizes/with-font-sizes.js +13 -10
  211. package/src/components/global-styles/advanced-panel.js +35 -16
  212. package/src/components/global-styles/filters-panel.js +2 -3
  213. package/src/components/global-styles/shadow-panel-components.js +1 -1
  214. package/src/components/global-styles/style.scss +9 -5
  215. package/src/components/gradients/with-gradient.js +7 -4
  216. package/src/components/inner-blocks/test/index.js +2 -0
  217. package/src/components/inspector-controls/fill.js +25 -5
  218. package/src/components/inspector-controls/index.js +1 -1
  219. package/src/components/inspector-controls-tabs/index.js +5 -1
  220. package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +3 -4
  221. package/src/components/link-control/test/index.js +6 -1
  222. package/src/components/list-view/block-select-button.js +16 -25
  223. package/src/components/list-view/block.js +38 -43
  224. package/src/components/list-view/utils.js +4 -2
  225. package/src/components/media-replace-flow/test/index.js +13 -11
  226. package/src/components/provider/index.js +11 -10
  227. package/src/components/provider/test/use-block-sync.js +1 -0
  228. package/src/components/provider/with-registry-provider.js +1 -1
  229. package/src/components/use-block-commands/index.js +0 -41
  230. package/src/hooks/cross-origin-isolation.js +19 -18
  231. package/src/hooks/custom-css.js +176 -0
  232. package/src/hooks/fit-text.js +20 -5
  233. package/src/hooks/grid-visualizer.js +15 -14
  234. package/src/hooks/index.js +4 -0
  235. package/src/hooks/layout.js +55 -43
  236. package/src/hooks/list-view.js +10 -6
  237. package/src/hooks/test/align.js +1 -0
  238. package/src/hooks/test/allowed-blocks.js +8 -0
  239. package/src/hooks/test/auto-inspector-controls.js +4 -0
  240. package/src/hooks/test/font-size.js +1 -0
  241. package/src/hooks/test/metadata.js +4 -0
  242. package/src/hooks/test/text-align.js +1 -0
  243. package/src/hooks/utils.js +123 -119
  244. package/src/layouts/grid.js +19 -3
  245. package/src/layouts/test/grid.js +1 -1
  246. package/src/store/defaults.js +4 -0
  247. package/src/store/private-selectors.js +94 -63
  248. package/src/store/test/actions.js +7 -0
  249. package/src/store/test/private-selectors.js +116 -119
  250. package/src/store/test/reducer.js +4 -0
  251. package/src/store/test/registry-selectors.js +2 -0
  252. package/src/store/test/selectors.js +19 -0
  253. package/src/utils/fit-text-utils.js +12 -2
  254. package/build/components/block-visibility/block-visibility-info.cjs +0 -63
  255. package/build/components/block-visibility/block-visibility-info.cjs.map +0 -7
  256. package/build/components/block-visibility/menu-item.cjs +0 -109
  257. package/build/components/block-visibility/menu-item.cjs.map +0 -7
  258. package/build/components/block-visibility/toolbar.cjs +0 -92
  259. package/build/components/block-visibility/toolbar.cjs.map +0 -7
  260. package/build-module/components/block-visibility/block-visibility-info.mjs +0 -47
  261. package/build-module/components/block-visibility/block-visibility-info.mjs.map +0 -7
  262. package/build-module/components/block-visibility/menu-item.mjs +0 -88
  263. package/build-module/components/block-visibility/menu-item.mjs.map +0 -7
  264. package/build-module/components/block-visibility/toolbar.mjs +0 -71
  265. package/build-module/components/block-visibility/toolbar.mjs.map +0 -7
  266. package/src/components/block-visibility/block-visibility-info.js +0 -62
  267. package/src/components/block-visibility/menu-item.js +0 -96
  268. package/src/components/block-visibility/toolbar.js +0 -88
@@ -0,0 +1,176 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useMemo } from '@wordpress/element';
5
+ import { useSelect } from '@wordpress/data';
6
+ import { useInstanceId } from '@wordpress/compose';
7
+ import { getBlockType, hasBlockSupport } from '@wordpress/blocks';
8
+ import { __, sprintf } from '@wordpress/i18n';
9
+ import { processCSSNesting } from '@wordpress/global-styles-engine';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import InspectorControls from '../components/inspector-controls';
15
+ import AdvancedPanel, {
16
+ validateCSS,
17
+ } from '../components/global-styles/advanced-panel';
18
+ import { cleanEmptyObject, useStyleOverride } from './utils';
19
+ import { store as blockEditorStore } from '../store';
20
+
21
+ // Stable reference for useInstanceId.
22
+ const CUSTOM_CSS_INSTANCE_REFERENCE = {};
23
+
24
+ // Stable empty object reference for useSelect.
25
+ const EMPTY_STYLE = {};
26
+
27
+ /**
28
+ * Inspector control for custom CSS.
29
+ *
30
+ * @param {Object} props Component props.
31
+ * @param {string} props.blockName Block name.
32
+ * @param {Function} props.setAttributes Function to set block attributes.
33
+ * @param {Object} props.style Block style attribute.
34
+ */
35
+ function CustomCSSControl( { blockName, setAttributes, style } ) {
36
+ const blockType = getBlockType( blockName );
37
+
38
+ function onChange( newStyle ) {
39
+ // Normalize whitespace-only CSS to undefined so it gets cleaned up.
40
+ const css = newStyle?.css?.trim() ? newStyle.css : undefined;
41
+ setAttributes( {
42
+ style: cleanEmptyObject( { ...newStyle, css } ),
43
+ } );
44
+ }
45
+
46
+ const cssHelpText = sprintf(
47
+ // translators: %s: is the name of a block e.g., 'Image' or 'Quote'.
48
+ __(
49
+ 'Add your own CSS to customize the appearance of the %s block. You do not need to include a CSS selector, just add the property and value, e.g. color: red;.'
50
+ ),
51
+ blockType?.title
52
+ );
53
+
54
+ return (
55
+ <InspectorControls group="advanced">
56
+ <AdvancedPanel
57
+ value={ style }
58
+ onChange={ onChange }
59
+ inheritedValue={ style }
60
+ help={ cssHelpText }
61
+ />
62
+ </InspectorControls>
63
+ );
64
+ }
65
+
66
+ function CustomCSSEdit( { clientId, name, setAttributes } ) {
67
+ const { style, canEditCSS } = useSelect(
68
+ ( select ) => {
69
+ const { getBlockAttributes, getSettings } =
70
+ select( blockEditorStore );
71
+ return {
72
+ style: getBlockAttributes( clientId )?.style || EMPTY_STYLE,
73
+ canEditCSS: getSettings().canEditCSS,
74
+ };
75
+ },
76
+ [ clientId ]
77
+ );
78
+
79
+ // Don't render the panel if user lacks edit_css capability.
80
+ if ( ! canEditCSS ) {
81
+ return null;
82
+ }
83
+
84
+ return (
85
+ <CustomCSSControl
86
+ blockName={ name }
87
+ setAttributes={ setAttributes }
88
+ style={ style }
89
+ />
90
+ );
91
+ }
92
+
93
+ /**
94
+ * Hook to handle custom CSS for a block in the editor.
95
+ * Generates a unique class and applies scoped CSS via style override.
96
+ *
97
+ * @param {Object} props Block props.
98
+ * @param {Object} props.style Block style attribute.
99
+ * @return {Object} Block props including className for custom CSS scoping.
100
+ */
101
+ function useBlockProps( { style } ) {
102
+ const customCSS = style?.css;
103
+
104
+ // Validate CSS is non-empty and passes validation checks.
105
+ const isValidCSS =
106
+ typeof customCSS === 'string' &&
107
+ customCSS.trim().length > 0 &&
108
+ validateCSS( customCSS );
109
+
110
+ const customCSSIdentifier = useInstanceId(
111
+ CUSTOM_CSS_INSTANCE_REFERENCE,
112
+ 'wp-custom-css'
113
+ );
114
+
115
+ const customCSSSelector = `.${ customCSSIdentifier }`;
116
+
117
+ // Transform the custom CSS using the same logic as global styles.
118
+ // Only process if CSS is valid (doesn't contain HTML markup).
119
+ const transformedCSS = useMemo( () => {
120
+ if ( ! isValidCSS ) {
121
+ return undefined;
122
+ }
123
+ return processCSSNesting( customCSS, customCSSSelector );
124
+ }, [ customCSS, customCSSSelector, isValidCSS ] );
125
+
126
+ // Inject the CSS via style override.
127
+ useStyleOverride( { css: transformedCSS } );
128
+
129
+ // Only add the class if there's valid custom CSS.
130
+ if ( ! isValidCSS ) {
131
+ return {};
132
+ }
133
+
134
+ return {
135
+ className: customCSSIdentifier,
136
+ };
137
+ }
138
+
139
+ /**
140
+ * Adds a marker class to blocks with custom CSS for server-side rendering.
141
+ *
142
+ * @param {Object} props Additional props applied to save element.
143
+ * @param {Object} blockType Block type definition.
144
+ * @param {Object} attributes Block's attributes.
145
+ * @return {Object} Filtered props applied to save element.
146
+ */
147
+ function addSaveProps( props, blockType, attributes ) {
148
+ if ( ! hasBlockSupport( blockType, 'customCSS', true ) ) {
149
+ return props;
150
+ }
151
+
152
+ if ( ! attributes?.style?.css?.trim() ) {
153
+ return props;
154
+ }
155
+
156
+ // Add a class to indicate this block has custom CSS.
157
+ // The actual CSS is rendered server-side using the render_block filter.
158
+ const className = props.className
159
+ ? `${ props.className } has-custom-css`
160
+ : 'has-custom-css';
161
+
162
+ return {
163
+ ...props,
164
+ className,
165
+ };
166
+ }
167
+
168
+ export default {
169
+ edit: CustomCSSEdit,
170
+ useBlockProps,
171
+ addSaveProps,
172
+ attributeKeys: [ 'style' ],
173
+ hasSupport( name ) {
174
+ return hasBlockSupport( name, 'customCSS', true );
175
+ },
176
+ };
@@ -68,18 +68,25 @@ function useFitText( { fitText, name, clientId } ) {
68
68
  const hasFitTextSupport = hasBlockSupport( name, FIT_TEXT_SUPPORT_KEY );
69
69
  const blockElement = useBlockElement( clientId );
70
70
 
71
- // Monitor block attribute changes, and parent changes.
71
+ // Monitor block attribute changes, parent changes, and block mode.
72
72
  // Any attribute or parent change may change the available space.
73
- const { blockAttributes, parentId } = useSelect(
73
+ // Block mode is needed to disable fit text when in HTML editing mode.
74
+ const { blockAttributes, parentId, blockMode } = useSelect(
74
75
  ( select ) => {
75
76
  if ( ! clientId || ! hasFitTextSupport || ! fitText ) {
76
77
  return EMPTY_OBJECT;
77
78
  }
79
+ const _blockMode =
80
+ select( blockEditorStore ).getBlockMode( clientId );
81
+ if ( _blockMode === 'html' ) {
82
+ return { blockMode: _blockMode };
83
+ }
78
84
  return {
79
85
  blockAttributes:
80
86
  select( blockEditorStore ).getBlockAttributes( clientId ),
81
87
  parentId:
82
88
  select( blockEditorStore ).getBlockRootClientId( clientId ),
89
+ blockMode: _blockMode,
83
90
  };
84
91
  },
85
92
  [ clientId, hasFitTextSupport, fitText ]
@@ -118,7 +125,8 @@ function useFitText( { fitText, name, clientId } ) {
118
125
  ! fitText ||
119
126
  ! blockElement ||
120
127
  ! clientId ||
121
- ! hasFitTextSupport
128
+ ! hasFitTextSupport ||
129
+ blockMode === 'html'
122
130
  ) {
123
131
  return;
124
132
  }
@@ -189,11 +197,17 @@ function useFitText( { fitText, name, clientId } ) {
189
197
  applyFitText,
190
198
  blockElement,
191
199
  hasFitTextSupport,
200
+ blockMode,
192
201
  ] );
193
202
 
194
203
  // Trigger fit text recalculation when content changes
195
204
  useEffect( () => {
196
- if ( fitText && blockElement && hasFitTextSupport ) {
205
+ if (
206
+ fitText &&
207
+ blockElement &&
208
+ hasFitTextSupport &&
209
+ blockMode !== 'html'
210
+ ) {
197
211
  // Wait for next frame to ensure DOM has updated after content changes
198
212
  const frameId = window.requestAnimationFrame( () => {
199
213
  if ( blockElement ) {
@@ -209,6 +223,7 @@ function useFitText( { fitText, name, clientId } ) {
209
223
  applyFitText,
210
224
  blockElement,
211
225
  hasFitTextSupport,
226
+ blockMode,
212
227
  ] );
213
228
 
214
229
  return { fontSize };
@@ -360,7 +375,7 @@ function WithFitTextFontSize( { fitText, name, clientId, children } ) {
360
375
  * `editor.BlockEdit` filter.
361
376
  */
362
377
  const addFitTextControl = createHigherOrderComponent( ( BlockEdit ) => {
363
- return ( props ) => {
378
+ return function AddFitTextControl( props ) {
364
379
  const { name, attributes, clientId, isSelected, setAttributes } = props;
365
380
  const { fitText } = attributes;
366
381
  const supportsFitText = hasBlockSupport( name, FIT_TEXT_SUPPORT_KEY );
@@ -51,21 +51,22 @@ function GridTools( { clientId, layout } ) {
51
51
  }
52
52
 
53
53
  const addGridVisualizerToBlockEdit = createHigherOrderComponent(
54
- ( BlockEdit ) => ( props ) => {
55
- if ( props.attributes.layout?.type !== 'grid' ) {
56
- return <BlockEdit key="edit" { ...props } />;
57
- }
54
+ ( BlockEdit ) =>
55
+ function AddGridVisualizerToBlockEdit( props ) {
56
+ if ( props.attributes.layout?.type !== 'grid' ) {
57
+ return <BlockEdit key="edit" { ...props } />;
58
+ }
58
59
 
59
- return (
60
- <>
61
- <GridTools
62
- clientId={ props.clientId }
63
- layout={ props.attributes.layout }
64
- />
65
- <BlockEdit key="edit" { ...props } />
66
- </>
67
- );
68
- },
60
+ return (
61
+ <>
62
+ <GridTools
63
+ clientId={ props.clientId }
64
+ layout={ props.attributes.layout }
65
+ />
66
+ <BlockEdit key="edit" { ...props } />
67
+ </>
68
+ );
69
+ },
69
70
  'addGridVisualizerToBlockEdit'
70
71
  );
71
72
 
@@ -27,6 +27,7 @@ import fontSize from './font-size';
27
27
  import textAlign from './text-align';
28
28
  import fitText from './fit-text';
29
29
  import border from './border';
30
+ import customCSS from './custom-css';
30
31
  import position from './position';
31
32
  import blockStyleVariation from './block-style-variation';
32
33
  import layout from './layout';
@@ -47,6 +48,7 @@ createBlockEditFilter(
47
48
  anchor,
48
49
  customClassName,
49
50
  style,
51
+ customCSS,
50
52
  duotone,
51
53
  fitText,
52
54
  position,
@@ -73,6 +75,7 @@ createBlockListBlockFilter( [
73
75
  fontSize,
74
76
  fitText,
75
77
  border,
78
+ customCSS,
76
79
  position,
77
80
  blockStyleVariation,
78
81
  childLayout,
@@ -84,6 +87,7 @@ createBlockSaveFilter( [
84
87
  ariaLabel,
85
88
  customClassName,
86
89
  border,
90
+ customCSS,
87
91
  fitText,
88
92
  color,
89
93
  style,
@@ -30,6 +30,7 @@ import { useBlockEditingMode } from '../components/block-editing-mode';
30
30
  import { LAYOUT_DEFINITIONS } from '../layouts/definitions';
31
31
  import { useBlockSettings, useStyleOverride } from './utils';
32
32
  import { unlock } from '../lock-unlock';
33
+ import { globalStylesDataKey } from '../store/private-keys';
33
34
 
34
35
  const layoutBlockSupportKey = 'layout';
35
36
  const { kebabCase } = unlock( componentsPrivateApis );
@@ -367,6 +368,7 @@ function BlockWithLayoutStyles( {
367
368
  block: BlockListBlock,
368
369
  props,
369
370
  blockGapSupport,
371
+ globalBlockGapValue,
370
372
  layoutClasses,
371
373
  } ) {
372
374
  const { name, attributes } = props;
@@ -393,6 +395,7 @@ function BlockWithLayoutStyles( {
393
395
  layout: usedLayout,
394
396
  style: attributes?.style,
395
397
  hasBlockGapSupport,
398
+ globalBlockGapValue,
396
399
  } );
397
400
 
398
401
  // Attach a `wp-container-` id-based class name as well as a layout class name such as `is-layout-flex`.
@@ -421,56 +424,65 @@ function BlockWithLayoutStyles( {
421
424
  * @return {Function} Wrapped component.
422
425
  */
423
426
  export const withLayoutStyles = createHigherOrderComponent(
424
- ( BlockListBlock ) => ( props ) => {
425
- const { clientId, name, attributes } = props;
426
- const blockSupportsLayout = hasLayoutBlockSupport( name );
427
- const layoutClasses = useLayoutClasses( attributes, name );
428
- const extraProps = useSelect(
429
- ( select ) => {
430
- // The callback returns early to avoid block editor subscription.
431
- if ( ! blockSupportsLayout ) {
432
- return;
433
- }
434
-
435
- const { getSettings, getBlockSettings } = unlock(
436
- select( blockEditorStore )
437
- );
438
- const { disableLayoutStyles } = getSettings();
427
+ ( BlockListBlock ) =>
428
+ function WithLayoutStyles( props ) {
429
+ const { clientId, name, attributes } = props;
430
+ const blockSupportsLayout = hasLayoutBlockSupport( name );
431
+ const layoutClasses = useLayoutClasses( attributes, name );
432
+ const extraProps = useSelect(
433
+ ( select ) => {
434
+ // The callback returns early to avoid block editor subscription.
435
+ if ( ! blockSupportsLayout ) {
436
+ return;
437
+ }
439
438
 
440
- if ( disableLayoutStyles ) {
441
- return;
442
- }
439
+ const { getSettings, getBlockSettings } = unlock(
440
+ select( blockEditorStore )
441
+ );
442
+ const settings = getSettings();
443
+ const { disableLayoutStyles } = settings;
443
444
 
444
- const [ blockGapSupport ] = getBlockSettings(
445
- clientId,
446
- 'spacing.blockGap'
447
- );
445
+ if ( disableLayoutStyles ) {
446
+ return;
447
+ }
448
448
 
449
- return { blockGapSupport };
450
- },
451
- [ blockSupportsLayout, clientId ]
452
- );
449
+ const [ blockGapSupport ] = getBlockSettings(
450
+ clientId,
451
+ 'spacing.blockGap'
452
+ );
453
+
454
+ // Get default blockGap value from global styles for use in layouts like grid.
455
+ // Check block-specific styles first, then fall back to root styles.
456
+ const globalStyles = settings[ globalStylesDataKey ];
457
+ const globalBlockGapValue =
458
+ globalStyles?.blocks?.[ name ]?.spacing?.blockGap ??
459
+ globalStyles?.spacing?.blockGap;
460
+
461
+ return { blockGapSupport, globalBlockGapValue };
462
+ },
463
+ [ blockSupportsLayout, clientId ]
464
+ );
465
+
466
+ if ( ! extraProps ) {
467
+ return (
468
+ <BlockListBlock
469
+ { ...props }
470
+ __unstableLayoutClassNames={
471
+ blockSupportsLayout ? layoutClasses : undefined
472
+ }
473
+ />
474
+ );
475
+ }
453
476
 
454
- if ( ! extraProps ) {
455
477
  return (
456
- <BlockListBlock
457
- { ...props }
458
- __unstableLayoutClassNames={
459
- blockSupportsLayout ? layoutClasses : undefined
460
- }
478
+ <BlockWithLayoutStyles
479
+ block={ BlockListBlock }
480
+ props={ props }
481
+ layoutClasses={ layoutClasses }
482
+ { ...extraProps }
461
483
  />
462
484
  );
463
- }
464
-
465
- return (
466
- <BlockWithLayoutStyles
467
- block={ BlockListBlock }
468
- props={ props }
469
- layoutClasses={ layoutClasses }
470
- { ...extraProps }
471
- />
472
- );
473
- },
485
+ },
474
486
  'withLayoutStyles'
475
487
  );
476
488
 
@@ -4,7 +4,7 @@
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { PanelBody } from '@wordpress/components';
6
6
  import { useSelect } from '@wordpress/data';
7
- import { store as blocksStore, hasBlockSupport } from '@wordpress/blocks';
7
+ import { hasBlockSupport } from '@wordpress/blocks';
8
8
  import { useContext } from '@wordpress/element';
9
9
 
10
10
  /**
@@ -14,6 +14,7 @@ import { store as blockEditorStore } from '../store';
14
14
  import { PrivateListView } from '../components/list-view';
15
15
  import InspectorControls from '../components/inspector-controls/fill';
16
16
  import { PrivateBlockContext } from '../components/block-list/private-block-context';
17
+ import useBlockDisplayTitle from '../components/block-title/use-block-display-title';
17
18
 
18
19
  export const LIST_VIEW_SUPPORT_KEY = 'listView';
19
20
 
@@ -39,7 +40,7 @@ export function ListViewPanel( { clientId, name } ) {
39
40
  const { isSelectionWithinCurrentSection } =
40
41
  useContext( PrivateBlockContext );
41
42
  const isEnabled = hasListViewSupport( name );
42
- const { hasChildren, blockTitle, isNestedListView } = useSelect(
43
+ const { hasChildren, isNestedListView } = useSelect(
43
44
  ( select ) => {
44
45
  const { getBlockCount, getBlockParents, getBlockName } =
45
46
  select( blockEditorStore );
@@ -64,12 +65,15 @@ export function ListViewPanel( { clientId, name } ) {
64
65
 
65
66
  return {
66
67
  hasChildren: !! getBlockCount( clientId ),
67
- blockTitle: select( blocksStore ).getBlockType( name )?.title,
68
68
  isNestedListView: _isNestedListView,
69
69
  };
70
70
  },
71
- [ clientId, name, isSelectionWithinCurrentSection ]
71
+ [ clientId, isSelectionWithinCurrentSection ]
72
72
  );
73
+ const title = useBlockDisplayTitle( {
74
+ clientId,
75
+ context: 'list-view',
76
+ } );
73
77
 
74
78
  if ( ! isEnabled || isNestedListView ) {
75
79
  return null;
@@ -79,7 +83,7 @@ export function ListViewPanel( { clientId, name } ) {
79
83
 
80
84
  return (
81
85
  <InspectorControls group="list">
82
- <PanelBody title={ showBlockTitle ? blockTitle : undefined }>
86
+ <PanelBody title={ showBlockTitle ? title : undefined }>
83
87
  { ! hasChildren && (
84
88
  <p className="block-editor-block-inspector__no-blocks">
85
89
  { __( 'No items yet.' ) }
@@ -88,7 +92,7 @@ export function ListViewPanel( { clientId, name } ) {
88
92
  <PrivateListView
89
93
  rootClientId={ clientId }
90
94
  isExpanded
91
- description={ blockTitle }
95
+ description={ title }
92
96
  showAppender
93
97
  />
94
98
  </PanelBody>
@@ -17,6 +17,7 @@ const noop = () => {};
17
17
 
18
18
  describe( 'align', () => {
19
19
  const blockSettings = {
20
+ apiVersion: 3,
20
21
  save: noop,
21
22
  category: 'text',
22
23
  title: 'block title',
@@ -22,6 +22,7 @@ describe( 'allowedBlocks', () => {
22
22
  describe( 'addTransforms()', () => {
23
23
  it( 'should not preserve allowedBlocks in wrapping transforms', () => {
24
24
  registerBlockType( 'core/bar', {
25
+ apiVersion: 3,
25
26
  title: 'Bar',
26
27
  supports: { allowedBlocks: true },
27
28
  } );
@@ -53,6 +54,7 @@ describe( 'allowedBlocks', () => {
53
54
 
54
55
  it( 'should not preserve allowedBlocks in one-to-many transforms', () => {
55
56
  registerBlockType( 'core/bar', {
57
+ apiVersion: 3,
56
58
  title: 'Bar',
57
59
  supports: { allowedBlocks: true },
58
60
  } );
@@ -83,6 +85,7 @@ describe( 'allowedBlocks', () => {
83
85
 
84
86
  it( 'should not preserve allowedBlocks in many-to-one transforms', () => {
85
87
  registerBlockType( 'core/bar', {
88
+ apiVersion: 3,
86
89
  title: 'Bar',
87
90
  supports: { allowedBlocks: true },
88
91
  } );
@@ -114,6 +117,7 @@ describe( 'allowedBlocks', () => {
114
117
 
115
118
  it( 'should not preserve allowedBlocks in many-to-many transforms with different counts', () => {
116
119
  registerBlockType( 'core/bar', {
120
+ apiVersion: 3,
117
121
  title: 'Bar',
118
122
  supports: { allowedBlocks: true },
119
123
  } );
@@ -155,6 +159,7 @@ describe( 'allowedBlocks', () => {
155
159
 
156
160
  it( 'should preserve allowedBlocks in many-to-many transforms with same counts', () => {
157
161
  registerBlockType( 'core/bar', {
162
+ apiVersion: 3,
158
163
  title: 'Bar',
159
164
  supports: { allowedBlocks: true },
160
165
  } );
@@ -194,6 +199,7 @@ describe( 'allowedBlocks', () => {
194
199
 
195
200
  it( "should filter allowedBlocks based on destination block's allowedBlocks", () => {
196
201
  registerBlockType( 'core/bar', {
202
+ apiVersion: 3,
197
203
  title: 'Bar',
198
204
  supports: { allowedBlocks: true },
199
205
  allowedBlocks: [ 'core/paragraph' ],
@@ -227,6 +233,7 @@ describe( 'allowedBlocks', () => {
227
233
 
228
234
  it( 'should not override existing allowedBlocks in target block', () => {
229
235
  registerBlockType( 'core/bar', {
236
+ apiVersion: 3,
230
237
  title: 'Bar',
231
238
  supports: { allowedBlocks: true },
232
239
  } );
@@ -253,6 +260,7 @@ describe( 'allowedBlocks', () => {
253
260
 
254
261
  it( 'should not preserve allowedBlocks when target block does not support allowedBlocks', () => {
255
262
  registerBlockType( 'core/bar', {
263
+ apiVersion: 3,
256
264
  title: 'Bar',
257
265
  } );
258
266
 
@@ -24,6 +24,7 @@ describe( 'auto-inspector-controls', () => {
24
24
  describe( 'hasSupport()', () => {
25
25
  it( 'should return false for blocks without __experimentalAutoInspectorControl markers', () => {
26
26
  registerBlockType( blockName, {
27
+ apiVersion: 3,
27
28
  title: 'Test Block',
28
29
  category: 'text',
29
30
  attributes: {
@@ -42,6 +43,7 @@ describe( 'auto-inspector-controls', () => {
42
43
 
43
44
  it( 'should return true for blocks with __experimentalAutoInspectorControl markers', () => {
44
45
  registerBlockType( blockName, {
46
+ apiVersion: 3,
45
47
  title: 'Test Block',
46
48
  category: 'text',
47
49
  attributes: {
@@ -71,6 +73,7 @@ describe( 'auto-inspector-controls', () => {
71
73
 
72
74
  it( 'should return false for blocks with no attributes', () => {
73
75
  registerBlockType( blockName, {
76
+ apiVersion: 3,
74
77
  title: 'Test Block',
75
78
  category: 'text',
76
79
  edit: () => null,
@@ -84,6 +87,7 @@ describe( 'auto-inspector-controls', () => {
84
87
 
85
88
  it( 'should return true when at least one attribute has __experimentalAutoInspectorControl', () => {
86
89
  registerBlockType( blockName, {
90
+ apiVersion: 3,
87
91
  title: 'Test Block',
88
92
  category: 'text',
89
93
  attributes: {
@@ -39,6 +39,7 @@ function addUseSettingFilter( callback ) {
39
39
 
40
40
  describe( 'useBlockProps', () => {
41
41
  const blockSettings = {
42
+ apiVersion: 3,
42
43
  save: () => noop,
43
44
  category: 'text',
44
45
  title: 'font size title',
@@ -174,6 +174,7 @@ describe( 'metadata', () => {
174
174
 
175
175
  it( 'should preserve custom name metadata', () => {
176
176
  registerBlockType( 'core/bar', {
177
+ apiVersion: 3,
177
178
  title: 'Bar',
178
179
  } );
179
180
  const source = [
@@ -199,6 +200,7 @@ describe( 'metadata', () => {
199
200
 
200
201
  it( 'should not preserve custom name metadata when target block does not support renaming', () => {
201
202
  registerBlockType( 'core/bar', {
203
+ apiVersion: 3,
202
204
  title: 'Bar',
203
205
  supports: {
204
206
  renaming: false,
@@ -226,6 +228,7 @@ describe( 'metadata', () => {
226
228
 
227
229
  it( 'should preserve block visibility metadata', () => {
228
230
  registerBlockType( 'core/bar', {
231
+ apiVersion: 3,
229
232
  title: 'Bar',
230
233
  } );
231
234
 
@@ -252,6 +255,7 @@ describe( 'metadata', () => {
252
255
 
253
256
  it( 'should not preserve block visibility metadata when target block does not support it', () => {
254
257
  registerBlockType( 'core/bar', {
258
+ apiVersion: 3,
255
259
  title: 'Bar',
256
260
  supports: {
257
261
  visibility: false,
@@ -16,6 +16,7 @@ const noop = () => {};
16
16
 
17
17
  describe( 'textAlign', () => {
18
18
  const blockSettings = {
19
+ apiVersion: 3,
19
20
  save: noop,
20
21
  category: 'text',
21
22
  title: 'block title',