@wordpress/block-library 8.26.0 → 8.27.1

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 (275) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/avatar/edit.js +2 -2
  3. package/build/avatar/edit.js.map +1 -1
  4. package/build/block/edit.js +76 -13
  5. package/build/block/edit.js.map +1 -1
  6. package/build/block/{v1/edit.native.js → edit.native.js} +4 -4
  7. package/build/block/edit.native.js.map +1 -0
  8. package/build/block/index.js +5 -3
  9. package/build/block/index.js.map +1 -1
  10. package/build/button/edit.js +24 -6
  11. package/build/button/edit.js.map +1 -1
  12. package/build/button/index.js +1 -0
  13. package/build/button/index.js.map +1 -1
  14. package/build/button/save.js +3 -1
  15. package/build/button/save.js.map +1 -1
  16. package/build/cover/edit/index.js +2 -1
  17. package/build/cover/edit/index.js.map +1 -1
  18. package/build/cover/edit/inspector-controls.js +13 -1
  19. package/build/cover/edit/inspector-controls.js.map +1 -1
  20. package/build/cover/edit.native.js +1 -0
  21. package/build/cover/edit.native.js.map +1 -1
  22. package/build/cover/index.js +3 -0
  23. package/build/cover/index.js.map +1 -1
  24. package/build/embed/edit.js +3 -2
  25. package/build/embed/edit.js.map +1 -1
  26. package/build/file/index.js +0 -1
  27. package/build/file/index.js.map +1 -1
  28. package/build/footnotes/edit.js +2 -1
  29. package/build/footnotes/edit.js.map +1 -1
  30. package/build/footnotes/format.js +17 -19
  31. package/build/footnotes/format.js.map +1 -1
  32. package/build/group/index.js +1 -0
  33. package/build/group/index.js.map +1 -1
  34. package/build/heading/edit.js +2 -1
  35. package/build/heading/edit.js.map +1 -1
  36. package/build/heading/edit.native.js +141 -0
  37. package/build/heading/edit.native.js.map +1 -0
  38. package/build/heading/index.js +1 -0
  39. package/build/heading/index.js.map +1 -1
  40. package/build/image/edit.js +8 -4
  41. package/build/image/edit.js.map +1 -1
  42. package/build/image/image.js +33 -7
  43. package/build/image/image.js.map +1 -1
  44. package/build/image/index.js +6 -3
  45. package/build/image/index.js.map +1 -1
  46. package/build/more/index.js +4 -0
  47. package/build/more/index.js.map +1 -1
  48. package/build/navigation/edit/index.js +2 -2
  49. package/build/navigation/edit/index.js.map +1 -1
  50. package/build/navigation/index.js +0 -1
  51. package/build/navigation/index.js.map +1 -1
  52. package/build/paragraph/edit.js +2 -1
  53. package/build/paragraph/edit.js.map +1 -1
  54. package/build/paragraph/index.js +1 -2
  55. package/build/paragraph/index.js.map +1 -1
  56. package/build/paragraph/transforms.js +1 -2
  57. package/build/paragraph/transforms.js.map +1 -1
  58. package/build/post-content/edit.js +2 -2
  59. package/build/post-content/edit.js.map +1 -1
  60. package/build/post-date/edit.js +1 -1
  61. package/build/post-date/edit.js.map +1 -1
  62. package/build/post-navigation-link/edit.js +43 -2
  63. package/build/post-navigation-link/edit.js.map +1 -1
  64. package/build/post-navigation-link/index.js +8 -0
  65. package/build/post-navigation-link/index.js.map +1 -1
  66. package/build/pullquote/index.js +4 -0
  67. package/build/pullquote/index.js.map +1 -1
  68. package/build/query/edit/inspector-controls/index.js +3 -3
  69. package/build/query/edit/inspector-controls/index.js.map +1 -1
  70. package/build/query/edit/query-content.js +2 -2
  71. package/build/query/edit/query-content.js.map +1 -1
  72. package/build/query/edit/query-placeholder.js +6 -7
  73. package/build/query/edit/query-placeholder.js.map +1 -1
  74. package/build/query/index.js +1 -2
  75. package/build/query/index.js.map +1 -1
  76. package/build/query/variations.js +8 -1
  77. package/build/query/variations.js.map +1 -1
  78. package/build/query/view.js +31 -12
  79. package/build/query/view.js.map +1 -1
  80. package/build/search/index.js +0 -1
  81. package/build/search/index.js.map +1 -1
  82. package/build/table-of-contents/hooks.js +2 -2
  83. package/build/table-of-contents/hooks.js.map +1 -1
  84. package/build/template-part/edit/advanced-controls.js +1 -4
  85. package/build/template-part/edit/advanced-controls.js.map +1 -1
  86. package/build/template-part/edit/index.js +39 -17
  87. package/build/template-part/edit/index.js.map +1 -1
  88. package/build/video/edit.native.js +7 -2
  89. package/build/video/edit.native.js.map +1 -1
  90. package/build/video/transforms.js +17 -0
  91. package/build/video/transforms.js.map +1 -1
  92. package/build-module/avatar/edit.js +2 -2
  93. package/build-module/avatar/edit.js.map +1 -1
  94. package/build-module/block/edit.js +76 -13
  95. package/build-module/block/edit.js.map +1 -1
  96. package/build-module/block/{v1/edit.native.js → edit.native.js} +3 -3
  97. package/build-module/block/edit.native.js.map +1 -0
  98. package/build-module/block/index.js +5 -3
  99. package/build-module/block/index.js.map +1 -1
  100. package/build-module/button/edit.js +25 -7
  101. package/build-module/button/edit.js.map +1 -1
  102. package/build-module/button/index.js +1 -0
  103. package/build-module/button/index.js.map +1 -1
  104. package/build-module/button/save.js +4 -2
  105. package/build-module/button/save.js.map +1 -1
  106. package/build-module/cover/edit/index.js +2 -1
  107. package/build-module/cover/edit/index.js.map +1 -1
  108. package/build-module/cover/edit/inspector-controls.js +14 -2
  109. package/build-module/cover/edit/inspector-controls.js.map +1 -1
  110. package/build-module/cover/edit.native.js +1 -0
  111. package/build-module/cover/edit.native.js.map +1 -1
  112. package/build-module/cover/index.js +3 -0
  113. package/build-module/cover/index.js.map +1 -1
  114. package/build-module/embed/edit.js +3 -2
  115. package/build-module/embed/edit.js.map +1 -1
  116. package/build-module/file/index.js +0 -1
  117. package/build-module/file/index.js.map +1 -1
  118. package/build-module/footnotes/edit.js +2 -1
  119. package/build-module/footnotes/edit.js.map +1 -1
  120. package/build-module/footnotes/format.js +17 -19
  121. package/build-module/footnotes/format.js.map +1 -1
  122. package/build-module/group/index.js +1 -0
  123. package/build-module/group/index.js.map +1 -1
  124. package/build-module/heading/edit.js +3 -2
  125. package/build-module/heading/edit.js.map +1 -1
  126. package/build-module/heading/edit.native.js +132 -0
  127. package/build-module/heading/edit.native.js.map +1 -0
  128. package/build-module/heading/index.js +1 -0
  129. package/build-module/heading/index.js.map +1 -1
  130. package/build-module/image/edit.js +9 -5
  131. package/build-module/image/edit.js.map +1 -1
  132. package/build-module/image/image.js +33 -7
  133. package/build-module/image/image.js.map +1 -1
  134. package/build-module/image/index.js +6 -3
  135. package/build-module/image/index.js.map +1 -1
  136. package/build-module/more/index.js +4 -0
  137. package/build-module/more/index.js.map +1 -1
  138. package/build-module/navigation/edit/index.js +1 -1
  139. package/build-module/navigation/edit/index.js.map +1 -1
  140. package/build-module/navigation/index.js +0 -1
  141. package/build-module/navigation/index.js.map +1 -1
  142. package/build-module/paragraph/edit.js +3 -2
  143. package/build-module/paragraph/edit.js.map +1 -1
  144. package/build-module/paragraph/index.js +1 -2
  145. package/build-module/paragraph/index.js.map +1 -1
  146. package/build-module/paragraph/transforms.js +1 -2
  147. package/build-module/paragraph/transforms.js.map +1 -1
  148. package/build-module/post-content/edit.js +1 -1
  149. package/build-module/post-content/edit.js.map +1 -1
  150. package/build-module/post-date/edit.js +1 -1
  151. package/build-module/post-date/edit.js.map +1 -1
  152. package/build-module/post-navigation-link/edit.js +44 -3
  153. package/build-module/post-navigation-link/edit.js.map +1 -1
  154. package/build-module/post-navigation-link/index.js +8 -0
  155. package/build-module/post-navigation-link/index.js.map +1 -1
  156. package/build-module/pullquote/index.js +4 -0
  157. package/build-module/pullquote/index.js.map +1 -1
  158. package/build-module/query/edit/inspector-controls/index.js +4 -4
  159. package/build-module/query/edit/inspector-controls/index.js.map +1 -1
  160. package/build-module/query/edit/query-content.js +2 -2
  161. package/build-module/query/edit/query-content.js.map +1 -1
  162. package/build-module/query/edit/query-placeholder.js +7 -8
  163. package/build-module/query/edit/query-placeholder.js.map +1 -1
  164. package/build-module/query/index.js +1 -2
  165. package/build-module/query/index.js.map +1 -1
  166. package/build-module/query/variations.js +8 -1
  167. package/build-module/query/variations.js.map +1 -1
  168. package/build-module/query/view.js +30 -9
  169. package/build-module/query/view.js.map +1 -1
  170. package/build-module/search/index.js +0 -1
  171. package/build-module/search/index.js.map +1 -1
  172. package/build-module/table-of-contents/hooks.js +2 -2
  173. package/build-module/table-of-contents/hooks.js.map +1 -1
  174. package/build-module/template-part/edit/advanced-controls.js +1 -4
  175. package/build-module/template-part/edit/advanced-controls.js.map +1 -1
  176. package/build-module/template-part/edit/index.js +38 -16
  177. package/build-module/template-part/edit/index.js.map +1 -1
  178. package/build-module/video/edit.native.js +7 -2
  179. package/build-module/video/edit.native.js.map +1 -1
  180. package/build-module/video/transforms.js +17 -0
  181. package/build-module/video/transforms.js.map +1 -1
  182. package/build-style/common-rtl.css +4 -2
  183. package/build-style/common.css +4 -2
  184. package/build-style/cover/style-rtl.css +2 -4
  185. package/build-style/cover/style.css +2 -4
  186. package/build-style/editor-rtl.css +6 -4
  187. package/build-style/editor.css +6 -4
  188. package/build-style/gallery/style-rtl.css +2 -4
  189. package/build-style/gallery/style.css +2 -4
  190. package/build-style/image/editor-rtl.css +6 -0
  191. package/build-style/image/editor.css +6 -0
  192. package/build-style/page-list/editor-rtl.css +0 -4
  193. package/build-style/page-list/editor.css +0 -4
  194. package/build-style/pullquote/style-rtl.css +10 -1
  195. package/build-style/pullquote/style.css +10 -1
  196. package/build-style/search/style-rtl.css +2 -1
  197. package/build-style/search/style.css +2 -1
  198. package/build-style/style-rtl.css +20 -13
  199. package/build-style/style.css +20 -13
  200. package/build-style/video/style-rtl.css +1 -2
  201. package/build-style/video/style.css +1 -2
  202. package/package.json +34 -32
  203. package/src/avatar/edit.js +16 -18
  204. package/src/block/block.json +3 -0
  205. package/src/block/edit.js +102 -20
  206. package/src/block/{v1/edit.native.js → edit.native.js} +4 -4
  207. package/src/block/index.js +2 -3
  208. package/src/block/index.php +3 -31
  209. package/src/button/block.json +1 -0
  210. package/src/button/edit.js +76 -43
  211. package/src/button/save.js +3 -0
  212. package/src/buttons/test/__snapshots__/edit.native.js.snap +6 -0
  213. package/src/buttons/test/edit.native.js +49 -0
  214. package/src/cover/block.json +3 -0
  215. package/src/cover/edit/index.js +2 -1
  216. package/src/cover/edit/inspector-controls.js +14 -1
  217. package/src/cover/edit.native.js +1 -0
  218. package/src/cover/style.scss +2 -3
  219. package/src/embed/edit.js +3 -2
  220. package/src/file/block.json +0 -1
  221. package/src/file/index.php +11 -57
  222. package/src/footnotes/edit.js +2 -1
  223. package/src/footnotes/format.js +34 -31
  224. package/src/footnotes/index.php +20 -11
  225. package/src/gallery/index.php +0 -3
  226. package/src/group/block.json +1 -0
  227. package/src/heading/block.json +1 -0
  228. package/src/heading/edit.js +18 -14
  229. package/src/heading/edit.native.js +144 -0
  230. package/src/image/block.json +7 -3
  231. package/src/image/edit.js +19 -6
  232. package/src/image/editor.scss +6 -1
  233. package/src/image/image.js +101 -42
  234. package/src/image/index.js +6 -0
  235. package/src/image/index.php +14 -51
  236. package/src/more/index.js +6 -0
  237. package/src/navigation/block.json +0 -1
  238. package/src/navigation/edit/index.js +2 -2
  239. package/src/navigation/index.php +777 -28
  240. package/src/navigation-link/index.php +78 -16
  241. package/src/page-list/editor.scss +0 -4
  242. package/src/paragraph/block.json +1 -2
  243. package/src/paragraph/edit.js +23 -19
  244. package/src/post-content/edit.js +2 -2
  245. package/src/post-date/edit.js +38 -33
  246. package/src/post-navigation-link/block.json +8 -0
  247. package/src/post-navigation-link/edit.js +63 -1
  248. package/src/post-navigation-link/index.php +17 -3
  249. package/src/post-terms/index.php +13 -4
  250. package/src/pullquote/block.json +4 -0
  251. package/src/pullquote/style.scss +13 -1
  252. package/src/query/block.json +1 -2
  253. package/src/query/edit/inspector-controls/index.js +137 -146
  254. package/src/query/edit/query-content.js +9 -7
  255. package/src/query/edit/query-placeholder.js +11 -11
  256. package/src/query/index.php +33 -71
  257. package/src/query/variations.js +4 -0
  258. package/src/query/view.js +24 -19
  259. package/src/search/block.json +0 -1
  260. package/src/search/index.php +18 -36
  261. package/src/table-of-contents/hooks.js +2 -2
  262. package/src/template-part/edit/advanced-controls.js +2 -3
  263. package/src/template-part/edit/index.js +77 -50
  264. package/src/template-part/index.php +2 -2
  265. package/src/video/edit.native.js +5 -2
  266. package/src/video/test/edit.native.js +38 -0
  267. package/src/video/transforms.js +32 -0
  268. package/tsconfig.json +1 -0
  269. package/build/block/v1/edit.js +0 -116
  270. package/build/block/v1/edit.js.map +0 -1
  271. package/build/block/v1/edit.native.js.map +0 -1
  272. package/build-module/block/v1/edit.js +0 -108
  273. package/build-module/block/v1/edit.js.map +0 -1
  274. package/build-module/block/v1/edit.native.js.map +0 -1
  275. package/src/block/v1/edit.js +0 -163
@@ -9,6 +9,7 @@ import classnames from 'classnames';
9
9
  import { NEW_TAB_TARGET, NOFOLLOW_REL } from './constants';
10
10
  import { getUpdatedLinkAttributes } from './get-updated-link-attributes';
11
11
  import removeAnchorTag from '../utils/remove-anchor-tag';
12
+ import { unlock } from '../lock-unlock';
12
13
 
13
14
  /**
14
15
  * WordPress dependencies
@@ -32,9 +33,11 @@ import {
32
33
  __experimentalUseBorderProps as useBorderProps,
33
34
  __experimentalUseColorProps as useColorProps,
34
35
  __experimentalGetSpacingClassesAndStyles as useSpacingProps,
36
+ __experimentalUseShadowProps as useShadowProps,
35
37
  __experimentalLinkControl as LinkControl,
36
38
  __experimentalGetElementClassName,
37
39
  store as blockEditorStore,
40
+ useBlockEditingMode,
38
41
  } from '@wordpress/block-editor';
39
42
  import { displayShortcut, isKeyboardEvent, ENTER } from '@wordpress/keycodes';
40
43
  import { link, linkOff } from '@wordpress/icons';
@@ -163,6 +166,7 @@ function ButtonEdit( props ) {
163
166
  text,
164
167
  url,
165
168
  width,
169
+ metadata,
166
170
  } = attributes;
167
171
 
168
172
  const TagName = tagName || 'a';
@@ -183,12 +187,14 @@ function ButtonEdit( props ) {
183
187
  const borderProps = useBorderProps( attributes );
184
188
  const colorProps = useColorProps( attributes );
185
189
  const spacingProps = useSpacingProps( attributes );
190
+ const shadowProps = useShadowProps( attributes );
186
191
  const ref = useRef();
187
192
  const richTextRef = useRef();
188
193
  const blockProps = useBlockProps( {
189
194
  ref: useMergeRefs( [ setPopoverAnchor, ref ] ),
190
195
  onKeyDown,
191
196
  } );
197
+ const blockEditingMode = useBlockEditingMode();
192
198
 
193
199
  const [ isEditingURL, setIsEditingURL ] = useState( false );
194
200
  const isURLSet = !! url;
@@ -226,6 +232,27 @@ function ButtonEdit( props ) {
226
232
  const useEnterRef = useEnter( { content: text, clientId } );
227
233
  const mergedRef = useMergeRefs( [ useEnterRef, richTextRef ] );
228
234
 
235
+ const { lockUrlControls = false } = useSelect(
236
+ ( select ) => {
237
+ if ( ! isSelected ) {
238
+ return {};
239
+ }
240
+
241
+ const { getBlockBindingsSource } = unlock(
242
+ select( blockEditorStore )
243
+ );
244
+
245
+ return {
246
+ lockUrlControls:
247
+ !! metadata?.bindings?.url &&
248
+ getBlockBindingsSource(
249
+ metadata?.bindings?.url?.source?.name
250
+ )?.lockAttributesEditing === true,
251
+ };
252
+ },
253
+ [ isSelected ]
254
+ );
255
+
229
256
  return (
230
257
  <>
231
258
  <div
@@ -264,6 +291,7 @@ function ButtonEdit( props ) {
264
291
  ...borderProps.style,
265
292
  ...colorProps.style,
266
293
  ...spacingProps.style,
294
+ ...shadowProps.style,
267
295
  } }
268
296
  onSplit={ ( value ) =>
269
297
  createBlock( 'core/button', {
@@ -277,13 +305,15 @@ function ButtonEdit( props ) {
277
305
  />
278
306
  </div>
279
307
  <BlockControls group="block">
280
- <AlignmentControl
281
- value={ textAlign }
282
- onChange={ ( nextAlign ) => {
283
- setAttributes( { textAlign: nextAlign } );
284
- } }
285
- />
286
- { ! isURLSet && isLinkTag && (
308
+ { blockEditingMode === 'default' && (
309
+ <AlignmentControl
310
+ value={ textAlign }
311
+ onChange={ ( nextAlign ) => {
312
+ setAttributes( { textAlign: nextAlign } );
313
+ } }
314
+ />
315
+ ) }
316
+ { ! isURLSet && isLinkTag && ! lockUrlControls && (
287
317
  <ToolbarButton
288
318
  name="link"
289
319
  icon={ link }
@@ -292,7 +322,7 @@ function ButtonEdit( props ) {
292
322
  onClick={ startEditing }
293
323
  />
294
324
  ) }
295
- { isURLSet && isLinkTag && (
325
+ { isURLSet && isLinkTag && ! lockUrlControls && (
296
326
  <ToolbarButton
297
327
  name="link"
298
328
  icon={ linkOff }
@@ -303,43 +333,46 @@ function ButtonEdit( props ) {
303
333
  />
304
334
  ) }
305
335
  </BlockControls>
306
- { isLinkTag && isSelected && ( isEditingURL || isURLSet ) && (
307
- <Popover
308
- placement="bottom"
309
- onClose={ () => {
310
- setIsEditingURL( false );
311
- richTextRef.current?.focus();
312
- } }
313
- anchor={ popoverAnchor }
314
- focusOnMount={ isEditingURL ? 'firstElement' : false }
315
- __unstableSlotName={ '__unstable-block-tools-after' }
316
- shift
317
- >
318
- <LinkControl
319
- value={ linkValue }
320
- onChange={ ( {
321
- url: newURL,
322
- opensInNewTab: newOpensInNewTab,
323
- nofollow: newNofollow,
324
- } ) =>
325
- setAttributes(
326
- getUpdatedLinkAttributes( {
327
- rel,
328
- url: newURL,
329
- opensInNewTab: newOpensInNewTab,
330
- nofollow: newNofollow,
331
- } )
332
- )
333
- }
334
- onRemove={ () => {
335
- unlink();
336
+ { isLinkTag &&
337
+ isSelected &&
338
+ ( isEditingURL || isURLSet ) &&
339
+ ! lockUrlControls && (
340
+ <Popover
341
+ placement="bottom"
342
+ onClose={ () => {
343
+ setIsEditingURL( false );
336
344
  richTextRef.current?.focus();
337
345
  } }
338
- forceIsEditingLink={ isEditingURL }
339
- settings={ LINK_SETTINGS }
340
- />
341
- </Popover>
342
- ) }
346
+ anchor={ popoverAnchor }
347
+ focusOnMount={ isEditingURL ? 'firstElement' : false }
348
+ __unstableSlotName={ '__unstable-block-tools-after' }
349
+ shift
350
+ >
351
+ <LinkControl
352
+ value={ linkValue }
353
+ onChange={ ( {
354
+ url: newURL,
355
+ opensInNewTab: newOpensInNewTab,
356
+ nofollow: newNofollow,
357
+ } ) =>
358
+ setAttributes(
359
+ getUpdatedLinkAttributes( {
360
+ rel,
361
+ url: newURL,
362
+ opensInNewTab: newOpensInNewTab,
363
+ nofollow: newNofollow,
364
+ } )
365
+ )
366
+ }
367
+ onRemove={ () => {
368
+ unlink();
369
+ richTextRef.current?.focus();
370
+ } }
371
+ forceIsEditingLink={ isEditingURL }
372
+ settings={ LINK_SETTINGS }
373
+ />
374
+ </Popover>
375
+ ) }
343
376
  <InspectorControls>
344
377
  <WidthPanel
345
378
  selectedWidth={ width }
@@ -12,6 +12,7 @@ import {
12
12
  __experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles,
13
13
  __experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
14
14
  __experimentalGetSpacingClassesAndStyles as getSpacingClassesAndStyles,
15
+ __experimentalGetShadowClassesAndStyles as getShadowClassesAndStyles,
15
16
  __experimentalGetElementClassName,
16
17
  } from '@wordpress/block-editor';
17
18
 
@@ -40,6 +41,7 @@ export default function save( { attributes, className } ) {
40
41
  const borderProps = getBorderClassesAndStyles( attributes );
41
42
  const colorProps = getColorClassesAndStyles( attributes );
42
43
  const spacingProps = getSpacingClassesAndStyles( attributes );
44
+ const shadowProps = getShadowClassesAndStyles( attributes );
43
45
  const buttonClasses = classnames(
44
46
  'wp-block-button__link',
45
47
  colorProps.className,
@@ -56,6 +58,7 @@ export default function save( { attributes, className } ) {
56
58
  ...borderProps.style,
57
59
  ...colorProps.style,
58
60
  ...spacingProps.style,
61
+ ...shadowProps.style,
59
62
  };
60
63
 
61
64
  // The use of a `title` attribute here is soft-deprecated, but still applied
@@ -6,6 +6,12 @@ exports[`Buttons block color customization sets a background color 1`] = `
6
6
  <!-- /wp:buttons -->"
7
7
  `;
8
8
 
9
+ exports[`Buttons block color customization sets a custom gradient background color 1`] = `
10
+ "<!-- wp:buttons -->
11
+ <div class="wp-block-buttons"><!-- wp:button {"style":{"color":{"gradient":"linear-gradient(200deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)"}}} /--></div>
12
+ <!-- /wp:buttons -->"
13
+ `;
14
+
9
15
  exports[`Buttons block color customization sets a gradient background color 1`] = `
10
16
  "<!-- wp:buttons -->
11
17
  <div class="wp-block-buttons"><!-- wp:button {"gradient":"light-green-cyan-to-vivid-green-cyan"} /--></div>
@@ -10,6 +10,7 @@ import {
10
10
  initializeEditor,
11
11
  triggerBlockListLayout,
12
12
  typeInRichText,
13
+ openBlockSettings,
13
14
  waitFor,
14
15
  } from 'test/helpers';
15
16
 
@@ -391,5 +392,53 @@ describe( 'Buttons block', () => {
391
392
  // Assert
392
393
  expect( getEditorHtml() ).toMatchSnapshot();
393
394
  } );
395
+
396
+ it( 'sets a custom gradient background color', async () => {
397
+ // Arrange
398
+ const screen = await initializeEditor();
399
+ await addBlock( screen, 'Buttons' );
400
+
401
+ // Act
402
+ const buttonsBlock = getBlock( screen, 'Buttons' );
403
+ fireEvent.press( buttonsBlock );
404
+
405
+ // Trigger onLayout for the list
406
+ await triggerBlockListLayout( buttonsBlock );
407
+
408
+ const buttonBlock = await getBlock( screen, 'Button' );
409
+ fireEvent.press( buttonBlock );
410
+
411
+ // Open Block Settings.
412
+ await openBlockSettings( screen );
413
+
414
+ // Open Text color settings
415
+ fireEvent.press( screen.getByLabelText( 'Background, Default' ) );
416
+
417
+ // Tap on the gradient segment
418
+ fireEvent.press( screen.getByLabelText( 'Gradient' ) );
419
+
420
+ // Tap one gradient color
421
+ fireEvent.press(
422
+ screen.getByLabelText( 'Light green cyan to vivid green cyan' )
423
+ );
424
+
425
+ // Tap on Customize Gradient
426
+ fireEvent.press( screen.getByLabelText( /Customize Gradient/ ) );
427
+
428
+ // Change the current angle
429
+ fireEvent.press( screen.getByText( '135', { hidden: true } ) );
430
+ const angleTextInput = screen.getByDisplayValue( '135', {
431
+ hidden: true,
432
+ } );
433
+ fireEvent.changeText( angleTextInput, '200' );
434
+
435
+ // Go back to the settings list.
436
+ fireEvent.press( await screen.findByLabelText( 'Go back' ) );
437
+
438
+ // Assert
439
+ const customButton = await screen.findByText( 'CUSTOM' );
440
+ expect( customButton ).toBeVisible();
441
+ expect( getEditorHtml() ).toMatchSnapshot();
442
+ } );
394
443
  } );
395
444
  } );
@@ -114,6 +114,9 @@
114
114
  "__experimentalSkipSerialization": [ "gradients" ],
115
115
  "enableContrastChecker": false
116
116
  },
117
+ "dimensions": {
118
+ "aspectRatio": true
119
+ },
117
120
  "typography": {
118
121
  "fontSize": true,
119
122
  "lineHeight": true,
@@ -431,7 +431,8 @@ function CoverEdit( {
431
431
  toggleSelection( true );
432
432
  setAttributes( { minHeight: newMinHeight } );
433
433
  },
434
- showHandle: true,
434
+ // Hide the resize handle if an aspect ratio is set, as the aspect ratio takes precedence.
435
+ showHandle: ! attributes.style?.dimensions?.aspectRatio ? true : false,
435
436
  size: resizableBoxDimensions,
436
437
  width,
437
438
  };
@@ -24,6 +24,7 @@ import {
24
24
  __experimentalColorGradientSettingsDropdown as ColorGradientSettingsDropdown,
25
25
  __experimentalUseGradient,
26
26
  __experimentalUseMultipleOriginColorsAndGradients as useMultipleOriginColorsAndGradients,
27
+ privateApis as blockEditorPrivateApis,
27
28
  } from '@wordpress/block-editor';
28
29
  import { __ } from '@wordpress/i18n';
29
30
 
@@ -31,6 +32,9 @@ import { __ } from '@wordpress/i18n';
31
32
  * Internal dependencies
32
33
  */
33
34
  import { COVER_MIN_HEIGHT, mediaPosition } from '../shared';
35
+ import { unlock } from '../../lock-unlock';
36
+
37
+ const { cleanEmptyObject } = unlock( blockEditorPrivateApis );
34
38
 
35
39
  function CoverHeightInput( {
36
40
  onChange,
@@ -306,7 +310,16 @@ export default function CoverInspectorControls( {
306
310
  value={ minHeight }
307
311
  unit={ minHeightUnit }
308
312
  onChange={ ( newMinHeight ) =>
309
- setAttributes( { minHeight: newMinHeight } )
313
+ setAttributes( {
314
+ minHeight: newMinHeight,
315
+ style: cleanEmptyObject( {
316
+ ...attributes?.style,
317
+ dimensions: {
318
+ ...attributes?.style?.dimensions,
319
+ aspectRatio: undefined, // Reset aspect ratio when minHeight is set.
320
+ },
321
+ } ),
322
+ } )
310
323
  }
311
324
  onUnitChange={ ( nextUnit ) =>
312
325
  setAttributes( {
@@ -538,6 +538,7 @@ const Cover = ( {
538
538
  <BottomSheetConsumer>
539
539
  { ( { shouldEnableBottomSheetScroll } ) => (
540
540
  <ColorPalette
541
+ enableCustomColor={ true }
541
542
  customColorIndicatorStyles={
542
543
  styles.paletteColorIndicator
543
544
  }
@@ -8,10 +8,9 @@
8
8
  align-items: center;
9
9
  padding: 1em;
10
10
  // Prevent the `wp-block-cover__background` span from overflowing the container when border-radius is applied.
11
- // `overflow: hidden` is provided as a fallback for browsers that don't support `overflow: clip`.
12
- overflow: hidden;
13
11
  // Use clip instead of overflow: hidden so that sticky position works on child elements.
14
- overflow: clip;
12
+ // Use overflow-x instead of overflow so that aspect-ratio allows content to expand the area of the cover block.
13
+ overflow-x: clip;
15
14
  // This block has customizable padding, border-box makes that more predictable.
16
15
  box-sizing: border-box;
17
16
  // Keep the flex layout direction to the physical direction (LTR) in RTL languages.
package/src/embed/edit.js CHANGED
@@ -127,16 +127,17 @@ const EmbedEdit = ( props ) => {
127
127
  };
128
128
 
129
129
  useEffect( () => {
130
- if ( ! preview?.html || ! cannotEmbed || fetching ) {
130
+ if ( preview?.html || ! cannotEmbed || fetching ) {
131
131
  return;
132
132
  }
133
+
133
134
  // At this stage, we're not fetching the preview and know it can't be embedded,
134
135
  // so try removing any trailing slash, and resubmit.
135
136
  const newURL = attributesUrl.replace( /\/$/, '' );
136
137
  setURL( newURL );
137
138
  setIsEditingURL( false );
138
139
  setAttributes( { url: newURL } );
139
- }, [ preview?.html, attributesUrl, cannotEmbed, fetching ] );
140
+ }, [ preview?.html, attributesUrl, cannotEmbed, fetching, setAttributes ] );
140
141
 
141
142
  // Try a different provider in case the embed url is not supported.
142
143
  useEffect( () => {
@@ -72,7 +72,6 @@
72
72
  },
73
73
  "interactivity": true
74
74
  },
75
- "viewScript": "file:./view.min.js",
76
75
  "editorStyle": "wp-block-file-editor",
77
76
  "style": "wp-block-file"
78
77
  }
@@ -14,35 +14,8 @@
14
14
  *
15
15
  * @return string Returns the block content.
16
16
  */
17
- function render_block_core_file( $attributes, $content, $block ) {
18
- $is_gutenberg_plugin = defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN;
19
- $should_load_view_script = ! empty( $attributes['displayPreview'] );
20
- $view_js_file = 'wp-block-file-view';
21
- $script_handles = $block->block_type->view_script_handles;
22
-
23
- if ( $is_gutenberg_plugin ) {
24
- if ( $should_load_view_script ) {
25
- gutenberg_enqueue_module( '@wordpress/block-library/file-block' );
26
- }
27
- // Remove the view script because we are using the module.
28
- $block->block_type->view_script_handles = array_diff( $script_handles, array( $view_js_file ) );
29
- } else {
30
- // If the script already exists, there is no point in removing it from viewScript.
31
- if ( ! wp_script_is( $view_js_file ) ) {
32
-
33
- // If the script is not needed, and it is still in the `view_script_handles`, remove it.
34
- if ( ! $should_load_view_script && in_array( $view_js_file, $script_handles, true ) ) {
35
- $block->block_type->view_script_handles = array_diff( $script_handles, array( $view_js_file ) );
36
- }
37
- // If the script is needed, but it was previously removed, add it again.
38
- if ( $should_load_view_script && ! in_array( $view_js_file, $script_handles, true ) ) {
39
- $block->block_type->view_script_handles = array_merge( $script_handles, array( $view_js_file ) );
40
- }
41
- }
42
- }
43
-
17
+ function render_block_core_file( $attributes, $content ) {
44
18
  // Update object's aria-label attribute if present in block HTML.
45
-
46
19
  // Match an aria-label attribute from an object tag.
47
20
  $pattern = '@<object.+(?<attribute>aria-label="(?<filename>[^"]+)?")@i';
48
21
  $content = preg_replace_callback(
@@ -63,8 +36,10 @@ function render_block_core_file( $attributes, $content, $block ) {
63
36
  $content
64
37
  );
65
38
 
66
- // If it uses the Interactivity API, add the directives.
67
- if ( $should_load_view_script ) {
39
+ // If it's interactive, enqueue the script module and add the directives.
40
+ if ( ! empty( $attributes['displayPreview'] ) ) {
41
+ wp_enqueue_script_module( '@wordpress/block-library/file' );
42
+
68
43
  $processor = new WP_HTML_Tag_Processor( $content );
69
44
  $processor->next_tag();
70
45
  $processor->set_attribute( 'data-wp-interactive', '{"namespace":"core/file"}' );
@@ -77,25 +52,6 @@ function render_block_core_file( $attributes, $content, $block ) {
77
52
  return $content;
78
53
  }
79
54
 
80
- /**
81
- * Ensure that the view script has the `wp-interactivity` dependency.
82
- *
83
- * @since 6.4.0
84
- *
85
- * @global WP_Scripts $wp_scripts
86
- */
87
- function block_core_file_ensure_interactivity_dependency() {
88
- global $wp_scripts;
89
- if (
90
- isset( $wp_scripts->registered['wp-block-file-view'] ) &&
91
- ! in_array( 'wp-interactivity', $wp_scripts->registered['wp-block-file-view']->deps, true )
92
- ) {
93
- $wp_scripts->registered['wp-block-file-view']->deps[] = 'wp-interactivity';
94
- }
95
- }
96
-
97
- add_action( 'wp_print_scripts', 'block_core_file_ensure_interactivity_dependency' );
98
-
99
55
  /**
100
56
  * Registers the `core/file` block on server.
101
57
  */
@@ -107,13 +63,11 @@ function register_block_core_file() {
107
63
  )
108
64
  );
109
65
 
110
- if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
111
- gutenberg_register_module(
112
- '@wordpress/block-library/file-block',
113
- gutenberg_url( '/build/interactivity/file.min.js' ),
114
- array( '@wordpress/interactivity' ),
115
- defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' )
116
- );
117
- }
66
+ wp_register_script_module(
67
+ '@wordpress/block-library/file',
68
+ defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ? gutenberg_url( '/build/interactivity/file.min.js' ) : includes_url( 'blocks/file/view.min.js' ),
69
+ array( '@wordpress/interactivity' ),
70
+ defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' )
71
+ );
118
72
  }
119
73
  add_action( 'init', 'register_block_core_file' );
@@ -14,10 +14,11 @@ export default function FootnotesEdit( { context: { postType, postId } } ) {
14
14
  'meta',
15
15
  postId
16
16
  );
17
+ const footnotesSupported = 'string' === typeof meta?.footnotes;
17
18
  const footnotes = meta?.footnotes ? JSON.parse( meta.footnotes ) : [];
18
19
  const blockProps = useBlockProps();
19
20
 
20
- if ( postType !== 'post' && postType !== 'page' ) {
21
+ if ( ! footnotesSupported ) {
21
22
  return (
22
23
  <div { ...blockProps }>
23
24
  <Placeholder
@@ -15,6 +15,7 @@ import {
15
15
  privateApis,
16
16
  } from '@wordpress/block-editor';
17
17
  import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
18
+ import { store as coreDataStore } from '@wordpress/core-data';
18
19
  import { createBlock, store as blocksStore } from '@wordpress/blocks';
19
20
 
20
21
  /**
@@ -38,12 +39,12 @@ export const format = {
38
39
  },
39
40
  interactive: true,
40
41
  contentEditable: false,
41
- [ usesContextKey ]: [ 'postType' ],
42
+ [ usesContextKey ]: [ 'postType', 'postId' ],
42
43
  edit: function Edit( {
43
44
  value,
44
45
  onChange,
45
46
  isObjectActive,
46
- context: { postType },
47
+ context: { postType, postId },
47
48
  } ) {
48
49
  const registry = useRegistry();
49
50
  const {
@@ -53,40 +54,42 @@ export const format = {
53
54
  getBlockName,
54
55
  getBlockParentsByBlockName,
55
56
  } = registry.select( blockEditorStore );
56
- const hasFootnotesBlockType = useSelect(
57
- ( select ) =>
58
- !! select( blocksStore ).getBlockType( 'core/footnotes' ),
59
- []
57
+ const isFootnotesSupported = useSelect(
58
+ ( select ) => {
59
+ if (
60
+ ! select( blocksStore ).getBlockType( 'core/footnotes' )
61
+ ) {
62
+ return false;
63
+ }
64
+
65
+ const entityRecord = select( coreDataStore ).getEntityRecord(
66
+ 'postType',
67
+ postType,
68
+ postId
69
+ );
70
+
71
+ if ( 'string' !== typeof entityRecord?.meta?.footnotes ) {
72
+ return false;
73
+ }
74
+
75
+ // Checks if the selected block lives within a pattern.
76
+ const {
77
+ getBlockParentsByBlockName: _getBlockParentsByBlockName,
78
+ getSelectedBlockClientId: _getSelectedBlockClientId,
79
+ } = select( blockEditorStore );
80
+ const parentCoreBlocks = _getBlockParentsByBlockName(
81
+ _getSelectedBlockClientId(),
82
+ SYNCED_PATTERN_BLOCK_NAME
83
+ );
84
+ return ! parentCoreBlocks || parentCoreBlocks.length === 0;
85
+ },
86
+ [ postType, postId ]
60
87
  );
61
- /*
62
- * This useSelect exists because we need to use its return value
63
- * outside the event callback.
64
- */
65
- const isBlockWithinPattern = useSelect( ( select ) => {
66
- const {
67
- getBlockParentsByBlockName: _getBlockParentsByBlockName,
68
- getSelectedBlockClientId: _getSelectedBlockClientId,
69
- } = select( blockEditorStore );
70
- const parentCoreBlocks = _getBlockParentsByBlockName(
71
- _getSelectedBlockClientId(),
72
- SYNCED_PATTERN_BLOCK_NAME
73
- );
74
- return parentCoreBlocks && parentCoreBlocks.length > 0;
75
- }, [] );
76
88
 
77
89
  const { selectionChange, insertBlock } =
78
90
  useDispatch( blockEditorStore );
79
91
 
80
- if ( ! hasFootnotesBlockType ) {
81
- return null;
82
- }
83
-
84
- if ( postType !== 'post' && postType !== 'page' ) {
85
- return null;
86
- }
87
-
88
- // Checks if the selected block lives within a pattern.
89
- if ( isBlockWithinPattern ) {
92
+ if ( ! isFootnotesSupported ) {
90
93
  return null;
91
94
  }
92
95
 
@@ -68,17 +68,26 @@ function render_block_core_footnotes( $attributes, $content, $block ) {
68
68
  * @since 6.3.0
69
69
  */
70
70
  function register_block_core_footnotes() {
71
- foreach ( array( 'post', 'page' ) as $post_type ) {
72
- register_post_meta(
73
- $post_type,
74
- 'footnotes',
75
- array(
76
- 'show_in_rest' => true,
77
- 'single' => true,
78
- 'type' => 'string',
79
- 'revisions_enabled' => true,
80
- )
81
- );
71
+ $post_types = get_post_types(
72
+ array(
73
+ 'show_in_rest' => true,
74
+ 'public' => true,
75
+ )
76
+ );
77
+ foreach ( $post_types as $post_type ) {
78
+ // Only register the meta field if the post type supports the editor, custom fields, and revisions.
79
+ if ( post_type_supports( $post_type, 'editor' ) && post_type_supports( $post_type, 'custom-fields' ) && post_type_supports( $post_type, 'revisions' ) ) {
80
+ register_post_meta(
81
+ $post_type,
82
+ 'footnotes',
83
+ array(
84
+ 'show_in_rest' => true,
85
+ 'single' => true,
86
+ 'type' => 'string',
87
+ 'revisions_enabled' => true,
88
+ )
89
+ );
90
+ }
82
91
  }
83
92
  register_block_type_from_metadata(
84
93
  __DIR__ . '/footnotes',
@@ -42,9 +42,6 @@ function block_core_gallery_random_order( $parsed_block ) {
42
42
  if ( 'core/gallery' === $parsed_block['blockName'] && ! empty( $parsed_block['attrs']['randomOrder'] ) ) {
43
43
  shuffle( $parsed_block['innerBlocks'] );
44
44
  }
45
-
46
- return $parsed_block;
47
-
48
45
  return $parsed_block;
49
46
  }
50
47
 
@@ -55,6 +55,7 @@
55
55
  }
56
56
  },
57
57
  "dimensions": {
58
+ "aspectRatio": true,
58
59
  "minHeight": true
59
60
  },
60
61
  "__experimentalBorder": {
@@ -7,6 +7,7 @@
7
7
  "description": "Introduce new sections and organize content to help visitors (and search engines) understand the structure of your content.",
8
8
  "keywords": [ "title", "subtitle" ],
9
9
  "textdomain": "default",
10
+ "usesContext": [ "pattern/overrides" ],
10
11
  "attributes": {
11
12
  "textAlign": {
12
13
  "type": "string"