@wordpress/block-editor 11.7.0 → 11.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +42 -55
  3. package/build/components/block-list/block.native.js +4 -3
  4. package/build/components/block-list/block.native.js.map +1 -1
  5. package/build/components/block-list/index.native.js +11 -21
  6. package/build/components/block-list/index.native.js.map +1 -1
  7. package/build/components/block-list/use-in-between-inserter.js +3 -1
  8. package/build/components/block-list/use-in-between-inserter.js.map +1 -1
  9. package/build/components/block-popover/inbetween.js +2 -9
  10. package/build/components/block-popover/inbetween.js.map +1 -1
  11. package/build/components/block-settings-menu/block-settings-dropdown.js +1 -10
  12. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  13. package/build/components/caption/index.native.js +0 -1
  14. package/build/components/caption/index.native.js.map +1 -1
  15. package/build/components/date-format-picker/index.js +1 -1
  16. package/build/components/date-format-picker/index.js.map +1 -1
  17. package/build/components/global-styles/border-panel.js +15 -29
  18. package/build/components/global-styles/border-panel.js.map +1 -1
  19. package/build/components/global-styles/dimensions-panel.js +15 -14
  20. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  21. package/build/components/global-styles/effects-panel.js +244 -0
  22. package/build/components/global-styles/effects-panel.js.map +1 -0
  23. package/build/components/global-styles/filters-panel.js +151 -0
  24. package/build/components/global-styles/filters-panel.js.map +1 -0
  25. package/build/components/global-styles/get-block-css-selector.js +1 -12
  26. package/build/components/global-styles/get-block-css-selector.js.map +1 -1
  27. package/build/components/global-styles/hooks.js +7 -0
  28. package/build/components/global-styles/hooks.js.map +1 -1
  29. package/build/components/global-styles/index.js +28 -0
  30. package/build/components/global-styles/index.js.map +1 -1
  31. package/build/components/global-styles/use-global-styles-output.js +15 -7
  32. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  33. package/build/components/iframe/index.js +1 -1
  34. package/build/components/iframe/index.js.map +1 -1
  35. package/build/components/image-size-control/use-dimension-handler.js +5 -3
  36. package/build/components/image-size-control/use-dimension-handler.js.map +1 -1
  37. package/build/components/index.js +16 -0
  38. package/build/components/index.js.map +1 -1
  39. package/build/components/inserter/block-patterns-tab.js +4 -2
  40. package/build/components/inserter/block-patterns-tab.js.map +1 -1
  41. package/build/components/inspector-controls-tabs/utils.js +5 -3
  42. package/build/components/inspector-controls-tabs/utils.js.map +1 -1
  43. package/build/components/list-view/block.js +1 -0
  44. package/build/components/list-view/block.js.map +1 -1
  45. package/build/components/list-view/index.js +22 -4
  46. package/build/components/list-view/index.js.map +1 -1
  47. package/build/components/list-view/use-list-view-client-ids.js +7 -3
  48. package/build/components/list-view/use-list-view-client-ids.js.map +1 -1
  49. package/build/components/list-view/use-list-view-drop-zone.js +8 -2
  50. package/build/components/list-view/use-list-view-drop-zone.js.map +1 -1
  51. package/build/components/off-canvas-editor/block-contents.js +6 -1
  52. package/build/components/off-canvas-editor/block-contents.js.map +1 -1
  53. package/build/components/off-canvas-editor/index.js +17 -14
  54. package/build/components/off-canvas-editor/index.js.map +1 -1
  55. package/build/components/resizable-box-popover/index.js +38 -0
  56. package/build/components/resizable-box-popover/index.js.map +1 -0
  57. package/build/components/rich-text/index.js +0 -1
  58. package/build/components/rich-text/index.js.map +1 -1
  59. package/build/components/rich-text/index.native.js +7 -11
  60. package/build/components/rich-text/index.native.js.map +1 -1
  61. package/build/components/spacing-sizes-control/spacing-input-control.js +8 -0
  62. package/build/components/spacing-sizes-control/spacing-input-control.js.map +1 -1
  63. package/build/hooks/anchor.js +1 -1
  64. package/build/hooks/anchor.js.map +1 -1
  65. package/build/hooks/border.js +1 -1
  66. package/build/hooks/border.js.map +1 -1
  67. package/build/hooks/duotone.js +92 -66
  68. package/build/hooks/duotone.js.map +1 -1
  69. package/build/hooks/margin.js +27 -17
  70. package/build/hooks/margin.js.map +1 -1
  71. package/build/hooks/padding.js +19 -9
  72. package/build/hooks/padding.js.map +1 -1
  73. package/build/hooks/utils.js +7 -4
  74. package/build/hooks/utils.js.map +1 -1
  75. package/build/layouts/utils.js +3 -2
  76. package/build/layouts/utils.js.map +1 -1
  77. package/build/private-apis.js +4 -1
  78. package/build/private-apis.js.map +1 -1
  79. package/build/store/actions.js +1 -1
  80. package/build/store/actions.js.map +1 -1
  81. package/build/utils/object.js +1 -1
  82. package/build/utils/object.js.map +1 -1
  83. package/build-module/components/block-list/block.native.js +4 -3
  84. package/build-module/components/block-list/block.native.js.map +1 -1
  85. package/build-module/components/block-list/index.native.js +11 -19
  86. package/build-module/components/block-list/index.native.js.map +1 -1
  87. package/build-module/components/block-list/use-in-between-inserter.js +2 -1
  88. package/build-module/components/block-list/use-in-between-inserter.js.map +1 -1
  89. package/build-module/components/block-popover/inbetween.js +2 -9
  90. package/build-module/components/block-popover/inbetween.js.map +1 -1
  91. package/build-module/components/block-settings-menu/block-settings-dropdown.js +1 -9
  92. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  93. package/build-module/components/caption/index.native.js +0 -1
  94. package/build-module/components/caption/index.native.js.map +1 -1
  95. package/build-module/components/date-format-picker/index.js +1 -1
  96. package/build-module/components/date-format-picker/index.js.map +1 -1
  97. package/build-module/components/global-styles/border-panel.js +15 -29
  98. package/build-module/components/global-styles/border-panel.js.map +1 -1
  99. package/build-module/components/global-styles/dimensions-panel.js +15 -14
  100. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  101. package/build-module/components/global-styles/effects-panel.js +228 -0
  102. package/build-module/components/global-styles/effects-panel.js.map +1 -0
  103. package/build-module/components/global-styles/filters-panel.js +139 -0
  104. package/build-module/components/global-styles/filters-panel.js.map +1 -0
  105. package/build-module/components/global-styles/get-block-css-selector.js +1 -12
  106. package/build-module/components/global-styles/get-block-css-selector.js.map +1 -1
  107. package/build-module/components/global-styles/hooks.js +7 -0
  108. package/build-module/components/global-styles/hooks.js.map +1 -1
  109. package/build-module/components/global-styles/index.js +2 -0
  110. package/build-module/components/global-styles/index.js.map +1 -1
  111. package/build-module/components/global-styles/use-global-styles-output.js +16 -8
  112. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  113. package/build-module/components/iframe/index.js +1 -1
  114. package/build-module/components/iframe/index.js.map +1 -1
  115. package/build-module/components/image-size-control/use-dimension-handler.js +5 -3
  116. package/build-module/components/image-size-control/use-dimension-handler.js.map +1 -1
  117. package/build-module/components/index.js +1 -0
  118. package/build-module/components/index.js.map +1 -1
  119. package/build-module/components/inserter/block-patterns-tab.js +5 -2
  120. package/build-module/components/inserter/block-patterns-tab.js.map +1 -1
  121. package/build-module/components/inspector-controls-tabs/utils.js +4 -3
  122. package/build-module/components/inspector-controls-tabs/utils.js.map +1 -1
  123. package/build-module/components/list-view/block.js +1 -0
  124. package/build-module/components/list-view/block.js.map +1 -1
  125. package/build-module/components/list-view/index.js +21 -4
  126. package/build-module/components/list-view/index.js.map +1 -1
  127. package/build-module/components/list-view/use-list-view-client-ids.js +7 -3
  128. package/build-module/components/list-view/use-list-view-client-ids.js.map +1 -1
  129. package/build-module/components/list-view/use-list-view-drop-zone.js +8 -4
  130. package/build-module/components/list-view/use-list-view-drop-zone.js.map +1 -1
  131. package/build-module/components/off-canvas-editor/block-contents.js +5 -1
  132. package/build-module/components/off-canvas-editor/block-contents.js.map +1 -1
  133. package/build-module/components/off-canvas-editor/index.js +17 -14
  134. package/build-module/components/off-canvas-editor/index.js.map +1 -1
  135. package/build-module/components/resizable-box-popover/index.js +26 -0
  136. package/build-module/components/resizable-box-popover/index.js.map +1 -0
  137. package/build-module/components/rich-text/index.js +0 -1
  138. package/build-module/components/rich-text/index.js.map +1 -1
  139. package/build-module/components/rich-text/index.native.js +7 -10
  140. package/build-module/components/rich-text/index.native.js.map +1 -1
  141. package/build-module/components/spacing-sizes-control/spacing-input-control.js +7 -0
  142. package/build-module/components/spacing-sizes-control/spacing-input-control.js.map +1 -1
  143. package/build-module/hooks/anchor.js +1 -1
  144. package/build-module/hooks/anchor.js.map +1 -1
  145. package/build-module/hooks/border.js +1 -1
  146. package/build-module/hooks/border.js.map +1 -1
  147. package/build-module/hooks/duotone.js +90 -66
  148. package/build-module/hooks/duotone.js.map +1 -1
  149. package/build-module/hooks/margin.js +29 -18
  150. package/build-module/hooks/margin.js.map +1 -1
  151. package/build-module/hooks/padding.js +21 -10
  152. package/build-module/hooks/padding.js.map +1 -1
  153. package/build-module/hooks/utils.js +8 -5
  154. package/build-module/hooks/utils.js.map +1 -1
  155. package/build-module/layouts/utils.js +3 -2
  156. package/build-module/layouts/utils.js.map +1 -1
  157. package/build-module/private-apis.js +3 -1
  158. package/build-module/private-apis.js.map +1 -1
  159. package/build-module/store/actions.js +1 -1
  160. package/build-module/store/actions.js.map +1 -1
  161. package/build-module/utils/object.js +1 -1
  162. package/build-module/utils/object.js.map +1 -1
  163. package/build-style/style-rtl.css +51 -10
  164. package/build-style/style.css +51 -10
  165. package/package.json +31 -31
  166. package/src/components/block-inspector/style.scss +6 -4
  167. package/src/components/block-list/block.native.js +3 -2
  168. package/src/components/block-list/index.native.js +19 -38
  169. package/src/components/block-list/use-in-between-inserter.js +4 -1
  170. package/src/components/block-popover/inbetween.js +2 -13
  171. package/src/components/block-settings-menu/block-settings-dropdown.js +2 -12
  172. package/src/components/caption/index.native.js +0 -1
  173. package/src/components/date-format-picker/index.js +1 -1
  174. package/src/components/global-styles/README.md +129 -16
  175. package/src/components/global-styles/border-panel.js +13 -32
  176. package/src/components/global-styles/dimensions-panel.js +30 -13
  177. package/src/components/global-styles/effects-panel.js +228 -0
  178. package/src/components/global-styles/filters-panel.js +157 -0
  179. package/src/components/global-styles/get-block-css-selector.js +0 -11
  180. package/src/components/global-styles/hooks.js +10 -0
  181. package/src/components/global-styles/index.js +2 -0
  182. package/src/components/global-styles/style.scss +42 -0
  183. package/src/components/global-styles/test/use-global-styles-output.js +4 -4
  184. package/src/components/global-styles/use-global-styles-output.js +27 -11
  185. package/src/components/iframe/index.js +1 -1
  186. package/src/components/image-size-control/use-dimension-handler.js +4 -3
  187. package/src/components/index.js +4 -1
  188. package/src/components/inserter/block-patterns-tab.js +3 -1
  189. package/src/components/inspector-controls-tabs/utils.js +4 -3
  190. package/src/components/list-view/README.md +2 -0
  191. package/src/components/list-view/block.js +1 -0
  192. package/src/components/list-view/index.js +18 -2
  193. package/src/components/list-view/style.scss +3 -1
  194. package/src/components/list-view/test/use-list-view-drop-zone.js +188 -0
  195. package/src/components/list-view/use-list-view-client-ids.js +5 -3
  196. package/src/components/list-view/use-list-view-drop-zone.js +9 -3
  197. package/src/components/off-canvas-editor/block-contents.js +4 -0
  198. package/src/components/off-canvas-editor/index.js +15 -11
  199. package/src/components/resizable-box-popover/index.js +27 -0
  200. package/src/components/rich-text/index.js +0 -1
  201. package/src/components/rich-text/index.native.js +2 -5
  202. package/src/components/spacing-sizes-control/spacing-input-control.js +10 -0
  203. package/src/components/spacing-sizes-control/style.scss +7 -7
  204. package/src/hooks/anchor.js +1 -1
  205. package/src/hooks/border.js +1 -1
  206. package/src/hooks/duotone.js +116 -74
  207. package/src/hooks/margin.js +31 -26
  208. package/src/hooks/padding.js +24 -18
  209. package/src/hooks/utils.js +4 -4
  210. package/src/layouts/utils.js +2 -2
  211. package/src/private-apis.js +2 -0
  212. package/src/store/actions.js +1 -1
  213. package/src/style.scss +1 -0
  214. package/src/utils/object.js +1 -1
  215. package/src/utils/test/object.js +38 -0
  216. package/build/components/rich-text/use-native-props.js +0 -11
  217. package/build/components/rich-text/use-native-props.js.map +0 -1
  218. package/build/components/rich-text/use-native-props.native.js +0 -24
  219. package/build/components/rich-text/use-native-props.native.js.map +0 -1
  220. package/build-module/components/rich-text/use-native-props.js +0 -4
  221. package/build-module/components/rich-text/use-native-props.js.map +0 -1
  222. package/build-module/components/rich-text/use-native-props.native.js +0 -15
  223. package/build-module/components/rich-text/use-native-props.native.js.map +0 -1
  224. package/src/components/rich-text/use-native-props.js +0 -3
  225. package/src/components/rich-text/use-native-props.native.js +0 -17
@@ -32,6 +32,8 @@ import {
32
32
  __unstableDuotoneStylesheet as DuotoneStylesheet,
33
33
  __unstableDuotoneUnsetStylesheet as DuotoneUnsetStylesheet,
34
34
  } from '../components/duotone';
35
+ import { getBlockCSSSelector } from '../components/global-styles/get-block-css-selector';
36
+ import { scopeSelector } from '../components/global-styles/utils';
35
37
  import { store as blockEditorStore } from '../store';
36
38
 
37
39
  const EMPTY_ARRAY = [];
@@ -166,7 +168,9 @@ function DuotonePanel( { attributes, setAttributes } ) {
166
168
  * @return {Object} Filtered block settings.
167
169
  */
168
170
  function addDuotoneAttributes( settings ) {
169
- if ( ! hasBlockSupport( settings, 'color.__experimentalDuotone' ) ) {
171
+ // Previous `color.__experimentalDuotone` support flag is migrated via
172
+ // block_type_metadata_settings filter in `lib/block-supports/duotone.php`.
173
+ if ( ! hasBlockSupport( settings, 'filter.duotone' ) ) {
170
174
  return settings;
171
175
  }
172
176
 
@@ -193,10 +197,13 @@ function addDuotoneAttributes( settings ) {
193
197
  */
194
198
  const withDuotoneControls = createHigherOrderComponent(
195
199
  ( BlockEdit ) => ( props ) => {
200
+ // Previous `color.__experimentalDuotone` support flag is migrated via
201
+ // block_type_metadata_settings filter in `lib/block-supports/duotone.php`.
196
202
  const hasDuotoneSupport = hasBlockSupport(
197
203
  props.name,
198
- 'color.__experimentalDuotone'
204
+ 'filter.duotone'
199
205
  );
206
+
200
207
  const isContentLocked = useSelect(
201
208
  ( select ) => {
202
209
  return select(
@@ -222,76 +229,71 @@ const withDuotoneControls = createHigherOrderComponent(
222
229
  'withDuotoneControls'
223
230
  );
224
231
 
225
- /**
226
- * Function that scopes a selector with another one. This works a bit like
227
- * SCSS nesting except the `&` operator isn't supported.
228
- *
229
- * @example
230
- * ```js
231
- * const scope = '.a, .b .c';
232
- * const selector = '> .x, .y';
233
- * const merged = scopeSelector( scope, selector );
234
- * // merged is '.a > .x, .a .y, .b .c > .x, .b .c .y'
235
- * ```
236
- *
237
- * @param {string} scope Selector to scope to.
238
- * @param {string} selector Original selector.
239
- *
240
- * @return {string} Scoped selector.
241
- */
242
- function scopeSelector( scope, selector ) {
243
- const scopes = scope.split( ',' );
244
- const selectors = selector.split( ',' );
245
-
246
- const selectorsScoped = [];
247
- scopes.forEach( ( outer ) => {
248
- selectors.forEach( ( inner ) => {
249
- selectorsScoped.push( `${ outer.trim() } ${ inner.trim() }` );
250
- } );
251
- } );
252
-
253
- return selectorsScoped.join( ', ' );
254
- }
232
+ function DuotoneStyles( {
233
+ id: filterId,
234
+ selector: duotoneSelector,
235
+ attribute: duotoneAttr,
236
+ } ) {
237
+ const element = useContext( BlockList.__unstableElementContext );
255
238
 
256
- function BlockDuotoneStyles( { name, duotoneStyle, id } ) {
257
239
  const duotonePalette = useMultiOriginPresets( {
258
240
  presetSetting: 'color.duotone',
259
241
  defaultSetting: 'color.defaultDuotone',
260
242
  } );
261
243
 
262
- const element = useContext( BlockList.__unstableElementContext );
263
-
264
- // Portals cannot exist without a container.
265
- // Guard against empty Duotone styles.
266
- if ( ! element || ! duotoneStyle ) {
267
- return null;
244
+ // Possible values for duotone attribute:
245
+ // 1. Array of colors - e.g. ['#000000', '#ffffff'].
246
+ // 2. Variable for an existing Duotone preset - e.g. 'var:preset|duotone|green-blue' or 'var(--wp--preset--duotone--green-blue)''
247
+ // 3. A CSS string - e.g. 'unset' to remove globally applied duotone.
248
+ const isCustom = Array.isArray( duotoneAttr );
249
+ const duotonePreset = isCustom
250
+ ? undefined
251
+ : getColorsFromDuotonePreset( duotoneAttr, duotonePalette );
252
+ const isPreset = typeof duotoneAttr === 'string' && duotonePreset;
253
+ const isCSS = typeof duotoneAttr === 'string' && ! isPreset;
254
+
255
+ // Match the structure of WP_Duotone_Gutenberg::render_duotone_support() in PHP.
256
+ let colors = null;
257
+ if ( isPreset ) {
258
+ // Array of colors.
259
+ colors = duotonePreset;
260
+ } else if ( isCSS ) {
261
+ // CSS filter property string (e.g. 'unset').
262
+ colors = duotoneAttr;
263
+ } else if ( isCustom ) {
264
+ // Array of colors.
265
+ colors = duotoneAttr;
268
266
  }
269
267
 
270
- let colors = duotoneStyle;
268
+ // Build the CSS selectors to which the filter will be applied.
269
+ const selectors = duotoneSelector.split( ',' );
271
270
 
272
- if ( ! Array.isArray( colors ) && colors !== 'unset' ) {
273
- colors = getColorsFromDuotonePreset( colors, duotonePalette );
274
- }
271
+ const selectorsScoped = selectors.map( ( selectorPart ) => {
272
+ // Extra .editor-styles-wrapper specificity is needed in the editor
273
+ // since we're not using inline styles to apply the filter. We need to
274
+ // override duotone applied by global styles and theme.json.
275
275
 
276
- const duotoneSupportSelectors =
277
- getBlockType( name ).selectors?.filter?.duotone ||
278
- getBlockSupport( name, 'color.__experimentalDuotone' );
276
+ // Assuming the selector part is a subclass selector (not a tag name)
277
+ // so we can prepend the filter id class. If we want to support elements
278
+ // such as `img` or namespaces, we'll need to add a case for that here.
279
+ return `.editor-styles-wrapper .${ filterId }${ selectorPart.trim() }`;
280
+ } );
279
281
 
280
- // Extra .editor-styles-wrapper specificity is needed in the editor
281
- // since we're not using inline styles to apply the filter. We need to
282
- // override duotone applied by global styles and theme.json.
283
- const selectorsGroup = scopeSelector(
284
- `.editor-styles-wrapper .${ id }`,
285
- duotoneSupportSelectors
286
- );
282
+ const selector = selectorsScoped.join( ', ' );
287
283
 
288
- return createPortal(
289
- <InlineDuotone
290
- selector={ selectorsGroup }
291
- id={ id }
292
- colors={ colors }
293
- />,
294
- element
284
+ const isValidFilter = Array.isArray( colors ) || colors === 'unset';
285
+
286
+ return (
287
+ element &&
288
+ isValidFilter &&
289
+ createPortal(
290
+ <InlineDuotone
291
+ selector={ selector }
292
+ id={ filterId }
293
+ colors={ colors }
294
+ />,
295
+ element
296
+ )
295
297
  );
296
298
  }
297
299
 
@@ -304,16 +306,56 @@ function BlockDuotoneStyles( { name, duotoneStyle, id } ) {
304
306
  */
305
307
  const withDuotoneStyles = createHigherOrderComponent(
306
308
  ( BlockListBlock ) => ( props ) => {
307
- const duotoneSupport = getBlockSupport(
308
- props.name,
309
- 'color.__experimentalDuotone'
310
- );
311
-
312
- const id = `wp-duotone-${ useInstanceId( BlockListBlock ) }`;
313
- const className = duotoneSupport
314
- ? classnames( props?.className, id )
309
+ const id = useInstanceId( BlockListBlock );
310
+
311
+ const selector = useMemo( () => {
312
+ const blockType = getBlockType( props.name );
313
+
314
+ if ( blockType ) {
315
+ // Backwards compatibility for `supports.color.__experimentalDuotone`
316
+ // is provided via the `block_type_metadata_settings` filter. If
317
+ // `supports.filter.duotone` has not been set and the
318
+ // experimental property has been, the experimental property
319
+ // value is copied into `supports.filter.duotone`.
320
+ const duotoneSupport = getBlockSupport(
321
+ blockType,
322
+ 'filter.duotone',
323
+ false
324
+ );
325
+ if ( ! duotoneSupport ) {
326
+ return null;
327
+ }
328
+
329
+ // If the experimental duotone support was set, that value is
330
+ // to be treated as a selector and requires scoping.
331
+ const experimentalDuotone = getBlockSupport(
332
+ blockType,
333
+ 'color.__experimentalDuotone',
334
+ false
335
+ );
336
+ if ( experimentalDuotone ) {
337
+ const rootSelector = getBlockCSSSelector( blockType );
338
+ return typeof experimentalDuotone === 'string'
339
+ ? scopeSelector( rootSelector, experimentalDuotone )
340
+ : rootSelector;
341
+ }
342
+
343
+ // Regular filter.duotone support uses filter.duotone selectors with fallbacks.
344
+ return getBlockCSSSelector( blockType, 'filter.duotone', {
345
+ fallback: true,
346
+ } );
347
+ }
348
+ }, [ props.name ] );
349
+
350
+ const attribute = props?.attributes?.style?.color?.duotone;
351
+
352
+ const filterClass = `wp-duotone-${ id }`;
353
+
354
+ const shouldRender = selector && attribute;
355
+
356
+ const className = shouldRender
357
+ ? classnames( props?.className, filterClass )
315
358
  : props?.className;
316
- const duotoneStyle = props?.attributes?.style?.color?.duotone;
317
359
 
318
360
  // CAUTION: code added before this line will be executed
319
361
  // for all blocks, not just those that support duotone. Code added
@@ -321,11 +363,11 @@ const withDuotoneStyles = createHigherOrderComponent(
321
363
  // performance.
322
364
  return (
323
365
  <>
324
- { duotoneSupport && duotoneStyle && (
325
- <BlockDuotoneStyles
326
- name={ props?.name }
327
- duotoneStyle={ duotoneStyle }
328
- id={ id }
366
+ { shouldRender && (
367
+ <DuotoneStyles
368
+ id={ filterClass }
369
+ selector={ selector }
370
+ attribute={ attribute }
329
371
  />
330
372
  ) }
331
373
  <BlockListBlock { ...props } className={ className } />
@@ -1,43 +1,48 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { useMemo, useRef, useState, useEffect } from '@wordpress/element';
4
+ import { useState, useRef, useEffect } from '@wordpress/element';
5
5
  import isShallowEqual from '@wordpress/is-shallow-equal';
6
6
 
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
10
  import BlockPopover from '../components/block-popover';
11
- import { getSpacingPresetCssVar } from '../components/spacing-sizes-control/utils';
11
+ import { __unstableUseBlockElement as useBlockElement } from '../components/block-list/use-block-props/use-block-refs';
12
+
13
+ function getComputedCSS( element, property ) {
14
+ return element.ownerDocument.defaultView
15
+ .getComputedStyle( element )
16
+ .getPropertyValue( property );
17
+ }
12
18
 
13
19
  export function MarginVisualizer( { clientId, attributes, forceShow } ) {
20
+ const blockElement = useBlockElement( clientId );
21
+ const [ style, setStyle ] = useState();
22
+
14
23
  const margin = attributes?.style?.spacing?.margin;
15
24
 
16
- const style = useMemo( () => {
17
- const marginTop = margin?.top
18
- ? getSpacingPresetCssVar( margin?.top )
19
- : 0;
20
- const marginRight = margin?.right
21
- ? getSpacingPresetCssVar( margin?.right )
22
- : 0;
23
- const marginBottom = margin?.bottom
24
- ? getSpacingPresetCssVar( margin?.bottom )
25
- : 0;
26
- const marginLeft = margin?.left
27
- ? getSpacingPresetCssVar( margin?.left )
28
- : 0;
25
+ useEffect( () => {
26
+ if ( ! blockElement ) {
27
+ return;
28
+ }
29
29
 
30
- return {
31
- borderTopWidth: marginTop,
32
- borderRightWidth: marginRight,
33
- borderBottomWidth: marginBottom,
34
- borderLeftWidth: marginLeft,
35
- top: marginTop ? `calc(${ marginTop } * -1)` : 0,
36
- right: marginRight ? `calc(${ marginRight } * -1)` : 0,
37
- bottom: marginBottom ? `calc(${ marginBottom } * -1)` : 0,
38
- left: marginLeft ? `calc(${ marginLeft } * -1)` : 0,
39
- };
40
- }, [ margin ] );
30
+ const top = getComputedCSS( blockElement, 'margin-top' );
31
+ const right = getComputedCSS( blockElement, 'margin-right' );
32
+ const bottom = getComputedCSS( blockElement, 'margin-bottom' );
33
+ const left = getComputedCSS( blockElement, 'margin-left' );
34
+
35
+ setStyle( {
36
+ borderTopWidth: top,
37
+ borderRightWidth: right,
38
+ borderBottomWidth: bottom,
39
+ borderLeftWidth: left,
40
+ top: top ? `-${ top }` : 0,
41
+ right: right ? `-${ right }` : 0,
42
+ bottom: bottom ? `-${ bottom }` : 0,
43
+ left: left ? `-${ left }` : 0,
44
+ } );
45
+ }, [ blockElement, margin ] );
41
46
 
42
47
  const [ isActive, setIsActive ] = useState( false );
43
48
  const valueRef = useRef( margin );
@@ -1,33 +1,39 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { useState, useRef, useEffect, useMemo } from '@wordpress/element';
4
+ import { useState, useRef, useEffect } from '@wordpress/element';
5
5
  import isShallowEqual from '@wordpress/is-shallow-equal';
6
6
 
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
10
  import BlockPopover from '../components/block-popover';
11
- import { getSpacingPresetCssVar } from '../components/spacing-sizes-control/utils';
11
+ import { __unstableUseBlockElement as useBlockElement } from '../components/block-list/use-block-props/use-block-refs';
12
+
13
+ function getComputedCSS( element, property ) {
14
+ return element.ownerDocument.defaultView
15
+ .getComputedStyle( element )
16
+ .getPropertyValue( property );
17
+ }
12
18
 
13
19
  export function PaddingVisualizer( { clientId, attributes, forceShow } ) {
20
+ const blockElement = useBlockElement( clientId );
21
+ const [ style, setStyle ] = useState();
22
+
14
23
  const padding = attributes?.style?.spacing?.padding;
15
- const style = useMemo( () => {
16
- return {
17
- borderTopWidth: padding?.top
18
- ? getSpacingPresetCssVar( padding?.top )
19
- : 0,
20
- borderRightWidth: padding?.right
21
- ? getSpacingPresetCssVar( padding?.right )
22
- : 0,
23
- borderBottomWidth: padding?.bottom
24
- ? getSpacingPresetCssVar( padding?.bottom )
25
- : 0,
26
- borderLeftWidth: padding?.left
27
- ? getSpacingPresetCssVar( padding?.left )
28
- : 0,
29
- };
30
- }, [ padding ] );
24
+
25
+ useEffect( () => {
26
+ if ( ! blockElement ) {
27
+ return;
28
+ }
29
+
30
+ setStyle( {
31
+ borderTopWidth: getComputedCSS( blockElement, 'padding-top' ),
32
+ borderRightWidth: getComputedCSS( blockElement, 'padding-right' ),
33
+ borderBottomWidth: getComputedCSS( blockElement, 'padding-bottom' ),
34
+ borderLeftWidth: getComputedCSS( blockElement, 'padding-left' ),
35
+ } );
36
+ }, [ blockElement, padding ] );
31
37
 
32
38
  const [ isActive, setIsActive ] = useState( false );
33
39
  const valueRef = useRef( padding );
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { isEmpty, mapValues, get } from 'lodash';
4
+ import { isEmpty, get } from 'lodash';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
@@ -31,9 +31,9 @@ export const cleanEmptyObject = ( object ) => {
31
31
  return object;
32
32
  }
33
33
  const cleanedNestedObjects = Object.fromEntries(
34
- Object.entries( mapValues( object, cleanEmptyObject ) ).filter(
35
- ( [ , value ] ) => Boolean( value )
36
- )
34
+ Object.entries( object )
35
+ .map( ( [ key, value ] ) => [ key, cleanEmptyObject( value ) ] )
36
+ .filter( ( [ , value ] ) => Boolean( value ) )
37
37
  );
38
38
  return isEmpty( cleanedNestedObjects ) ? undefined : cleanedNestedObjects;
39
39
  };
@@ -83,10 +83,10 @@ export function getBlockGapCSS(
83
83
  * @return {Object} An object with contextual info per alignment.
84
84
  */
85
85
  export function getAlignmentsInfo( layout ) {
86
- const { contentSize, wideSize } = layout;
86
+ const { contentSize, wideSize, type = 'default' } = layout;
87
87
  const alignmentInfo = {};
88
88
  const sizeRegex = /^(?!0)\d+(px|em|rem|vw|vh|%)?$/i;
89
- if ( sizeRegex.test( contentSize ) ) {
89
+ if ( sizeRegex.test( contentSize ) && type === 'constrained' ) {
90
90
  // translators: %s: container size (i.e. 600px etc)
91
91
  alignmentInfo.none = sprintf( __( 'Max %s wide' ), contentSize );
92
92
  }
@@ -6,6 +6,7 @@ import { ExperimentalBlockEditorProvider } from './components/provider';
6
6
  import { lock } from './lock-unlock';
7
7
  import OffCanvasEditor from './components/off-canvas-editor';
8
8
  import LeafMoreMenu from './components/off-canvas-editor/leaf-more-menu';
9
+ import ResizableBoxPopover from './components/resizable-box-popover';
9
10
  import { ComposedPrivateInserter as PrivateInserter } from './components/inserter';
10
11
  import { PrivateListView } from './components/list-view';
11
12
 
@@ -20,4 +21,5 @@ lock( privateApis, {
20
21
  OffCanvasEditor,
21
22
  PrivateInserter,
22
23
  PrivateListView,
24
+ ResizableBoxPopover,
23
25
  } );
@@ -75,7 +75,7 @@ export const resetBlocks =
75
75
  /**
76
76
  * Block validity is a function of blocks state (at the point of a
77
77
  * reset) and the template setting. As a compromise to its placement
78
- * across distinct parts of state, it is implemented here as a side-
78
+ * across distinct parts of state, it is implemented here as a side
79
79
  * effect of the block reset action.
80
80
  *
81
81
  * @param {Array} blocks Array of blocks.
package/src/style.scss CHANGED
@@ -26,6 +26,7 @@
26
26
  @import "./components/date-format-picker/style.scss";
27
27
  @import "./components/duotone-control/style.scss";
28
28
  @import "./components/font-appearance-control/style.scss";
29
+ @import "./components/global-styles/style.scss";
29
30
  @import "./components/height-control/style.scss";
30
31
  @import "./components/image-size-control/style.scss";
31
32
  @import "./components/inserter-list-item/style.scss";
@@ -27,7 +27,7 @@ function normalizePath( path ) {
27
27
  * @return {*} Cloned object, or original literal non-object value.
28
28
  */
29
29
  function cloneObject( object ) {
30
- if ( typeof object === 'object' ) {
30
+ if ( object && typeof object === 'object' ) {
31
31
  return {
32
32
  ...Object.fromEntries(
33
33
  Object.entries( object ).map( ( [ key, value ] ) => [
@@ -84,6 +84,44 @@ describe( 'immutableSet', () => {
84
84
  } );
85
85
  } );
86
86
  } );
87
+
88
+ describe( 'for nested falsey values', () => {
89
+ it( 'overwrites undefined values', () => {
90
+ const result = immutableSet( { test: undefined }, 'test', 1 );
91
+
92
+ expect( result ).toEqual( { test: 1 } );
93
+ } );
94
+
95
+ it( 'overwrites null values', () => {
96
+ const result = immutableSet( { test: null }, 'test', 1 );
97
+
98
+ expect( result ).toEqual( { test: 1 } );
99
+ } );
100
+
101
+ it( 'overwrites false values', () => {
102
+ const result = immutableSet( { test: false }, 'test', 1 );
103
+
104
+ expect( result ).toEqual( { test: 1 } );
105
+ } );
106
+
107
+ it( 'overwrites `0` values', () => {
108
+ const result = immutableSet( { test: 0 }, 'test', 1 );
109
+
110
+ expect( result ).toEqual( { test: 1 } );
111
+ } );
112
+
113
+ it( 'overwrites empty string values', () => {
114
+ const result = immutableSet( { test: '' }, 'test', 1 );
115
+
116
+ expect( result ).toEqual( { test: 1 } );
117
+ } );
118
+
119
+ it( 'overwrites NaN values', () => {
120
+ const result = immutableSet( { test: NaN }, 'test', 1 );
121
+
122
+ expect( result ).toEqual( { test: 1 } );
123
+ } );
124
+ } );
87
125
  } );
88
126
 
89
127
  describe( 'does not mutate the original object', () => {
@@ -1,11 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useNativeProps = useNativeProps;
7
-
8
- function useNativeProps() {
9
- return {};
10
- }
11
- //# sourceMappingURL=use-native-props.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["@wordpress/block-editor/src/components/rich-text/use-native-props.js"],"names":["useNativeProps"],"mappings":";;;;;;;AAAO,SAASA,cAAT,GAA0B;AAChC,SAAO,EAAP;AACA","sourcesContent":["export function useNativeProps() {\n\treturn {};\n}\n"]}
@@ -1,24 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useNativeProps = useNativeProps;
7
-
8
- var _element = require("@wordpress/element");
9
-
10
- var _blockList = require("../block-list");
11
-
12
- /**
13
- * WordPress dependencies
14
- */
15
-
16
- /**
17
- * Internal dependencies
18
- */
19
- function useNativeProps() {
20
- return {
21
- onCaretVerticalPositionChange: (0, _element.useContext)(_blockList.OnCaretVerticalPositionChange)
22
- };
23
- }
24
- //# sourceMappingURL=use-native-props.native.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["@wordpress/block-editor/src/components/rich-text/use-native-props.native.js"],"names":["useNativeProps","onCaretVerticalPositionChange","OnCaretVerticalPositionChange"],"mappings":";;;;;;;AAGA;;AAKA;;AARA;AACA;AACA;;AAGA;AACA;AACA;AAGO,SAASA,cAAT,GAA0B;AAChC,SAAO;AACNC,IAAAA,6BAA6B,EAAE,yBAC9BC,wCAD8B;AADzB,GAAP;AAKA","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useContext } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { OnCaretVerticalPositionChange } from '../block-list';\n\nexport function useNativeProps() {\n\treturn {\n\t\tonCaretVerticalPositionChange: useContext(\n\t\t\tOnCaretVerticalPositionChange\n\t\t),\n\t};\n}\n"]}
@@ -1,4 +0,0 @@
1
- export function useNativeProps() {
2
- return {};
3
- }
4
- //# sourceMappingURL=use-native-props.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["@wordpress/block-editor/src/components/rich-text/use-native-props.js"],"names":["useNativeProps"],"mappings":"AAAA,OAAO,SAASA,cAAT,GAA0B;AAChC,SAAO,EAAP;AACA","sourcesContent":["export function useNativeProps() {\n\treturn {};\n}\n"]}
@@ -1,15 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { useContext } from '@wordpress/element';
5
- /**
6
- * Internal dependencies
7
- */
8
-
9
- import { OnCaretVerticalPositionChange } from '../block-list';
10
- export function useNativeProps() {
11
- return {
12
- onCaretVerticalPositionChange: useContext(OnCaretVerticalPositionChange)
13
- };
14
- }
15
- //# sourceMappingURL=use-native-props.native.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["@wordpress/block-editor/src/components/rich-text/use-native-props.native.js"],"names":["useContext","OnCaretVerticalPositionChange","useNativeProps","onCaretVerticalPositionChange"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,UAAT,QAA2B,oBAA3B;AAEA;AACA;AACA;;AACA,SAASC,6BAAT,QAA8C,eAA9C;AAEA,OAAO,SAASC,cAAT,GAA0B;AAChC,SAAO;AACNC,IAAAA,6BAA6B,EAAEH,UAAU,CACxCC,6BADwC;AADnC,GAAP;AAKA","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useContext } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { OnCaretVerticalPositionChange } from '../block-list';\n\nexport function useNativeProps() {\n\treturn {\n\t\tonCaretVerticalPositionChange: useContext(\n\t\t\tOnCaretVerticalPositionChange\n\t\t),\n\t};\n}\n"]}
@@ -1,3 +0,0 @@
1
- export function useNativeProps() {
2
- return {};
3
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { useContext } from '@wordpress/element';
5
-
6
- /**
7
- * Internal dependencies
8
- */
9
- import { OnCaretVerticalPositionChange } from '../block-list';
10
-
11
- export function useNativeProps() {
12
- return {
13
- onCaretVerticalPositionChange: useContext(
14
- OnCaretVerticalPositionChange
15
- ),
16
- };
17
- }