@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
@@ -0,0 +1,157 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ __experimentalToolsPanel as ToolsPanel,
6
+ __experimentalToolsPanelItem as ToolsPanelItem,
7
+ __experimentalVStack as VStack,
8
+ DuotonePicker,
9
+ } from '@wordpress/components';
10
+ import { __ } from '@wordpress/i18n';
11
+ import { useCallback, useMemo } from '@wordpress/element';
12
+
13
+ /**
14
+ * Internal dependencies
15
+ */
16
+ import { getValueFromVariable } from './utils';
17
+ import { immutableSet } from '../../utils/object';
18
+
19
+ const EMPTY_ARRAY = [];
20
+ function useMultiOriginColorPresets(
21
+ settings,
22
+ { presetSetting, defaultSetting }
23
+ ) {
24
+ const disableDefault = ! settings?.color?.[ defaultSetting ];
25
+ const userPresets =
26
+ settings?.color?.[ presetSetting ]?.custom || EMPTY_ARRAY;
27
+ const themePresets =
28
+ settings?.color?.[ presetSetting ]?.theme || EMPTY_ARRAY;
29
+ const defaultPresets =
30
+ settings?.color?.[ presetSetting ]?.default || EMPTY_ARRAY;
31
+ return useMemo(
32
+ () => [
33
+ ...userPresets,
34
+ ...themePresets,
35
+ ...( disableDefault ? EMPTY_ARRAY : defaultPresets ),
36
+ ],
37
+ [ disableDefault, userPresets, themePresets, defaultPresets ]
38
+ );
39
+ }
40
+
41
+ export function useHasFiltersPanel( settings ) {
42
+ const hasDuotone = useHasDuotoneControl( settings );
43
+
44
+ return hasDuotone;
45
+ }
46
+
47
+ function useHasDuotoneControl( settings ) {
48
+ return settings.color.customDuotone || settings.color.defaultDuotone;
49
+ }
50
+
51
+ function FiltersToolsPanel( {
52
+ resetAllFilter,
53
+ onChange,
54
+ value,
55
+ panelId,
56
+ children,
57
+ } ) {
58
+ const resetAll = () => {
59
+ const updatedValue = resetAllFilter( value );
60
+ onChange( updatedValue );
61
+ };
62
+
63
+ return (
64
+ <ToolsPanel
65
+ label={ __( 'Filters' ) }
66
+ resetAll={ resetAll }
67
+ panelId={ panelId }
68
+ >
69
+ { children }
70
+ </ToolsPanel>
71
+ );
72
+ }
73
+
74
+ const DEFAULT_CONTROLS = {
75
+ duotone: true,
76
+ };
77
+
78
+ export default function FiltersPanel( {
79
+ as: Wrapper = FiltersToolsPanel,
80
+ value,
81
+ onChange,
82
+ inheritedValue = value,
83
+ settings,
84
+ panelId,
85
+ defaultControls = DEFAULT_CONTROLS,
86
+ } ) {
87
+ const decodeValue = ( rawValue ) =>
88
+ getValueFromVariable( { settings }, '', rawValue );
89
+
90
+ // Duotone
91
+ const hasDuotoneEnabled = useHasDuotoneControl( settings );
92
+ const duotonePalette = useMultiOriginColorPresets( settings, {
93
+ presetSetting: 'duotone',
94
+ defaultSetting: 'defaultDuotone',
95
+ } );
96
+ const colorPalette = useMultiOriginColorPresets( settings, {
97
+ presetSetting: 'palette',
98
+ defaultSetting: 'defaultPalette',
99
+ } );
100
+ const duotone = decodeValue( inheritedValue?.filter?.duotone );
101
+ const setDuotone = ( newValue ) => {
102
+ const duotonePreset = duotonePalette.find( ( { colors } ) => {
103
+ return colors === newValue;
104
+ } );
105
+ const settedValue = duotonePreset
106
+ ? `var:preset|duotone|${ duotonePreset.slug }`
107
+ : newValue;
108
+ onChange( immutableSet( value, [ 'filter', 'duotone' ], settedValue ) );
109
+ };
110
+ const hasDuotone = () => !! value?.filter?.duotone;
111
+ const resetDuotone = () => setDuotone( undefined );
112
+
113
+ const resetAllFilter = useCallback( ( previousValue ) => {
114
+ return {
115
+ ...previousValue,
116
+ filter: {
117
+ ...previousValue.filter,
118
+ duotone: undefined,
119
+ },
120
+ };
121
+ }, [] );
122
+
123
+ return (
124
+ <Wrapper
125
+ resetAllFilter={ resetAllFilter }
126
+ value={ value }
127
+ onChange={ onChange }
128
+ panelId={ panelId }
129
+ >
130
+ { hasDuotoneEnabled && (
131
+ <ToolsPanelItem
132
+ label={ __( 'Duotone' ) }
133
+ hasValue={ hasDuotone }
134
+ onDeselect={ resetDuotone }
135
+ isShownByDefault={ defaultControls.duotone }
136
+ panelId={ panelId }
137
+ >
138
+ <VStack>
139
+ <p>
140
+ { __(
141
+ 'Create a two-tone color effect without losing your original image.'
142
+ ) }
143
+ </p>
144
+ <DuotonePicker
145
+ colorPalette={ colorPalette }
146
+ duotonePalette={ duotonePalette }
147
+ disableCustomColors={ true }
148
+ disableCustomDuotone={ true }
149
+ value={ duotone }
150
+ onChange={ setDuotone }
151
+ />
152
+ </VStack>
153
+ </ToolsPanelItem>
154
+ ) }
155
+ </Wrapper>
156
+ );
157
+ }
@@ -34,17 +34,6 @@ export function getBlockCSSSelector(
34
34
  const hasSelectors = ! isEmpty( selectors );
35
35
  const path = Array.isArray( target ) ? target.join( '.' ) : target;
36
36
 
37
- // Duotone ( no fallback selectors for Duotone ).
38
- if ( path === 'filter.duotone' ) {
39
- // If selectors API in use, only use its value or null.
40
- if ( hasSelectors ) {
41
- return get( selectors, path, null );
42
- }
43
-
44
- // Selectors API, not available, check for old experimental selector.
45
- return get( supports, 'color.__experimentalDuotone', null );
46
- }
47
-
48
37
  // Root selector.
49
38
 
50
39
  // Calculated before returning as it can be used as a fallback for feature
@@ -283,6 +283,12 @@ export function useSettingsForBlockElement(
283
283
  updatedSettings.color.customGradient = false;
284
284
  }
285
285
 
286
+ // If filters are not supported by the block/element, disable duotone.
287
+ if ( ! supportedStyles.includes( 'filter' ) ) {
288
+ updatedSettings.color.defaultDuotone = false;
289
+ updatedSettings.color.customDuotone = false;
290
+ }
291
+
286
292
  [
287
293
  'lineHeight',
288
294
  'fontStyle',
@@ -360,6 +366,10 @@ export function useSettingsForBlockElement(
360
366
  }
361
367
  } );
362
368
 
369
+ updatedSettings.shadow = supportedStyles.includes( 'shadow' )
370
+ ? updatedSettings.shadow
371
+ : false;
372
+
363
373
  return updatedSettings;
364
374
  }, [ parentSettings, supportedStyles, supports ] );
365
375
  }
@@ -17,3 +17,5 @@ export {
17
17
  } from './dimensions-panel';
18
18
  export { default as BorderPanel, useHasBorderPanel } from './border-panel';
19
19
  export { default as ColorPanel, useHasColorPanel } from './color-panel';
20
+ export { default as EffectsPanel, useHasEffectsPanel } from './effects-panel';
21
+ export { default as FiltersPanel, useHasFiltersPanel } from './filters-panel';
@@ -0,0 +1,42 @@
1
+ .block-editor-global-styles-effects-panel__toggle-icon {
2
+ fill: currentColor;
3
+ }
4
+
5
+ .block-editor-global-styles-effects-panel__shadow-popover-container {
6
+ width: 230px;
7
+ }
8
+
9
+ .block-editor-global-styles-effects-panel__shadow-dropdown {
10
+ display: block;
11
+ padding: 0;
12
+
13
+ > button {
14
+ width: 100%;
15
+ padding: $grid-unit-10;
16
+
17
+ &.is-open {
18
+ background-color: $gray-100;
19
+ }
20
+ }
21
+ }
22
+
23
+ // wrapper to clip the shadow beyond 6px
24
+ .block-editor-global-styles-effects-panel__shadow-indicator-wrapper {
25
+ padding: 6px;
26
+ overflow: hidden;
27
+ display: flex;
28
+ align-items: center;
29
+ justify-content: center;
30
+ }
31
+
32
+ // These styles are similar to the color palette.
33
+ .block-editor-global-styles-effects-panel__shadow-indicator {
34
+ color: $gray-800;
35
+ border: $gray-200 $border-width solid;
36
+ border-radius: $radius-block-ui;
37
+ cursor: pointer;
38
+ padding: 0;
39
+
40
+ height: 24px;
41
+ width: 24px;
42
+ }
@@ -612,7 +612,7 @@ describe( 'global styles renderer', () => {
612
612
  } );
613
613
 
614
614
  expect( layoutStyles ).toEqual(
615
- 'body .is-layout-flow > * { margin-block-start: 0; margin-block-end: 0; }body .is-layout-flow > * + * { margin-block-start: 0.5em; margin-block-end: 0; }body .is-layout-flex { gap: 0.5em; }body { --wp--style--block-gap: 0.5em; }body .is-layout-flow > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }body .is-layout-flow > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }body .is-layout-flow > .aligncenter { margin-left: auto !important; margin-right: auto !important; }body .is-layout-flex { display:flex; }body .is-layout-flex { flex-wrap: wrap; align-items: center; }body .is-layout-flex > * { margin: 0; }'
615
+ ':where(body .is-layout-flow) > * { margin-block-start: 0; margin-block-end: 0; }:where(body .is-layout-flow) > * + * { margin-block-start: 0.5em; margin-block-end: 0; }:where(body .is-layout-flex) { gap: 0.5em; }body { --wp--style--block-gap: 0.5em; }body .is-layout-flow > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }body .is-layout-flow > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }body .is-layout-flow > .aligncenter { margin-left: auto !important; margin-right: auto !important; }body .is-layout-flex { display:flex; }body .is-layout-flex { flex-wrap: wrap; align-items: center; }body .is-layout-flex > * { margin: 0; }'
616
616
  );
617
617
  } );
618
618
 
@@ -628,7 +628,7 @@ describe( 'global styles renderer', () => {
628
628
  } );
629
629
 
630
630
  expect( layoutStyles ).toEqual(
631
- 'body .is-layout-flow > * { margin-block-start: 0; margin-block-end: 0; }body .is-layout-flow > * + * { margin-block-start: 12px; margin-block-end: 0; }body .is-layout-flex { gap: 12px; }body { --wp--style--block-gap: 12px; }body .is-layout-flow > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }body .is-layout-flow > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }body .is-layout-flow > .aligncenter { margin-left: auto !important; margin-right: auto !important; }body .is-layout-flex { display:flex; }body .is-layout-flex { flex-wrap: wrap; align-items: center; }body .is-layout-flex > * { margin: 0; }'
631
+ ':where(body .is-layout-flow) > * { margin-block-start: 0; margin-block-end: 0; }:where(body .is-layout-flow) > * + * { margin-block-start: 12px; margin-block-end: 0; }:where(body .is-layout-flex) { gap: 12px; }body { --wp--style--block-gap: 12px; }body .is-layout-flow > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }body .is-layout-flow > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }body .is-layout-flow > .aligncenter { margin-left: auto !important; margin-right: auto !important; }body .is-layout-flex { display:flex; }body .is-layout-flex { flex-wrap: wrap; align-items: center; }body .is-layout-flex > * { margin: 0; }'
632
632
  );
633
633
  } );
634
634
 
@@ -644,7 +644,7 @@ describe( 'global styles renderer', () => {
644
644
  } );
645
645
 
646
646
  expect( layoutStyles ).toEqual(
647
- '.wp-block-group-is-layout-flow.wp-block-group-is-layout-flow > * { margin-block-start: 0; margin-block-end: 0; }.wp-block-group-is-layout-flow.wp-block-group-is-layout-flow > * + * { margin-block-start: 12px; margin-block-end: 0; }.wp-block-group-is-layout-flex.wp-block-group-is-layout-flex { gap: 12px; }'
647
+ '.wp-block-group-is-layout-flow > * { margin-block-start: 0; margin-block-end: 0; }.wp-block-group-is-layout-flow > * + * { margin-block-start: 12px; margin-block-end: 0; }.wp-block-group-is-layout-flex { gap: 12px; }'
648
648
  );
649
649
  } );
650
650
 
@@ -713,7 +713,7 @@ describe( 'global styles renderer', () => {
713
713
  'core/image': {
714
714
  name: imageBlock.name,
715
715
  selector: imageSupports.__experimentalSelector,
716
- duotoneSelector: imageSupports.color.__experimentalDuotone,
716
+ duotoneSelector: '.my-image img',
717
717
  fallbackGapValue: undefined,
718
718
  featureSelectors: {
719
719
  root: '.my-image',
@@ -9,6 +9,7 @@ import { get, isEmpty, kebabCase, set } from 'lodash';
9
9
  import {
10
10
  __EXPERIMENTAL_STYLE_PROPERTY as STYLE_PROPERTY,
11
11
  __EXPERIMENTAL_ELEMENTS as ELEMENTS,
12
+ getBlockSupport,
12
13
  getBlockTypes,
13
14
  store as blocksStore,
14
15
  } from '@wordpress/blocks';
@@ -483,10 +484,10 @@ export function getLayoutStyles( {
483
484
  } else {
484
485
  combinedSelector =
485
486
  selector === ROOT_BLOCK_SELECTOR
486
- ? `${ selector } .${ className }${
487
+ ? `:where(${ selector } .${ className })${
487
488
  spacingStyle?.selector || ''
488
489
  }`
489
- : `${ selector }-${ className }${ selector }-${ className }${
490
+ : `${ selector }-${ className }${
490
491
  spacingStyle?.selector || ''
491
492
  }`;
492
493
  }
@@ -852,17 +853,16 @@ export const toStyles = (
852
853
  delete styles.filter;
853
854
  }
854
855
 
855
- // Process duotone styles (they use color.__experimentalDuotone selector).
856
+ // Process duotone styles.
856
857
  if ( duotoneSelector ) {
857
858
  const duotoneDeclarations =
858
859
  getStylesDeclarations( duotoneStyles );
859
860
  if ( duotoneDeclarations.length > 0 ) {
860
861
  ruleset =
861
862
  ruleset +
862
- `${ scopeSelector(
863
- selector,
864
- duotoneSelector
865
- ) }{${ duotoneDeclarations.join( ';' ) };}`;
863
+ `${ duotoneSelector }{${ duotoneDeclarations.join(
864
+ ';'
865
+ ) };}`;
866
866
  }
867
867
  }
868
868
 
@@ -948,10 +948,13 @@ export const toStyles = (
948
948
  getGapCSSValue( tree?.styles?.spacing?.blockGap ) || '0.5em';
949
949
  ruleset =
950
950
  ruleset +
951
- '.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }';
951
+ `:where(.wp-site-blocks) > * { margin-block-start: ${ gapValue }; margin-block-end: 0; }`;
952
952
  ruleset =
953
953
  ruleset +
954
- `.wp-site-blocks > * + * { margin-block-start: ${ gapValue }; }`;
954
+ ':where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }';
955
+ ruleset =
956
+ ruleset +
957
+ ':where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }';
955
958
  }
956
959
 
957
960
  nodesWithSettings.forEach( ( { selector, presets } ) => {
@@ -1002,11 +1005,24 @@ export const getBlockSelectors = ( blockTypes, getBlockStyles ) => {
1002
1005
  const result = {};
1003
1006
  blockTypes.forEach( ( blockType ) => {
1004
1007
  const name = blockType.name;
1005
- const selector = getBlockCSSSelector( blockType, 'root' );
1006
- const duotoneSelector = getBlockCSSSelector(
1008
+ const selector = getBlockCSSSelector( blockType );
1009
+ let duotoneSelector = getBlockCSSSelector(
1007
1010
  blockType,
1008
1011
  'filter.duotone'
1009
1012
  );
1013
+
1014
+ // Keep backwards compatibility for support.color.__experimentalDuotone.
1015
+ if ( ! duotoneSelector ) {
1016
+ const rootSelector = getBlockCSSSelector( blockType );
1017
+ const duotoneSupport = getBlockSupport(
1018
+ blockType,
1019
+ 'color.__experimentalDuotone',
1020
+ false
1021
+ );
1022
+ duotoneSelector =
1023
+ duotoneSupport && scopeSelector( rootSelector, duotoneSupport );
1024
+ }
1025
+
1010
1026
  const hasLayoutSupport = !! blockType?.supports?.__experimentalLayout;
1011
1027
  const fallbackGapValue =
1012
1028
  blockType?.supports?.spacing?.blockGap?.__experimentalDefault;
@@ -71,7 +71,7 @@ function bubbleEvents( doc ) {
71
71
  }
72
72
  }
73
73
 
74
- const eventTypes = [ 'dragover' ];
74
+ const eventTypes = [ 'dragover', 'mousemove' ];
75
75
 
76
76
  for ( const name of eventTypes ) {
77
77
  doc.addEventListener( name, bubbleEvent );
@@ -47,13 +47,14 @@ export default function useDimensionHandler(
47
47
  }, [ customWidth, customHeight ] );
48
48
 
49
49
  const updateDimension = ( dimension, value ) => {
50
+ const parsedValue = value === '' ? undefined : parseInt( value, 10 );
50
51
  if ( dimension === 'width' ) {
51
- setCurrentWidth( value );
52
+ setCurrentWidth( parsedValue );
52
53
  } else {
53
- setCurrentHeight( value );
54
+ setCurrentHeight( parsedValue );
54
55
  }
55
56
  onChange( {
56
- [ dimension ]: value === '' ? undefined : parseInt( value, 10 ),
57
+ [ dimension ]: parsedValue,
57
58
  } );
58
59
  };
59
60
 
@@ -92,7 +92,10 @@ export { default as URLPopover } from './url-popover';
92
92
  export { __experimentalImageURLInputUI } from './url-popover/image-url-input-ui';
93
93
  export { default as withColorContext } from './color-palette/with-color-context';
94
94
  export { default as __experimentalSpacingSizesControl } from './spacing-sizes-control';
95
-
95
+ export {
96
+ getSpacingPresetCssVar,
97
+ isValueSpacingPreset,
98
+ } from './spacing-sizes-control/utils';
96
99
  /*
97
100
  * Content Related Components
98
101
  */
@@ -28,6 +28,8 @@ import BlockPatternList from '../block-patterns-list';
28
28
  import PatternsExplorerModal from './block-patterns-explorer/explorer';
29
29
  import MobileTabNavigation from './mobile-tab-navigation';
30
30
 
31
+ const noop = () => {};
32
+
31
33
  // Preferred order of pattern categories. Any other categories should
32
34
  // be at the bottom without any re-ordering.
33
35
  const patternCategoriesOrder = [
@@ -134,7 +136,7 @@ export function BlockPatternsCategoryDialog( {
134
136
  export function BlockPatternsCategoryPanel( {
135
137
  rootClientId,
136
138
  onInsert,
137
- onHover,
139
+ onHover = noop,
138
140
  category,
139
141
  showTitlesAsTooltip,
140
142
  } ) {
@@ -2,10 +2,11 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { cog, styles, listView } from '@wordpress/icons';
5
+ import { __ } from '@wordpress/i18n';
5
6
 
6
7
  export const TAB_SETTINGS = {
7
8
  name: 'settings',
8
- title: 'Settings',
9
+ title: __( 'Settings' ),
9
10
  value: 'settings',
10
11
  icon: cog,
11
12
  className: 'block-editor-block-inspector__tab-item',
@@ -13,7 +14,7 @@ export const TAB_SETTINGS = {
13
14
 
14
15
  export const TAB_STYLES = {
15
16
  name: 'styles',
16
- title: 'Styles',
17
+ title: __( 'Styles' ),
17
18
  value: 'styles',
18
19
  icon: styles,
19
20
  className: 'block-editor-block-inspector__tab-item',
@@ -21,7 +22,7 @@ export const TAB_STYLES = {
21
22
 
22
23
  export const TAB_LIST_VIEW = {
23
24
  name: 'list',
24
- title: 'List View',
25
+ title: __( 'List View' ),
25
26
  value: 'list-view',
26
27
  icon: listView,
27
28
  className: 'block-editor-block-inspector__tab-item',
@@ -2,6 +2,8 @@
2
2
 
3
3
  The ListView component provides an overview of the hierarchical structure of all blocks in the editor. The blocks are presented vertically one below the other.
4
4
 
5
+ By providing the `rootClientId` prop you can restrict the blocks that are shown to only children of the block with that client id.
6
+
5
7
  Blocks that have child blocks (such as group or column blocks) are presented with the parent at the top and the nested children below.
6
8
 
7
9
  In addition to presenting the structure of the blocks in the editor, the ListView component lets users navigate to each block by clicking on its line in the hierarchy tree. Multiple blocks at the same level of nesting can be selected by holding down the `SHIFT` key and clicking blocks within the list.
@@ -248,6 +248,7 @@ function ListViewBlock( {
248
248
  path={ path }
249
249
  id={ `list-view-block-${ clientId }` }
250
250
  data-block={ clientId }
251
+ data-expanded={ canExpand ? isExpanded : undefined }
251
252
  isExpanded={ canExpand ? isExpanded : undefined }
252
253
  aria-selected={ !! isSelected || forceSelectionContentLock }
253
254
  ref={ rowRef }
@@ -7,6 +7,7 @@ import {
7
7
  } from '@wordpress/compose';
8
8
  import { __experimentalTreeGrid as TreeGrid } from '@wordpress/components';
9
9
  import { AsyncModeProvider, useSelect } from '@wordpress/data';
10
+ import deprecated from '@wordpress/deprecated';
10
11
  import {
11
12
  useCallback,
12
13
  useEffect,
@@ -56,11 +57,12 @@ export const BLOCK_LIST_ITEM_HEIGHT = 36;
56
57
  *
57
58
  * @param {Object} props Components props.
58
59
  * @param {string} props.id An HTML element id for the root element of ListView.
59
- * @param {Array} props.blocks Custom subset of block client IDs to be used instead of the default hierarchy.
60
+ * @param {Array} props.blocks _deprecated_ Custom subset of block client IDs to be used instead of the default hierarchy.
60
61
  * @param {?boolean} props.showBlockMovers Flag to enable block movers. Defaults to `false`.
61
62
  * @param {?boolean} props.isExpanded Flag to determine whether nested levels are expanded by default. Defaults to `false`.
62
63
  * @param {?boolean} props.showAppender Flag to show or hide the block appender. Defaults to `false`.
63
64
  * @param {?ComponentType} props.blockSettingsMenu Optional more menu substitution. Defaults to the standard `BlockSettingsDropdown` component.
65
+ * @param {string} props.rootClientId The client id of the root block from which we determine the blocks to show in the list.
64
66
  * @param {Ref} ref Forwarded ref
65
67
  */
66
68
  function ListViewComponent(
@@ -71,11 +73,23 @@ function ListViewComponent(
71
73
  isExpanded = false,
72
74
  showAppender = false,
73
75
  blockSettingsMenu: BlockSettingsMenu = BlockSettingsDropdown,
76
+ rootClientId,
74
77
  },
75
78
  ref
76
79
  ) {
80
+ // This can be removed once we no longer need to support the blocks prop.
81
+ if ( blocks ) {
82
+ deprecated(
83
+ '`blocks` property in `wp.blockEditor.__experimentalListView`',
84
+ {
85
+ since: '6.3',
86
+ alternative: '`rootClientId` property',
87
+ }
88
+ );
89
+ }
90
+
77
91
  const { clientIdsTree, draggedClientIds, selectedClientIds } =
78
- useListViewClientIds( blocks );
92
+ useListViewClientIds( { blocks, rootClientId } );
79
93
 
80
94
  const { visibleBlockCount, shouldShowInnerBlocks } = useSelect(
81
95
  ( select ) => {
@@ -219,6 +233,7 @@ function ListViewComponent(
219
233
  <ListViewContext.Provider value={ contextValue }>
220
234
  <ListViewBranch
221
235
  blocks={ clientIdsTree }
236
+ parentId={ rootClientId }
222
237
  selectBlock={ selectEditorBlock }
223
238
  showBlockMovers={ showBlockMovers }
224
239
  fixedListWindow={ fixedListWindow }
@@ -241,6 +256,7 @@ export default forwardRef( ( props, ref ) => {
241
256
  { ...props }
242
257
  showAppender={ false }
243
258
  blockSettingsMenu={ BlockSettingsDropdown }
259
+ rootClientId={ null }
244
260
  />
245
261
  );
246
262
  } );
@@ -400,7 +400,9 @@ $block-navigation-max-indent: 8;
400
400
 
401
401
  .block-editor-list-view-drop-indicator__line {
402
402
  background: var(--wp-admin-theme-color);
403
- height: $border-width;
403
+ height: 6px;
404
+ border: 1px solid $white;
405
+ border-radius: 4px;
404
406
  }
405
407
  }
406
408