@wordpress/block-library 9.35.1-next.dc3f6d3c1.0 → 9.36.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 (262) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/accordion/view.js +46 -4
  3. package/build/accordion/view.js.map +2 -2
  4. package/build/accordion-heading/block.json +1 -1
  5. package/build/accordion-heading/deprecated.js +1 -1
  6. package/build/accordion-heading/deprecated.js.map +2 -2
  7. package/build/accordion-panel/block.json +1 -1
  8. package/build/audio/index.js +12 -9
  9. package/build/audio/index.js.map +3 -3
  10. package/build/button/index.js +13 -10
  11. package/build/button/index.js.map +3 -3
  12. package/build/code/index.js +9 -6
  13. package/build/code/index.js.map +3 -3
  14. package/build/cover/edit/block-controls.js +37 -3
  15. package/build/cover/edit/block-controls.js.map +3 -3
  16. package/build/cover/edit/cover-placeholder.js +0 -1
  17. package/build/cover/edit/cover-placeholder.js.map +2 -2
  18. package/build/cover/edit/embed-video-url-input.js +83 -0
  19. package/build/cover/edit/embed-video-url-input.js.map +7 -0
  20. package/build/cover/edit/index.js +60 -0
  21. package/build/cover/edit/index.js.map +2 -2
  22. package/build/cover/embed-video-utils.js +151 -0
  23. package/build/cover/embed-video-utils.js.map +7 -0
  24. package/build/cover/index.js +10 -4
  25. package/build/cover/index.js.map +3 -3
  26. package/build/cover/save.js +12 -0
  27. package/build/cover/save.js.map +2 -2
  28. package/build/cover/shared.js +3 -0
  29. package/build/cover/shared.js.map +2 -2
  30. package/build/details/index.js +9 -6
  31. package/build/details/index.js.map +3 -3
  32. package/build/file/index.js +14 -14
  33. package/build/file/index.js.map +3 -3
  34. package/build/freeform/block.json +1 -1
  35. package/build/gallery/edit.js +0 -2
  36. package/build/gallery/edit.js.map +2 -2
  37. package/build/heading/index.js +9 -6
  38. package/build/heading/index.js.map +3 -3
  39. package/build/html/modal.js +127 -118
  40. package/build/html/modal.js.map +3 -3
  41. package/build/image/edit.js +0 -1
  42. package/build/image/edit.js.map +2 -2
  43. package/build/image/image.js +0 -1
  44. package/build/image/image.js.map +2 -2
  45. package/build/image/index.js +18 -18
  46. package/build/image/index.js.map +3 -3
  47. package/build/list-item/index.js +8 -6
  48. package/build/list-item/index.js.map +3 -3
  49. package/build/math/block.json +28 -1
  50. package/build/math/edit.js +4 -1
  51. package/build/math/edit.js.map +2 -2
  52. package/build/media-text/index.js +15 -8
  53. package/build/media-text/index.js.map +3 -3
  54. package/build/media-text/media-container.js +0 -2
  55. package/build/media-text/media-container.js.map +2 -2
  56. package/build/missing/block.json +1 -1
  57. package/build/missing/edit.js +2 -2
  58. package/build/missing/edit.js.map +1 -1
  59. package/build/more/index.js +9 -6
  60. package/build/more/index.js.map +3 -3
  61. package/build/navigation-link/edit.js +36 -11
  62. package/build/navigation-link/edit.js.map +2 -2
  63. package/build/navigation-link/index.js +11 -8
  64. package/build/navigation-link/index.js.map +3 -3
  65. package/build/navigation-submenu/index.js +11 -8
  66. package/build/navigation-submenu/index.js.map +3 -3
  67. package/build/paragraph/deprecated-attributes.js +68 -0
  68. package/build/paragraph/deprecated-attributes.js.map +7 -0
  69. package/build/paragraph/edit.js +2 -0
  70. package/build/paragraph/edit.js.map +3 -3
  71. package/build/paragraph/index.js +9 -6
  72. package/build/paragraph/index.js.map +3 -3
  73. package/build/pattern/block.json +1 -1
  74. package/build/preformatted/index.js +9 -6
  75. package/build/preformatted/index.js.map +3 -3
  76. package/build/pullquote/index.js +11 -11
  77. package/build/pullquote/index.js.map +3 -3
  78. package/build/search/index.js +14 -16
  79. package/build/search/index.js.map +3 -3
  80. package/build/social-link/index.js +11 -8
  81. package/build/social-link/index.js.map +3 -3
  82. package/build/template-part/edit/index.js +37 -7
  83. package/build/template-part/edit/index.js.map +2 -2
  84. package/build/template-part/edit/utils/hooks.js +2 -3
  85. package/build/template-part/edit/utils/hooks.js.map +2 -2
  86. package/build/term-count/index.js +1 -0
  87. package/build/term-count/index.js.map +2 -2
  88. package/build/term-name/index.js +1 -0
  89. package/build/term-name/index.js.map +2 -2
  90. package/build/verse/index.js +9 -6
  91. package/build/verse/index.js.map +3 -3
  92. package/build/video/index.js +12 -9
  93. package/build/video/index.js.map +3 -3
  94. package/build-module/accordion/view.js +46 -4
  95. package/build-module/accordion/view.js.map +2 -2
  96. package/build-module/accordion-heading/block.json +1 -1
  97. package/build-module/accordion-heading/deprecated.js +1 -1
  98. package/build-module/accordion-heading/deprecated.js.map +2 -2
  99. package/build-module/accordion-panel/block.json +1 -1
  100. package/build-module/audio/index.js +12 -9
  101. package/build-module/audio/index.js.map +2 -2
  102. package/build-module/button/index.js +13 -10
  103. package/build-module/button/index.js.map +2 -2
  104. package/build-module/code/index.js +9 -6
  105. package/build-module/code/index.js.map +2 -2
  106. package/build-module/cover/edit/block-controls.js +27 -3
  107. package/build-module/cover/edit/block-controls.js.map +2 -2
  108. package/build-module/cover/edit/cover-placeholder.js +0 -1
  109. package/build-module/cover/edit/cover-placeholder.js.map +2 -2
  110. package/build-module/cover/edit/embed-video-url-input.js +67 -0
  111. package/build-module/cover/edit/embed-video-url-input.js.map +7 -0
  112. package/build-module/cover/edit/index.js +61 -0
  113. package/build-module/cover/edit/index.js.map +2 -2
  114. package/build-module/cover/embed-video-utils.js +122 -0
  115. package/build-module/cover/embed-video-utils.js.map +7 -0
  116. package/build-module/cover/index.js +10 -4
  117. package/build-module/cover/index.js.map +2 -2
  118. package/build-module/cover/save.js +13 -0
  119. package/build-module/cover/save.js.map +2 -2
  120. package/build-module/cover/shared.js +2 -0
  121. package/build-module/cover/shared.js.map +2 -2
  122. package/build-module/details/index.js +9 -6
  123. package/build-module/details/index.js.map +2 -2
  124. package/build-module/file/index.js +14 -14
  125. package/build-module/file/index.js.map +2 -2
  126. package/build-module/freeform/block.json +1 -1
  127. package/build-module/gallery/edit.js +0 -2
  128. package/build-module/gallery/edit.js.map +2 -2
  129. package/build-module/heading/index.js +9 -6
  130. package/build-module/heading/index.js.map +2 -2
  131. package/build-module/html/modal.js +128 -119
  132. package/build-module/html/modal.js.map +2 -2
  133. package/build-module/image/edit.js +0 -1
  134. package/build-module/image/edit.js.map +2 -2
  135. package/build-module/image/image.js +0 -1
  136. package/build-module/image/image.js.map +2 -2
  137. package/build-module/image/index.js +18 -18
  138. package/build-module/image/index.js.map +2 -2
  139. package/build-module/list-item/index.js +8 -6
  140. package/build-module/list-item/index.js.map +2 -2
  141. package/build-module/math/block.json +28 -1
  142. package/build-module/math/edit.js +4 -1
  143. package/build-module/math/edit.js.map +2 -2
  144. package/build-module/media-text/index.js +15 -8
  145. package/build-module/media-text/index.js.map +2 -2
  146. package/build-module/media-text/media-container.js +0 -2
  147. package/build-module/media-text/media-container.js.map +2 -2
  148. package/build-module/missing/block.json +1 -1
  149. package/build-module/missing/edit.js +2 -2
  150. package/build-module/missing/edit.js.map +1 -1
  151. package/build-module/more/index.js +9 -6
  152. package/build-module/more/index.js.map +2 -2
  153. package/build-module/navigation-link/edit.js +37 -12
  154. package/build-module/navigation-link/edit.js.map +2 -2
  155. package/build-module/navigation-link/index.js +11 -8
  156. package/build-module/navigation-link/index.js.map +2 -2
  157. package/build-module/navigation-submenu/index.js +11 -8
  158. package/build-module/navigation-submenu/index.js.map +2 -2
  159. package/build-module/paragraph/deprecated-attributes.js +37 -0
  160. package/build-module/paragraph/deprecated-attributes.js.map +7 -0
  161. package/build-module/paragraph/edit.js +2 -0
  162. package/build-module/paragraph/edit.js.map +2 -2
  163. package/build-module/paragraph/index.js +9 -6
  164. package/build-module/paragraph/index.js.map +2 -2
  165. package/build-module/pattern/block.json +1 -1
  166. package/build-module/preformatted/index.js +9 -6
  167. package/build-module/preformatted/index.js.map +2 -2
  168. package/build-module/pullquote/index.js +11 -11
  169. package/build-module/pullquote/index.js.map +2 -2
  170. package/build-module/search/index.js +14 -16
  171. package/build-module/search/index.js.map +2 -2
  172. package/build-module/social-link/index.js +11 -8
  173. package/build-module/social-link/index.js.map +2 -2
  174. package/build-module/template-part/edit/index.js +37 -7
  175. package/build-module/template-part/edit/index.js.map +2 -2
  176. package/build-module/template-part/edit/utils/hooks.js +2 -3
  177. package/build-module/template-part/edit/utils/hooks.js.map +2 -2
  178. package/build-module/term-count/index.js +1 -0
  179. package/build-module/term-count/index.js.map +2 -2
  180. package/build-module/term-name/index.js +1 -0
  181. package/build-module/term-name/index.js.map +2 -2
  182. package/build-module/verse/index.js +9 -6
  183. package/build-module/verse/index.js.map +2 -2
  184. package/build-module/video/index.js +12 -9
  185. package/build-module/video/index.js.map +2 -2
  186. package/build-style/accordion/style-rtl.css +3 -0
  187. package/build-style/accordion/style.css +3 -0
  188. package/build-style/accordion-heading/style-rtl.css +1 -2
  189. package/build-style/accordion-heading/style.css +1 -2
  190. package/build-style/accordion-item/style-rtl.css +0 -7
  191. package/build-style/accordion-item/style.css +0 -7
  192. package/build-style/accordion-panel/style-rtl.css +1 -4
  193. package/build-style/accordion-panel/style.css +1 -4
  194. package/build-style/cover/style-rtl.css +47 -0
  195. package/build-style/cover/style.css +47 -0
  196. package/build-style/editor-rtl.css +11 -13
  197. package/build-style/editor.css +11 -13
  198. package/build-style/html/editor-rtl.css +11 -13
  199. package/build-style/html/editor.css +11 -13
  200. package/build-style/style-rtl.css +52 -12
  201. package/build-style/style.css +52 -12
  202. package/package.json +37 -37
  203. package/src/accordion/style.scss +4 -0
  204. package/src/accordion/view.js +60 -3
  205. package/src/accordion-heading/block.json +1 -1
  206. package/src/accordion-heading/deprecated.js +1 -1
  207. package/src/accordion-heading/style.scss +1 -9
  208. package/src/accordion-item/index.php +1 -0
  209. package/src/accordion-item/style.scss +2 -9
  210. package/src/accordion-panel/block.json +1 -1
  211. package/src/accordion-panel/style.scss +1 -5
  212. package/src/audio/index.js +13 -9
  213. package/src/breadcrumbs/index.php +71 -82
  214. package/src/button/index.js +14 -10
  215. package/src/code/index.js +10 -6
  216. package/src/cover/edit/block-controls.js +26 -2
  217. package/src/cover/edit/cover-placeholder.js +0 -1
  218. package/src/cover/edit/embed-video-url-input.js +74 -0
  219. package/src/cover/edit/index.js +81 -0
  220. package/src/cover/embed-video-utils.js +196 -0
  221. package/src/cover/index.js +11 -4
  222. package/src/cover/index.php +106 -0
  223. package/src/cover/save.js +14 -0
  224. package/src/cover/shared.js +1 -0
  225. package/src/cover/style.scss +47 -0
  226. package/src/details/index.js +10 -6
  227. package/src/file/index.js +15 -14
  228. package/src/freeform/block.json +1 -1
  229. package/src/gallery/edit.js +0 -2
  230. package/src/heading/index.js +10 -6
  231. package/src/html/editor.scss +10 -15
  232. package/src/html/modal.js +15 -10
  233. package/src/image/edit.js +0 -1
  234. package/src/image/image.js +0 -1
  235. package/src/image/index.js +19 -18
  236. package/src/image/index.php +1 -0
  237. package/src/list-item/index.js +9 -6
  238. package/src/math/block.json +28 -1
  239. package/src/math/edit.js +4 -1
  240. package/src/media-text/index.js +16 -8
  241. package/src/media-text/media-container.js +0 -2
  242. package/src/missing/block.json +1 -1
  243. package/src/missing/edit.js +2 -2
  244. package/src/more/index.js +10 -6
  245. package/src/navigation-link/edit.js +72 -26
  246. package/src/navigation-link/index.js +12 -8
  247. package/src/navigation-submenu/index.js +12 -8
  248. package/src/paragraph/deprecated-attributes.js +45 -0
  249. package/src/paragraph/edit.js +2 -0
  250. package/src/paragraph/index.js +10 -6
  251. package/src/pattern/block.json +1 -1
  252. package/src/preformatted/index.js +10 -6
  253. package/src/pullquote/index.js +12 -11
  254. package/src/search/index.js +14 -15
  255. package/src/social-link/index.js +12 -8
  256. package/src/style.scss +1 -0
  257. package/src/template-part/edit/index.js +44 -6
  258. package/src/template-part/edit/utils/hooks.js +2 -4
  259. package/src/term-count/index.js +1 -0
  260. package/src/term-name/index.js +1 -0
  261. package/src/verse/index.js +10 -6
  262. package/src/video/index.js +13 -9
@@ -30,7 +30,7 @@ import { useState, useEffect, useRef, useCallback } from '@wordpress/element';
30
30
  import { decodeEntities } from '@wordpress/html-entities';
31
31
  import { link as linkIcon, addSubmenu } from '@wordpress/icons';
32
32
  import { store as coreStore } from '@wordpress/core-data';
33
- import { useMergeRefs, usePrevious, useInstanceId } from '@wordpress/compose';
33
+ import { useMergeRefs, useInstanceId } from '@wordpress/compose';
34
34
 
35
35
  /**
36
36
  * Internal dependencies
@@ -213,8 +213,11 @@ export default function NavigationLinkEdit( {
213
213
  const itemLabelPlaceholder = __( 'Add label…' );
214
214
  const ref = useRef();
215
215
  const linkUIref = useRef();
216
- const prevUrl = usePrevious( url );
217
- const isNewLink = useRef( ! url );
216
+ // A link is "new" only if it has an undefined label
217
+ // After the link is created, even if no label is provided, it's set to an empty string.
218
+ const isNewLink = useRef( label === undefined );
219
+ // Track whether we should focus the submenu appender when closing the link UI
220
+ const shouldSelectSubmenuAppenderOnClose = useRef( false );
218
221
 
219
222
  const {
220
223
  isAtMaxNesting,
@@ -223,6 +226,7 @@ export default function NavigationLinkEdit( {
223
226
  hasChildren,
224
227
  validateLinkStatus,
225
228
  parentBlockClientId,
229
+ isSubmenu,
226
230
  } = useSelect(
227
231
  ( select ) => {
228
232
  const {
@@ -267,6 +271,7 @@ export default function NavigationLinkEdit( {
267
271
  hasChildren: !! getBlockCount( clientId ),
268
272
  validateLinkStatus: enableLinkStatusValidation,
269
273
  parentBlockClientId: parentBlockId,
274
+ isSubmenu: parentBlockName === 'core/navigation-submenu',
270
275
  };
271
276
  },
272
277
  [ clientId, maxNestingLevel ]
@@ -314,7 +319,7 @@ export default function NavigationLinkEdit( {
314
319
  // If we leave focus on this block, then when we close the link without creating a link, focus will
315
320
  // be lost during the new block selection process.
316
321
  useEffect( () => {
317
- if ( isNewLink.current && isSelected && ! url ) {
322
+ if ( isNewLink.current && isSelected ) {
318
323
  selectBlock( parentBlockClientId );
319
324
  }
320
325
  }, [] ); // eslint-disable-line react-hooks/exhaustive-deps
@@ -333,20 +338,46 @@ export default function NavigationLinkEdit( {
333
338
  transformToSubmenu,
334
339
  ] );
335
340
 
336
- // If the LinkControl popover is open and the URL has changed, close the LinkControl and focus the label text.
341
+ // Handle link UI when a new link is created
337
342
  useEffect( () => {
338
- // We only want to do this when the URL has gone from nothing to a new URL AND the label looks like a URL
339
- if (
340
- ! prevUrl &&
341
- url &&
342
- isLinkOpen &&
343
- isURL( prependHTTP( label ) ) &&
344
- /^.+\.[a-z]+/.test( label )
345
- ) {
343
+ // We know if a link was just created from our link UI if
344
+ // 1. isNewLink.current is true
345
+ // 2. url has a value
346
+ // 3. isLinkOpen is true
347
+ if ( ! isNewLink.current || ! url || ! isLinkOpen ) {
348
+ return;
349
+ }
350
+
351
+ // Ensure this only runs once
352
+ isNewLink.current = false;
353
+
354
+ // We just created a link and the block is now selected.
355
+ // If the label looks like a URL, focus and select the label text.
356
+ if ( isURL( prependHTTP( label ) ) && /^.+\.[a-z]+/.test( label ) ) {
346
357
  // Focus and select the label text.
347
358
  selectLabelText();
359
+ } else {
360
+ // If the link was just created, we want to select the block so the inspector controls
361
+ // are accurate.
362
+ selectBlock( clientId, null );
363
+
364
+ // Edge case: When the created link is the first child of a submenu, the focus will have
365
+ // originated from the add submenu toolbar button. In this case, we need to return focus
366
+ // to the submenu appender if the user closes the link ui using the keyboard.
367
+ // Check if this is the first and only child of a newly created submenu.
368
+ if ( isSubmenu ) {
369
+ const parentBlocks = getBlocks( parentBlockClientId );
370
+ // If this is the only child, then this is a new submenu.
371
+ // Set the flag to select the submenu appender when the link ui is closed.
372
+ if (
373
+ parentBlocks.length === 1 &&
374
+ parentBlocks[ 0 ].clientId === clientId
375
+ ) {
376
+ shouldSelectSubmenuAppenderOnClose.current = true;
377
+ }
378
+ }
348
379
  }
349
- }, [ prevUrl, url, isLinkOpen, label ] );
380
+ }, [ url, isLinkOpen, isNewLink, label ] );
350
381
 
351
382
  /**
352
383
  * Focus the Link label text and select it.
@@ -444,23 +475,20 @@ export default function NavigationLinkEdit( {
444
475
  }
445
476
  );
446
477
 
447
- if (
448
- ! url ||
478
+ const needsValidLink =
479
+ ( ! url && ! ( hasUrlBinding && isBoundEntityAvailable ) ) ||
449
480
  isInvalid ||
450
481
  isDraft ||
451
- ( hasUrlBinding && ! isBoundEntityAvailable )
452
- ) {
482
+ ( hasUrlBinding && ! isBoundEntityAvailable );
483
+
484
+ if ( needsValidLink ) {
453
485
  blockProps.onClick = () => {
454
486
  setIsLinkOpen( true );
455
487
  };
456
488
  }
457
489
 
458
490
  const classes = clsx( 'wp-block-navigation-item__content', {
459
- 'wp-block-navigation-link__placeholder':
460
- ! url ||
461
- isInvalid ||
462
- isDraft ||
463
- ( hasUrlBinding && ! isBoundEntityAvailable ),
491
+ 'wp-block-navigation-link__placeholder': needsValidLink,
464
492
  } );
465
493
 
466
494
  const missingText = getMissingText( type );
@@ -589,9 +617,27 @@ export default function NavigationLinkEdit( {
589
617
  // Don't remove if binding exists (even if entity is unavailable) so user can fix it.
590
618
  if ( ! url && ! hasUrlBinding ) {
591
619
  onReplace( [] );
592
- } else if ( isNewLink.current ) {
593
- // If we just created a new link, select it
594
- selectBlock( clientId );
620
+ return;
621
+ }
622
+
623
+ // Edge case: If this is the first child of a new submenu, focus the submenu's appender
624
+ if (
625
+ shouldSelectSubmenuAppenderOnClose.current
626
+ ) {
627
+ shouldSelectSubmenuAppenderOnClose.current = false;
628
+
629
+ // The appender is the next sibling in the DOM after the current block
630
+ if (
631
+ listItemRef.current?.nextElementSibling
632
+ ) {
633
+ const appenderButton =
634
+ listItemRef.current.nextElementSibling.querySelector(
635
+ '.block-editor-button-block-appender'
636
+ );
637
+ if ( appenderButton ) {
638
+ appenderButton.focus();
639
+ }
640
+ }
595
641
  }
596
642
  } }
597
643
  anchor={ popoverAnchor }
@@ -5,6 +5,7 @@ import { _x, __ } from '@wordpress/i18n';
5
5
  import { customLink as linkIcon } from '@wordpress/icons';
6
6
  import { InnerBlocks } from '@wordpress/block-editor';
7
7
  import { addFilter } from '@wordpress/hooks';
8
+ import { privateApis as blocksPrivateApis } from '@wordpress/blocks';
8
9
 
9
10
  /**
10
11
  * Internal dependencies
@@ -15,6 +16,9 @@ import edit from './edit';
15
16
  import save from './save';
16
17
  import { enhanceNavigationLinkVariations } from './hooks';
17
18
  import transforms from './transforms';
19
+ import { unlock } from '../lock-unlock';
20
+
21
+ const { fieldsKey, formKey } = unlock( blocksPrivateApis );
18
22
 
19
23
  const { name } = metadata;
20
24
 
@@ -90,19 +94,16 @@ export const settings = {
90
94
  };
91
95
 
92
96
  if ( window.__experimentalContentOnlyPatternInsertion ) {
93
- settings.fields = [
97
+ settings[ fieldsKey ] = [
94
98
  {
99
+ id: 'label',
95
100
  label: __( 'Label' ),
96
- type: 'RichText',
97
- shownByDefault: true,
98
- mapping: {
99
- value: 'label',
100
- },
101
+ type: 'richtext',
101
102
  },
102
103
  {
104
+ id: 'link',
103
105
  label: __( 'Link' ),
104
- type: 'Link',
105
- shownByDefault: false,
106
+ type: 'link',
106
107
  mapping: {
107
108
  href: 'url',
108
109
  rel: 'rel',
@@ -110,6 +111,9 @@ if ( window.__experimentalContentOnlyPatternInsertion ) {
110
111
  },
111
112
  },
112
113
  ];
114
+ settings[ formKey ] = {
115
+ fields: [ 'label' ],
116
+ };
113
117
  }
114
118
 
115
119
  export const init = () => {
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { page, addSubmenu } from '@wordpress/icons';
5
5
  import { _x, __ } from '@wordpress/i18n';
6
+ import { privateApis as blocksPrivateApis } from '@wordpress/blocks';
6
7
 
7
8
  /**
8
9
  * Internal dependencies
@@ -12,6 +13,9 @@ import metadata from './block.json';
12
13
  import edit from './edit';
13
14
  import save from './save';
14
15
  import transforms from './transforms';
16
+ import { unlock } from '../lock-unlock';
17
+
18
+ const { fieldsKey, formKey } = unlock( blocksPrivateApis );
15
19
 
16
20
  const { name } = metadata;
17
21
 
@@ -49,19 +53,16 @@ export const settings = {
49
53
  };
50
54
 
51
55
  if ( window.__experimentalContentOnlyPatternInsertion ) {
52
- settings.fields = [
56
+ settings[ fieldsKey ] = [
53
57
  {
58
+ id: 'label',
54
59
  label: __( 'Label' ),
55
- type: 'RichText',
56
- shownByDefault: true,
57
- mapping: {
58
- value: 'label',
59
- },
60
+ type: 'richtext',
60
61
  },
61
62
  {
63
+ id: 'link',
62
64
  label: __( 'Link' ),
63
- type: 'Link',
64
- shownByDefault: false,
65
+ type: 'link',
65
66
  mapping: {
66
67
  href: 'url',
67
68
  rel: 'rel',
@@ -69,6 +70,9 @@ if ( window.__experimentalContentOnlyPatternInsertion ) {
69
70
  },
70
71
  },
71
72
  ];
73
+ settings[ formKey ] = {
74
+ fields: [ 'label' ],
75
+ };
72
76
  }
73
77
 
74
78
  export const init = () => initBlock( { name, metadata, settings } );
@@ -0,0 +1,45 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useEvent } from '@wordpress/compose';
5
+ import { useEffect, useRef } from '@wordpress/element';
6
+ import deprecated from '@wordpress/deprecated';
7
+ import { useDispatch } from '@wordpress/data';
8
+ import { store as blockEditorStore } from '@wordpress/block-editor';
9
+
10
+ /**
11
+ * If a plugin is still using the old align attribute, we need to migrate its value
12
+ * to the new style.typography.textAlign attribute.
13
+ *
14
+ * @param {string?} align Align attribute value.
15
+ * @param {Object?} style Style attribute value.
16
+ * @param {(Object) => void} setAttributes Updater function for block attributes.
17
+ */
18
+ export default function useDeprecatedAlign( align, style, setAttributes ) {
19
+ const { __unstableMarkNextChangeAsNotPersistent } =
20
+ useDispatch( blockEditorStore );
21
+ const updateStyleWithAlign = useEvent( () => {
22
+ deprecated( 'align attribute in paragraph block', {
23
+ alternative: 'style.typography.textAlign',
24
+ since: '7.0',
25
+ } );
26
+ __unstableMarkNextChangeAsNotPersistent();
27
+ setAttributes( {
28
+ style: {
29
+ ...style,
30
+ typography: {
31
+ ...style?.typography,
32
+ textAlign: align,
33
+ },
34
+ },
35
+ } );
36
+ } );
37
+ const lastUpdatedAlignRef = useRef();
38
+ useEffect( () => {
39
+ if ( align === lastUpdatedAlignRef.current ) {
40
+ return;
41
+ }
42
+ lastUpdatedAlignRef.current = align;
43
+ updateStyleWithAlign();
44
+ }, [ align, updateStyleWithAlign ] );
45
+ }
@@ -26,6 +26,7 @@ import { formatLtr } from '@wordpress/icons';
26
26
  * Internal dependencies
27
27
  */
28
28
  import { useOnEnter } from './use-enter';
29
+ import useDeprecatedAlign from './deprecated-attributes';
29
30
 
30
31
  function ParagraphRTLControl( { direction, setDirection } ) {
31
32
  return (
@@ -110,6 +111,7 @@ function ParagraphBlock( {
110
111
  } ) {
111
112
  const { content, direction, dropCap, placeholder, style } = attributes;
112
113
  const textAlign = style?.typography?.textAlign;
114
+ useDeprecatedAlign( attributes.align, style, setAttributes );
113
115
  const blockProps = useBlockProps( {
114
116
  ref: useOnEnter( { clientId, content } ),
115
117
  className: clsx( {
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { paragraph as icon } from '@wordpress/icons';
6
+ import { privateApis as blocksPrivateApis } from '@wordpress/blocks';
6
7
 
7
8
  /**
8
9
  * Internal dependencies
@@ -14,6 +15,9 @@ import metadata from './block.json';
14
15
  import save from './save';
15
16
  import transforms from './transforms';
16
17
  import variations from './variations';
18
+ import { unlock } from '../lock-unlock';
19
+
20
+ const { fieldsKey, formKey } = unlock( blocksPrivateApis );
17
21
 
18
22
  const { name } = metadata;
19
23
 
@@ -59,16 +63,16 @@ export const settings = {
59
63
  };
60
64
 
61
65
  if ( window.__experimentalContentOnlyPatternInsertion ) {
62
- settings.fields = [
66
+ settings[ fieldsKey ] = [
63
67
  {
68
+ id: 'content',
64
69
  label: __( 'Content' ),
65
- type: 'RichText',
66
- shownByDefault: true,
67
- mapping: {
68
- value: 'content',
69
- },
70
+ type: 'richtext',
70
71
  },
71
72
  ];
73
+ settings[ formKey ] = {
74
+ fields: [ 'content' ],
75
+ };
72
76
  }
73
77
 
74
78
  export const init = () => initBlock( { name, metadata, settings } );
@@ -9,7 +9,7 @@
9
9
  "html": false,
10
10
  "inserter": false,
11
11
  "renaming": false,
12
- "blockVisibility": false,
12
+ "visibility": false,
13
13
  "interactivity": {
14
14
  "clientNavigation": true
15
15
  }
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { preformatted as icon } from '@wordpress/icons';
6
+ import { privateApis as blocksPrivateApis } from '@wordpress/blocks';
6
7
 
7
8
  /**
8
9
  * Internal dependencies
@@ -12,6 +13,9 @@ import edit from './edit';
12
13
  import metadata from './block.json';
13
14
  import save from './save';
14
15
  import transforms from './transforms';
16
+ import { unlock } from '../lock-unlock';
17
+
18
+ const { fieldsKey, formKey } = unlock( blocksPrivateApis );
15
19
 
16
20
  const { name } = metadata;
17
21
 
@@ -40,16 +44,16 @@ export const settings = {
40
44
  };
41
45
 
42
46
  if ( window.__experimentalContentOnlyPatternInsertion ) {
43
- settings.fields = [
47
+ settings[ fieldsKey ] = [
44
48
  {
49
+ id: 'content',
45
50
  label: __( 'Content' ),
46
- type: 'RichText',
47
- shownByDefault: true,
48
- mapping: {
49
- value: 'content',
50
- },
51
+ type: 'richtext',
51
52
  },
52
53
  ];
54
+ settings[ formKey ] = {
55
+ fields: [ 'content' ],
56
+ };
53
57
  }
54
58
 
55
59
  export const init = () => initBlock( { name, metadata, settings } );
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { pullquote as icon } from '@wordpress/icons';
6
+ import { privateApis as blocksPrivateApis } from '@wordpress/blocks';
6
7
 
7
8
  /**
8
9
  * Internal dependencies
@@ -13,6 +14,9 @@ import edit from './edit';
13
14
  import metadata from './block.json';
14
15
  import save from './save';
15
16
  import transforms from './transforms';
17
+ import { unlock } from '../lock-unlock';
18
+
19
+ const { fieldsKey, formKey } = unlock( blocksPrivateApis );
16
20
 
17
21
  const { name } = metadata;
18
22
 
@@ -37,24 +41,21 @@ export const settings = {
37
41
  };
38
42
 
39
43
  if ( window.__experimentalContentOnlyPatternInsertion ) {
40
- settings.fields = [
44
+ settings[ fieldsKey ] = [
41
45
  {
46
+ id: 'value',
42
47
  label: __( 'Content' ),
43
- type: 'RichText',
44
- shownByDefault: true,
45
- mapping: {
46
- value: 'value',
47
- },
48
+ type: 'richtext',
48
49
  },
49
50
  {
51
+ id: 'citation',
50
52
  label: __( 'Citation' ),
51
- type: 'RichText',
52
- shownByDefault: false,
53
- mapping: {
54
- value: 'citation',
55
- },
53
+ type: 'richtext',
56
54
  },
57
55
  ];
56
+ settings[ formKey ] = {
57
+ fields: [ 'value' ],
58
+ };
58
59
  }
59
60
 
60
61
  export const init = () => initBlock( { name, metadata, settings } );
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { search as icon } from '@wordpress/icons';
6
+ import { privateApis as blocksPrivateApis } from '@wordpress/blocks';
6
7
 
7
8
  /**
8
9
  * Internal dependencies
@@ -11,6 +12,9 @@ import initBlock from '../utils/init-block';
11
12
  import metadata from './block.json';
12
13
  import edit from './edit';
13
14
  import variations from './variations';
15
+ import { unlock } from '../lock-unlock';
16
+
17
+ const { fieldsKey, formKey } = unlock( blocksPrivateApis );
14
18
 
15
19
  const { name } = metadata;
16
20
 
@@ -27,32 +31,27 @@ export const settings = {
27
31
  };
28
32
 
29
33
  if ( window.__experimentalContentOnlyPatternInsertion ) {
30
- settings.fields = [
34
+ settings[ fieldsKey ] = [
31
35
  {
36
+ id: 'label',
32
37
  label: __( 'Label' ),
33
- type: 'RichText',
38
+ type: 'richtext',
34
39
  shownByDefault: true,
35
- mapping: {
36
- value: 'label',
37
- },
38
40
  },
39
41
  {
42
+ id: 'buttonText',
40
43
  label: __( 'Button text' ),
41
- type: 'RichText',
42
- shownByDefault: false,
43
- mapping: {
44
- value: 'buttonText',
45
- },
44
+ type: 'richtext',
46
45
  },
47
46
  {
47
+ id: 'placeholder',
48
48
  label: __( 'Placeholder' ),
49
- type: 'RichText',
50
- shownByDefault: false,
51
- mapping: {
52
- value: 'placeholder',
53
- },
49
+ type: 'richtext',
54
50
  },
55
51
  ];
52
+ settings[ formKey ] = {
53
+ fields: [ 'label' ],
54
+ };
56
55
  }
57
56
 
58
57
  export const init = () => initBlock( { name, metadata, settings } );
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
5
  import { share as icon } from '@wordpress/icons';
6
+ import { privateApis as blocksPrivateApis } from '@wordpress/blocks';
6
7
 
7
8
  /**
8
9
  * Internal dependencies
@@ -11,6 +12,9 @@ import initBlock from '../utils/init-block';
11
12
  import edit from './edit';
12
13
  import metadata from './block.json';
13
14
  import variations from './variations';
15
+ import { unlock } from '../lock-unlock';
16
+
17
+ const { fieldsKey, formKey } = unlock( blocksPrivateApis );
14
18
 
15
19
  const { name } = metadata;
16
20
 
@@ -23,25 +27,25 @@ export const settings = {
23
27
  };
24
28
 
25
29
  if ( window.__experimentalContentOnlyPatternInsertion ) {
26
- settings.fields = [
30
+ settings[ fieldsKey ] = [
27
31
  {
32
+ id: 'link',
28
33
  label: __( 'Link' ),
29
- type: 'Link',
30
- shownByDefault: true,
34
+ type: 'link',
31
35
  mapping: {
32
36
  href: 'url',
33
37
  rel: 'rel',
34
38
  },
35
39
  },
36
40
  {
41
+ id: 'label',
37
42
  label: __( 'Label' ),
38
- type: 'RichText',
39
- shownByDefault: false,
40
- mapping: {
41
- value: 'label',
42
- },
43
+ type: 'richtext',
43
44
  },
44
45
  ];
46
+ settings[ formKey ] = {
47
+ fields: [ 'link' ],
48
+ };
45
49
  }
46
50
 
47
51
  export const init = () => initBlock( { name, metadata, settings } );
package/src/style.scss CHANGED
@@ -1,3 +1,4 @@
1
+ @use "./accordion/style.scss" as *;
1
2
  @use "./accordion-item/style.scss" as *;
2
3
  @use "./accordion-heading/style.scss" as *;
3
4
  @use "./accordion-panel/style.scss" as *;
@@ -39,6 +39,17 @@ import {
39
39
  useAlternativeTemplateParts,
40
40
  useTemplatePartArea,
41
41
  } from './utils/hooks';
42
+ import { unlock } from '../../lock-unlock';
43
+
44
+ function getTemplatePartEditButtonTitle( clientId, editedContentOnlySection ) {
45
+ if ( ! window?.__experimentalContentOnlyPatternInsertion ) {
46
+ return __( 'Edit' );
47
+ }
48
+
49
+ return editedContentOnlySection === clientId
50
+ ? __( 'Exit section' )
51
+ : __( 'Edit section' );
52
+ }
42
53
 
43
54
  function ReplaceButton( {
44
55
  isEntityAvailable,
@@ -108,8 +119,18 @@ export default function TemplatePartEdit( {
108
119
  } ) {
109
120
  const { createSuccessNotice } = useDispatch( noticesStore );
110
121
  const { editEntityRecord } = useDispatch( coreStore );
111
- const currentTheme = useSelect(
112
- ( select ) => select( coreStore ).getCurrentTheme()?.stylesheet,
122
+ const { editContentOnlySection, stopEditingContentOnlySection } = unlock(
123
+ useDispatch( blockEditorStore )
124
+ );
125
+ const { currentTheme, editedContentOnlySection } = useSelect(
126
+ ( select ) => {
127
+ return {
128
+ currentTheme: select( coreStore ).getCurrentTheme()?.stylesheet,
129
+ editedContentOnlySection: unlock(
130
+ select( blockEditorStore )
131
+ ).getEditedContentOnlySection(),
132
+ };
133
+ },
113
134
  []
114
135
  );
115
136
  const { slug, theme = currentTheme, tagName, layout = {} } = attributes;
@@ -240,14 +261,31 @@ export default function TemplatePartEdit( {
240
261
  canUserEdit && (
241
262
  <BlockControls group="other">
242
263
  <ToolbarButton
243
- onClick={ () =>
264
+ onClick={ () => {
265
+ if (
266
+ window?.__experimentalContentOnlyPatternInsertion
267
+ ) {
268
+ if (
269
+ editedContentOnlySection !==
270
+ clientId
271
+ ) {
272
+ editContentOnlySection( clientId );
273
+ } else {
274
+ stopEditingContentOnlySection();
275
+ }
276
+ return;
277
+ }
278
+
244
279
  onNavigateToEntityRecord( {
245
280
  postId: templatePartId,
246
281
  postType: 'wp_template_part',
247
- } )
248
- }
282
+ } );
283
+ } }
249
284
  >
250
- { __( 'Edit' ) }
285
+ { getTemplatePartEditButtonTitle(
286
+ clientId,
287
+ editedContentOnlySection
288
+ ) }
251
289
  </ToolbarButton>
252
290
  </BlockControls>
253
291
  ) }
@@ -83,10 +83,8 @@ export function useAlternativeBlockPatterns( area, clientId ) {
83
83
  const blockNameWithArea = area
84
84
  ? `core/template-part/${ area }`
85
85
  : 'core/template-part';
86
- const { getBlockRootClientId, getPatternsByBlockTypes } =
87
- select( blockEditorStore );
88
- const rootClientId = getBlockRootClientId( clientId );
89
- return getPatternsByBlockTypes( blockNameWithArea, rootClientId );
86
+ const { getPatternsByBlockTypes } = select( blockEditorStore );
87
+ return getPatternsByBlockTypes( blockNameWithArea, clientId );
90
88
  },
91
89
  [ area, clientId ]
92
90
  );
@@ -15,6 +15,7 @@ export { metadata, name };
15
15
 
16
16
  export const settings = {
17
17
  icon,
18
+ example: {},
18
19
  edit,
19
20
  };
20
21