@wordpress/block-editor 11.5.0 → 11.6.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 (198) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-list/block-invalid-warning.js +63 -80
  3. package/build/components/block-list/block-invalid-warning.js.map +1 -1
  4. package/build/components/block-settings-menu-controls/index.js +1 -1
  5. package/build/components/block-settings-menu-controls/index.js.map +1 -1
  6. package/build/components/block-switcher/block-transformations-menu.native.js +1 -0
  7. package/build/components/block-switcher/block-transformations-menu.native.js.map +1 -1
  8. package/build/components/convert-to-group-buttons/use-convert-to-group-button-props.js +6 -3
  9. package/build/components/convert-to-group-buttons/use-convert-to-group-button-props.js.map +1 -1
  10. package/build/components/global-styles/border-panel.js +306 -0
  11. package/build/components/global-styles/border-panel.js.map +1 -0
  12. package/build/components/global-styles/hooks.js +57 -3
  13. package/build/components/global-styles/hooks.js.map +1 -1
  14. package/build/components/global-styles/index.js +20 -0
  15. package/build/components/global-styles/index.js.map +1 -1
  16. package/build/components/global-styles/typography-panel.js +62 -15
  17. package/build/components/global-styles/typography-panel.js.map +1 -1
  18. package/build/components/global-styles/use-global-styles-output.js +20 -13
  19. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  20. package/build/components/inserter/index.js +29 -17
  21. package/build/components/inserter/index.js.map +1 -1
  22. package/build/components/inserter/menu.js +1 -1
  23. package/build/components/inserter/menu.js.map +1 -1
  24. package/build/components/inserter/quick-inserter.js +4 -2
  25. package/build/components/inserter/quick-inserter.js.map +1 -1
  26. package/build/components/inserter/search-results.js +10 -3
  27. package/build/components/inserter/search-results.js.map +1 -1
  28. package/build/components/inserter/tabs.js +1 -1
  29. package/build/components/inserter/tabs.js.map +1 -1
  30. package/build/components/link-control/index.js +1 -1
  31. package/build/components/link-control/index.js.map +1 -1
  32. package/build/components/link-control/search-item.js +5 -2
  33. package/build/components/link-control/search-item.js.map +1 -1
  34. package/build/components/list-view/use-block-selection.js +1 -2
  35. package/build/components/list-view/use-block-selection.js.map +1 -1
  36. package/build/components/off-canvas-editor/appender.js +28 -3
  37. package/build/components/off-canvas-editor/appender.js.map +1 -1
  38. package/build/components/off-canvas-editor/branch.js +5 -3
  39. package/build/components/off-canvas-editor/branch.js.map +1 -1
  40. package/build/components/off-canvas-editor/index.js +9 -7
  41. package/build/components/off-canvas-editor/index.js.map +1 -1
  42. package/build/components/off-canvas-editor/link-ui.js +0 -1
  43. package/build/components/off-canvas-editor/link-ui.js.map +1 -1
  44. package/build/components/provider/use-block-sync.js +17 -3
  45. package/build/components/provider/use-block-sync.js.map +1 -1
  46. package/build/components/rich-text/format-toolbar-container.js +0 -3
  47. package/build/components/rich-text/format-toolbar-container.js.map +1 -1
  48. package/build/hooks/border.js +91 -240
  49. package/build/hooks/border.js.map +1 -1
  50. package/build/hooks/custom-class-name.js +4 -4
  51. package/build/hooks/custom-class-name.js.map +1 -1
  52. package/build/hooks/custom-class-name.native.js +3 -4
  53. package/build/hooks/custom-class-name.native.js.map +1 -1
  54. package/build/hooks/layout.js +19 -22
  55. package/build/hooks/layout.js.map +1 -1
  56. package/build/hooks/supports.js +7 -1
  57. package/build/hooks/supports.js.map +1 -1
  58. package/build/hooks/typography.js +2 -1
  59. package/build/hooks/typography.js.map +1 -1
  60. package/build/hooks/utils.js +27 -1
  61. package/build/hooks/utils.js.map +1 -1
  62. package/build/layouts/constrained.js +6 -2
  63. package/build/layouts/constrained.js.map +1 -1
  64. package/build/private-apis.js +4 -1
  65. package/build/private-apis.js.map +1 -1
  66. package/build/store/actions.js +10 -8
  67. package/build/store/actions.js.map +1 -1
  68. package/build/store/selectors.js +19 -3
  69. package/build/store/selectors.js.map +1 -1
  70. package/build/utils/parse-css-unit-to-px.js +15 -9
  71. package/build/utils/parse-css-unit-to-px.js.map +1 -1
  72. package/build-module/components/block-list/block-invalid-warning.js +66 -78
  73. package/build-module/components/block-list/block-invalid-warning.js.map +1 -1
  74. package/build-module/components/block-settings-menu-controls/index.js +1 -1
  75. package/build-module/components/block-settings-menu-controls/index.js.map +1 -1
  76. package/build-module/components/block-switcher/block-transformations-menu.native.js +1 -0
  77. package/build-module/components/block-switcher/block-transformations-menu.native.js.map +1 -1
  78. package/build-module/components/convert-to-group-buttons/use-convert-to-group-button-props.js +6 -3
  79. package/build-module/components/convert-to-group-buttons/use-convert-to-group-button-props.js.map +1 -1
  80. package/build-module/components/global-styles/border-panel.js +291 -0
  81. package/build-module/components/global-styles/border-panel.js.map +1 -0
  82. package/build-module/components/global-styles/hooks.js +54 -3
  83. package/build-module/components/global-styles/hooks.js.map +1 -1
  84. package/build-module/components/global-styles/index.js +2 -1
  85. package/build-module/components/global-styles/index.js.map +1 -1
  86. package/build-module/components/global-styles/typography-panel.js +62 -16
  87. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  88. package/build-module/components/global-styles/use-global-styles-output.js +20 -13
  89. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  90. package/build-module/components/inserter/index.js +28 -16
  91. package/build-module/components/inserter/index.js.map +1 -1
  92. package/build-module/components/inserter/menu.js +1 -1
  93. package/build-module/components/inserter/menu.js.map +1 -1
  94. package/build-module/components/inserter/quick-inserter.js +4 -2
  95. package/build-module/components/inserter/quick-inserter.js.map +1 -1
  96. package/build-module/components/inserter/search-results.js +10 -3
  97. package/build-module/components/inserter/search-results.js.map +1 -1
  98. package/build-module/components/inserter/tabs.js +1 -1
  99. package/build-module/components/inserter/tabs.js.map +1 -1
  100. package/build-module/components/link-control/index.js +1 -1
  101. package/build-module/components/link-control/index.js.map +1 -1
  102. package/build-module/components/link-control/search-item.js +4 -2
  103. package/build-module/components/link-control/search-item.js.map +1 -1
  104. package/build-module/components/list-view/use-block-selection.js +1 -2
  105. package/build-module/components/list-view/use-block-selection.js.map +1 -1
  106. package/build-module/components/off-canvas-editor/appender.js +28 -4
  107. package/build-module/components/off-canvas-editor/appender.js.map +1 -1
  108. package/build-module/components/off-canvas-editor/branch.js +5 -3
  109. package/build-module/components/off-canvas-editor/branch.js.map +1 -1
  110. package/build-module/components/off-canvas-editor/index.js +9 -7
  111. package/build-module/components/off-canvas-editor/index.js.map +1 -1
  112. package/build-module/components/off-canvas-editor/link-ui.js +0 -1
  113. package/build-module/components/off-canvas-editor/link-ui.js.map +1 -1
  114. package/build-module/components/provider/use-block-sync.js +17 -3
  115. package/build-module/components/provider/use-block-sync.js.map +1 -1
  116. package/build-module/components/rich-text/format-toolbar-container.js +0 -3
  117. package/build-module/components/rich-text/format-toolbar-container.js.map +1 -1
  118. package/build-module/hooks/border.js +93 -240
  119. package/build-module/hooks/border.js.map +1 -1
  120. package/build-module/hooks/custom-class-name.js +4 -4
  121. package/build-module/hooks/custom-class-name.js.map +1 -1
  122. package/build-module/hooks/custom-class-name.native.js +3 -4
  123. package/build-module/hooks/custom-class-name.native.js.map +1 -1
  124. package/build-module/hooks/layout.js +19 -22
  125. package/build-module/hooks/layout.js.map +1 -1
  126. package/build-module/hooks/supports.js +7 -1
  127. package/build-module/hooks/supports.js.map +1 -1
  128. package/build-module/hooks/typography.js +2 -1
  129. package/build-module/hooks/typography.js.map +1 -1
  130. package/build-module/hooks/utils.js +27 -1
  131. package/build-module/hooks/utils.js.map +1 -1
  132. package/build-module/layouts/constrained.js +6 -2
  133. package/build-module/layouts/constrained.js.map +1 -1
  134. package/build-module/private-apis.js +3 -1
  135. package/build-module/private-apis.js.map +1 -1
  136. package/build-module/store/actions.js +10 -8
  137. package/build-module/store/actions.js.map +1 -1
  138. package/build-module/store/selectors.js +17 -3
  139. package/build-module/store/selectors.js.map +1 -1
  140. package/build-module/utils/parse-css-unit-to-px.js +15 -9
  141. package/build-module/utils/parse-css-unit-to-px.js.map +1 -1
  142. package/build-style/style-rtl.css +6 -6
  143. package/build-style/style.css +6 -6
  144. package/package.json +31 -31
  145. package/src/components/block-inspector/style.scss +3 -0
  146. package/src/components/block-list/block-invalid-warning.js +72 -64
  147. package/src/components/block-mover/test/__snapshots__/index.native.js.snap +20 -2
  148. package/src/components/block-preview/test/index.js +0 -2
  149. package/src/components/block-settings-menu-controls/index.js +2 -1
  150. package/src/components/block-styles/style.scss +2 -2
  151. package/src/components/block-switcher/block-transformations-menu.native.js +1 -0
  152. package/src/components/color-palette/test/__snapshots__/control.js.snap +16 -14
  153. package/src/components/convert-to-group-buttons/use-convert-to-group-button-props.js +48 -38
  154. package/src/components/global-styles/border-panel.js +285 -0
  155. package/src/components/global-styles/hooks.js +74 -1
  156. package/src/components/global-styles/index.js +2 -0
  157. package/src/components/global-styles/test/use-global-styles-output.js +1 -1
  158. package/src/components/global-styles/typography-panel.js +48 -1
  159. package/src/components/global-styles/use-global-styles-output.js +13 -13
  160. package/src/components/inserter/index.js +30 -11
  161. package/src/components/inserter/menu.js +0 -1
  162. package/src/components/inserter/quick-inserter.js +2 -0
  163. package/src/components/inserter/search-results.js +7 -1
  164. package/src/components/inserter/style.scss +3 -0
  165. package/src/components/inserter/tabs.js +1 -9
  166. package/src/components/link-control/index.js +1 -1
  167. package/src/components/link-control/search-item.js +3 -1
  168. package/src/components/link-control/style.scss +0 -4
  169. package/src/components/link-control/test/index.js +0 -2
  170. package/src/components/list-view/use-block-selection.js +0 -2
  171. package/src/components/off-canvas-editor/appender.js +31 -5
  172. package/src/components/off-canvas-editor/branch.js +3 -1
  173. package/src/components/off-canvas-editor/index.js +7 -7
  174. package/src/components/off-canvas-editor/link-ui.js +0 -1
  175. package/src/components/provider/use-block-sync.js +21 -4
  176. package/src/components/rich-text/format-toolbar-container.js +1 -7
  177. package/src/components/url-popover/test/index.js +0 -2
  178. package/src/hooks/border.js +94 -225
  179. package/src/hooks/custom-class-name.js +4 -4
  180. package/src/hooks/custom-class-name.native.js +3 -4
  181. package/src/hooks/layout.js +19 -16
  182. package/src/hooks/supports.js +6 -0
  183. package/src/hooks/test/style.js +2 -1
  184. package/src/hooks/test/use-typography-props.js +2 -0
  185. package/src/hooks/typography.js +2 -0
  186. package/src/hooks/utils.js +36 -0
  187. package/src/layouts/constrained.js +23 -17
  188. package/src/private-apis.js +2 -0
  189. package/src/store/actions.js +10 -8
  190. package/src/store/selectors.js +20 -3
  191. package/src/utils/parse-css-unit-to-px.js +14 -9
  192. package/src/utils/test/parse-css-unit-to-px.js +1 -2
  193. package/tsconfig.tsbuildinfo +1 -1
  194. package/build/hooks/border-radius.js +0 -100
  195. package/build/hooks/border-radius.js.map +0 -1
  196. package/build-module/hooks/border-radius.js +0 -84
  197. package/build-module/hooks/border-radius.js.map +0 -1
  198. package/src/hooks/border-radius.js +0 -70
@@ -7,66 +7,29 @@ import classnames from 'classnames';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { getBlockSupport } from '@wordpress/blocks';
10
- import {
11
- __experimentalBorderBoxControl as BorderBoxControl,
12
- __experimentalHasSplitBorders as hasSplitBorders,
13
- __experimentalIsDefinedBorder as isDefinedBorder,
14
- __experimentalToolsPanelItem as ToolsPanelItem,
15
- } from '@wordpress/components';
10
+ import { __experimentalHasSplitBorders as hasSplitBorders } from '@wordpress/components';
16
11
  import { createHigherOrderComponent } from '@wordpress/compose';
17
- import { Platform } from '@wordpress/element';
12
+ import { Platform, useCallback, useMemo } from '@wordpress/element';
18
13
  import { addFilter } from '@wordpress/hooks';
19
- import { __ } from '@wordpress/i18n';
20
14
 
21
15
  /**
22
16
  * Internal dependencies
23
17
  */
24
- import {
25
- BorderRadiusEdit,
26
- hasBorderRadiusValue,
27
- resetBorderRadius,
28
- } from './border-radius';
29
18
  import { getColorClassName } from '../components/colors';
30
19
  import InspectorControls from '../components/inspector-controls';
31
20
  import useMultipleOriginColorsAndGradients from '../components/colors-gradients/use-multiple-origin-colors-and-gradients';
32
- import useSetting from '../components/use-setting';
33
- import { cleanEmptyObject, shouldSkipSerialization } from './utils';
21
+ import {
22
+ cleanEmptyObject,
23
+ shouldSkipSerialization,
24
+ useBlockSettings,
25
+ } from './utils';
26
+ import {
27
+ useHasBorderPanel,
28
+ BorderPanel as StylesBorderPanel,
29
+ } from '../components/global-styles';
34
30
 
35
31
  export const BORDER_SUPPORT_KEY = '__experimentalBorder';
36
32
 
37
- const borderSides = [ 'top', 'right', 'bottom', 'left' ];
38
-
39
- const hasBorderValue = ( props ) => {
40
- const { borderColor, style } = props.attributes;
41
- return isDefinedBorder( style?.border ) || !! borderColor;
42
- };
43
-
44
- // The border color, style, and width are omitted so they get undefined. The
45
- // border radius is separate and must retain its selection.
46
- const resetBorder = ( { attributes = {}, setAttributes } ) => {
47
- const { style } = attributes;
48
- setAttributes( {
49
- borderColor: undefined,
50
- style: {
51
- ...style,
52
- border: cleanEmptyObject( {
53
- radius: style?.border?.radius,
54
- } ),
55
- },
56
- } );
57
- };
58
-
59
- const resetBorderFilter = ( newAttributes ) => ( {
60
- ...newAttributes,
61
- borderColor: undefined,
62
- style: {
63
- ...newAttributes.style,
64
- border: {
65
- radius: newAttributes.style?.border?.radius,
66
- },
67
- },
68
- } );
69
-
70
33
  const getColorByProperty = ( colors, property, value ) => {
71
34
  let matchedColor;
72
35
 
@@ -103,51 +66,6 @@ export const getMultiOriginColor = ( { colors, namedColor, customColor } ) => {
103
66
  return colorObject ? colorObject : { color: customColor };
104
67
  };
105
68
 
106
- const getBorderObject = ( attributes, colors ) => {
107
- const { borderColor, style } = attributes;
108
- const { border: borderStyles } = style || {};
109
-
110
- // If we have a named color for a flat border. Fetch that color object and
111
- // apply that color's value to the color property within the style object.
112
- if ( borderColor ) {
113
- const { color } = getMultiOriginColor( {
114
- colors,
115
- namedColor: borderColor,
116
- } );
117
-
118
- return color ? { ...borderStyles, color } : borderStyles;
119
- }
120
-
121
- // Individual side border color slugs are stored within the border style
122
- // object. If we don't have a border styles object we have nothing further
123
- // to hydrate.
124
- if ( ! borderStyles ) {
125
- return borderStyles;
126
- }
127
-
128
- // If we have named colors for the individual side borders, retrieve their
129
- // related color objects and apply the real color values to the split
130
- // border objects.
131
- const hydratedBorderStyles = { ...borderStyles };
132
- borderSides.forEach( ( side ) => {
133
- const colorSlug = getColorSlugFromVariable(
134
- hydratedBorderStyles[ side ]?.color
135
- );
136
- if ( colorSlug ) {
137
- const { color } = getMultiOriginColor( {
138
- colors,
139
- namedColor: colorSlug,
140
- } );
141
- hydratedBorderStyles[ side ] = {
142
- ...hydratedBorderStyles[ side ],
143
- color,
144
- };
145
- }
146
- } );
147
-
148
- return hydratedBorderStyles;
149
- };
150
-
151
69
  function getColorSlugFromVariable( value ) {
152
70
  const namedColor = /var:preset\|color\|(.+)/.exec( value );
153
71
  if ( namedColor && namedColor[ 1 ] ) {
@@ -156,150 +74,101 @@ function getColorSlugFromVariable( value ) {
156
74
  return null;
157
75
  }
158
76
 
159
- export function BorderPanel( props ) {
160
- const { attributes, clientId, setAttributes } = props;
161
- const { style } = attributes;
162
- const { colors } = useMultipleOriginColorsAndGradients();
163
-
164
- const isSupported = hasBorderSupport( props.name );
165
- const isColorSupported =
166
- useSetting( 'border.color' ) && hasBorderSupport( props.name, 'color' );
167
- const isRadiusSupported =
168
- useSetting( 'border.radius' ) &&
169
- hasBorderSupport( props.name, 'radius' );
170
- const isStyleSupported =
171
- useSetting( 'border.style' ) && hasBorderSupport( props.name, 'style' );
172
- const isWidthSupported =
173
- useSetting( 'border.width' ) && hasBorderSupport( props.name, 'width' );
174
-
175
- const isDisabled = [
176
- ! isColorSupported,
177
- ! isRadiusSupported,
178
- ! isStyleSupported,
179
- ! isWidthSupported,
180
- ].every( Boolean );
181
-
182
- if ( isDisabled || ! isSupported ) {
183
- return null;
77
+ function styleToAttributes( style ) {
78
+ if ( hasSplitBorders( style?.border ) ) {
79
+ return {
80
+ style,
81
+ borderColor: undefined,
82
+ };
184
83
  }
185
84
 
186
- const defaultBorderControls = getBlockSupport( props.name, [
187
- BORDER_SUPPORT_KEY,
188
- '__experimentalDefaultControls',
189
- ] );
85
+ const borderColorValue = style?.border?.color;
86
+ const borderColorSlug = borderColorValue?.startsWith( 'var:preset|color|' )
87
+ ? borderColorSlug.substring( 'var:preset|color|'.length )
88
+ : undefined;
89
+ const updatedStyle = { ...style };
90
+ updatedStyle.border = {
91
+ ...updatedStyle.border,
92
+ color: borderColorSlug ? undefined : borderColorValue,
93
+ };
94
+ return {
95
+ style: cleanEmptyObject( updatedStyle ),
96
+ borderColor: borderColorSlug,
97
+ };
98
+ }
190
99
 
191
- const showBorderByDefault =
192
- defaultBorderControls?.color || defaultBorderControls?.width;
193
-
194
- const onBorderChange = ( newBorder ) => {
195
- // Filter out named colors and apply them to appropriate block
196
- // attributes so that CSS classes can be used to apply those colors.
197
- // e.g. has-primary-border-top-color.
198
-
199
- let newBorderStyles = { ...newBorder };
200
- let newBorderColor;
201
-
202
- if ( hasSplitBorders( newBorder ) ) {
203
- // For each side check if the side has a color value set
204
- // If so, determine if it belongs to a named color, in which case
205
- // we update the color property.
206
- //
207
- // This deliberately overwrites `newBorderStyles` to avoid mutating
208
- // the passed object which causes problems otherwise.
209
- newBorderStyles = {
210
- top: { ...newBorder.top },
211
- right: { ...newBorder.right },
212
- bottom: { ...newBorder.bottom },
213
- left: { ...newBorder.left },
100
+ function attributesToStyle( attributes ) {
101
+ if ( hasSplitBorders( attributes.style?.border ) ) {
102
+ return attributes.style;
103
+ }
104
+ return {
105
+ ...attributes.style,
106
+ border: {
107
+ ...attributes.style?.border,
108
+ color: attributes.borderColor
109
+ ? 'var:preset|color|' + attributes.borderColor
110
+ : attributes.style?.border?.color,
111
+ },
112
+ };
113
+ }
114
+
115
+ function BordersInspectorControl( { children, resetAllFilter } ) {
116
+ const attributesResetAllFilter = useCallback(
117
+ ( attributes ) => {
118
+ const existingStyle = attributesToStyle( attributes );
119
+ const updatedStyle = resetAllFilter( existingStyle );
120
+ return {
121
+ ...attributes,
122
+ ...styleToAttributes( updatedStyle ),
214
123
  };
124
+ },
125
+ [ resetAllFilter ]
126
+ );
215
127
 
216
- borderSides.forEach( ( side ) => {
217
- if ( newBorder[ side ]?.color ) {
218
- const colorObject = getMultiOriginColor( {
219
- colors,
220
- customColor: newBorder[ side ]?.color,
221
- } );
222
-
223
- if ( colorObject.slug ) {
224
- newBorderStyles[
225
- side
226
- ].color = `var:preset|color|${ colorObject.slug }`;
227
- }
228
- }
229
- } );
230
- } else if ( newBorder?.color ) {
231
- // We have a flat border configuration. Apply named color slug to
232
- // `borderColor` attribute and clear color style property if found.
233
- const customColor = newBorder?.color;
234
- const colorObject = getMultiOriginColor( { colors, customColor } );
235
-
236
- if ( colorObject.slug ) {
237
- newBorderColor = colorObject.slug;
238
- newBorderStyles.color = undefined;
239
- }
240
- }
128
+ return (
129
+ <InspectorControls
130
+ group="border"
131
+ resetAllFilter={ attributesResetAllFilter }
132
+ >
133
+ { children }
134
+ </InspectorControls>
135
+ );
136
+ }
241
137
 
242
- // Ensure previous border radius styles are maintained and clean
243
- // overall result for empty objects or properties.
244
- const newStyle = cleanEmptyObject( {
245
- ...style,
246
- border: { radius: style?.border?.radius, ...newBorderStyles },
138
+ export function BorderPanel( props ) {
139
+ const { clientId, name, attributes, setAttributes } = props;
140
+ const settings = useBlockSettings( name );
141
+ const isEnabled = useHasBorderPanel( settings );
142
+ const value = useMemo( () => {
143
+ return attributesToStyle( {
144
+ style: attributes.style,
145
+ borderColor: attributes.borderColor,
247
146
  } );
147
+ }, [ attributes.style, attributes.borderColor ] );
248
148
 
249
- setAttributes( {
250
- style: newStyle,
251
- borderColor: newBorderColor,
252
- } );
149
+ const onChange = ( newStyle ) => {
150
+ setAttributes( styleToAttributes( newStyle ) );
253
151
  };
254
152
 
255
- const hydratedBorder = getBorderObject( attributes, colors );
153
+ if ( ! isEnabled ) {
154
+ return null;
155
+ }
156
+
157
+ const defaultControls = getBlockSupport( props.name, [
158
+ BORDER_SUPPORT_KEY,
159
+ '__experimentalDefaultControls',
160
+ ] );
256
161
 
257
162
  return (
258
- <InspectorControls group="border">
259
- { ( isWidthSupported || isColorSupported ) && (
260
- <ToolsPanelItem
261
- hasValue={ () => hasBorderValue( props ) }
262
- label={ __( 'Border' ) }
263
- onDeselect={ () => resetBorder( props ) }
264
- isShownByDefault={ showBorderByDefault }
265
- resetAllFilter={ resetBorderFilter }
266
- panelId={ clientId }
267
- >
268
- <BorderBoxControl
269
- colors={ colors }
270
- enableAlpha={ true }
271
- enableStyle={ isStyleSupported }
272
- onChange={ onBorderChange }
273
- popoverOffset={ 40 }
274
- popoverPlacement="left-start"
275
- size="__unstable-large"
276
- value={ hydratedBorder }
277
- __experimentalIsRenderedInSidebar={ true }
278
- />
279
- </ToolsPanelItem>
280
- ) }
281
- { isRadiusSupported && (
282
- <ToolsPanelItem
283
- hasValue={ () => hasBorderRadiusValue( props ) }
284
- label={ __( 'Radius' ) }
285
- onDeselect={ () => resetBorderRadius( props ) }
286
- isShownByDefault={ defaultBorderControls?.radius }
287
- resetAllFilter={ ( newAttributes ) => ( {
288
- ...newAttributes,
289
- style: {
290
- ...newAttributes.style,
291
- border: {
292
- ...newAttributes.style?.border,
293
- radius: undefined,
294
- },
295
- },
296
- } ) }
297
- panelId={ clientId }
298
- >
299
- <BorderRadiusEdit { ...props } />
300
- </ToolsPanelItem>
301
- ) }
302
- </InspectorControls>
163
+ <StylesBorderPanel
164
+ as={ BordersInspectorControl }
165
+ panelId={ clientId }
166
+ name={ name }
167
+ settings={ settings }
168
+ value={ value }
169
+ onChange={ onChange }
170
+ defaultControls={ defaultControls }
171
+ />
303
172
  );
304
173
  }
305
174
 
@@ -18,8 +18,7 @@ import { createHigherOrderComponent } from '@wordpress/compose';
18
18
  import { InspectorControls } from '../components';
19
19
 
20
20
  /**
21
- * Filters registered block settings, extending attributes with anchor using ID
22
- * of the first node.
21
+ * Filters registered block settings, extending attributes to include `className`.
23
22
  *
24
23
  * @param {Object} settings Original block settings.
25
24
  *
@@ -42,6 +41,7 @@ export function addAttribute( settings ) {
42
41
  /**
43
42
  * Override the default edit UI to include a new block inspector control for
44
43
  * assigning the custom class name, if block supports custom class name.
44
+ * The control is displayed within the Advanced panel in the block inspector.
45
45
  *
46
46
  * @param {WPComponent} BlockEdit Original component.
47
47
  *
@@ -89,8 +89,8 @@ export const withInspectorControl = createHigherOrderComponent(
89
89
  );
90
90
 
91
91
  /**
92
- * Override props assigned to save component to inject anchor ID, if block
93
- * supports anchor. This is only applied if the block's save result is an
92
+ * Override props assigned to save component to inject the className, if block
93
+ * supports customClassName. This is only applied if the block's save result is an
94
94
  * element and not a markup string.
95
95
  *
96
96
  * @param {Object} extraProps Additional props applied to save element.
@@ -10,8 +10,7 @@ import { addFilter } from '@wordpress/hooks';
10
10
  import { hasBlockSupport } from '@wordpress/blocks';
11
11
 
12
12
  /**
13
- * Filters registered block settings, extending attributes with anchor using ID
14
- * of the first node.
13
+ * Filters registered block settings, extending attributes to include `className`.
15
14
  *
16
15
  * @param {Object} settings Original block settings.
17
16
  *
@@ -32,8 +31,8 @@ export function addAttribute( settings ) {
32
31
  }
33
32
 
34
33
  /**
35
- * Override props assigned to save component to inject anchor ID, if block
36
- * supports anchor. This is only applied if the block's save result is an
34
+ * Override props assigned to save component to inject the className, if block
35
+ * supports customClassName. This is only applied if the block's save result is an
37
36
  * element and not a markup string.
38
37
  *
39
38
  * @param {Object} extraProps Additional props applied to save element.
@@ -35,11 +35,12 @@ const layoutBlockSupportKey = '__experimentalLayout';
35
35
  /**
36
36
  * Generates the utility classnames for the given block's layout attributes.
37
37
  *
38
- * @param { Object } block Block object.
38
+ * @param { Object } blockAttributes Block attributes.
39
+ * @param { string } blockName Block name.
39
40
  *
40
41
  * @return { Array } Array of CSS classname strings.
41
42
  */
42
- export function useLayoutClasses( block = {} ) {
43
+ export function useLayoutClasses( blockAttributes = {}, blockName = '' ) {
43
44
  const rootPaddingAlignment = useSelect( ( select ) => {
44
45
  const { getSettings } = select( blockEditorStore );
45
46
  return getSettings().__experimentalFeatures
@@ -47,11 +48,10 @@ export function useLayoutClasses( block = {} ) {
47
48
  }, [] );
48
49
  const globalLayoutSettings = useSetting( 'layout' ) || {};
49
50
 
50
- const { attributes = {}, name } = block;
51
- const { layout } = attributes;
51
+ const { layout } = blockAttributes;
52
52
 
53
53
  const { default: defaultBlockLayout } =
54
- getBlockSupport( name, layoutBlockSupportKey ) || {};
54
+ getBlockSupport( blockName, layoutBlockSupportKey ) || {};
55
55
  const usedLayout =
56
56
  layout?.inherit || layout?.contentSize || layout?.wideSize
57
57
  ? { ...layout, type: 'constrained' }
@@ -63,10 +63,13 @@ export function useLayoutClasses( block = {} ) {
63
63
  globalLayoutSettings?.definitions?.[ usedLayout?.type || 'default' ]
64
64
  ?.className
65
65
  ) {
66
- layoutClassnames.push(
66
+ const baseClassName =
67
67
  globalLayoutSettings?.definitions?.[ usedLayout?.type || 'default' ]
68
- ?.className
69
- );
68
+ ?.className;
69
+ const compoundClassName = `wp-block-${ blockName
70
+ .split( '/' )
71
+ .pop() }-${ baseClassName }`;
72
+ layoutClassnames.push( baseClassName, compoundClassName );
70
73
  }
71
74
 
72
75
  if (
@@ -100,14 +103,14 @@ export function useLayoutClasses( block = {} ) {
100
103
  /**
101
104
  * Generates a CSS rule with the given block's layout styles.
102
105
  *
103
- * @param { Object } block Block object.
104
- * @param { string } selector A selector to use in generating the CSS rule.
106
+ * @param { Object } blockAttributes Block attributes.
107
+ * @param { string } blockName Block name.
108
+ * @param { string } selector A selector to use in generating the CSS rule.
105
109
  *
106
110
  * @return { string } CSS rule.
107
111
  */
108
- export function useLayoutStyles( block = {}, selector ) {
109
- const { attributes = {}, name } = block;
110
- const { layout = {}, style = {} } = attributes;
112
+ export function useLayoutStyles( blockAttributes = {}, blockName, selector ) {
113
+ const { layout = {}, style = {} } = blockAttributes;
111
114
  // Update type for blocks using legacy layouts.
112
115
  const usedLayout =
113
116
  layout?.inherit || layout?.contentSize || layout?.wideSize
@@ -118,7 +121,7 @@ export function useLayoutStyles( block = {}, selector ) {
118
121
  const blockGapSupport = useSetting( 'spacing.blockGap' );
119
122
  const hasBlockGapSupport = blockGapSupport !== null;
120
123
  const css = fullLayoutType?.getLayoutStyle?.( {
121
- blockName: name,
124
+ blockName,
122
125
  selector,
123
126
  layout,
124
127
  layoutDefinitions: globalLayoutSettings?.definitions,
@@ -351,7 +354,7 @@ export const withInspectorControls = createHigherOrderComponent(
351
354
  */
352
355
  export const withLayoutStyles = createHigherOrderComponent(
353
356
  ( BlockListBlock ) => ( props ) => {
354
- const { name, attributes, block } = props;
357
+ const { name, attributes } = props;
355
358
  const hasLayoutBlockSupport = hasBlockSupport(
356
359
  name,
357
360
  layoutBlockSupportKey
@@ -373,7 +376,7 @@ export const withLayoutStyles = createHigherOrderComponent(
373
376
  ? { ...layout, type: 'constrained' }
374
377
  : layout || defaultBlockLayout || {};
375
378
  const layoutClasses = hasLayoutBlockSupport
376
- ? useLayoutClasses( block )
379
+ ? useLayoutClasses( attributes, name )
377
380
  : null;
378
381
  // Higher specificity to override defaults from theme.json.
379
382
  const selector = `.wp-container-${ id }.wp-container-${ id }`;
@@ -20,6 +20,11 @@ const FONT_STYLE_SUPPORT_KEY = 'typography.__experimentalFontStyle';
20
20
  * Key within block settings' support array indicating support for font weight.
21
21
  */
22
22
  const FONT_WEIGHT_SUPPORT_KEY = 'typography.__experimentalFontWeight';
23
+ /**
24
+ * Key within block settings' supports array indicating support for text
25
+ * columns e.g. settings found in `block.json`.
26
+ */
27
+ const TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns';
23
28
  /**
24
29
  * Key within block settings' supports array indicating support for text
25
30
  * decorations e.g. settings found in `block.json`.
@@ -42,6 +47,7 @@ const TYPOGRAPHY_SUPPORT_KEYS = [
42
47
  FONT_STYLE_SUPPORT_KEY,
43
48
  FONT_WEIGHT_SUPPORT_KEY,
44
49
  FONT_FAMILY_SUPPORT_KEY,
50
+ TEXT_COLUMNS_SUPPORT_KEY,
45
51
  TEXT_DECORATION_SUPPORT_KEY,
46
52
  TEXT_TRANSFORM_SUPPORT_KEY,
47
53
  LETTER_SPACING_SUPPORT_KEY,
@@ -21,7 +21,7 @@ describe( 'getInlineStyles', () => {
21
21
  expect(
22
22
  getInlineStyles( {
23
23
  color: { text: 'red', background: 'black' },
24
- typography: { lineHeight: 1.5, fontSize: 10 },
24
+ typography: { lineHeight: 1.5, fontSize: 10, textColumns: 2 },
25
25
  border: {
26
26
  radius: '10px',
27
27
  width: '1em',
@@ -44,6 +44,7 @@ describe( 'getInlineStyles', () => {
44
44
  borderStyle: 'dotted',
45
45
  borderWidth: '1em',
46
46
  color: 'red',
47
+ columnCount: 2,
47
48
  lineHeight: 1.5,
48
49
  fontSize: 10,
49
50
  marginBottom: '15px',
@@ -12,6 +12,7 @@ describe( 'getTypographyClassesAndStyles', () => {
12
12
  typography: {
13
13
  letterSpacing: '22px',
14
14
  fontSize: '2rem',
15
+ textColumns: 3,
15
16
  textTransform: 'uppercase',
16
17
  },
17
18
  },
@@ -19,6 +20,7 @@ describe( 'getTypographyClassesAndStyles', () => {
19
20
  expect( getTypographyClassesAndStyles( attributes ) ).toEqual( {
20
21
  className: 'has-tofu-font-family has-large-font-size',
21
22
  style: {
23
+ columnCount: 3,
22
24
  letterSpacing: '22px',
23
25
  fontSize: '2rem',
24
26
  textTransform: 'uppercase',
@@ -27,6 +27,7 @@ function omit( object, keys ) {
27
27
  const LETTER_SPACING_SUPPORT_KEY = 'typography.__experimentalLetterSpacing';
28
28
  const TEXT_TRANSFORM_SUPPORT_KEY = 'typography.__experimentalTextTransform';
29
29
  const TEXT_DECORATION_SUPPORT_KEY = 'typography.__experimentalTextDecoration';
30
+ const TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns';
30
31
  const FONT_STYLE_SUPPORT_KEY = 'typography.__experimentalFontStyle';
31
32
  const FONT_WEIGHT_SUPPORT_KEY = 'typography.__experimentalFontWeight';
32
33
  export const TYPOGRAPHY_SUPPORT_KEY = 'typography';
@@ -36,6 +37,7 @@ export const TYPOGRAPHY_SUPPORT_KEYS = [
36
37
  FONT_STYLE_SUPPORT_KEY,
37
38
  FONT_WEIGHT_SUPPORT_KEY,
38
39
  FONT_FAMILY_SUPPORT_KEY,
40
+ TEXT_COLUMNS_SUPPORT_KEY,
39
41
  TEXT_DECORATION_SUPPORT_KEY,
40
42
  TEXT_TRANSFORM_SUPPORT_KEY,
41
43
  LETTER_SPACING_SUPPORT_KEY,
@@ -202,6 +202,7 @@ export function useBlockSettings( name, parentLayout ) {
202
202
  const fontStyle = useSetting( 'typography.fontStyle' );
203
203
  const fontWeight = useSetting( 'typography.fontWeight' );
204
204
  const lineHeight = useSetting( 'typography.lineHeight' );
205
+ const textColumns = useSetting( 'typography.textColumns' );
205
206
  const textDecoration = useSetting( 'typography.textDecoration' );
206
207
  const textTransform = useSetting( 'typography.textTransform' );
207
208
  const letterSpacing = useSetting( 'typography.letterSpacing' );
@@ -212,9 +213,27 @@ export function useBlockSettings( name, parentLayout ) {
212
213
  const units = useSetting( 'spacing.units' );
213
214
  const minHeight = useSetting( 'dimensions.minHeight' );
214
215
  const layout = useSetting( 'layout' );
216
+ const borderColor = useSetting( 'border.color' );
217
+ const borderRadius = useSetting( 'border.radius' );
218
+ const borderStyle = useSetting( 'border.style' );
219
+ const borderWidth = useSetting( 'border.width' );
220
+ const customColorsEnabled = useSetting( 'color.custom' );
221
+ const customColors = useSetting( 'color.palette.custom' );
222
+ const themeColors = useSetting( 'color.palette.theme' );
223
+ const defaultColors = useSetting( 'color.palette.default' );
224
+ const defaultPalette = useSetting( 'color.defaultPalette' );
215
225
 
216
226
  const rawSettings = useMemo( () => {
217
227
  return {
228
+ color: {
229
+ palette: {
230
+ custom: customColors,
231
+ theme: themeColors,
232
+ default: defaultColors,
233
+ },
234
+ defaultPalette,
235
+ custom: customColorsEnabled,
236
+ },
218
237
  typography: {
219
238
  fontFamilies: {
220
239
  custom: fontFamilies,
@@ -226,6 +245,7 @@ export function useBlockSettings( name, parentLayout ) {
226
245
  fontStyle,
227
246
  fontWeight,
228
247
  lineHeight,
248
+ textColumns,
229
249
  textDecoration,
230
250
  textTransform,
231
251
  letterSpacing,
@@ -239,6 +259,12 @@ export function useBlockSettings( name, parentLayout ) {
239
259
  blockGap,
240
260
  units,
241
261
  },
262
+ border: {
263
+ color: borderColor,
264
+ radius: borderRadius,
265
+ style: borderStyle,
266
+ width: borderWidth,
267
+ },
242
268
  dimensions: {
243
269
  minHeight,
244
270
  },
@@ -252,6 +278,7 @@ export function useBlockSettings( name, parentLayout ) {
252
278
  fontStyle,
253
279
  fontWeight,
254
280
  lineHeight,
281
+ textColumns,
255
282
  textDecoration,
256
283
  textTransform,
257
284
  letterSpacing,
@@ -263,6 +290,15 @@ export function useBlockSettings( name, parentLayout ) {
263
290
  minHeight,
264
291
  layout,
265
292
  parentLayout,
293
+ borderColor,
294
+ borderRadius,
295
+ borderStyle,
296
+ borderWidth,
297
+ customColorsEnabled,
298
+ customColors,
299
+ themeColors,
300
+ defaultColors,
301
+ defaultPalette,
266
302
  ] );
267
303
 
268
304
  return useSettingsForBlockElement( rawSettings, name );