@wordpress/block-library 8.25.0 → 8.26.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 (235) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/LICENSE.md +1 -1
  3. package/build/audio/edit.js +10 -12
  4. package/build/audio/edit.js.map +1 -1
  5. package/build/block/edit.js +79 -32
  6. package/build/block/edit.js.map +1 -1
  7. package/build/comments-title/deprecated.js +1 -1
  8. package/build/comments-title/index.js +1 -1
  9. package/build/cover/edit/inspector-controls.js +1 -1
  10. package/build/cover/edit/inspector-controls.js.map +1 -1
  11. package/build/embed/util.js +4 -4
  12. package/build/embed/util.js.map +1 -1
  13. package/build/file/edit.js +19 -27
  14. package/build/file/edit.js.map +1 -1
  15. package/build/gallery/edit.js +36 -17
  16. package/build/gallery/edit.js.map +1 -1
  17. package/build/gallery/gallery.js +3 -2
  18. package/build/gallery/gallery.js.map +1 -1
  19. package/build/gallery/index.js +4 -0
  20. package/build/gallery/index.js.map +1 -1
  21. package/build/gallery/transforms.js +4 -68
  22. package/build/gallery/transforms.js.map +1 -1
  23. package/build/group/index.js +5 -1
  24. package/build/group/index.js.map +1 -1
  25. package/build/image/deprecated.js +11 -0
  26. package/build/image/deprecated.js.map +1 -1
  27. package/build/image/edit.native.js +3 -0
  28. package/build/image/edit.native.js.map +1 -1
  29. package/build/image/image.js +22 -21
  30. package/build/image/image.js.map +1 -1
  31. package/build/image/view.js +7 -1
  32. package/build/image/view.js.map +1 -1
  33. package/build/list/edit.js +10 -15
  34. package/build/list/edit.js.map +1 -1
  35. package/build/list-item/edit.js +17 -2
  36. package/build/list-item/edit.js.map +1 -1
  37. package/build/list-item/hooks/use-enter.js +5 -3
  38. package/build/list-item/hooks/use-enter.js.map +1 -1
  39. package/build/list-item/hooks/use-enter.native.js +4 -3
  40. package/build/list-item/hooks/use-enter.native.js.map +1 -1
  41. package/build/list-item/hooks/use-indent-list-item.js +2 -3
  42. package/build/list-item/hooks/use-indent-list-item.js.map +1 -1
  43. package/build/list-item/hooks/use-merge.js +1 -1
  44. package/build/list-item/hooks/use-merge.js.map +1 -1
  45. package/build/list-item/hooks/use-outdent-list-item.js +3 -17
  46. package/build/list-item/hooks/use-outdent-list-item.js.map +1 -1
  47. package/build/list-item/hooks/use-space.js +8 -4
  48. package/build/list-item/hooks/use-space.js.map +1 -1
  49. package/build/media-text/media-container.native.js +3 -0
  50. package/build/media-text/media-container.native.js.map +1 -1
  51. package/build/navigation/constants.js +3 -1
  52. package/build/navigation/constants.js.map +1 -1
  53. package/build/navigation/edit/index.js +4 -0
  54. package/build/navigation/edit/index.js.map +1 -1
  55. package/build/navigation/view.js +25 -1
  56. package/build/navigation/view.js.map +1 -1
  57. package/build/pattern/edit.js +24 -2
  58. package/build/pattern/edit.js.map +1 -1
  59. package/build/pattern/recursion-detector.js +147 -0
  60. package/build/pattern/recursion-detector.js.map +1 -0
  61. package/build/post-featured-image/edit.js +19 -2
  62. package/build/post-featured-image/edit.js.map +1 -1
  63. package/build/post-featured-image/index.js +4 -0
  64. package/build/post-featured-image/index.js.map +1 -1
  65. package/build/query/edit/inspector-controls/index.js +3 -1
  66. package/build/query/edit/inspector-controls/index.js.map +1 -1
  67. package/build/query-pagination-numbers/index.js +1 -1
  68. package/build/search/edit.js +3 -5
  69. package/build/search/edit.js.map +1 -1
  70. package/build/search/index.js +0 -4
  71. package/build/search/index.js.map +1 -1
  72. package/build/site-logo/edit.js +7 -6
  73. package/build/site-logo/edit.js.map +1 -1
  74. package/build/spacer/edit.native.js +2 -2
  75. package/build/spacer/edit.native.js.map +1 -1
  76. package/build/tag-cloud/edit.js +5 -9
  77. package/build/tag-cloud/edit.js.map +1 -1
  78. package/build/utils/constants.js +16 -0
  79. package/build/utils/constants.js.map +1 -0
  80. package/build/video/edit.js +11 -8
  81. package/build/video/edit.js.map +1 -1
  82. package/build-module/audio/edit.js +10 -12
  83. package/build-module/audio/edit.js.map +1 -1
  84. package/build-module/block/edit.js +83 -36
  85. package/build-module/block/edit.js.map +1 -1
  86. package/build-module/comments-title/deprecated.js +1 -1
  87. package/build-module/comments-title/index.js +1 -1
  88. package/build-module/cover/edit/inspector-controls.js +1 -1
  89. package/build-module/cover/edit/inspector-controls.js.map +1 -1
  90. package/build-module/embed/util.js +4 -4
  91. package/build-module/embed/util.js.map +1 -1
  92. package/build-module/file/edit.js +19 -27
  93. package/build-module/file/edit.js.map +1 -1
  94. package/build-module/gallery/edit.js +36 -17
  95. package/build-module/gallery/edit.js.map +1 -1
  96. package/build-module/gallery/gallery.js +3 -2
  97. package/build-module/gallery/gallery.js.map +1 -1
  98. package/build-module/gallery/index.js +4 -0
  99. package/build-module/gallery/index.js.map +1 -1
  100. package/build-module/gallery/transforms.js +4 -68
  101. package/build-module/gallery/transforms.js.map +1 -1
  102. package/build-module/group/index.js +5 -1
  103. package/build-module/group/index.js.map +1 -1
  104. package/build-module/image/deprecated.js +11 -0
  105. package/build-module/image/deprecated.js.map +1 -1
  106. package/build-module/image/edit.native.js +3 -0
  107. package/build-module/image/edit.native.js.map +1 -1
  108. package/build-module/image/image.js +17 -16
  109. package/build-module/image/image.js.map +1 -1
  110. package/build-module/image/view.js +7 -1
  111. package/build-module/image/view.js.map +1 -1
  112. package/build-module/list/edit.js +10 -15
  113. package/build-module/list/edit.js.map +1 -1
  114. package/build-module/list-item/edit.js +18 -3
  115. package/build-module/list-item/edit.js.map +1 -1
  116. package/build-module/list-item/hooks/use-enter.js +5 -3
  117. package/build-module/list-item/hooks/use-enter.js.map +1 -1
  118. package/build-module/list-item/hooks/use-enter.native.js +4 -3
  119. package/build-module/list-item/hooks/use-enter.native.js.map +1 -1
  120. package/build-module/list-item/hooks/use-indent-list-item.js +2 -3
  121. package/build-module/list-item/hooks/use-indent-list-item.js.map +1 -1
  122. package/build-module/list-item/hooks/use-merge.js +1 -1
  123. package/build-module/list-item/hooks/use-merge.js.map +1 -1
  124. package/build-module/list-item/hooks/use-outdent-list-item.js +3 -17
  125. package/build-module/list-item/hooks/use-outdent-list-item.js.map +1 -1
  126. package/build-module/list-item/hooks/use-space.js +8 -4
  127. package/build-module/list-item/hooks/use-space.js.map +1 -1
  128. package/build-module/media-text/media-container.native.js +3 -0
  129. package/build-module/media-text/media-container.native.js.map +1 -1
  130. package/build-module/navigation/constants.js +1 -0
  131. package/build-module/navigation/constants.js.map +1 -1
  132. package/build-module/navigation/edit/index.js +5 -1
  133. package/build-module/navigation/edit/index.js.map +1 -1
  134. package/build-module/navigation/view.js +25 -1
  135. package/build-module/navigation/view.js.map +1 -1
  136. package/build-module/pattern/edit.js +26 -4
  137. package/build-module/pattern/edit.js.map +1 -1
  138. package/build-module/pattern/recursion-detector.js +139 -0
  139. package/build-module/pattern/recursion-detector.js.map +1 -0
  140. package/build-module/post-featured-image/edit.js +19 -2
  141. package/build-module/post-featured-image/edit.js.map +1 -1
  142. package/build-module/post-featured-image/index.js +4 -0
  143. package/build-module/post-featured-image/index.js.map +1 -1
  144. package/build-module/query/edit/inspector-controls/index.js +3 -1
  145. package/build-module/query/edit/inspector-controls/index.js.map +1 -1
  146. package/build-module/query-pagination-numbers/index.js +1 -1
  147. package/build-module/search/edit.js +3 -5
  148. package/build-module/search/edit.js.map +1 -1
  149. package/build-module/search/index.js +0 -4
  150. package/build-module/search/index.js.map +1 -1
  151. package/build-module/site-logo/edit.js +7 -6
  152. package/build-module/site-logo/edit.js.map +1 -1
  153. package/build-module/spacer/edit.native.js +2 -2
  154. package/build-module/spacer/edit.native.js.map +1 -1
  155. package/build-module/tag-cloud/edit.js +6 -10
  156. package/build-module/tag-cloud/edit.js.map +1 -1
  157. package/build-module/utils/constants.js +9 -0
  158. package/build-module/utils/constants.js.map +1 -0
  159. package/build-module/video/edit.js +11 -8
  160. package/build-module/video/edit.js.map +1 -1
  161. package/build-style/button/editor-rtl.css +0 -37
  162. package/build-style/button/editor.css +0 -37
  163. package/build-style/button/style-rtl.css +6 -6
  164. package/build-style/button/style.css +6 -6
  165. package/build-style/editor-rtl.css +2 -44
  166. package/build-style/editor.css +2 -44
  167. package/build-style/navigation/editor-rtl.css +2 -4
  168. package/build-style/navigation/editor.css +2 -4
  169. package/build-style/navigation/style-rtl.css +14 -18
  170. package/build-style/navigation/style.css +14 -18
  171. package/build-style/search/style-rtl.css +26 -27
  172. package/build-style/search/style.css +26 -27
  173. package/build-style/style-rtl.css +46 -51
  174. package/build-style/style.css +46 -51
  175. package/build-style/table/editor-rtl.css +0 -3
  176. package/build-style/table/editor.css +0 -3
  177. package/package.json +32 -32
  178. package/src/audio/edit.js +19 -19
  179. package/src/audio/test/__snapshots__/edit.native.js.snap +12 -0
  180. package/src/audio/test/edit.native.js +29 -0
  181. package/src/block/edit.js +114 -60
  182. package/src/button/editor.scss +0 -43
  183. package/src/button/style.scss +6 -6
  184. package/src/comments-title/block.json +1 -1
  185. package/src/cover/edit/inspector-controls.js +1 -1
  186. package/src/embed/util.js +2 -2
  187. package/src/file/edit.js +17 -24
  188. package/src/gallery/block.json +4 -0
  189. package/src/gallery/edit.js +69 -42
  190. package/src/gallery/gallery.js +4 -1
  191. package/src/gallery/index.php +18 -0
  192. package/src/gallery/transforms.js +2 -55
  193. package/src/group/block.json +5 -1
  194. package/src/image/deprecated.js +8 -0
  195. package/src/image/edit.native.js +3 -0
  196. package/src/image/image.js +54 -35
  197. package/src/image/index.php +1 -6
  198. package/src/image/view.js +5 -2
  199. package/src/list/edit.js +27 -35
  200. package/src/list-item/edit.js +18 -2
  201. package/src/list-item/hooks/use-enter.js +63 -62
  202. package/src/list-item/hooks/use-enter.native.js +9 -5
  203. package/src/list-item/hooks/use-indent-list-item.js +43 -53
  204. package/src/list-item/hooks/use-merge.js +1 -1
  205. package/src/list-item/hooks/use-outdent-list-item.js +50 -69
  206. package/src/list-item/hooks/use-space.js +7 -4
  207. package/src/media-text/media-container.native.js +3 -1
  208. package/src/navigation/constants.js +2 -0
  209. package/src/navigation/edit/index.js +11 -1
  210. package/src/navigation/editor.scss +1 -1
  211. package/src/navigation/style.scss +18 -16
  212. package/src/navigation/view.js +29 -3
  213. package/src/paragraph/test/__snapshots__/edit.native.js.snap +12 -0
  214. package/src/paragraph/test/edit.native.js +114 -0
  215. package/src/pattern/edit.js +35 -3
  216. package/src/pattern/index.php +16 -0
  217. package/src/pattern/recursion-detector.js +145 -0
  218. package/src/pattern/test/index.js +74 -0
  219. package/src/post-featured-image/block.json +4 -0
  220. package/src/post-featured-image/edit.js +32 -1
  221. package/src/post-featured-image/index.php +31 -0
  222. package/src/query/edit/inspector-controls/index.js +2 -0
  223. package/src/query-pagination-numbers/block.json +1 -1
  224. package/src/search/block.json +0 -4
  225. package/src/search/edit.js +2 -8
  226. package/src/search/index.php +3 -7
  227. package/src/search/style.scss +27 -29
  228. package/src/site-logo/edit.js +3 -4
  229. package/src/social-link/index.php +1 -1
  230. package/src/spacer/edit.native.js +4 -2
  231. package/src/table/editor.scss +0 -3
  232. package/src/tag-cloud/edit.js +7 -7
  233. package/src/template-part/index.php +6 -0
  234. package/src/utils/constants.js +8 -0
  235. package/src/video/edit.js +29 -27
@@ -7,10 +7,6 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
7
7
  import { createBlock, cloneBlock } from '@wordpress/blocks';
8
8
 
9
9
  export default function useIndentListItem( clientId ) {
10
- const canIndent = useSelect(
11
- ( select ) => select( blockEditorStore ).getBlockIndex( clientId ) > 0,
12
- [ clientId ]
13
- );
14
10
  const { replaceBlocks, selectionChange, multiSelect } =
15
11
  useDispatch( blockEditorStore );
16
12
  const {
@@ -21,55 +17,49 @@ export default function useIndentListItem( clientId ) {
21
17
  hasMultiSelection,
22
18
  getMultiSelectedBlockClientIds,
23
19
  } = useSelect( blockEditorStore );
24
- return [
25
- canIndent,
26
- useCallback( () => {
27
- const _hasMultiSelection = hasMultiSelection();
28
- const clientIds = _hasMultiSelection
29
- ? getMultiSelectedBlockClientIds()
30
- : [ clientId ];
31
- const clonedBlocks = clientIds.map( ( _clientId ) =>
32
- cloneBlock( getBlock( _clientId ) )
33
- );
34
- const previousSiblingId = getPreviousBlockClientId( clientId );
35
- const newListItem = cloneBlock( getBlock( previousSiblingId ) );
36
- // If the sibling has no innerBlocks, create a new `list` block.
37
- if ( ! newListItem.innerBlocks?.length ) {
38
- newListItem.innerBlocks = [ createBlock( 'core/list' ) ];
39
- }
40
- // A list item usually has one `list`, but it's possible to have
41
- // more. So we need to preserve the previous `list` blocks and
42
- // merge the new blocks to the last `list`.
43
- newListItem.innerBlocks[
44
- newListItem.innerBlocks.length - 1
45
- ].innerBlocks.push( ...clonedBlocks );
20
+ return useCallback( () => {
21
+ const _hasMultiSelection = hasMultiSelection();
22
+ const clientIds = _hasMultiSelection
23
+ ? getMultiSelectedBlockClientIds()
24
+ : [ clientId ];
25
+ const clonedBlocks = clientIds.map( ( _clientId ) =>
26
+ cloneBlock( getBlock( _clientId ) )
27
+ );
28
+ const previousSiblingId = getPreviousBlockClientId( clientId );
29
+ const newListItem = cloneBlock( getBlock( previousSiblingId ) );
30
+ // If the sibling has no innerBlocks, create a new `list` block.
31
+ if ( ! newListItem.innerBlocks?.length ) {
32
+ newListItem.innerBlocks = [ createBlock( 'core/list' ) ];
33
+ }
34
+ // A list item usually has one `list`, but it's possible to have
35
+ // more. So we need to preserve the previous `list` blocks and
36
+ // merge the new blocks to the last `list`.
37
+ newListItem.innerBlocks[
38
+ newListItem.innerBlocks.length - 1
39
+ ].innerBlocks.push( ...clonedBlocks );
46
40
 
47
- // We get the selection start/end here, because when
48
- // we replace blocks, the selection is updated too.
49
- const selectionStart = getSelectionStart();
50
- const selectionEnd = getSelectionEnd();
51
- // Replace the previous sibling of the block being indented and the indented blocks,
52
- // with a new block whose attributes are equal to the ones of the previous sibling and
53
- // whose descendants are the children of the previous sibling, followed by the indented blocks.
54
- replaceBlocks(
55
- [ previousSiblingId, ...clientIds ],
56
- [ newListItem ]
41
+ // We get the selection start/end here, because when
42
+ // we replace blocks, the selection is updated too.
43
+ const selectionStart = getSelectionStart();
44
+ const selectionEnd = getSelectionEnd();
45
+ // Replace the previous sibling of the block being indented and the indented blocks,
46
+ // with a new block whose attributes are equal to the ones of the previous sibling and
47
+ // whose descendants are the children of the previous sibling, followed by the indented blocks.
48
+ replaceBlocks( [ previousSiblingId, ...clientIds ], [ newListItem ] );
49
+ if ( ! _hasMultiSelection ) {
50
+ selectionChange(
51
+ clonedBlocks[ 0 ].clientId,
52
+ selectionEnd.attributeKey,
53
+ selectionEnd.clientId === selectionStart.clientId
54
+ ? selectionStart.offset
55
+ : selectionEnd.offset,
56
+ selectionEnd.offset
57
+ );
58
+ } else {
59
+ multiSelect(
60
+ clonedBlocks[ 0 ].clientId,
61
+ clonedBlocks[ clonedBlocks.length - 1 ].clientId
57
62
  );
58
- if ( ! _hasMultiSelection ) {
59
- selectionChange(
60
- clonedBlocks[ 0 ].clientId,
61
- selectionEnd.attributeKey,
62
- selectionEnd.clientId === selectionStart.clientId
63
- ? selectionStart.offset
64
- : selectionEnd.offset,
65
- selectionEnd.offset
66
- );
67
- } else {
68
- multiSelect(
69
- clonedBlocks[ 0 ].clientId,
70
- clonedBlocks[ clonedBlocks.length - 1 ].clientId
71
- );
72
- }
73
- }, [ clientId ] ),
74
- ];
63
+ }
64
+ }, [ clientId ] );
75
65
  }
@@ -20,7 +20,7 @@ export default function useMerge( clientId, onMerge ) {
20
20
  } = useSelect( blockEditorStore );
21
21
  const { mergeBlocks, moveBlocksToPosition } =
22
22
  useDispatch( blockEditorStore );
23
- const [ , outdentListItem ] = useOutdentListItem( clientId );
23
+ const outdentListItem = useOutdentListItem();
24
24
 
25
25
  function getTrailingId( id ) {
26
26
  const order = getBlockOrder( id );
@@ -6,24 +6,8 @@ import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
6
6
  import { store as blockEditorStore } from '@wordpress/block-editor';
7
7
  import { cloneBlock } from '@wordpress/blocks';
8
8
 
9
- export default function useOutdentListItem( clientId ) {
9
+ export default function useOutdentListItem() {
10
10
  const registry = useRegistry();
11
- const { canOutdent } = useSelect(
12
- ( innerSelect ) => {
13
- const { getBlockRootClientId, getBlockName } =
14
- innerSelect( blockEditorStore );
15
- const grandParentId = getBlockRootClientId(
16
- getBlockRootClientId( clientId )
17
- );
18
- const grandParentName = getBlockName( grandParentId );
19
- const isListItem = grandParentName === 'core/list-item';
20
-
21
- return {
22
- canOutdent: isListItem,
23
- };
24
- },
25
- [ clientId ]
26
- );
27
11
  const {
28
12
  moveBlocksToPosition,
29
13
  removeBlock,
@@ -48,69 +32,66 @@ export default function useOutdentListItem( clientId ) {
48
32
  return parentListItemId;
49
33
  }
50
34
 
51
- return [
52
- canOutdent,
53
- useCallback( ( clientIds = getSelectedBlockClientIds() ) => {
54
- if ( ! Array.isArray( clientIds ) ) {
55
- clientIds = [ clientIds ];
56
- }
57
-
58
- if ( ! clientIds.length ) return;
35
+ return useCallback( ( clientIds = getSelectedBlockClientIds() ) => {
36
+ if ( ! Array.isArray( clientIds ) ) {
37
+ clientIds = [ clientIds ];
38
+ }
59
39
 
60
- const firstClientId = clientIds[ 0 ];
40
+ if ( ! clientIds.length ) return;
61
41
 
62
- // Can't outdent if it's not a list item.
63
- if ( getBlockName( firstClientId ) !== 'core/list-item' ) return;
42
+ const firstClientId = clientIds[ 0 ];
64
43
 
65
- const parentListItemId = getParentListItemId( firstClientId );
44
+ // Can't outdent if it's not a list item.
45
+ if ( getBlockName( firstClientId ) !== 'core/list-item' ) return;
66
46
 
67
- // Can't outdent if it's at the top level.
68
- if ( ! parentListItemId ) return;
47
+ const parentListItemId = getParentListItemId( firstClientId );
69
48
 
70
- const parentListId = getBlockRootClientId( firstClientId );
71
- const lastClientId = clientIds[ clientIds.length - 1 ];
72
- const order = getBlockOrder( parentListId );
73
- const followingListItems = order.slice(
74
- getBlockIndex( lastClientId ) + 1
75
- );
49
+ // Can't outdent if it's at the top level.
50
+ if ( ! parentListItemId ) return;
76
51
 
77
- registry.batch( () => {
78
- if ( followingListItems.length ) {
79
- let nestedListId = getBlockOrder( firstClientId )[ 0 ];
52
+ const parentListId = getBlockRootClientId( firstClientId );
53
+ const lastClientId = clientIds[ clientIds.length - 1 ];
54
+ const order = getBlockOrder( parentListId );
55
+ const followingListItems = order.slice(
56
+ getBlockIndex( lastClientId ) + 1
57
+ );
80
58
 
81
- if ( ! nestedListId ) {
82
- const nestedListBlock = cloneBlock(
83
- getBlock( parentListId ),
84
- {},
85
- []
86
- );
87
- nestedListId = nestedListBlock.clientId;
88
- insertBlock( nestedListBlock, 0, firstClientId, false );
89
- // Immediately update the block list settings, otherwise
90
- // blocks can't be moved here due to canInsert checks.
91
- updateBlockListSettings(
92
- nestedListId,
93
- getBlockListSettings( parentListId )
94
- );
95
- }
59
+ registry.batch( () => {
60
+ if ( followingListItems.length ) {
61
+ let nestedListId = getBlockOrder( firstClientId )[ 0 ];
96
62
 
97
- moveBlocksToPosition(
98
- followingListItems,
99
- parentListId,
100
- nestedListId
63
+ if ( ! nestedListId ) {
64
+ const nestedListBlock = cloneBlock(
65
+ getBlock( parentListId ),
66
+ {},
67
+ []
68
+ );
69
+ nestedListId = nestedListBlock.clientId;
70
+ insertBlock( nestedListBlock, 0, firstClientId, false );
71
+ // Immediately update the block list settings, otherwise
72
+ // blocks can't be moved here due to canInsert checks.
73
+ updateBlockListSettings(
74
+ nestedListId,
75
+ getBlockListSettings( parentListId )
101
76
  );
102
77
  }
78
+
103
79
  moveBlocksToPosition(
104
- clientIds,
80
+ followingListItems,
105
81
  parentListId,
106
- getBlockRootClientId( parentListItemId ),
107
- getBlockIndex( parentListItemId ) + 1
82
+ nestedListId
108
83
  );
109
- if ( ! getBlockOrder( parentListId ).length ) {
110
- const shouldSelectParent = false;
111
- removeBlock( parentListId, shouldSelectParent );
112
- }
113
- } );
114
- }, [] ),
115
- ];
84
+ }
85
+ moveBlocksToPosition(
86
+ clientIds,
87
+ parentListId,
88
+ getBlockRootClientId( parentListItemId ),
89
+ getBlockIndex( parentListItemId ) + 1
90
+ );
91
+ if ( ! getBlockOrder( parentListId ).length ) {
92
+ const shouldSelectParent = false;
93
+ removeBlock( parentListId, shouldSelectParent );
94
+ }
95
+ } );
96
+ }, [] );
116
97
  }
@@ -12,9 +12,9 @@ import { useSelect } from '@wordpress/data';
12
12
  import useIndentListItem from './use-indent-list-item';
13
13
 
14
14
  export default function useSpace( clientId ) {
15
- const { getSelectionStart, getSelectionEnd } =
15
+ const { getSelectionStart, getSelectionEnd, getBlockIndex } =
16
16
  useSelect( blockEditorStore );
17
- const [ canIndent, indentListItem ] = useIndentListItem( clientId );
17
+ const indentListItem = useIndentListItem( clientId );
18
18
 
19
19
  return useRefEffect(
20
20
  ( element ) => {
@@ -23,7 +23,6 @@ export default function useSpace( clientId ) {
23
23
 
24
24
  if (
25
25
  event.defaultPrevented ||
26
- ! canIndent ||
27
26
  keyCode !== SPACE ||
28
27
  // Only override when no modifiers are pressed.
29
28
  shiftKey ||
@@ -34,6 +33,10 @@ export default function useSpace( clientId ) {
34
33
  return;
35
34
  }
36
35
 
36
+ if ( getBlockIndex( clientId ) === 0 ) {
37
+ return;
38
+ }
39
+
37
40
  const selectionStart = getSelectionStart();
38
41
  const selectionEnd = getSelectionEnd();
39
42
  if (
@@ -50,6 +53,6 @@ export default function useSpace( clientId ) {
50
53
  element.removeEventListener( 'keydown', onKeyDown );
51
54
  };
52
55
  },
53
- [ canIndent, indentListItem ]
56
+ [ clientId, indentListItem ]
54
57
  );
55
58
  }
@@ -170,7 +170,7 @@ class MediaContainer extends Component {
170
170
  mediaWidth,
171
171
  shouldStack,
172
172
  } = this.props;
173
- const { isUploadFailed, retryMessage } = params;
173
+ const { isUploadFailed, isUploadPaused, retryMessage } = params;
174
174
  const focalPointValues = ! focalPoint
175
175
  ? IMAGE_DEFAULT_FOCAL_POINT
176
176
  : focalPoint;
@@ -203,6 +203,7 @@ class MediaContainer extends Component {
203
203
  focalPoint={ imageFill && focalPointValues }
204
204
  isSelected={ isMediaSelected }
205
205
  isUploadFailed={ isUploadFailed }
206
+ isUploadPaused={ isUploadPaused }
206
207
  isUploadInProgress={ isUploadInProgress }
207
208
  onSelectMediaUploadOption={
208
209
  this.onSelectMediaUploadOption
@@ -340,6 +341,7 @@ class MediaContainer extends Component {
340
341
  { getMediaOptions() }
341
342
 
342
343
  <MediaUploadProgress
344
+ enablePausedUploads
343
345
  coverUrl={ coverUrl }
344
346
  mediaId={ mediaId }
345
347
  onUpdateMediaProgress={
@@ -37,3 +37,5 @@ export const SELECT_NAVIGATION_MENUS_ARGS = [
37
37
  'wp_navigation',
38
38
  PRELOADED_NAVIGATION_MENUS_QUERY,
39
39
  ];
40
+
41
+ export const NAVIGATION_MOBILE_COLLAPSE = '600px';
@@ -42,7 +42,7 @@ import {
42
42
  import { __, sprintf } from '@wordpress/i18n';
43
43
  import { speak } from '@wordpress/a11y';
44
44
  import { close, Icon } from '@wordpress/icons';
45
- import { useInstanceId } from '@wordpress/compose';
45
+ import { useInstanceId, useMediaQuery } from '@wordpress/compose';
46
46
 
47
47
  /**
48
48
  * Internal dependencies
@@ -71,6 +71,7 @@ import MenuInspectorControls from './menu-inspector-controls';
71
71
  import DeletedNavigationWarning from './deleted-navigation-warning';
72
72
  import AccessibleDescription from './accessible-description';
73
73
  import AccessibleMenuDescription from './accessible-menu-description';
74
+ import { NAVIGATION_MOBILE_COLLAPSE } from '../constants';
74
75
  import { unlock } from '../../lock-unlock';
75
76
 
76
77
  function Navigation( {
@@ -297,6 +298,14 @@ function Navigation( {
297
298
  [ clientId ]
298
299
  );
299
300
  const isResponsive = 'never' !== overlayMenu;
301
+ const isMobileBreakPoint = useMediaQuery(
302
+ `(max-width: ${ NAVIGATION_MOBILE_COLLAPSE })`
303
+ );
304
+
305
+ const isCollapsed =
306
+ ( 'mobile' === overlayMenu && isMobileBreakPoint ) ||
307
+ 'always' === overlayMenu;
308
+
300
309
  const blockProps = useBlockProps( {
301
310
  ref: navRef,
302
311
  className: classnames(
@@ -310,6 +319,7 @@ function Navigation( {
310
319
  'is-vertical': orientation === 'vertical',
311
320
  'no-wrap': flexWrap === 'nowrap',
312
321
  'is-responsive': isResponsive,
322
+ 'is-collapsed': isCollapsed,
313
323
  'has-text-color': !! textColor.color || !! textColor?.class,
314
324
  [ getColorClassName( 'color', textColor?.slug ) ]:
315
325
  !! textColor?.slug,
@@ -429,7 +429,7 @@ $color-control-label-height: 20px;
429
429
  // These needs extra specificity in the editor.
430
430
  .wp-block-navigation__responsive-container:not(.is-menu-open) {
431
431
  .components-button.wp-block-navigation__responsive-container-close {
432
- @include break-small {
432
+ .is-collapsed & {
433
433
  display: none;
434
434
  }
435
435
  }
@@ -611,18 +611,19 @@ button.wp-block-navigation-item__content {
611
611
  }
612
612
  }
613
613
 
614
- @include break-small() {
615
- &:not(.hidden-by-default) {
616
- &:not(.is-menu-open) {
617
- display: block;
618
- width: 100%;
619
- position: relative;
620
- z-index: auto;
621
- background-color: inherit;
622
-
623
- .wp-block-navigation__responsive-container-close {
624
- display: none;
625
- }
614
+ // When the menu is collapsed, the menu button is visible.
615
+ // We are using the > selector combined with the :not(is-collapsed) selector
616
+ // as a way to target the class being added to the parent nav element.
617
+ :not(.is-collapsed) > & {
618
+ &:not(.is-menu-open) {
619
+ display: block;
620
+ width: 100%;
621
+ position: relative;
622
+ z-index: auto;
623
+ background-color: inherit;
624
+
625
+ .wp-block-navigation__responsive-container-close {
626
+ display: none;
626
627
  }
627
628
  }
628
629
 
@@ -686,10 +687,11 @@ button.wp-block-navigation-item__content {
686
687
  font-size: inherit;
687
688
  }
688
689
 
689
- &:not(.always-shown) {
690
- @include break-small {
691
- display: none;
692
- }
690
+ // When the menu is collapsed, the menu button is visible.
691
+ // We are using the > selector combined with the :not(is-collapsed) selector
692
+ // as a way to target the class being added to the parent nav element.
693
+ :not(.is-collapsed) > & {
694
+ display: none;
693
695
  }
694
696
  }
695
697
 
@@ -3,6 +3,11 @@
3
3
  */
4
4
  import { store, getContext, getElement } from '@wordpress/interactivity';
5
5
 
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { NAVIGATION_MOBILE_COLLAPSE } from './constants';
10
+
6
11
  const focusableSelectors = [
7
12
  'a[href]',
8
13
  'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',
@@ -180,10 +185,31 @@ const { state, actions } = store( 'core/navigation', {
180
185
  focusFirstElement() {
181
186
  const { ref } = getElement();
182
187
  if ( state.isMenuOpen ) {
183
- ref.querySelector(
184
- '.wp-block-navigation-item > *:first-child'
185
- ).focus();
188
+ const focusableElements =
189
+ ref.querySelectorAll( focusableSelectors );
190
+ focusableElements?.[ 0 ]?.focus();
191
+ }
192
+ },
193
+ initNav() {
194
+ const context = getContext();
195
+ const mediaQuery = window.matchMedia(
196
+ `(max-width: ${ NAVIGATION_MOBILE_COLLAPSE })`
197
+ );
198
+
199
+ // Run once to set the initial state.
200
+ context.isCollapsed = mediaQuery.matches;
201
+
202
+ function handleCollapse( event ) {
203
+ context.isCollapsed = event.matches;
186
204
  }
205
+
206
+ // Run on resize to update the state.
207
+ mediaQuery.addEventListener( 'change', handleCollapse );
208
+
209
+ // Remove the listener when the component is unmounted.
210
+ return () => {
211
+ mediaQuery.removeEventListener( 'change', handleCollapse );
212
+ };
187
213
  },
188
214
  },
189
215
  } );
@@ -38,3 +38,15 @@ exports[`Paragraph block should render without crashing and match snapshot 1`] =
38
38
  />
39
39
  </View>
40
40
  `;
41
+
42
+ exports[`Paragraph block should set a font size value 1`] = `
43
+ "<!-- wp:paragraph {"style":{"typography":{"fontSize":"30px"}}} -->
44
+ <p style="font-size:30px">A quick brown fox jumps over the lazy dog.</p>
45
+ <!-- /wp:paragraph -->"
46
+ `;
47
+
48
+ exports[`Paragraph block should set a line height value 1`] = `
49
+ "<!-- wp:paragraph {"style":{"typography":{"lineHeight":1.8}}} -->
50
+ <p style="line-height:1.8">A quick brown fox jumps over the lazy dog.</p>
51
+ <!-- /wp:paragraph -->"
52
+ `;
@@ -4,6 +4,7 @@
4
4
  import {
5
5
  act,
6
6
  addBlock,
7
+ dismissModal,
7
8
  getBlock,
8
9
  typeInRichText,
9
10
  fireEvent,
@@ -15,6 +16,7 @@ import {
15
16
  within,
16
17
  withFakeTimers,
17
18
  waitForElementToBeRemoved,
19
+ waitForModalVisible,
18
20
  } from 'test/helpers';
19
21
  import Clipboard from '@react-native-clipboard/clipboard';
20
22
  import TextInputState from 'react-native/Libraries/Components/TextInput/TextInputState';
@@ -687,6 +689,118 @@ describe( 'Paragraph block', () => {
687
689
  ` );
688
690
  } );
689
691
 
692
+ it( 'should show the expected font sizes values', async () => {
693
+ // Arrange
694
+ const screen = await initializeEditor( { withGlobalStyles: true } );
695
+ await addBlock( screen, 'Paragraph' );
696
+
697
+ // Act
698
+ const paragraphBlock = getBlock( screen, 'Paragraph' );
699
+ fireEvent.press( paragraphBlock );
700
+ const paragraphTextInput =
701
+ within( paragraphBlock ).getByPlaceholderText( 'Start writing…' );
702
+ typeInRichText(
703
+ paragraphTextInput,
704
+ 'A quick brown fox jumps over the lazy dog.'
705
+ );
706
+ // Open Block Settings.
707
+ fireEvent.press( screen.getByLabelText( 'Open Settings' ) );
708
+
709
+ // Wait for Block Settings to be visible.
710
+ const blockSettingsModal = screen.getByTestId( 'block-settings-modal' );
711
+ await waitForModalVisible( blockSettingsModal );
712
+
713
+ // Open Font size settings
714
+ fireEvent.press( screen.getByLabelText( 'Font Size, Custom' ) );
715
+ await waitFor( () => screen.getByLabelText( 'Selected: Default' ) );
716
+
717
+ // Assert
718
+ const modalContent = within( blockSettingsModal );
719
+ expect( modalContent.getByLabelText( 'Small' ) ).toBeVisible();
720
+ expect( modalContent.getByText( '14px' ) ).toBeVisible();
721
+ expect( modalContent.getByLabelText( 'Medium' ) ).toBeVisible();
722
+ expect( modalContent.getByText( '17px' ) ).toBeVisible();
723
+ expect( modalContent.getByLabelText( 'Large' ) ).toBeVisible();
724
+ expect( modalContent.getByText( '30px' ) ).toBeVisible();
725
+ expect( modalContent.getByLabelText( 'Extra Large' ) ).toBeVisible();
726
+ expect( modalContent.getByText( '40px' ) ).toBeVisible();
727
+ expect(
728
+ modalContent.getByLabelText( 'Extra Extra Large' )
729
+ ).toBeVisible();
730
+ expect( modalContent.getByText( '52px' ) ).toBeVisible();
731
+ } );
732
+
733
+ it( 'should set a font size value', async () => {
734
+ // Arrange
735
+ const screen = await initializeEditor( { withGlobalStyles: true } );
736
+ await addBlock( screen, 'Paragraph' );
737
+
738
+ // Act
739
+ const paragraphBlock = getBlock( screen, 'Paragraph' );
740
+ fireEvent.press( paragraphBlock );
741
+ const paragraphTextInput =
742
+ within( paragraphBlock ).getByPlaceholderText( 'Start writing…' );
743
+ typeInRichText(
744
+ paragraphTextInput,
745
+ 'A quick brown fox jumps over the lazy dog.'
746
+ );
747
+ // Open Block Settings.
748
+ fireEvent.press( screen.getByLabelText( 'Open Settings' ) );
749
+
750
+ // Wait for Block Settings to be visible.
751
+ const blockSettingsModal = screen.getByTestId( 'block-settings-modal' );
752
+ await waitForModalVisible( blockSettingsModal );
753
+
754
+ // Open Font size settings
755
+ fireEvent.press( screen.getByLabelText( 'Font Size, Custom' ) );
756
+
757
+ // Tap one font size
758
+ fireEvent.press( screen.getByLabelText( 'Large' ) );
759
+
760
+ // Dismiss the Block Settings modal.
761
+ await dismissModal( blockSettingsModal );
762
+
763
+ // Assert
764
+ expect( getEditorHtml() ).toMatchSnapshot();
765
+ } );
766
+
767
+ it( 'should set a line height value', async () => {
768
+ // Arrange
769
+ const screen = await initializeEditor( { withGlobalStyles: true } );
770
+ await addBlock( screen, 'Paragraph' );
771
+
772
+ // Act
773
+ const paragraphBlock = getBlock( screen, 'Paragraph' );
774
+ fireEvent.press( paragraphBlock );
775
+ const paragraphTextInput =
776
+ within( paragraphBlock ).getByPlaceholderText( 'Start writing…' );
777
+ typeInRichText(
778
+ paragraphTextInput,
779
+ 'A quick brown fox jumps over the lazy dog.'
780
+ );
781
+ // Open Block Settings.
782
+ fireEvent.press( screen.getByLabelText( 'Open Settings' ) );
783
+
784
+ // Wait for Block Settings to be visible.
785
+ const blockSettingsModal = screen.getByTestId( 'block-settings-modal' );
786
+ await waitForModalVisible( blockSettingsModal );
787
+
788
+ const lineHeightControl = screen.getByLabelText( /Line Height/ );
789
+ fireEvent.press(
790
+ within( lineHeightControl ).getByText( '1.5', { hidden: true } )
791
+ );
792
+ const lineHeightTextInput = within(
793
+ lineHeightControl
794
+ ).getByDisplayValue( '1.5', { hidden: true } );
795
+ fireEvent.changeText( lineHeightTextInput, '1.8' );
796
+
797
+ // Dismiss the Block Settings modal.
798
+ await dismissModal( blockSettingsModal );
799
+
800
+ // Assert
801
+ expect( getEditorHtml() ).toMatchSnapshot();
802
+ } );
803
+
690
804
  it( 'should focus on the previous Paragraph block when backspacing in an empty Paragraph block', async () => {
691
805
  // Arrange
692
806
  const screen = await initializeEditor();