@wordpress/block-library 9.47.0 → 9.48.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 (35) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/comments/edit/placeholder.cjs +1 -1
  3. package/build/comments/edit/placeholder.cjs.map +2 -2
  4. package/build/cover/edit/inspector-controls.cjs +16 -4
  5. package/build/cover/edit/inspector-controls.cjs.map +2 -2
  6. package/build/image/image.cjs +14 -3
  7. package/build/image/image.cjs.map +2 -2
  8. package/build/image/use-open-image-media-editor-modal.cjs +8 -2
  9. package/build/image/use-open-image-media-editor-modal.cjs.map +2 -2
  10. package/build/post-featured-image/edit.cjs +6 -4
  11. package/build/post-featured-image/edit.cjs.map +2 -2
  12. package/build/site-logo/edit.cjs +4 -1
  13. package/build/site-logo/edit.cjs.map +2 -2
  14. package/build-module/comments/edit/placeholder.mjs +1 -1
  15. package/build-module/comments/edit/placeholder.mjs.map +2 -2
  16. package/build-module/cover/edit/inspector-controls.mjs +16 -4
  17. package/build-module/cover/edit/inspector-controls.mjs.map +2 -2
  18. package/build-module/image/image.mjs +15 -3
  19. package/build-module/image/image.mjs.map +2 -2
  20. package/build-module/image/use-open-image-media-editor-modal.mjs +8 -2
  21. package/build-module/image/use-open-image-media-editor-modal.mjs.map +2 -2
  22. package/build-module/post-featured-image/edit.mjs +6 -4
  23. package/build-module/post-featured-image/edit.mjs.map +2 -2
  24. package/build-module/site-logo/edit.mjs +5 -1
  25. package/build-module/site-logo/edit.mjs.map +2 -2
  26. package/package.json +42 -42
  27. package/src/comments/edit/placeholder.js +1 -1
  28. package/src/cover/edit/inspector-controls.js +61 -45
  29. package/src/cover/test/edit.js +38 -0
  30. package/src/image/image.js +50 -35
  31. package/src/image/test/use-open-image-media-editor-modal.js +41 -0
  32. package/src/image/use-open-image-media-editor-modal.js +7 -1
  33. package/src/navigation-link/test/__snapshots__/hooks.js.snap +45 -134
  34. package/src/post-featured-image/edit.js +15 -10
  35. package/src/site-logo/edit.js +5 -0
@@ -111,6 +111,45 @@ describe( 'useOpenImageMediaEditorModal', () => {
111
111
  jest.clearAllMocks();
112
112
  } );
113
113
 
114
+ it( 'passes an onClose handler for returning focus when the media editor closes', async () => {
115
+ const cropButton = document.createElement( 'button' );
116
+ const otherButton = document.createElement( 'button' );
117
+ document.body.append( cropButton, otherButton );
118
+ const registry = createRegistry();
119
+ useRegistry.mockReturnValue( registry );
120
+ const setAttributes = jest.fn();
121
+ const openMediaEditorModal = jest.fn();
122
+ mockMediaEditorModalSetting( openMediaEditorModal );
123
+ const onClose = () => cropButton.focus();
124
+ const { result } = renderHook( () =>
125
+ useOpenImageMediaEditorModal( {
126
+ attributes: {
127
+ id: 1,
128
+ url: 'original.jpg',
129
+ alt: '',
130
+ caption: '',
131
+ },
132
+ setAttributes,
133
+ onClose,
134
+ } )
135
+ );
136
+
137
+ try {
138
+ await act( async () => {
139
+ await result.current();
140
+ } );
141
+ otherButton.focus();
142
+ expect( otherButton ).toHaveFocus();
143
+
144
+ openMediaEditorModal.mock.calls[ 0 ][ 0 ].onClose();
145
+
146
+ expect( cropButton ).toHaveFocus();
147
+ } finally {
148
+ cropButton.remove();
149
+ otherButton.remove();
150
+ }
151
+ } );
152
+
114
153
  it( 'resolves fresh attachment metadata when the same attachment id has a stale cache', async () => {
115
154
  const originalAttachment = {
116
155
  id: 1,
@@ -187,6 +226,7 @@ describe( 'useOpenImageMediaEditorModal', () => {
187
226
  expect( openMediaEditorModal ).toHaveBeenCalledWith( {
188
227
  id: 1,
189
228
  onUpdate: expect.any( Function ),
229
+ onClose: undefined,
190
230
  } );
191
231
  expect( setAttributes ).toHaveBeenCalledWith( {
192
232
  alt: 'Updated alt',
@@ -229,6 +269,7 @@ describe( 'useOpenImageMediaEditorModal', () => {
229
269
  expect( openMediaEditorModal ).toHaveBeenCalledWith( {
230
270
  id: 1,
231
271
  onUpdate: expect.any( Function ),
272
+ onClose: undefined,
232
273
  } );
233
274
  expect( setAttributes ).toHaveBeenCalledWith( {
234
275
  caption: 'Updated attachment caption',
@@ -136,7 +136,11 @@ function hasKnownAttachmentMetadata( attachment ) {
136
136
  return hasKnownAlt && hasKnownCaption;
137
137
  }
138
138
 
139
- export function useOpenImageMediaEditorModal( { attributes, setAttributes } ) {
139
+ export function useOpenImageMediaEditorModal( {
140
+ attributes,
141
+ setAttributes,
142
+ onClose,
143
+ } ) {
140
144
  // Keep this hook private to the Image block and pass the block attributes
141
145
  // object so the callsite stays compact. Destructure only the attributes
142
146
  // currently used for metadata sync; add more here if the sync policy grows.
@@ -342,11 +346,13 @@ export function useOpenImageMediaEditorModal( { attributes, setAttributes } ) {
342
346
  openMediaEditorModal( {
343
347
  id,
344
348
  onUpdate: handleMediaUpdate,
349
+ onClose,
345
350
  } );
346
351
  }, [
347
352
  getCachedAttachmentRecord,
348
353
  handleMediaUpdate,
349
354
  id,
355
+ onClose,
350
356
  openMediaEditorModal,
351
357
  resolveAttachmentRecord,
352
358
  ] );
@@ -8,30 +8,14 @@ exports[`hooks enhanceNavigationLinkVariations enhances variations with icon and
8
8
  {
9
9
  "attributes": {},
10
10
  "description": "A link to a custom URL.",
11
- "icon": {
12
- "$$typeof": Symbol(react.transitional.element),
13
- "_owner": null,
14
- "_store": {},
15
- "key": null,
16
- "props": {
17
- "children": {
18
- "$$typeof": Symbol(react.transitional.element),
19
- "_owner": null,
20
- "_store": {},
21
- "key": null,
22
- "props": {
23
- "d": "M4 20h9v-1.5H4V20zm0-5.5V16h16v-1.5H4zm.8-4l.7.7 2-2V12h1V9.2l2 2 .7-.7-2-2H12v-1H9.2l2-2-.7-.7-2 2V4h-1v2.8l-2-2-.7.7 2 2H4v1h2.8l-2 2z",
24
- },
25
- "type": [Function],
26
- },
27
- "viewBox": "0 0 24 24",
28
- "xmlns": "http://www.w3.org/2000/svg",
29
- },
30
- "type": {
31
- "$$typeof": Symbol(react.forward_ref),
32
- "render": [Function],
33
- },
34
- },
11
+ "icon": <SVG
12
+ viewBox="0 0 24 24"
13
+ xmlns="http://www.w3.org/2000/svg"
14
+ >
15
+ <Path
16
+ d="M4 20h9v-1.5H4V20zm0-5.5V16h16v-1.5H4zm.8-4l.7.7 2-2V12h1V9.2l2 2 .7-.7-2-2H12v-1H9.2l2-2-.7-.7-2 2V4h-1v2.8l-2-2-.7.7 2 2H4v1h2.8l-2 2z"
17
+ />
18
+ </SVG>,
35
19
  "isActive": [Function],
36
20
  "name": "link",
37
21
  "title": "Custom Link",
@@ -41,30 +25,14 @@ exports[`hooks enhanceNavigationLinkVariations enhances variations with icon and
41
25
  "type": "post",
42
26
  },
43
27
  "description": "A link to a post.",
44
- "icon": {
45
- "$$typeof": Symbol(react.transitional.element),
46
- "_owner": null,
47
- "_store": {},
48
- "key": null,
49
- "props": {
50
- "children": {
51
- "$$typeof": Symbol(react.transitional.element),
52
- "_owner": null,
53
- "_store": {},
54
- "key": null,
55
- "props": {
56
- "d": "M18 5.5H6a.5.5 0 0 0-.5.5v12a.5.5 0 0 0 .5.5h12a.5.5 0 0 0 .5-.5V6a.5.5 0 0 0-.5-.5ZM6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm1 5h1.5v1.5H7V9Zm1.5 4.5H7V15h1.5v-1.5ZM10 9h7v1.5h-7V9Zm7 4.5h-7V15h7v-1.5Z",
57
- },
58
- "type": [Function],
59
- },
60
- "viewBox": "0 0 24 24",
61
- "xmlns": "http://www.w3.org/2000/svg",
62
- },
63
- "type": {
64
- "$$typeof": Symbol(react.forward_ref),
65
- "render": [Function],
66
- },
67
- },
28
+ "icon": <SVG
29
+ viewBox="0 0 24 24"
30
+ xmlns="http://www.w3.org/2000/svg"
31
+ >
32
+ <Path
33
+ d="M18 5.5H6a.5.5 0 0 0-.5.5v12a.5.5 0 0 0 .5.5h12a.5.5 0 0 0 .5-.5V6a.5.5 0 0 0-.5-.5ZM6 4h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm1 5h1.5v1.5H7V9Zm1.5 4.5H7V15h1.5v-1.5ZM10 9h7v1.5h-7V9Zm7 4.5h-7V15h7v-1.5Z"
34
+ />
35
+ </SVG>,
68
36
  "isActive": [Function],
69
37
  "name": "post",
70
38
  "title": "Post Link",
@@ -74,42 +42,17 @@ exports[`hooks enhanceNavigationLinkVariations enhances variations with icon and
74
42
  "type": "page",
75
43
  },
76
44
  "description": "A link to a page.",
77
- "icon": {
78
- "$$typeof": Symbol(react.transitional.element),
79
- "_owner": null,
80
- "_store": {},
81
- "key": null,
82
- "props": {
83
- "children": [
84
- {
85
- "$$typeof": Symbol(react.transitional.element),
86
- "_owner": null,
87
- "_store": {},
88
- "key": null,
89
- "props": {
90
- "d": "M15.5 7.5h-7V9h7V7.5Zm-7 3.5h7v1.5h-7V11Zm7 3.5h-7V16h7v-1.5Z",
91
- },
92
- "type": [Function],
93
- },
94
- {
95
- "$$typeof": Symbol(react.transitional.element),
96
- "_owner": null,
97
- "_store": {},
98
- "key": null,
99
- "props": {
100
- "d": "M17 4H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2ZM7 5.5h10a.5.5 0 0 1 .5.5v12a.5.5 0 0 1-.5.5H7a.5.5 0 0 1-.5-.5V6a.5.5 0 0 1 .5-.5Z",
101
- },
102
- "type": [Function],
103
- },
104
- ],
105
- "viewBox": "0 0 24 24",
106
- "xmlns": "http://www.w3.org/2000/svg",
107
- },
108
- "type": {
109
- "$$typeof": Symbol(react.forward_ref),
110
- "render": [Function],
111
- },
112
- },
45
+ "icon": <SVG
46
+ viewBox="0 0 24 24"
47
+ xmlns="http://www.w3.org/2000/svg"
48
+ >
49
+ <Path
50
+ d="M15.5 7.5h-7V9h7V7.5Zm-7 3.5h7v1.5h-7V11Zm7 3.5h-7V16h7v-1.5Z"
51
+ />
52
+ <Path
53
+ d="M17 4H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2ZM7 5.5h10a.5.5 0 0 1 .5.5v12a.5.5 0 0 1-.5.5H7a.5.5 0 0 1-.5-.5V6a.5.5 0 0 1 .5-.5Z"
54
+ />
55
+ </SVG>,
113
56
  "isActive": [Function],
114
57
  "name": "page",
115
58
  "title": "Page Link",
@@ -119,32 +62,16 @@ exports[`hooks enhanceNavigationLinkVariations enhances variations with icon and
119
62
  "type": "category",
120
63
  },
121
64
  "description": "A link to a category.",
122
- "icon": {
123
- "$$typeof": Symbol(react.transitional.element),
124
- "_owner": null,
125
- "_store": {},
126
- "key": null,
127
- "props": {
128
- "children": {
129
- "$$typeof": Symbol(react.transitional.element),
130
- "_owner": null,
131
- "_store": {},
132
- "key": null,
133
- "props": {
134
- "clipRule": "evenodd",
135
- "d": "M6 5.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5H6a.5.5 0 01-.5-.5V6a.5.5 0 01.5-.5zM4 6a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2H6a2 2 0 01-2-2V6zm11-.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5h-3a.5.5 0 01-.5-.5V6a.5.5 0 01.5-.5zM13 6a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2h-3a2 2 0 01-2-2V6zm5 8.5h-3a.5.5 0 00-.5.5v3a.5.5 0 00.5.5h3a.5.5 0 00.5-.5v-3a.5.5 0 00-.5-.5zM15 13a2 2 0 00-2 2v3a2 2 0 002 2h3a2 2 0 002-2v-3a2 2 0 00-2-2h-3zm-9 1.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5H6a.5.5 0 01-.5-.5v-3a.5.5 0 01.5-.5zM4 15a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2H6a2 2 0 01-2-2v-3z",
136
- "fillRule": "evenodd",
137
- },
138
- "type": [Function],
139
- },
140
- "viewBox": "0 0 24 24",
141
- "xmlns": "http://www.w3.org/2000/svg",
142
- },
143
- "type": {
144
- "$$typeof": Symbol(react.forward_ref),
145
- "render": [Function],
146
- },
147
- },
65
+ "icon": <SVG
66
+ viewBox="0 0 24 24"
67
+ xmlns="http://www.w3.org/2000/svg"
68
+ >
69
+ <Path
70
+ clipRule="evenodd"
71
+ d="M6 5.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5H6a.5.5 0 01-.5-.5V6a.5.5 0 01.5-.5zM4 6a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2H6a2 2 0 01-2-2V6zm11-.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5h-3a.5.5 0 01-.5-.5V6a.5.5 0 01.5-.5zM13 6a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2h-3a2 2 0 01-2-2V6zm5 8.5h-3a.5.5 0 00-.5.5v3a.5.5 0 00.5.5h3a.5.5 0 00.5-.5v-3a.5.5 0 00-.5-.5zM15 13a2 2 0 00-2 2v3a2 2 0 002 2h3a2 2 0 002-2v-3a2 2 0 00-2-2h-3zm-9 1.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5H6a.5.5 0 01-.5-.5v-3a.5.5 0 01.5-.5zM4 15a2 2 0 012-2h3a2 2 0 012 2v3a2 2 0 01-2 2H6a2 2 0 01-2-2v-3z"
72
+ fillRule="evenodd"
73
+ />
74
+ </SVG>,
148
75
  "isActive": [Function],
149
76
  "name": "category",
150
77
  "title": "Category Link",
@@ -154,30 +81,14 @@ exports[`hooks enhanceNavigationLinkVariations enhances variations with icon and
154
81
  "type": "tag",
155
82
  },
156
83
  "description": "A link to a tag.",
157
- "icon": {
158
- "$$typeof": Symbol(react.transitional.element),
159
- "_owner": null,
160
- "_store": {},
161
- "key": null,
162
- "props": {
163
- "children": {
164
- "$$typeof": Symbol(react.transitional.element),
165
- "_owner": null,
166
- "_store": {},
167
- "key": null,
168
- "props": {
169
- "d": "M4.75 4a.75.75 0 0 0-.75.75v7.826c0 .2.08.39.22.53l6.72 6.716a2.313 2.313 0 0 0 3.276-.001l5.61-5.611-.531-.53.532.528a2.315 2.315 0 0 0 0-3.264L13.104 4.22a.75.75 0 0 0-.53-.22H4.75ZM19 12.576a.815.815 0 0 1-.236.574l-5.61 5.611a.814.814 0 0 1-1.153 0L5.5 12.264V5.5h6.763l6.5 6.502a.816.816 0 0 1 .237.574ZM8.75 9.75a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z",
170
- },
171
- "type": [Function],
172
- },
173
- "viewBox": "0 0 24 24",
174
- "xmlns": "http://www.w3.org/2000/svg",
175
- },
176
- "type": {
177
- "$$typeof": Symbol(react.forward_ref),
178
- "render": [Function],
179
- },
180
- },
84
+ "icon": <SVG
85
+ viewBox="0 0 24 24"
86
+ xmlns="http://www.w3.org/2000/svg"
87
+ >
88
+ <Path
89
+ d="M4.75 4a.75.75 0 0 0-.75.75v7.826c0 .2.08.39.22.53l6.72 6.716a2.313 2.313 0 0 0 3.276-.001l5.61-5.611-.531-.53.532.528a2.315 2.315 0 0 0 0-3.264L13.104 4.22a.75.75 0 0 0-.53-.22H4.75ZM19 12.576a.815.815 0 0 1-.236.574l-5.61 5.611a.814.814 0 0 1-1.153 0L5.5 12.264V5.5h6.763l6.5 6.502a.816.816 0 0 1 .237.574ZM8.75 9.75a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"
90
+ />
91
+ </SVG>,
181
92
  "isActive": [Function],
182
93
  "name": "tag",
183
94
  "title": "Tag Link",
@@ -137,10 +137,12 @@ export default function PostFeaturedImageEdit( {
137
137
  return imageId;
138
138
  }, [ storedFeaturedImage, useFirstImageFromPost, postContent ] );
139
139
 
140
- const { media, postType, postPermalink } = useSelect(
140
+ const { media, postType, postPermalink, hasSelectedStyleState } = useSelect(
141
141
  ( select ) => {
142
142
  const { getEntityRecord, getPostType, getEditedEntityRecord } =
143
143
  select( coreStore );
144
+ const { hasSelectedStyleState: hasSelectedBlockStyleState } =
145
+ unlock( select( blockEditorStore ) );
144
146
  return {
145
147
  media:
146
148
  featuredImage &&
@@ -153,9 +155,10 @@ export default function PostFeaturedImageEdit( {
153
155
  postTypeSlug,
154
156
  postId
155
157
  )?.link,
158
+ hasSelectedStyleState: hasSelectedBlockStyleState( clientId ),
156
159
  };
157
160
  },
158
- [ featuredImage, postTypeSlug, postId ]
161
+ [ clientId, featuredImage, postTypeSlug, postId ]
159
162
  );
160
163
 
161
164
  const mediaUrl =
@@ -237,14 +240,16 @@ export default function PostFeaturedImageEdit( {
237
240
  clientId={ clientId }
238
241
  />
239
242
  </InspectorControls>
240
- <InspectorControls group="dimensions">
241
- <DimensionControls
242
- clientId={ clientId }
243
- attributes={ attributes }
244
- setAttributes={ setAttributes }
245
- media={ media }
246
- />
247
- </InspectorControls>
243
+ { ! hasSelectedStyleState && (
244
+ <InspectorControls group="dimensions">
245
+ <DimensionControls
246
+ clientId={ clientId }
247
+ attributes={ attributes }
248
+ setAttributes={ setAttributes }
249
+ media={ media }
250
+ />
251
+ </InspectorControls>
252
+ ) }
248
253
  { ( featuredImage || isDescendentOfQueryLoop || ! postId ) && (
249
254
  <InspectorControls>
250
255
  <ToolsPanel
@@ -10,6 +10,7 @@ import { isBlobURL } from '@wordpress/blob';
10
10
  import {
11
11
  createInterpolateElement,
12
12
  useEffect,
13
+ useRef,
13
14
  useState,
14
15
  } from '@wordpress/element';
15
16
  import { __, isRTL } from '@wordpress/i18n';
@@ -73,6 +74,7 @@ const SiteLogo = ( {
73
74
  const isResizable = ! isWideAligned && isLargeViewport;
74
75
  const [ { naturalWidth, naturalHeight }, setNaturalSize ] = useState( {} );
75
76
  const [ isEditingImage, setIsEditingImage ] = useState( false );
77
+ const cropButtonRef = useRef();
76
78
  const { toggleSelection } = useDispatch( blockEditorStore );
77
79
  const dropdownMenuProps = useToolsPanelDropdownMenuProps();
78
80
 
@@ -401,12 +403,15 @@ const SiteLogo = ( {
401
403
  shouldShowCropAndDimensions && (
402
404
  <BlockControls group="block">
403
405
  <ToolbarButton
406
+ ref={ cropButtonRef }
404
407
  onClick={
405
408
  openMediaEditorModal && logoId
406
409
  ? () =>
407
410
  openMediaEditorModal( {
408
411
  id: logoId,
409
412
  onUpdate: handleMediaUpdate,
413
+ onClose: () =>
414
+ cropButtonRef.current?.focus(),
410
415
  } )
411
416
  : () => setIsEditingImage( true )
412
417
  }