@wordpress/block-editor 12.21.0 → 12.22.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 (213) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/components/block-actions/index.js +2 -4
  3. package/build/components/block-actions/index.js.map +1 -1
  4. package/build/components/block-heading-level-dropdown/index.js +5 -5
  5. package/build/components/block-heading-level-dropdown/index.js.map +1 -1
  6. package/build/components/block-heading-level-dropdown/index.native.js +5 -4
  7. package/build/components/block-heading-level-dropdown/index.native.js.map +1 -1
  8. package/build/components/block-list/block-crash-boundary.native.js +49 -0
  9. package/build/components/block-list/block-crash-boundary.native.js.map +1 -0
  10. package/build/components/block-list/block-crash-warning.native.js +24 -0
  11. package/build/components/block-list/block-crash-warning.native.js.map +1 -0
  12. package/build/components/block-list/block.native.js +7 -2
  13. package/build/components/block-list/block.native.js.map +1 -1
  14. package/build/components/block-settings/container.native.js +2 -1
  15. package/build/components/block-settings/container.native.js.map +1 -1
  16. package/build/components/block-settings-menu/block-settings-dropdown.js +29 -29
  17. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  18. package/build/components/block-settings-menu-controls/index.js +1 -3
  19. package/build/components/block-settings-menu-controls/index.js.map +1 -1
  20. package/build/components/block-toolbar/index.js +3 -1
  21. package/build/components/block-toolbar/index.js.map +1 -1
  22. package/build/components/block-toolbar/shuffle.js +1 -1
  23. package/build/components/block-toolbar/shuffle.js.map +1 -1
  24. package/build/components/child-layout-control/index.js +108 -11
  25. package/build/components/child-layout-control/index.js.map +1 -1
  26. package/build/components/convert-to-group-buttons/toolbar.js +11 -0
  27. package/build/components/convert-to-group-buttons/toolbar.js.map +1 -1
  28. package/build/components/global-styles/dimensions-panel.js +8 -33
  29. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  30. package/build/components/global-styles/use-global-styles-output.js +1 -1
  31. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  32. package/build/components/global-styles/utils.js +1 -3
  33. package/build/components/global-styles/utils.js.map +1 -1
  34. package/build/components/iframe/index.js +34 -30
  35. package/build/components/iframe/index.js.map +1 -1
  36. package/build/components/inserter/block-patterns-explorer/index.js +3 -6
  37. package/build/components/inserter/block-patterns-explorer/index.js.map +1 -1
  38. package/build/components/inserter/block-patterns-explorer/pattern-list.js +3 -1
  39. package/build/components/inserter/block-patterns-explorer/pattern-list.js.map +1 -1
  40. package/build/components/inserter/menu.js +3 -9
  41. package/build/components/inserter/menu.js.map +1 -1
  42. package/build/components/inserter/mobile-tab-navigation.js +1 -1
  43. package/build/components/inserter/mobile-tab-navigation.js.map +1 -1
  44. package/build/components/inserter/search-results.js +2 -3
  45. package/build/components/inserter/search-results.js.map +1 -1
  46. package/build/components/inserter/tabs.js +1 -2
  47. package/build/components/inserter/tabs.js.map +1 -1
  48. package/build/components/inspector-controls-tabs/advanced-controls-panel.native.js +36 -0
  49. package/build/components/inspector-controls-tabs/advanced-controls-panel.native.js.map +1 -0
  50. package/build/components/list-view/block-select-button.js +2 -12
  51. package/build/components/list-view/block-select-button.js.map +1 -1
  52. package/build/components/list-view/block.js +4 -11
  53. package/build/components/list-view/block.js.map +1 -1
  54. package/build/components/list-view/utils.js +5 -3
  55. package/build/components/list-view/utils.js.map +1 -1
  56. package/build/components/spacing-sizes-control/sides-dropdown/index.js +1 -1
  57. package/build/components/spacing-sizes-control/sides-dropdown/index.js.map +1 -1
  58. package/build/components/use-moving-animation/index.js +4 -0
  59. package/build/components/use-moving-animation/index.js.map +1 -1
  60. package/build/components/warning/index.native.js +9 -4
  61. package/build/components/warning/index.native.js.map +1 -1
  62. package/build/hooks/anchor.js +7 -8
  63. package/build/hooks/anchor.js.map +1 -1
  64. package/build/hooks/background.js +39 -2
  65. package/build/hooks/background.js.map +1 -1
  66. package/build/hooks/index.js +2 -1
  67. package/build/hooks/index.js.map +1 -1
  68. package/build/hooks/layout-child.js +28 -6
  69. package/build/hooks/layout-child.js.map +1 -1
  70. package/build/hooks/layout.js +21 -10
  71. package/build/hooks/layout.js.map +1 -1
  72. package/build/hooks/position.js +1 -1
  73. package/build/hooks/position.js.map +1 -1
  74. package/build/private-apis.native.js +3 -1
  75. package/build/private-apis.native.js.map +1 -1
  76. package/build/store/reducer.js +31 -26
  77. package/build/store/reducer.js.map +1 -1
  78. package/build-module/components/block-actions/index.js +2 -4
  79. package/build-module/components/block-actions/index.js.map +1 -1
  80. package/build-module/components/block-heading-level-dropdown/index.js +5 -5
  81. package/build-module/components/block-heading-level-dropdown/index.js.map +1 -1
  82. package/build-module/components/block-heading-level-dropdown/index.native.js +5 -4
  83. package/build-module/components/block-heading-level-dropdown/index.native.js.map +1 -1
  84. package/build-module/components/block-list/block-crash-boundary.native.js +42 -0
  85. package/build-module/components/block-list/block-crash-boundary.native.js.map +1 -0
  86. package/build-module/components/block-list/block-crash-warning.native.js +15 -0
  87. package/build-module/components/block-list/block-crash-warning.native.js.map +1 -0
  88. package/build-module/components/block-list/block.native.js +7 -2
  89. package/build-module/components/block-list/block.native.js.map +1 -1
  90. package/build-module/components/block-settings/container.native.js +3 -2
  91. package/build-module/components/block-settings/container.native.js.map +1 -1
  92. package/build-module/components/block-settings-menu/block-settings-dropdown.js +30 -30
  93. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  94. package/build-module/components/block-settings-menu-controls/index.js +1 -3
  95. package/build-module/components/block-settings-menu-controls/index.js.map +1 -1
  96. package/build-module/components/block-toolbar/index.js +3 -1
  97. package/build-module/components/block-toolbar/index.js.map +1 -1
  98. package/build-module/components/block-toolbar/shuffle.js +1 -1
  99. package/build-module/components/block-toolbar/shuffle.js.map +1 -1
  100. package/build-module/components/child-layout-control/index.js +109 -12
  101. package/build-module/components/child-layout-control/index.js.map +1 -1
  102. package/build-module/components/convert-to-group-buttons/toolbar.js +12 -1
  103. package/build-module/components/convert-to-group-buttons/toolbar.js.map +1 -1
  104. package/build-module/components/global-styles/dimensions-panel.js +9 -34
  105. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  106. package/build-module/components/global-styles/use-global-styles-output.js +1 -1
  107. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  108. package/build-module/components/global-styles/utils.js +0 -2
  109. package/build-module/components/global-styles/utils.js.map +1 -1
  110. package/build-module/components/iframe/index.js +34 -30
  111. package/build-module/components/iframe/index.js.map +1 -1
  112. package/build-module/components/inserter/block-patterns-explorer/index.js +3 -6
  113. package/build-module/components/inserter/block-patterns-explorer/index.js.map +1 -1
  114. package/build-module/components/inserter/block-patterns-explorer/pattern-list.js +3 -1
  115. package/build-module/components/inserter/block-patterns-explorer/pattern-list.js.map +1 -1
  116. package/build-module/components/inserter/menu.js +3 -9
  117. package/build-module/components/inserter/menu.js.map +1 -1
  118. package/build-module/components/inserter/mobile-tab-navigation.js +1 -1
  119. package/build-module/components/inserter/mobile-tab-navigation.js.map +1 -1
  120. package/build-module/components/inserter/search-results.js +2 -3
  121. package/build-module/components/inserter/search-results.js.map +1 -1
  122. package/build-module/components/inserter/tabs.js +1 -2
  123. package/build-module/components/inserter/tabs.js.map +1 -1
  124. package/build-module/components/inspector-controls-tabs/advanced-controls-panel.native.js +28 -0
  125. package/build-module/components/inspector-controls-tabs/advanced-controls-panel.native.js.map +1 -0
  126. package/build-module/components/list-view/block-select-button.js +3 -13
  127. package/build-module/components/list-view/block-select-button.js.map +1 -1
  128. package/build-module/components/list-view/block.js +6 -13
  129. package/build-module/components/list-view/block.js.map +1 -1
  130. package/build-module/components/list-view/utils.js +2 -1
  131. package/build-module/components/list-view/utils.js.map +1 -1
  132. package/build-module/components/spacing-sizes-control/sides-dropdown/index.js +1 -1
  133. package/build-module/components/spacing-sizes-control/sides-dropdown/index.js.map +1 -1
  134. package/build-module/components/use-moving-animation/index.js +4 -0
  135. package/build-module/components/use-moving-animation/index.js.map +1 -1
  136. package/build-module/components/warning/index.native.js +9 -4
  137. package/build-module/components/warning/index.native.js.map +1 -1
  138. package/build-module/hooks/anchor.js +8 -9
  139. package/build-module/hooks/anchor.js.map +1 -1
  140. package/build-module/hooks/background.js +38 -1
  141. package/build-module/hooks/background.js.map +1 -1
  142. package/build-module/hooks/index.js +2 -1
  143. package/build-module/hooks/index.js.map +1 -1
  144. package/build-module/hooks/layout-child.js +28 -6
  145. package/build-module/hooks/layout-child.js.map +1 -1
  146. package/build-module/hooks/layout.js +21 -10
  147. package/build-module/hooks/layout.js.map +1 -1
  148. package/build-module/hooks/position.js +1 -1
  149. package/build-module/hooks/position.js.map +1 -1
  150. package/build-module/private-apis.native.js +3 -1
  151. package/build-module/private-apis.native.js.map +1 -1
  152. package/build-module/store/reducer.js +31 -26
  153. package/build-module/store/reducer.js.map +1 -1
  154. package/build-style/content-rtl.css +14 -0
  155. package/build-style/content.css +14 -0
  156. package/build-style/style-rtl.css +8 -20
  157. package/build-style/style.css +8 -20
  158. package/package.json +31 -31
  159. package/src/components/block-actions/index.js +2 -8
  160. package/src/components/block-bindings-toolbar-indicator/style.scss +10 -8
  161. package/src/components/block-heading-level-dropdown/README.md +5 -5
  162. package/src/components/block-heading-level-dropdown/index.js +5 -5
  163. package/src/components/block-heading-level-dropdown/index.native.js +5 -4
  164. package/src/components/block-list/block-crash-boundary.native.js +43 -0
  165. package/src/components/block-list/block-crash-warning.native.js +19 -0
  166. package/src/components/block-list/block.native.js +14 -7
  167. package/src/components/block-list/content.scss +16 -0
  168. package/src/components/block-settings/container.native.js +5 -1
  169. package/src/components/block-settings-menu/block-settings-dropdown.js +41 -56
  170. package/src/components/block-settings-menu-controls/README.md +0 -9
  171. package/src/components/block-settings-menu-controls/index.js +1 -6
  172. package/src/components/block-toolbar/index.js +3 -1
  173. package/src/components/block-toolbar/shuffle.js +1 -1
  174. package/src/components/block-toolbar/test/index.native.js +1 -7
  175. package/src/components/child-layout-control/index.js +147 -35
  176. package/src/components/convert-to-group-buttons/toolbar.js +13 -1
  177. package/src/components/global-styles/dimensions-panel.js +9 -34
  178. package/src/components/global-styles/test/use-global-styles-output.js +31 -0
  179. package/src/components/global-styles/use-global-styles-output.js +3 -1
  180. package/src/components/global-styles/utils.js +0 -18
  181. package/src/components/iframe/index.js +60 -44
  182. package/src/components/inserter/block-patterns-explorer/index.js +2 -9
  183. package/src/components/inserter/block-patterns-explorer/pattern-list.js +7 -1
  184. package/src/components/inserter/menu.js +4 -10
  185. package/src/components/inserter/mobile-tab-navigation.js +1 -1
  186. package/src/components/inserter/search-results.js +1 -2
  187. package/src/components/inserter/tabs.js +1 -2
  188. package/src/components/inspector-controls-tabs/advanced-controls-panel.native.js +31 -0
  189. package/src/components/link-control/style.scss +0 -5
  190. package/src/components/list-view/block-select-button.js +2 -18
  191. package/src/components/list-view/block.js +12 -21
  192. package/src/components/list-view/style.scss +34 -24
  193. package/src/components/list-view/utils.js +4 -1
  194. package/src/components/rich-text/README.md +6 -0
  195. package/src/components/spacing-sizes-control/sides-dropdown/index.js +1 -1
  196. package/src/components/use-moving-animation/index.js +1 -0
  197. package/src/components/warning/index.native.js +19 -15
  198. package/src/hooks/anchor.js +41 -61
  199. package/src/hooks/background.js +48 -3
  200. package/src/hooks/index.js +2 -0
  201. package/src/hooks/layout-child.js +44 -8
  202. package/src/hooks/layout.js +22 -18
  203. package/src/hooks/position.js +1 -1
  204. package/src/hooks/test/__snapshots__/anchor.native.js.snap +7 -0
  205. package/src/hooks/test/anchor.native.js +32 -0
  206. package/src/private-apis.native.js +2 -0
  207. package/src/store/reducer.js +41 -41
  208. package/tsconfig.json +1 -0
  209. package/build/utils/calculate-scale.js +0 -17
  210. package/build/utils/calculate-scale.js.map +0 -1
  211. package/build-module/utils/calculate-scale.js +0 -11
  212. package/build-module/utils/calculate-scale.js.map +0 -1
  213. package/src/utils/calculate-scale.js +0 -20
@@ -63,6 +63,7 @@ export function PrivateBlockToolbar( {
63
63
  isDefaultEditingMode,
64
64
  blockType,
65
65
  blockName,
66
+ toolbarKey,
66
67
  shouldShowVisualToolbar,
67
68
  showParentSelector,
68
69
  isUsingBindings,
@@ -103,6 +104,7 @@ export function PrivateBlockToolbar( {
103
104
  blockType: selectedBlockClientId && getBlockType( _blockName ),
104
105
  shouldShowVisualToolbar: isValid && isVisual,
105
106
  rootClientId: blockRootClientId,
107
+ toolbarKey: `${ selectedBlockClientId }${ firstParentClientId }`,
106
108
  showParentSelector:
107
109
  parentBlockType &&
108
110
  getBlockEditingMode( firstParentClientId ) === 'default' &&
@@ -159,7 +161,7 @@ export function PrivateBlockToolbar( {
159
161
  __experimentalOnIndexChange={ __experimentalOnIndexChange }
160
162
  // Resets the index whenever the active block changes so
161
163
  // this is not persisted. See https://github.com/WordPress/gutenberg/pull/25760#issuecomment-717906169
162
- key={ blockClientId }
164
+ key={ toolbarKey }
163
165
  >
164
166
  <div ref={ toolbarWrapperRef } className={ innerClasses }>
165
167
  { ! isMultiToolbar &&
@@ -56,7 +56,7 @@ export default function Shuffle( { clientId, as = Container } ) {
56
56
  // Check if the pattern has only one top level block,
57
57
  // otherwise we may shuffle to pattern that will not allow to continue shuffling.
58
58
  pattern.blocks.length === 1 &&
59
- pattern.categories.some( ( category ) => {
59
+ pattern.categories?.some( ( category ) => {
60
60
  return categories.includes( category );
61
61
  } )
62
62
  );
@@ -15,13 +15,7 @@ describe( 'Block Toolbar', () => {
15
15
  it( "doesn't render the block settings button if there aren't any settings for the current selected block", async () => {
16
16
  // Arrange
17
17
  const screen = await initializeEditor();
18
- await addBlock( screen, 'Image' );
19
-
20
- // Act
21
- fireEvent(
22
- screen.getByTestId( 'media-options-picker' ),
23
- 'backdropPress'
24
- );
18
+ await addBlock( screen, 'Shortcode' );
25
19
 
26
20
  // Assert
27
21
  expect( screen.queryByLabelText( 'Open Settings' ) ).toBeNull();
@@ -7,6 +7,10 @@ import {
7
7
  __experimentalUnitControl as UnitControl,
8
8
  __experimentalInputControl as InputControl,
9
9
  __experimentalHStack as HStack,
10
+ __experimentalVStack as VStack,
11
+ __experimentalToolsPanelItem as ToolsPanelItem,
12
+ Flex,
13
+ FlexItem,
10
14
  } from '@wordpress/components';
11
15
  import { __ } from '@wordpress/i18n';
12
16
  import { useEffect } from '@wordpress/element';
@@ -28,25 +32,62 @@ function helpText( selfStretch, parentLayout ) {
28
32
  /**
29
33
  * Form to edit the child layout value.
30
34
  *
31
- * @param {Object} props Props.
32
- * @param {Object} props.value The child layout value.
33
- * @param {Function} props.onChange Function to update the child layout value.
34
- * @param {Object} props.parentLayout The parent layout value.
35
+ * @param {Object} props Props.
36
+ * @param {Object} props.value The child layout value.
37
+ * @param {Function} props.onChange Function to update the child layout value.
38
+ * @param {Object} props.parentLayout The parent layout value.
35
39
  *
40
+ * @param {boolean} props.isShownByDefault
41
+ * @param {string} props.panelId
36
42
  * @return {Element} child layout edit element.
37
43
  */
38
44
  export default function ChildLayoutControl( {
39
45
  value: childLayout = {},
40
46
  onChange,
41
47
  parentLayout,
48
+ isShownByDefault,
49
+ panelId,
42
50
  } ) {
43
- const { selfStretch, flexSize, columnSpan, rowSpan } = childLayout;
51
+ const {
52
+ selfStretch,
53
+ flexSize,
54
+ columnStart,
55
+ rowStart,
56
+ columnSpan,
57
+ rowSpan,
58
+ } = childLayout;
44
59
  const {
45
60
  type: parentType,
46
61
  default: { type: defaultParentType = 'default' } = {},
62
+ orientation = 'horizontal',
47
63
  } = parentLayout ?? {};
48
64
  const parentLayoutType = parentType || defaultParentType;
49
65
 
66
+ const hasFlexValue = () => !! selfStretch;
67
+ const flexResetLabel =
68
+ orientation === 'horizontal' ? __( 'Width' ) : __( 'Height' );
69
+ const resetFlex = () => {
70
+ onChange( {
71
+ selfStretch: undefined,
72
+ flexSize: undefined,
73
+ } );
74
+ };
75
+
76
+ const hasStartValue = () => !! columnStart || !! rowStart;
77
+ const hasSpanValue = () => !! columnSpan || !! rowSpan;
78
+ const resetGridStarts = () => {
79
+ onChange( {
80
+ columnStart: undefined,
81
+ rowStart: undefined,
82
+ } );
83
+ };
84
+ const resetGridSpans = () => {
85
+ onChange( {
86
+ columnSpan: undefined,
87
+ rowSpan: undefined,
88
+ } );
89
+ };
90
+
50
91
  useEffect( () => {
51
92
  if ( selfStretch === 'fixed' && ! flexSize ) {
52
93
  onChange( {
@@ -59,7 +100,15 @@ export default function ChildLayoutControl( {
59
100
  return (
60
101
  <>
61
102
  { parentLayoutType === 'flex' && (
62
- <>
103
+ <VStack
104
+ as={ ToolsPanelItem }
105
+ spacing={ 2 }
106
+ hasValue={ hasFlexValue }
107
+ label={ flexResetLabel }
108
+ onDeselect={ resetFlex }
109
+ isShownByDefault={ isShownByDefault }
110
+ panelId={ panelId }
111
+ >
63
112
  <ToggleGroupControl
64
113
  __nextHasNoMarginBottom
65
114
  size={ '__unstable-large' }
@@ -104,37 +153,100 @@ export default function ChildLayoutControl( {
104
153
  value={ flexSize }
105
154
  />
106
155
  ) }
107
- </>
156
+ </VStack>
108
157
  ) }
109
158
  { parentLayoutType === 'grid' && (
110
- <HStack>
111
- <InputControl
112
- size={ '__unstable-large' }
113
- label={ __( 'Column Span' ) }
114
- type="number"
115
- onChange={ ( value ) => {
116
- onChange( {
117
- rowSpan,
118
- columnSpan: value,
119
- } );
120
- } }
121
- value={ columnSpan }
122
- min={ 1 }
123
- />
124
- <InputControl
125
- size={ '__unstable-large' }
126
- label={ __( 'Row Span' ) }
127
- type="number"
128
- onChange={ ( value ) => {
129
- onChange( {
130
- columnSpan,
131
- rowSpan: value,
132
- } );
133
- } }
134
- value={ rowSpan }
135
- min={ 1 }
136
- />
137
- </HStack>
159
+ <>
160
+ <HStack
161
+ as={ ToolsPanelItem }
162
+ hasValue={ hasSpanValue }
163
+ label={ __( 'Grid span' ) }
164
+ onDeselect={ resetGridSpans }
165
+ isShownByDefault={ isShownByDefault }
166
+ panelId={ panelId }
167
+ >
168
+ <InputControl
169
+ size={ '__unstable-large' }
170
+ label={ __( 'Column span' ) }
171
+ type="number"
172
+ onChange={ ( value ) => {
173
+ onChange( {
174
+ columnStart,
175
+ rowStart,
176
+ rowSpan,
177
+ columnSpan: value,
178
+ } );
179
+ } }
180
+ value={ columnSpan }
181
+ min={ 1 }
182
+ />
183
+ <InputControl
184
+ size={ '__unstable-large' }
185
+ label={ __( 'Row span' ) }
186
+ type="number"
187
+ onChange={ ( value ) => {
188
+ onChange( {
189
+ columnStart,
190
+ rowStart,
191
+ columnSpan,
192
+ rowSpan: value,
193
+ } );
194
+ } }
195
+ value={ rowSpan }
196
+ min={ 1 }
197
+ />
198
+ </HStack>
199
+ { window.__experimentalEnableGridInteractivity && (
200
+ // Use Flex with an explicit width on the FlexItem instead of HStack to
201
+ // work around an issue in webkit where inputs with a max attribute are
202
+ // sized incorrectly.
203
+ <Flex
204
+ as={ ToolsPanelItem }
205
+ hasValue={ hasStartValue }
206
+ label={ __( 'Grid placement' ) }
207
+ onDeselect={ resetGridStarts }
208
+ isShownByDefault={ false }
209
+ panelId={ panelId }
210
+ >
211
+ <FlexItem style={ { width: '50%' } }>
212
+ <InputControl
213
+ size={ '__unstable-large' }
214
+ label={ __( 'Column' ) }
215
+ type="number"
216
+ onChange={ ( value ) => {
217
+ onChange( {
218
+ columnStart: value,
219
+ rowStart,
220
+ columnSpan,
221
+ rowSpan,
222
+ } );
223
+ } }
224
+ value={ columnStart }
225
+ min={ 1 }
226
+ max={ parentLayout?.columnCount }
227
+ />
228
+ </FlexItem>
229
+ <FlexItem style={ { width: '50%' } }>
230
+ <InputControl
231
+ size={ '__unstable-large' }
232
+ label={ __( 'Row' ) }
233
+ type="number"
234
+ onChange={ ( value ) => {
235
+ onChange( {
236
+ columnStart,
237
+ rowStart: value,
238
+ columnSpan,
239
+ rowSpan,
240
+ } );
241
+ } }
242
+ value={ rowStart }
243
+ min={ 1 }
244
+ max={ parentLayout?.columnCount }
245
+ />
246
+ </FlexItem>
247
+ </Flex>
248
+ ) }
249
+ </>
138
250
  ) }
139
251
  </>
140
252
  );
@@ -4,7 +4,7 @@
4
4
  import { useDispatch, useSelect } from '@wordpress/data';
5
5
  import { switchToBlockType, store as blocksStore } from '@wordpress/blocks';
6
6
  import { ToolbarButton, ToolbarGroup } from '@wordpress/components';
7
- import { group, row, stack } from '@wordpress/icons';
7
+ import { group, row, stack, grid } from '@wordpress/icons';
8
8
  import { _x } from '@wordpress/i18n';
9
9
 
10
10
  /**
@@ -17,6 +17,7 @@ const layouts = {
17
17
  group: { type: 'constrained' },
18
18
  row: { type: 'flex', flexWrap: 'nowrap' },
19
19
  stack: { type: 'flex', orientation: 'vertical' },
20
+ grid: { type: 'grid' },
20
21
  };
21
22
 
22
23
  function BlockGroupToolbar() {
@@ -60,6 +61,7 @@ function BlockGroupToolbar() {
60
61
 
61
62
  const onConvertToRow = () => onConvertToGroup( 'row' );
62
63
  const onConvertToStack = () => onConvertToGroup( 'stack' );
64
+ const onConvertToGrid = () => onConvertToGroup( 'grid' );
63
65
 
64
66
  // Don't render the button if the current selection cannot be grouped.
65
67
  // A good example is selecting multiple button blocks within a Buttons block:
@@ -75,6 +77,9 @@ function BlockGroupToolbar() {
75
77
  const canInsertStack = !! variations.find(
76
78
  ( { name } ) => name === 'group-stack'
77
79
  );
80
+ const canInsertGrid = !! variations.find(
81
+ ( { name } ) => name === 'group-grid'
82
+ );
78
83
 
79
84
  return (
80
85
  <ToolbarGroup>
@@ -97,6 +102,13 @@ function BlockGroupToolbar() {
97
102
  onClick={ onConvertToStack }
98
103
  />
99
104
  ) }
105
+ { canInsertGrid && (
106
+ <ToolbarButton
107
+ icon={ grid }
108
+ label={ _x( 'Grid', 'verb' ) }
109
+ onClick={ onConvertToGrid }
110
+ />
111
+ ) }
100
112
  </ToolbarGroup>
101
113
  );
102
114
  }
@@ -12,7 +12,6 @@ import {
12
12
  __experimentalToolsPanelItem as ToolsPanelItem,
13
13
  __experimentalBoxControl as BoxControl,
14
14
  __experimentalHStack as HStack,
15
- __experimentalVStack as VStack,
16
15
  __experimentalUnitControl as UnitControl,
17
16
  __experimentalUseCustomUnits as useCustomUnits,
18
17
  __experimentalView as View,
@@ -396,16 +395,7 @@ export default function DimensionsPanel( {
396
395
  // Child Layout
397
396
  const showChildLayoutControl = useHasChildLayout( settings );
398
397
  const childLayout = inheritedValue?.layout;
399
- const { orientation = 'horizontal' } = settings?.parentLayout ?? {};
400
- const {
401
- type: parentType,
402
- default: { type: defaultParentType = 'default' } = {},
403
- } = settings?.parentLayout ?? {};
404
- const parentLayoutType = parentType || defaultParentType;
405
- const flexResetLabel =
406
- orientation === 'horizontal' ? __( 'Width' ) : __( 'Height' );
407
- const childLayoutResetLabel =
408
- parentLayoutType === 'flex' ? flexResetLabel : __( 'Grid spans' );
398
+
409
399
  const setChildLayout = ( newChildLayout ) => {
410
400
  onChange( {
411
401
  ...value,
@@ -414,15 +404,6 @@ export default function DimensionsPanel( {
414
404
  },
415
405
  } );
416
406
  };
417
- const resetChildLayoutValue = () => {
418
- setChildLayout( {
419
- selfStretch: undefined,
420
- flexSize: undefined,
421
- columnSpan: undefined,
422
- rowSpan: undefined,
423
- } );
424
- };
425
- const hasChildLayoutValue = () => !! value?.layout;
426
407
 
427
408
  const resetAllFilter = useCallback( ( previousValue ) => {
428
409
  return {
@@ -433,6 +414,8 @@ export default function DimensionsPanel( {
433
414
  wideSize: undefined,
434
415
  selfStretch: undefined,
435
416
  flexSize: undefined,
417
+ columnStart: undefined,
418
+ rowStart: undefined,
436
419
  columnSpan: undefined,
437
420
  rowSpan: undefined,
438
421
  } ),
@@ -650,24 +633,16 @@ export default function DimensionsPanel( {
650
633
  </ToolsPanelItem>
651
634
  ) }
652
635
  { showChildLayoutControl && (
653
- <VStack
654
- as={ ToolsPanelItem }
655
- spacing={ 2 }
656
- hasValue={ hasChildLayoutValue }
657
- label={ childLayoutResetLabel }
658
- onDeselect={ resetChildLayoutValue }
636
+ <ChildLayoutControl
637
+ value={ childLayout }
638
+ onChange={ setChildLayout }
639
+ parentLayout={ settings?.parentLayout }
640
+ panelId={ panelId }
659
641
  isShownByDefault={
660
642
  defaultControls.childLayout ??
661
643
  DEFAULT_CONTROLS.childLayout
662
644
  }
663
- panelId={ panelId }
664
- >
665
- <ChildLayoutControl
666
- value={ childLayout }
667
- onChange={ setChildLayout }
668
- parentLayout={ settings?.parentLayout }
669
- />
670
- </VStack>
645
+ />
671
646
  ) }
672
647
  { showMinHeightControl && (
673
648
  <ToolsPanelItem
@@ -968,6 +968,37 @@ describe( 'global styles renderer', () => {
968
968
  'font-size: 15px',
969
969
  ] );
970
970
  } );
971
+
972
+ it( 'should correctly resolve referenced values', () => {
973
+ const stylesWithRef = {
974
+ typography: {
975
+ fontSize: {
976
+ ref: 'styles.elements.h1.typography.fontSize',
977
+ },
978
+ letterSpacing: {
979
+ ref: 'styles.elements.h1.typography.letterSpacing',
980
+ },
981
+ },
982
+ };
983
+ const tree = {
984
+ styles: {
985
+ elements: {
986
+ h1: {
987
+ typography: {
988
+ fontSize: 'var:preset|font-size|xx-large',
989
+ letterSpacing: '2px',
990
+ },
991
+ },
992
+ },
993
+ },
994
+ };
995
+ expect(
996
+ getStylesDeclarations( stylesWithRef, '.wp-block', false, tree )
997
+ ).toEqual( [
998
+ 'font-size: var(--wp--preset--font-size--xx-large)',
999
+ 'letter-spacing: 2px',
1000
+ ] );
1001
+ } );
971
1002
  } );
972
1003
 
973
1004
  describe( 'processCSSNesting', () => {
@@ -409,7 +409,9 @@ export function getStylesDeclarations(
409
409
  let ruleValue = rule.value;
410
410
  if ( typeof ruleValue !== 'string' && ruleValue?.ref ) {
411
411
  const refPath = ruleValue.ref.split( '.' );
412
- ruleValue = getValueFromObjectPath( tree, refPath );
412
+ ruleValue = compileStyleValue(
413
+ getValueFromObjectPath( tree, refPath )
414
+ );
413
415
  // Presence of another ref indicates a reference to another dynamic value.
414
416
  // Pointing to another dynamic value is not supported.
415
417
  if ( ! ruleValue || ruleValue?.ref ) {
@@ -10,25 +10,7 @@ import { getTypographyFontSizeValue } from './typography-utils';
10
10
  import { getValueFromObjectPath } from '../../utils/object';
11
11
 
12
12
  /* Supporting data. */
13
- export const ROOT_BLOCK_NAME = 'root';
14
13
  export const ROOT_BLOCK_SELECTOR = 'body';
15
- export const ROOT_BLOCK_SUPPORTS = [
16
- 'background',
17
- 'backgroundColor',
18
- 'color',
19
- 'linkColor',
20
- 'captionColor',
21
- 'buttonColor',
22
- 'headingColor',
23
- 'fontFamily',
24
- 'fontSize',
25
- 'fontStyle',
26
- 'fontWeight',
27
- 'lineHeight',
28
- 'textDecoration',
29
- 'textTransform',
30
- 'padding',
31
- ];
32
14
 
33
15
  export const PRESET_METADATA = [
34
16
  {
@@ -30,7 +30,7 @@ import { useBlockSelectionClearer } from '../block-selection-clearer';
30
30
  import { useWritingFlow } from '../writing-flow';
31
31
  import { getCompatibilityStyles } from './get-compatibility-styles';
32
32
  import { store as blockEditorStore } from '../../store';
33
- import calculateScale from '../../utils/calculate-scale';
33
+
34
34
  function bubbleEvent( event, Constructor, frame ) {
35
35
  const init = {};
36
36
 
@@ -104,25 +104,21 @@ function Iframe( {
104
104
  contentRef,
105
105
  children,
106
106
  tabIndex = 0,
107
- shouldZoom = false,
107
+ scale = 1,
108
+ frameSize = 0,
108
109
  readonly,
109
110
  forwardedRef: ref,
110
111
  title = __( 'Editor canvas' ),
111
112
  ...props
112
113
  } ) {
113
- const { resolvedAssets, isPreviewMode, isZoomOutMode } = useSelect(
114
- ( select ) => {
115
- const { getSettings, __unstableGetEditorMode } =
116
- select( blockEditorStore );
117
- const settings = getSettings();
118
- return {
119
- resolvedAssets: settings.__unstableResolvedAssets,
120
- isPreviewMode: settings.__unstableIsPreviewMode,
121
- isZoomOutMode: __unstableGetEditorMode() === 'zoom-out',
122
- };
123
- },
124
- []
125
- );
114
+ const { resolvedAssets, isPreviewMode } = useSelect( ( select ) => {
115
+ const { getSettings } = select( blockEditorStore );
116
+ const settings = getSettings();
117
+ return {
118
+ resolvedAssets: settings.__unstableResolvedAssets,
119
+ isPreviewMode: settings.__unstableIsPreviewMode,
120
+ };
121
+ }, [] );
126
122
  const { styles = '', scripts = '' } = resolvedAssets;
127
123
  const [ iframeDocument, setIframeDocument ] = useState();
128
124
  const [ bodyClasses, setBodyClasses ] = useState( [] );
@@ -133,24 +129,6 @@ function Iframe( {
133
129
  { height: contentHeight, width: contentWidth },
134
130
  ] = useResizeObserver();
135
131
 
136
- // When zoom-out mode is enabled, the iframe is scaled down to fit the
137
- // content within the viewport.
138
- // At 1000px wide, the iframe is scaled to 45%.
139
- // At 400px wide, the iframe is scaled to 90%.
140
- const scale =
141
- isZoomOutMode && shouldZoom
142
- ? calculateScale(
143
- {
144
- maxWidth: 1000,
145
- minWidth: 400,
146
- maxScale: 0.45,
147
- minScale: 0.9,
148
- },
149
- contentWidth
150
- )
151
- : 1;
152
- const frameSize = isZoomOutMode ? 100 : 0;
153
-
154
132
  const setRef = useRefEffect( ( node ) => {
155
133
  node._load = () => {
156
134
  setIframeDocument( node.contentDocument );
@@ -229,6 +207,20 @@ function Iframe( {
229
207
  };
230
208
  }, [] );
231
209
 
210
+ const windowResizeRef = useRefEffect( ( node ) => {
211
+ const nodeWindow = node.ownerDocument.defaultView;
212
+
213
+ const onResize = () => {
214
+ setIframeWindowInnerHeight( nodeWindow.innerHeight );
215
+ };
216
+ nodeWindow.addEventListener( 'resize', onResize );
217
+ return () => {
218
+ nodeWindow.removeEventListener( 'resize', onResize );
219
+ };
220
+ }, [] );
221
+
222
+ const [ iframeWindowInnerHeight, setIframeWindowInnerHeight ] = useState();
223
+
232
224
  const disabledRef = useDisabled( { isDisabled: ! readonly } );
233
225
  const bodyRef = useMergeRefs( [
234
226
  useBubbleEvents( iframeDocument ),
@@ -236,6 +228,7 @@ function Iframe( {
236
228
  clearerRef,
237
229
  writingFlowRef,
238
230
  disabledRef,
231
+ windowResizeRef,
239
232
  ] );
240
233
 
241
234
  // Correct doctype is required to enable rendering in standards
@@ -276,25 +269,48 @@ function Iframe( {
276
269
 
277
270
  useEffect( () => cleanup, [ cleanup ] );
278
271
 
279
- // We need to counter the margin created by scaling the iframe. If the scale
280
- // is e.g. 0.45, then the top + bottom margin is 0.55 (1 - scale). Just the
281
- // top or bottom margin is 0.55 / 2 ((1 - scale) / 2).
282
- const marginFromScaling = ( contentHeight * ( 1 - scale ) ) / 2;
283
-
284
272
  useEffect( () => {
285
- if ( iframeDocument && scale !== 1 ) {
286
- iframeDocument.documentElement.style.transform = `scale( ${ scale } )`;
273
+ if ( ! iframeDocument ) {
274
+ return;
275
+ }
276
+
277
+ const _scale =
278
+ typeof scale === 'function'
279
+ ? scale( contentWidth, contentHeight )
280
+ : scale;
281
+
282
+ if ( _scale !== 1 ) {
283
+ // Hack to get proper margins when scaling the iframe document.
284
+ const bottomFrameSize = frameSize - contentHeight * ( 1 - _scale );
285
+
286
+ iframeDocument.body.classList.add( 'is-zoomed-out' );
287
+
288
+ iframeDocument.documentElement.style.transform = `scale( ${ _scale } )`;
287
289
  iframeDocument.documentElement.style.marginTop = `${ frameSize }px`;
288
- iframeDocument.documentElement.style.marginBottom = `${
289
- -marginFromScaling * 2 + frameSize
290
- }px`;
290
+ // TODO: `marginBottom` doesn't work in Firefox. We need another way to do this.
291
+ iframeDocument.documentElement.style.marginBottom = `${ bottomFrameSize }px`;
292
+ if ( iframeWindowInnerHeight > contentHeight * _scale ) {
293
+ iframeDocument.body.style.minHeight = `${ Math.floor(
294
+ ( iframeWindowInnerHeight - 2 * frameSize ) / _scale
295
+ ) }px`;
296
+ }
297
+
291
298
  return () => {
299
+ iframeDocument.body.classList.remove( 'is-zoomed-out' );
292
300
  iframeDocument.documentElement.style.transform = '';
293
301
  iframeDocument.documentElement.style.marginTop = '';
294
302
  iframeDocument.documentElement.style.marginBottom = '';
303
+ iframeDocument.body.style.minHeight = '';
295
304
  };
296
305
  }
297
- }, [ scale, frameSize, marginFromScaling, iframeDocument ] );
306
+ }, [
307
+ scale,
308
+ frameSize,
309
+ iframeDocument,
310
+ contentHeight,
311
+ iframeWindowInnerHeight,
312
+ contentWidth,
313
+ ] );
298
314
 
299
315
  // Make sure to not render the before and after focusable div elements in view
300
316
  // mode. They're only needed to capture focus in edit mode.
@@ -14,16 +14,11 @@ import { usePatternCategories } from '../block-patterns-tab/use-pattern-categori
14
14
 
15
15
  function PatternsExplorer( { initialCategory, rootClientId } ) {
16
16
  const [ searchValue, setSearchValue ] = useState( '' );
17
- const [ patternSourceFilter, setPatternSourceFilter ] = useState( 'all' );
18
-
19
17
  const [ selectedCategory, setSelectedCategory ] = useState(
20
18
  initialCategory?.name
21
19
  );
22
20
 
23
- const patternCategories = usePatternCategories(
24
- rootClientId,
25
- patternSourceFilter
26
- );
21
+ const patternCategories = usePatternCategories( rootClientId );
27
22
 
28
23
  return (
29
24
  <div className="block-editor-block-patterns-explorer">
@@ -33,14 +28,12 @@ function PatternsExplorer( { initialCategory, rootClientId } ) {
33
28
  onClickCategory={ setSelectedCategory }
34
29
  searchValue={ searchValue }
35
30
  setSearchValue={ setSearchValue }
36
- patternSourceFilter={ patternSourceFilter }
37
- setPatternSourceFilter={ setPatternSourceFilter }
38
31
  />
39
32
  <PatternList
40
33
  searchValue={ searchValue }
41
34
  selectedCategory={ selectedCategory }
42
35
  patternCategories={ patternCategories }
43
- patternSourceFilter={ patternSourceFilter }
36
+ rootClientId={ rootClientId }
44
37
  />
45
38
  </div>
46
39
  );