@wordpress/block-library 8.6.0 → 8.7.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 (193) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/buttons/index.js +1 -0
  3. package/build/buttons/index.js.map +1 -1
  4. package/build/buttons/transforms.js +1 -0
  5. package/build/buttons/transforms.js.map +1 -1
  6. package/build/columns/edit.js +4 -2
  7. package/build/columns/edit.js.map +1 -1
  8. package/build/columns/index.js +4 -0
  9. package/build/columns/index.js.map +1 -1
  10. package/build/cover/edit/inspector-controls.js +2 -2
  11. package/build/cover/edit/inspector-controls.js.map +1 -1
  12. package/build/gallery/edit.js +8 -5
  13. package/build/gallery/edit.js.map +1 -1
  14. package/build/gallery/use-image-sizes.js +1 -1
  15. package/build/gallery/use-image-sizes.js.map +1 -1
  16. package/build/group/deprecated.js +4 -2
  17. package/build/group/deprecated.js.map +1 -1
  18. package/build/group/edit.js +22 -5
  19. package/build/group/edit.js.map +1 -1
  20. package/build/group/placeholder.js +11 -1
  21. package/build/group/placeholder.js.map +1 -1
  22. package/build/group/variations.js +23 -3
  23. package/build/group/variations.js.map +1 -1
  24. package/build/image/edit.js +1 -1
  25. package/build/image/edit.js.map +1 -1
  26. package/build/image/edit.native.js +1 -1
  27. package/build/image/edit.native.js.map +1 -1
  28. package/build/image/image.js +8 -6
  29. package/build/image/image.js.map +1 -1
  30. package/build/image/index.js +7 -2
  31. package/build/image/index.js.map +1 -1
  32. package/build/latest-posts/edit.js +1 -0
  33. package/build/latest-posts/edit.js.map +1 -1
  34. package/build/media-text/deprecated.js +228 -18
  35. package/build/media-text/deprecated.js.map +1 -1
  36. package/build/media-text/edit.js +3 -3
  37. package/build/media-text/edit.js.map +1 -1
  38. package/build/media-text/index.js +1 -1
  39. package/build/navigation/edit/index.js +1 -12
  40. package/build/navigation/edit/index.js.map +1 -1
  41. package/build/navigation/edit/inner-blocks.js +1 -4
  42. package/build/navigation/edit/inner-blocks.js.map +1 -1
  43. package/build/navigation/index.js +0 -1
  44. package/build/navigation/index.js.map +1 -1
  45. package/build/post-date/edit.js +2 -1
  46. package/build/post-date/edit.js.map +1 -1
  47. package/build/post-date/index.js +4 -1
  48. package/build/post-date/index.js.map +1 -1
  49. package/build/post-date/variations.js +28 -0
  50. package/build/post-date/variations.js.map +1 -0
  51. package/build/post-excerpt/edit.js +39 -10
  52. package/build/post-excerpt/edit.js.map +1 -1
  53. package/build/post-featured-image/dimension-controls.js +2 -2
  54. package/build/post-featured-image/dimension-controls.js.map +1 -1
  55. package/build/post-template/index.js +1 -1
  56. package/build/post-time-to-read/index.js +17 -1
  57. package/build/post-time-to-read/index.js.map +1 -1
  58. package/build/quote/index.js +1 -0
  59. package/build/quote/index.js.map +1 -1
  60. package/build/spacer/edit.js +16 -6
  61. package/build/spacer/edit.js.map +1 -1
  62. package/build-module/buttons/index.js +1 -0
  63. package/build-module/buttons/index.js.map +1 -1
  64. package/build-module/buttons/transforms.js +1 -0
  65. package/build-module/buttons/transforms.js.map +1 -1
  66. package/build-module/columns/edit.js +4 -2
  67. package/build-module/columns/edit.js.map +1 -1
  68. package/build-module/columns/index.js +4 -0
  69. package/build-module/columns/index.js.map +1 -1
  70. package/build-module/cover/edit/inspector-controls.js +2 -2
  71. package/build-module/cover/edit/inspector-controls.js.map +1 -1
  72. package/build-module/gallery/edit.js +8 -5
  73. package/build-module/gallery/edit.js.map +1 -1
  74. package/build-module/gallery/use-image-sizes.js +1 -1
  75. package/build-module/gallery/use-image-sizes.js.map +1 -1
  76. package/build-module/group/deprecated.js +4 -2
  77. package/build-module/group/deprecated.js.map +1 -1
  78. package/build-module/group/edit.js +21 -5
  79. package/build-module/group/edit.js.map +1 -1
  80. package/build-module/group/placeholder.js +11 -1
  81. package/build-module/group/placeholder.js.map +1 -1
  82. package/build-module/group/variations.js +24 -1
  83. package/build-module/group/variations.js.map +1 -1
  84. package/build-module/image/edit.js +1 -1
  85. package/build-module/image/edit.js.map +1 -1
  86. package/build-module/image/edit.native.js +1 -1
  87. package/build-module/image/edit.native.js.map +1 -1
  88. package/build-module/image/image.js +8 -6
  89. package/build-module/image/image.js.map +1 -1
  90. package/build-module/image/index.js +7 -2
  91. package/build-module/image/index.js.map +1 -1
  92. package/build-module/latest-posts/edit.js +1 -0
  93. package/build-module/latest-posts/edit.js.map +1 -1
  94. package/build-module/media-text/deprecated.js +227 -18
  95. package/build-module/media-text/deprecated.js.map +1 -1
  96. package/build-module/media-text/edit.js +3 -3
  97. package/build-module/media-text/edit.js.map +1 -1
  98. package/build-module/media-text/index.js +1 -1
  99. package/build-module/navigation/edit/index.js +1 -12
  100. package/build-module/navigation/edit/index.js.map +1 -1
  101. package/build-module/navigation/edit/inner-blocks.js +1 -4
  102. package/build-module/navigation/edit/inner-blocks.js.map +1 -1
  103. package/build-module/navigation/index.js +0 -1
  104. package/build-module/navigation/index.js.map +1 -1
  105. package/build-module/post-date/edit.js +2 -1
  106. package/build-module/post-date/edit.js.map +1 -1
  107. package/build-module/post-date/index.js +3 -1
  108. package/build-module/post-date/index.js.map +1 -1
  109. package/build-module/post-date/variations.js +18 -0
  110. package/build-module/post-date/variations.js.map +1 -0
  111. package/build-module/post-excerpt/edit.js +38 -11
  112. package/build-module/post-excerpt/edit.js.map +1 -1
  113. package/build-module/post-featured-image/dimension-controls.js +2 -2
  114. package/build-module/post-featured-image/dimension-controls.js.map +1 -1
  115. package/build-module/post-template/index.js +1 -1
  116. package/build-module/post-time-to-read/index.js +17 -1
  117. package/build-module/post-time-to-read/index.js.map +1 -1
  118. package/build-module/quote/index.js +1 -0
  119. package/build-module/quote/index.js.map +1 -1
  120. package/build-module/spacer/edit.js +16 -6
  121. package/build-module/spacer/edit.js.map +1 -1
  122. package/build-style/categories/editor-rtl.css +5 -0
  123. package/build-style/categories/editor.css +5 -0
  124. package/build-style/categories/style-rtl.css +4 -0
  125. package/build-style/categories/style.css +4 -0
  126. package/build-style/editor-rtl.css +6 -0
  127. package/build-style/editor.css +6 -0
  128. package/build-style/navigation/style-rtl.css +2 -0
  129. package/build-style/navigation/style.css +2 -0
  130. package/build-style/post-featured-image/editor-rtl.css +1 -0
  131. package/build-style/post-featured-image/editor.css +1 -0
  132. package/build-style/post-template/style-rtl.css +1 -1
  133. package/build-style/post-template/style.css +1 -1
  134. package/build-style/post-time-to-read/style-rtl.css +91 -0
  135. package/build-style/post-time-to-read/style.css +91 -0
  136. package/build-style/search/style-rtl.css +8 -7
  137. package/build-style/search/style.css +8 -7
  138. package/build-style/style-rtl.css +19 -8
  139. package/build-style/style.css +19 -8
  140. package/package.json +31 -31
  141. package/src/buttons/block.json +1 -0
  142. package/src/categories/editor.scss +5 -0
  143. package/src/categories/style.scss +4 -0
  144. package/src/columns/block.json +4 -0
  145. package/src/columns/edit.js +2 -1
  146. package/src/comments/index.php +1 -0
  147. package/src/cover/edit/inspector-controls.js +4 -5
  148. package/src/cover/test/__snapshots__/transforms.native.js.snap +2 -2
  149. package/src/cover/test/edit.js +324 -0
  150. package/src/gallery/edit.js +5 -2
  151. package/src/gallery/use-image-sizes.js +1 -1
  152. package/src/group/deprecated.js +4 -2
  153. package/src/group/edit.js +27 -9
  154. package/src/group/placeholder.js +13 -1
  155. package/src/group/variations.js +14 -1
  156. package/src/home-link/index.php +2 -2
  157. package/src/image/block.json +7 -2
  158. package/src/image/edit.js +1 -1
  159. package/src/image/edit.native.js +1 -1
  160. package/src/image/image.js +15 -7
  161. package/src/image/index.php +7 -2
  162. package/src/image/test/__snapshots__/transforms.native.js.snap +1 -1
  163. package/src/latest-comments/style.scss +1 -1
  164. package/src/latest-posts/edit.js +3 -0
  165. package/src/media-text/block.json +1 -1
  166. package/src/media-text/deprecated.js +235 -3
  167. package/src/media-text/edit.js +7 -6
  168. package/src/media-text/test/__snapshots__/transforms.native.js.snap +4 -4
  169. package/src/navigation/block.json +0 -1
  170. package/src/navigation/edit/index.js +0 -13
  171. package/src/navigation/edit/inner-blocks.js +0 -3
  172. package/src/navigation/style.scss +6 -4
  173. package/src/navigation-link/index.php +2 -1
  174. package/src/navigation-submenu/index.php +30 -76
  175. package/src/post-author/index.php +1 -1
  176. package/src/post-date/edit.js +4 -1
  177. package/src/post-date/index.js +2 -0
  178. package/src/post-date/variations.js +20 -0
  179. package/src/post-excerpt/edit.js +48 -16
  180. package/src/post-featured-image/dimension-controls.js +2 -2
  181. package/src/post-featured-image/editor.scss +1 -0
  182. package/src/post-template/block.json +1 -1
  183. package/src/post-template/style.scss +1 -1
  184. package/src/post-time-to-read/block.json +17 -1
  185. package/src/post-time-to-read/style.scss +4 -0
  186. package/src/query-title/index.php +2 -5
  187. package/src/quote/block.json +1 -0
  188. package/src/search/style.scss +16 -12
  189. package/src/spacer/edit.js +18 -5
  190. package/src/style.scss +1 -0
  191. package/src/video/test/__snapshots__/transforms.native.js.snap +1 -1
  192. package/tsconfig.tsbuildinfo +1 -1
  193. package/src/cover/test/block-controls.js +0 -62
@@ -206,9 +206,7 @@ export default function CoverInspectorControls( {
206
206
  isImgElement && (
207
207
  <TextareaControl
208
208
  __nextHasNoMarginBottom
209
- label={ __(
210
- 'Alt text (alternative text)'
211
- ) }
209
+ label={ __( 'Alternative text' ) }
212
210
  value={ alt }
213
211
  onChange={ ( newAlt ) =>
214
212
  setAttributes( { alt: newAlt } )
@@ -217,11 +215,12 @@ export default function CoverInspectorControls( {
217
215
  <>
218
216
  <ExternalLink href="https://www.w3.org/WAI/tutorials/images/decision-tree">
219
217
  { __(
220
- 'Describe the purpose of the image'
218
+ 'Describe the purpose of the image.'
221
219
  ) }
222
220
  </ExternalLink>
221
+ <br />
223
222
  { __(
224
- 'Leave empty if the image is purely decorative.'
223
+ 'Leave empty if decorative.'
225
224
  ) }
226
225
  </>
227
226
  }
@@ -30,7 +30,7 @@ exports[`Cover block transformations with Image to Image block 1`] = `
30
30
 
31
31
  exports[`Cover block transformations with Image to Media & Text block 1`] = `
32
32
  "<!-- wp:media-text {"mediaId":890,"mediaType":"image","backgroundColor":"luminous-vivid-orange"} -->
33
- <div class="wp-block-media-text alignwide is-stacked-on-mobile has-luminous-vivid-orange-background-color has-background"><figure class="wp-block-media-text__media"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-890 size-full"/></figure><div class="wp-block-media-text__content"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","className":"has-text-color has-very-light-gray-color","fontSize":"large"} -->
33
+ <div class="wp-block-media-text is-stacked-on-mobile has-luminous-vivid-orange-background-color has-background"><figure class="wp-block-media-text__media"><img src="https://cldup.com/cXyG__fTLN.jpg" alt="" class="wp-image-890 size-full"/></figure><div class="wp-block-media-text__content"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","className":"has-text-color has-very-light-gray-color","fontSize":"large"} -->
34
34
  <p class="has-text-align-center has-text-color has-very-light-gray-color has-large-font-size">Cool cover</p>
35
35
  <!-- /wp:paragraph --></div></div>
36
36
  <!-- /wp:media-text -->"
@@ -60,7 +60,7 @@ exports[`Cover block transformations with Video to Group block 1`] = `
60
60
 
61
61
  exports[`Cover block transformations with Video to Media & Text block 1`] = `
62
62
  "<!-- wp:media-text {"mediaId":891,"mediaType":"video","backgroundColor":"luminous-vivid-orange"} -->
63
- <div class="wp-block-media-text alignwide is-stacked-on-mobile has-luminous-vivid-orange-background-color has-background"><figure class="wp-block-media-text__media"><video controls src="https://i.cloudup.com/YtZFJbuQCE.mov"></video></figure><div class="wp-block-media-text__content"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","className":"has-text-color has-very-light-gray-color","fontSize":"large"} -->
63
+ <div class="wp-block-media-text is-stacked-on-mobile has-luminous-vivid-orange-background-color has-background"><figure class="wp-block-media-text__media"><video controls src="https://i.cloudup.com/YtZFJbuQCE.mov"></video></figure><div class="wp-block-media-text__content"><!-- wp:paragraph {"align":"center","placeholder":"Write title…","className":"has-text-color has-very-light-gray-color","fontSize":"large"} -->
64
64
  <p class="has-text-align-center has-text-color has-very-light-gray-color has-large-font-size">Cool cover</p>
65
65
  <!-- /wp:paragraph --></div></div>
66
66
  <!-- /wp:media-text -->"
@@ -0,0 +1,324 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { screen, fireEvent, act, within } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import {
11
+ initializeEditor,
12
+ selectBlock,
13
+ } from 'test/integration/helpers/integration-test-editor';
14
+
15
+ async function setup( attributes ) {
16
+ const testBlock = { name: 'core/cover', attributes };
17
+ return initializeEditor( testBlock );
18
+ }
19
+
20
+ async function createAndSelectBlock() {
21
+ await userEvent.click(
22
+ screen.getByRole( 'button', {
23
+ name: 'Color: Black',
24
+ } )
25
+ );
26
+ await userEvent.click(
27
+ screen.getByRole( 'button', {
28
+ name: 'Select Cover',
29
+ } )
30
+ );
31
+ }
32
+
33
+ describe( 'Cover block', () => {
34
+ describe( 'Editor canvas', () => {
35
+ test( 'shows placeholder if background image and color not set', async () => {
36
+ await setup();
37
+
38
+ expect(
39
+ screen.getByRole( 'group', {
40
+ name: 'To edit this block, you need permission to upload media.',
41
+ } )
42
+ ).toBeInTheDocument();
43
+ } );
44
+
45
+ test( 'can set overlay color using color picker on block placeholder', async () => {
46
+ const { container } = await setup();
47
+ const colorPicker = screen.getByRole( 'button', {
48
+ name: 'Color: Black',
49
+ } );
50
+ await userEvent.click( colorPicker );
51
+ const color = colorPicker.style.backgroundColor;
52
+ expect(
53
+ screen.queryByRole( 'group', {
54
+ name: 'To edit this block, you need permission to upload media.',
55
+ } )
56
+ ).not.toBeInTheDocument();
57
+
58
+ // eslint-disable-next-line testing-library/no-node-access
59
+ const overlay = container.getElementsByClassName(
60
+ 'wp-block-cover__background'
61
+ );
62
+ expect( overlay[ 0 ] ).toHaveStyle(
63
+ `background-color: ${ color }`
64
+ );
65
+ } );
66
+
67
+ test( 'can have the title edited', async () => {
68
+ await setup();
69
+
70
+ await userEvent.click(
71
+ screen.getByRole( 'button', {
72
+ name: 'Color: Black',
73
+ } )
74
+ );
75
+
76
+ const title = screen.getByLabelText( 'Empty block;', {
77
+ exact: false,
78
+ } );
79
+ await userEvent.click( title );
80
+ await userEvent.keyboard( 'abc' );
81
+ expect( title ).toHaveTextContent( 'abc' );
82
+ } );
83
+ } );
84
+
85
+ describe( 'Block toolbar', () => {
86
+ test( 'full height toggle sets minHeight style attribute to 100vh when clicked', async () => {
87
+ await setup();
88
+ await createAndSelectBlock();
89
+
90
+ expect( screen.getByLabelText( 'Block: Cover' ) ).not.toHaveStyle(
91
+ 'min-height: 100vh;'
92
+ );
93
+
94
+ await userEvent.click(
95
+ screen.getByLabelText( 'Toggle full height' )
96
+ );
97
+
98
+ expect( screen.getByLabelText( 'Block: Cover' ) ).toHaveStyle(
99
+ 'min-height: 100vh;'
100
+ );
101
+ } );
102
+
103
+ test( 'content position button sets content position', async () => {
104
+ await setup();
105
+ await createAndSelectBlock();
106
+
107
+ await userEvent.click(
108
+ screen.getByLabelText( 'Change content position' )
109
+ );
110
+
111
+ expect( screen.getByLabelText( 'Block: Cover' ) ).not.toHaveClass(
112
+ 'has-custom-content-position'
113
+ );
114
+
115
+ await act( async () =>
116
+ within( screen.getByRole( 'grid' ) )
117
+ .getByRole( 'gridcell', {
118
+ name: 'top left',
119
+ } )
120
+ .focus()
121
+ );
122
+
123
+ expect( screen.getByLabelText( 'Block: Cover' ) ).toHaveClass(
124
+ 'has-custom-content-position'
125
+ );
126
+ expect( screen.getByLabelText( 'Block: Cover' ) ).toHaveClass(
127
+ 'is-position-top-left'
128
+ );
129
+ } );
130
+ } );
131
+
132
+ describe( 'Inspector controls', () => {
133
+ describe( 'Media settings', () => {
134
+ test( 'does not display media settings panel if url is not set', async () => {
135
+ await setup();
136
+ expect(
137
+ screen.queryByRole( 'button', {
138
+ name: 'Media settings',
139
+ } )
140
+ ).not.toBeInTheDocument();
141
+ } );
142
+ test( 'displays media settings panel if url is set', async () => {
143
+ await setup( {
144
+ url: 'http://localhost/my-image.jpg',
145
+ } );
146
+
147
+ await selectBlock( 'Block: Cover' );
148
+ expect(
149
+ screen.getByRole( 'button', {
150
+ name: 'Media settings',
151
+ } )
152
+ ).toBeInTheDocument();
153
+ } );
154
+ } );
155
+
156
+ test( 'sets hasParallax attribute to true if fixed background toggled', async () => {
157
+ await setup( {
158
+ url: 'http://localhost/my-image.jpg',
159
+ } );
160
+ expect( screen.getByLabelText( 'Block: Cover' ) ).not.toHaveClass(
161
+ 'has-parallax'
162
+ );
163
+ await selectBlock( 'Block: Cover' );
164
+ await userEvent.click(
165
+ screen.getByLabelText( 'Fixed background' )
166
+ );
167
+ expect( screen.getByLabelText( 'Block: Cover' ) ).toHaveClass(
168
+ 'has-parallax'
169
+ );
170
+ } );
171
+
172
+ test( 'sets isRepeated attribute to true if repeated background toggled', async () => {
173
+ await setup( {
174
+ url: 'http://localhost/my-image.jpg',
175
+ } );
176
+ expect( screen.getByLabelText( 'Block: Cover' ) ).not.toHaveClass(
177
+ 'is-repeated'
178
+ );
179
+ await selectBlock( 'Block: Cover' );
180
+ await userEvent.click(
181
+ screen.getByLabelText( 'Repeated background' )
182
+ );
183
+ expect( screen.getByLabelText( 'Block: Cover' ) ).toHaveClass(
184
+ 'is-repeated'
185
+ );
186
+ } );
187
+
188
+ test( 'sets left focalPoint attribute when focal point values changed', async () => {
189
+ await setup( {
190
+ url: 'http://localhost/my-image.jpg',
191
+ } );
192
+
193
+ await selectBlock( 'Block: Cover' );
194
+ await userEvent.clear( screen.getByLabelText( 'Left' ) );
195
+ await userEvent.type( screen.getByLabelText( 'Left' ), '100' );
196
+
197
+ expect(
198
+ within( screen.getByLabelText( 'Block: Cover' ) ).getByRole(
199
+ 'img'
200
+ )
201
+ ).toHaveStyle( 'object-position: 100% 50%;' );
202
+ } );
203
+
204
+ test( 'sets alt attribute if text entered in alt text box', async () => {
205
+ await setup( {
206
+ url: 'http://localhost/my-image.jpg',
207
+ } );
208
+
209
+ await selectBlock( 'Block: Cover' );
210
+ await userEvent.type(
211
+ screen.getByLabelText( 'Alt text (alternative text)' ),
212
+ 'Me'
213
+ );
214
+ expect( screen.getByAltText( 'Me' ) ).toBeInTheDocument();
215
+ } );
216
+
217
+ test( 'clears media when clear media button clicked', async () => {
218
+ await setup( {
219
+ url: 'http://localhost/my-image.jpg',
220
+ } );
221
+
222
+ await selectBlock( 'Block: Cover' );
223
+ expect(
224
+ within( screen.getByLabelText( 'Block: Cover' ) ).getByRole(
225
+ 'img'
226
+ )
227
+ ).toBeInTheDocument();
228
+
229
+ await userEvent.click(
230
+ screen.getByRole( 'button', {
231
+ name: 'Clear Media',
232
+ } )
233
+ );
234
+ expect(
235
+ within( screen.queryByLabelText( 'Block: Cover' ) ).queryByRole(
236
+ 'img'
237
+ )
238
+ ).not.toBeInTheDocument();
239
+ } );
240
+
241
+ describe( 'Color panel', () => {
242
+ test( 'applies selected opacity to block when number control value changed', async () => {
243
+ const { container } = await setup();
244
+
245
+ await createAndSelectBlock();
246
+
247
+ // eslint-disable-next-line testing-library/no-node-access
248
+ const overlay = container.getElementsByClassName(
249
+ 'wp-block-cover__background'
250
+ );
251
+
252
+ expect( overlay[ 0 ] ).toHaveClass( 'has-background-dim-100' );
253
+
254
+ await userEvent.click(
255
+ screen.getByRole( 'tab', {
256
+ name: 'Styles',
257
+ } )
258
+ );
259
+
260
+ fireEvent.change(
261
+ screen.getByRole( 'spinbutton', {
262
+ name: 'Overlay opacity',
263
+ } ),
264
+ {
265
+ target: { value: '40' },
266
+ }
267
+ );
268
+
269
+ expect( overlay[ 0 ] ).toHaveClass( 'has-background-dim-40' );
270
+ } );
271
+
272
+ test( 'applies selected opacity to block when slider moved', async () => {
273
+ const { container } = await setup();
274
+
275
+ await createAndSelectBlock();
276
+
277
+ // eslint-disable-next-line testing-library/no-node-access
278
+ const overlay = container.getElementsByClassName(
279
+ 'wp-block-cover__background'
280
+ );
281
+
282
+ expect( overlay[ 0 ] ).toHaveClass( 'has-background-dim-100' );
283
+
284
+ await userEvent.click(
285
+ screen.getByRole( 'tab', {
286
+ name: 'Styles',
287
+ } )
288
+ );
289
+
290
+ fireEvent.change(
291
+ screen.getByRole( 'slider', {
292
+ name: 'Overlay opacity',
293
+ } ),
294
+ { target: { value: 30 } }
295
+ );
296
+
297
+ expect( overlay[ 0 ] ).toHaveClass( 'has-background-dim-30' );
298
+ } );
299
+ } );
300
+
301
+ describe( 'Dimensions panel', () => {
302
+ test( 'sets minHeight attribute when number control value changed', async () => {
303
+ await setup();
304
+ await createAndSelectBlock();
305
+ await userEvent.click(
306
+ screen.getByRole( 'tab', {
307
+ name: 'Styles',
308
+ } )
309
+ );
310
+ await userEvent.clear(
311
+ screen.getByLabelText( 'Minimum height of cover' )
312
+ );
313
+ await userEvent.type(
314
+ screen.getByLabelText( 'Minimum height of cover' ),
315
+ '300'
316
+ );
317
+
318
+ expect( screen.getByLabelText( 'Block: Cover' ) ).toHaveStyle(
319
+ 'min-height: 300px;'
320
+ );
321
+ } );
322
+ } );
323
+ } );
324
+ } );
@@ -562,6 +562,7 @@ function GalleryEdit( props ) {
562
562
  max={ Math.min( MAX_COLUMNS, images.length ) }
563
563
  { ...MOBILE_CONTROL_PROPS_RANGE_CONTROL }
564
564
  required
565
+ size="__unstable-large"
565
566
  />
566
567
  ) }
567
568
  <ToggleControl
@@ -578,6 +579,7 @@ function GalleryEdit( props ) {
578
579
  onChange={ setLinkTo }
579
580
  options={ linkOptions }
580
581
  hideCancelButton={ true }
582
+ size="__unstable-large"
581
583
  />
582
584
  { hasLinkTo && (
583
585
  <ToggleControl
@@ -590,7 +592,7 @@ function GalleryEdit( props ) {
590
592
  { imageSizeOptions?.length > 0 && (
591
593
  <SelectControl
592
594
  __nextHasNoMarginBottom
593
- label={ __( 'Image size' ) }
595
+ label={ __( 'Resolution' ) }
594
596
  help={ __(
595
597
  'Select the size of the source images.'
596
598
  ) }
@@ -598,12 +600,13 @@ function GalleryEdit( props ) {
598
600
  options={ imageSizeOptions }
599
601
  onChange={ updateImagesSize }
600
602
  hideCancelButton={ true }
603
+ size="__unstable-large"
601
604
  />
602
605
  ) }
603
606
  { Platform.isWeb && ! imageSizeOptions && hasImageIds && (
604
607
  <BaseControl className={ 'gallery-image-sizes' }>
605
608
  <BaseControl.VisualLabel>
606
- { __( 'Image size' ) }
609
+ { __( 'Resolution' ) }
607
610
  </BaseControl.VisualLabel>
608
611
  <View className={ 'gallery-image-sizes__loading' }>
609
612
  <Spinner />
@@ -5,7 +5,7 @@ import { useMemo } from '@wordpress/element';
5
5
 
6
6
  /**
7
7
  * Calculates the image sizes that are avaible for the current gallery images in order to
8
- * populate the 'Image size' selector.
8
+ * populate the 'Resolution' selector.
9
9
  *
10
10
  * @param {Array} images Basic image block data taken from current gallery innerBlock
11
11
  * @param {boolean} isSelected Is the block currently selected in the editor.
@@ -50,7 +50,8 @@ const deprecated = [
50
50
  default: 'div',
51
51
  },
52
52
  templateLock: {
53
- type: 'string',
53
+ type: [ 'string', 'boolean' ],
54
+ enum: [ 'all', 'insert', false ],
54
55
  },
55
56
  },
56
57
  supports: {
@@ -135,7 +136,8 @@ const deprecated = [
135
136
  default: 'div',
136
137
  },
137
138
  templateLock: {
138
- type: 'string',
139
+ type: [ 'string', 'boolean' ],
140
+ enum: [ 'all', 'insert', false ],
139
141
  },
140
142
  },
141
143
  supports: {
package/src/group/edit.js CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  } from '@wordpress/block-editor';
13
13
  import { SelectControl } from '@wordpress/components';
14
14
  import { __ } from '@wordpress/i18n';
15
+ import { View } from '@wordpress/primitives';
15
16
 
16
17
  /**
17
18
  * Internal dependencies
@@ -97,7 +98,8 @@ function GroupEdit( {
97
98
  ? { ...defaultLayout, ...layout, type: 'default' }
98
99
  : { ...defaultLayout, ...layout };
99
100
  const { type = 'default' } = usedLayout;
100
- const layoutSupportEnabled = themeSupportsLayout || type === 'flex';
101
+ const layoutSupportEnabled =
102
+ themeSupportsLayout || type === 'flex' || type === 'grid';
101
103
 
102
104
  // Hooks.
103
105
  const blockProps = useBlockProps( {
@@ -108,15 +110,28 @@ function GroupEdit( {
108
110
  usedLayoutType: usedLayout?.type,
109
111
  hasInnerBlocks,
110
112
  } );
113
+
114
+ // Default to the regular appender being rendered.
115
+ let renderAppender;
116
+ if ( showPlaceholder ) {
117
+ // In the placeholder state, ensure the appender is not rendered.
118
+ // This is needed because `...innerBlocksProps` is used in the placeholder
119
+ // state so that blocks can dragged onto the placeholder area
120
+ // from both the list view and in the editor canvas.
121
+ renderAppender = false;
122
+ } else if ( ! hasInnerBlocks ) {
123
+ // When there is no placeholder, but the block is also empty,
124
+ // use the larger button appender.
125
+ renderAppender = InnerBlocks.ButtonBlockAppender;
126
+ }
127
+
111
128
  const innerBlocksProps = useInnerBlocksProps(
112
129
  layoutSupportEnabled
113
130
  ? blockProps
114
131
  : { className: 'wp-block-group__inner-container' },
115
132
  {
116
133
  templateLock,
117
- renderAppender: hasInnerBlocks
118
- ? undefined
119
- : InnerBlocks.ButtonBlockAppender,
134
+ renderAppender,
120
135
  __unstableDisableLayoutClassNames: ! layoutSupportEnabled,
121
136
  }
122
137
  );
@@ -138,11 +153,14 @@ function GroupEdit( {
138
153
  }
139
154
  />
140
155
  { showPlaceholder && (
141
- <GroupPlaceHolder
142
- clientId={ clientId }
143
- name={ name }
144
- onSelect={ selectVariation }
145
- />
156
+ <View { ...innerBlocksProps }>
157
+ { innerBlocksProps.children }
158
+ <GroupPlaceHolder
159
+ clientId={ clientId }
160
+ name={ name }
161
+ onSelect={ selectVariation }
162
+ />
163
+ </View>
146
164
  ) }
147
165
  { layoutSupportEnabled && ! showPlaceholder && (
148
166
  <TagName { ...innerBlocksProps } />
@@ -47,6 +47,17 @@ const getGroupPlaceholderIcons = ( name = 'group' ) => {
47
47
  <Path d="M42 0H2C.9 0 0 .9 0 2v12.5c0 .6.4 1 1 1h42c.6 0 1-.4 1-1V2c0-1.1-.9-2-2-2zm1 16.5H1c-.6 0-1 .4-1 1V30c0 1.1.9 2 2 2h40c1.1 0 2-.9 2-2V17.5c0-.6-.4-1-1-1z" />
48
48
  </SVG>
49
49
  ),
50
+ 'group-grid': (
51
+ <SVG
52
+ xmlns="http://www.w3.org/2000/svg"
53
+ width="44"
54
+ height="32"
55
+ viewBox="0 0 44 32"
56
+ >
57
+ <Path d="m20.30137,-0.00025l-18.9728,0c-0.86524,0.07234 -1.41711,0.79149 -1.41711,1.89149l0,12.64468c0,0.6 0.73401,0.96383 1.0304,0.96383l19.67469,0.03617c0.29639,0 1.0304,-0.4 1.0304,-1l-0.03576,-12.7532c0,-1.1 -0.76644,-1.78297 -1.30983,-1.78297zm0.52975,16.60851l-19.99654,-0.03617c-0.29639,0 -0.92312,0.36383 -0.92312,0.96383l-0.03576,12.68085c0,1.1 0.8022,1.81915 1.34559,1.81915l19.00857,0c0.54339,0 1.45287,-0.71915 1.45287,-1.81915l0,-12.53617c0,-0.6 -0.5552,-1.07234 -0.8516,-1.07234z" />
58
+ <Path d="m42.73056,-0.03617l-18.59217,0c-0.84788,0.07234 -1.38868,0.79149 -1.38868,1.89149l0,12.64468c0,0.6 0.71928,0.96383 1.00973,0.96383l19.27997,0.03617c0.29045,0 1.00973,-0.4 1.00973,-1l-0.03504,-12.7532c0,-1.1 -0.75106,-1.78297 -1.28355,-1.78297zm0.51912,16.60851l-19.59537,-0.03617c-0.29045,0 -0.9046,0.36383 -0.9046,0.96383l-0.03504,12.68085c0,1.1 0.78611,1.81915 1.31859,1.81915l18.62721,0c0.53249,0 1.42372,-0.71915 1.42372,-1.81915l0,-12.53617c0,-0.6 -0.54407,-1.07234 -0.83451,-1.07234z" />
59
+ </SVG>
60
+ ),
50
61
  };
51
62
  return icons?.[ name ];
52
63
  };
@@ -85,7 +96,8 @@ export function useShouldShowPlaceHolder( {
85
96
  ! fontSize &&
86
97
  ! textColor &&
87
98
  ! style &&
88
- usedLayoutType !== 'flex'
99
+ usedLayoutType !== 'flex' &&
100
+ usedLayoutType !== 'grid'
89
101
  );
90
102
 
91
103
  useEffect( () => {
@@ -2,7 +2,7 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { __, _x } from '@wordpress/i18n';
5
- import { group, row, stack } from '@wordpress/icons';
5
+ import { group, row, stack, grid } from '@wordpress/icons';
6
6
 
7
7
  const variations = [
8
8
  {
@@ -44,4 +44,17 @@ const variations = [
44
44
  },
45
45
  ];
46
46
 
47
+ if ( window?.__experimentalEnableGroupGridVariation ) {
48
+ variations.push( {
49
+ name: 'group-grid',
50
+ title: __( 'Grid' ),
51
+ description: __( 'Arrange blocks in a grid.' ),
52
+ attributes: { layout: { type: 'grid' } },
53
+ scope: [ 'block', 'inserter', 'transform' ],
54
+ isActive: ( blockAttributes ) =>
55
+ blockAttributes.layout?.type === 'grid',
56
+ icon: grid,
57
+ } );
58
+ }
59
+
47
60
  export default variations;
@@ -98,12 +98,12 @@ function block_core_home_link_build_li_wrapper_attributes( $context ) {
98
98
  $colors['css_classes'],
99
99
  $font_sizes['css_classes']
100
100
  );
101
+ $classes[] = 'wp-block-navigation-item';
101
102
  $style_attribute = ( $colors['inline_styles'] . $font_sizes['inline_styles'] );
102
- $css_classes = trim( implode( ' ', $classes ) ) . ' wp-block-navigation-item';
103
103
 
104
104
  $wrapper_attributes = get_block_wrapper_attributes(
105
105
  array(
106
- 'class' => $css_classes,
106
+ 'class' => implode( ' ', $classes ),
107
107
  'style' => $style_attribute,
108
108
  )
109
109
  );
@@ -85,7 +85,7 @@
85
85
  "supports": {
86
86
  "anchor": true,
87
87
  "color": {
88
- "__experimentalDuotone": "img, .components-placeholder",
88
+ "__experimentalDuotone": true,
89
89
  "text": false,
90
90
  "background": false
91
91
  },
@@ -93,7 +93,6 @@
93
93
  "color": true,
94
94
  "radius": true,
95
95
  "width": true,
96
- "__experimentalSelector": "img, .wp-block-image__crop-area",
97
96
  "__experimentalSkipSerialization": true,
98
97
  "__experimentalDefaultControls": {
99
98
  "color": true,
@@ -102,6 +101,12 @@
102
101
  }
103
102
  }
104
103
  },
104
+ "selectors": {
105
+ "border": ".wp-block-image img, .wp-block-image .wp-block-image__crop-area",
106
+ "filter": {
107
+ "duotone": "img, .components-placeholder"
108
+ }
109
+ },
105
110
  "styles": [
106
111
  {
107
112
  "name": "default",
package/src/image/edit.js CHANGED
@@ -211,7 +211,7 @@ export function ImageEdit( {
211
211
  : 'full',
212
212
  };
213
213
  } else {
214
- // Keep the same url when selecting the same file, so "Image Size"
214
+ // Keep the same url when selecting the same file, so "Resolution"
215
215
  // option is not changed.
216
216
  additionalAttributes = { url };
217
217
  }
@@ -578,7 +578,7 @@ export class ImageEdit extends Component {
578
578
  footerNote={
579
579
  <>
580
580
  { __(
581
- 'Describe the purpose of the image. Leave empty if the image is purely decorative.'
581
+ 'Describe the purpose of the image. Leave empty if decorative.'
582
582
  ) }{ ' ' }
583
583
  <FooterMessageLink
584
584
  href={