@wordpress/block-library 8.31.0 → 8.32.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.
- package/CHANGELOG.md +2 -0
- package/build/block/edit.js +5 -8
- package/build/block/edit.js.map +1 -1
- package/build/button/edit.native.js +1 -1
- package/build/button/edit.native.js.map +1 -1
- package/build/image/edit.js +10 -39
- package/build/image/edit.js.map +1 -1
- package/build/image/image.js +27 -6
- package/build/image/image.js.map +1 -1
- package/build/navigation/view.js +12 -2
- package/build/navigation/view.js.map +1 -1
- package/build/navigation-link/edit.js +41 -18
- package/build/navigation-link/edit.js.map +1 -1
- package/build/navigation-submenu/edit.js +27 -9
- package/build/navigation-submenu/edit.js.map +1 -1
- package/build/pattern/edit.js +3 -1
- package/build/pattern/edit.js.map +1 -1
- package/build/post-featured-image/edit.js +12 -3
- package/build/post-featured-image/edit.js.map +1 -1
- package/build/post-featured-image/index.js +8 -3
- package/build/post-featured-image/index.js.map +1 -1
- package/build/post-featured-image/overlay-controls.js +82 -0
- package/build/post-featured-image/overlay-controls.js.map +1 -0
- package/build/post-featured-image/overlay.js +5 -54
- package/build/post-featured-image/overlay.js.map +1 -1
- package/build/quote/edit.js +18 -23
- package/build/quote/edit.js.map +1 -1
- package/build/site-tagline/edit.js +13 -4
- package/build/site-tagline/edit.js.map +1 -1
- package/build/site-tagline/index.js +4 -0
- package/build/site-tagline/index.js.map +1 -1
- package/build/template-part/edit/index.js +55 -47
- package/build/template-part/edit/index.js.map +1 -1
- package/build/template-part/edit/inner-blocks.js +106 -10
- package/build/template-part/edit/inner-blocks.js.map +1 -1
- package/build/template-part/edit/selection-modal.js +1 -9
- package/build/template-part/edit/selection-modal.js.map +1 -1
- package/build/utils/caption.js +19 -13
- package/build/utils/caption.js.map +1 -1
- package/build/utils/hooks.js +1 -0
- package/build/utils/hooks.js.map +1 -1
- package/build-module/block/edit.js +5 -8
- package/build-module/block/edit.js.map +1 -1
- package/build-module/button/edit.native.js +1 -1
- package/build-module/button/edit.native.js.map +1 -1
- package/build-module/image/edit.js +11 -40
- package/build-module/image/edit.js.map +1 -1
- package/build-module/image/image.js +27 -6
- package/build-module/image/image.js.map +1 -1
- package/build-module/navigation/view.js +12 -2
- package/build-module/navigation/view.js.map +1 -1
- package/build-module/navigation-link/edit.js +43 -20
- package/build-module/navigation-link/edit.js.map +1 -1
- package/build-module/navigation-submenu/edit.js +27 -9
- package/build-module/navigation-submenu/edit.js.map +1 -1
- package/build-module/pattern/edit.js +3 -1
- package/build-module/pattern/edit.js.map +1 -1
- package/build-module/post-featured-image/edit.js +12 -3
- package/build-module/post-featured-image/edit.js.map +1 -1
- package/build-module/post-featured-image/index.js +8 -3
- package/build-module/post-featured-image/index.js.map +1 -1
- package/build-module/post-featured-image/overlay-controls.js +75 -0
- package/build-module/post-featured-image/overlay-controls.js.map +1 -0
- package/build-module/post-featured-image/overlay.js +7 -56
- package/build-module/post-featured-image/overlay.js.map +1 -1
- package/build-module/quote/edit.js +20 -25
- package/build-module/quote/edit.js.map +1 -1
- package/build-module/site-tagline/edit.js +14 -5
- package/build-module/site-tagline/edit.js.map +1 -1
- package/build-module/site-tagline/index.js +4 -0
- package/build-module/site-tagline/index.js.map +1 -1
- package/build-module/template-part/edit/index.js +58 -50
- package/build-module/template-part/edit/index.js.map +1 -1
- package/build-module/template-part/edit/inner-blocks.js +108 -12
- package/build-module/template-part/edit/inner-blocks.js.map +1 -1
- package/build-module/template-part/edit/selection-modal.js +2 -10
- package/build-module/template-part/edit/selection-modal.js.map +1 -1
- package/build-module/utils/caption.js +19 -13
- package/build-module/utils/caption.js.map +1 -1
- package/build-module/utils/hooks.js +1 -0
- package/build-module/utils/hooks.js.map +1 -1
- package/build-style/audio/theme-rtl.css +1 -1
- package/build-style/audio/theme.css +1 -1
- package/build-style/cover/style-rtl.css +5 -2
- package/build-style/cover/style.css +5 -2
- package/build-style/editor-rtl.css +12 -8
- package/build-style/editor.css +12 -8
- package/build-style/embed/theme-rtl.css +1 -1
- package/build-style/embed/theme.css +1 -1
- package/build-style/image/theme-rtl.css +1 -1
- package/build-style/image/theme.css +1 -1
- package/build-style/pullquote/theme-rtl.css +2 -1
- package/build-style/pullquote/theme.css +2 -1
- package/build-style/quote/theme-rtl.css +6 -6
- package/build-style/quote/theme.css +6 -6
- package/build-style/search/style-rtl.css +10 -0
- package/build-style/search/style.css +10 -0
- package/build-style/social-links/editor-rtl.css +0 -4
- package/build-style/social-links/editor.css +0 -4
- package/build-style/style-rtl.css +15 -2
- package/build-style/style.css +15 -2
- package/build-style/table/theme-rtl.css +4 -3
- package/build-style/table/theme.css +4 -3
- package/build-style/template-part/editor-rtl.css +12 -4
- package/build-style/template-part/editor.css +12 -4
- package/build-style/template-part/theme-rtl.css +1 -1
- package/build-style/template-part/theme.css +1 -1
- package/build-style/theme-rtl.css +17 -15
- package/build-style/theme.css +17 -15
- package/build-style/video/theme-rtl.css +1 -1
- package/build-style/video/theme.css +1 -1
- package/package.json +34 -34
- package/src/audio/theme.scss +1 -1
- package/src/block/edit.js +5 -17
- package/src/button/edit.native.js +1 -1
- package/src/cover/style.scss +6 -2
- package/src/embed/theme.scss +1 -1
- package/src/gallery/editor.scss +1 -1
- package/src/gallery/index.php +1 -1
- package/src/image/edit.js +11 -40
- package/src/image/editor.scss +2 -2
- package/src/image/image.js +25 -7
- package/src/image/theme.scss +1 -1
- package/src/navigation/index.php +8 -0
- package/src/navigation/view.js +11 -2
- package/src/navigation-link/edit.js +53 -27
- package/src/navigation-submenu/edit.js +30 -10
- package/src/pattern/edit.js +4 -0
- package/src/post-featured-image/block.json +8 -3
- package/src/post-featured-image/edit.js +12 -1
- package/src/post-featured-image/editor.scss +1 -1
- package/src/post-featured-image/overlay-controls.js +88 -0
- package/src/post-featured-image/overlay.js +17 -84
- package/src/pullquote/theme.scss +3 -1
- package/src/query-no-results/index.php +2 -0
- package/src/query-pagination-next/index.php +2 -0
- package/src/query-pagination-numbers/index.php +2 -0
- package/src/quote/edit.js +27 -43
- package/src/quote/test/edit.native.js +4 -6
- package/src/quote/theme.scss +1 -2
- package/src/search/style.scss +11 -0
- package/src/site-logo/editor.scss +2 -2
- package/src/site-tagline/block.json +4 -0
- package/src/site-tagline/edit.js +16 -3
- package/src/site-tagline/index.php +9 -1
- package/src/social-links/editor.scss +1 -9
- package/src/table/theme.scss +4 -2
- package/src/template-part/edit/index.js +87 -79
- package/src/template-part/edit/inner-blocks.js +126 -13
- package/src/template-part/edit/selection-modal.js +1 -22
- package/src/template-part/editor.scss +11 -3
- package/src/template-part/index.php +2 -0
- package/src/template-part/theme.scss +1 -1
- package/src/utils/caption.js +19 -16
- package/src/utils/hooks.js +1 -0
- package/src/video/editor.scss +2 -2
- package/src/video/theme.scss +1 -1
package/src/block/edit.js
CHANGED
|
@@ -38,7 +38,7 @@ import { name as patternBlockName } from './index';
|
|
|
38
38
|
import { unlock } from '../lock-unlock';
|
|
39
39
|
|
|
40
40
|
const { useLayoutClasses } = unlock( blockEditorPrivateApis );
|
|
41
|
-
const {
|
|
41
|
+
const { isOverridableBlock } = unlock( patternsPrivateApis );
|
|
42
42
|
|
|
43
43
|
const fullAlignments = [ 'full', 'wide', 'left', 'right' ];
|
|
44
44
|
|
|
@@ -90,21 +90,9 @@ const useInferredLayout = ( blocks, parentLayout ) => {
|
|
|
90
90
|
}, [ blocks, parentLayout ] );
|
|
91
91
|
};
|
|
92
92
|
|
|
93
|
-
function hasOverridableAttributes( block ) {
|
|
94
|
-
return (
|
|
95
|
-
Object.keys( PARTIAL_SYNCING_SUPPORTED_BLOCKS ).includes(
|
|
96
|
-
block.name
|
|
97
|
-
) &&
|
|
98
|
-
!! block.attributes.metadata?.bindings &&
|
|
99
|
-
Object.values( block.attributes.metadata.bindings ).some(
|
|
100
|
-
( binding ) => binding.source === 'core/pattern-overrides'
|
|
101
|
-
)
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
93
|
function hasOverridableBlocks( blocks ) {
|
|
106
94
|
return blocks.some( ( block ) => {
|
|
107
|
-
if (
|
|
95
|
+
if ( isOverridableBlock( block ) ) return true;
|
|
108
96
|
return hasOverridableBlocks( block.innerBlocks );
|
|
109
97
|
} );
|
|
110
98
|
}
|
|
@@ -133,7 +121,7 @@ function applyInitialContentValuesToInnerBlocks(
|
|
|
133
121
|
const metadataName =
|
|
134
122
|
legacyIdMap?.[ block.clientId ] ?? block.attributes.metadata?.name;
|
|
135
123
|
|
|
136
|
-
if ( ! metadataName || !
|
|
124
|
+
if ( ! metadataName || ! isOverridableBlock( block ) ) {
|
|
137
125
|
return { ...block, innerBlocks };
|
|
138
126
|
}
|
|
139
127
|
|
|
@@ -184,7 +172,7 @@ function getContentValuesFromInnerBlocks( blocks, defaultValues, legacyIdMap ) {
|
|
|
184
172
|
}
|
|
185
173
|
const metadataName =
|
|
186
174
|
legacyIdMap?.[ block.clientId ] ?? block.attributes.metadata?.name;
|
|
187
|
-
if ( ! metadataName || !
|
|
175
|
+
if ( ! metadataName || ! isOverridableBlock( block ) ) {
|
|
188
176
|
continue;
|
|
189
177
|
}
|
|
190
178
|
|
|
@@ -217,7 +205,7 @@ function setBlockEditMode( setEditMode, blocks, mode ) {
|
|
|
217
205
|
blocks.forEach( ( block ) => {
|
|
218
206
|
const editMode =
|
|
219
207
|
mode ||
|
|
220
|
-
(
|
|
208
|
+
( isOverridableBlock( block ) ? 'contentOnly' : 'disabled' );
|
|
221
209
|
setEditMode( block.clientId, editMode );
|
|
222
210
|
|
|
223
211
|
setBlockEditMode(
|
package/src/cover/style.scss
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
// Lowest specificity styles are used to ensure that the default styles for the cover block can be overridden by global styles.
|
|
2
|
+
:where(.wp-block-cover-image, .wp-block-cover) {
|
|
3
|
+
min-height: 430px;
|
|
4
|
+
padding: 1em;
|
|
5
|
+
}
|
|
6
|
+
|
|
1
7
|
.wp-block-cover-image,
|
|
2
8
|
.wp-block-cover {
|
|
3
9
|
position: relative;
|
|
4
10
|
background-position: center center;
|
|
5
|
-
min-height: 430px;
|
|
6
11
|
display: flex;
|
|
7
12
|
justify-content: center;
|
|
8
13
|
align-items: center;
|
|
9
|
-
padding: 1em;
|
|
10
14
|
// Prevent the `wp-block-cover__background` span from overflowing the container when border-radius is applied.
|
|
11
15
|
// `overflow: hidden` is provided as a fallback for browsers that don't support `overflow: clip`.
|
|
12
16
|
overflow: hidden;
|
package/src/embed/theme.scss
CHANGED
package/src/gallery/editor.scss
CHANGED
|
@@ -27,7 +27,7 @@ figure.wp-block-gallery {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
// @todo
|
|
30
|
+
// @todo this deserves a refactor, by being moved to the toolbar.
|
|
31
31
|
.block-editor-media-placeholder.is-appender {
|
|
32
32
|
.components-placeholder__label {
|
|
33
33
|
display: none;
|
package/src/gallery/index.php
CHANGED
|
@@ -131,7 +131,7 @@ function block_core_gallery_render( $attributes, $content ) {
|
|
|
131
131
|
* the `$parsed_block['innerBlocks']` via the `render_block_data` hook.
|
|
132
132
|
* However, this hook doesn't apply inner block updates when blocks are
|
|
133
133
|
* nested.
|
|
134
|
-
* @todo
|
|
134
|
+
* @todo In the future, if this hook supports updating innerBlocks in
|
|
135
135
|
* nested blocks, it should be refactored.
|
|
136
136
|
*
|
|
137
137
|
* @see: https://github.com/WordPress/gutenberg/pull/58733
|
package/src/image/edit.js
CHANGED
|
@@ -6,7 +6,7 @@ import classnames from 'classnames';
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import { isBlobURL } from '@wordpress/blob';
|
|
10
10
|
import { store as blocksStore } from '@wordpress/blocks';
|
|
11
11
|
import { Placeholder } from '@wordpress/components';
|
|
12
12
|
import { useDispatch, useSelect } from '@wordpress/data';
|
|
@@ -28,6 +28,7 @@ import { store as noticesStore } from '@wordpress/notices';
|
|
|
28
28
|
* Internal dependencies
|
|
29
29
|
*/
|
|
30
30
|
import { unlock } from '../lock-unlock';
|
|
31
|
+
import { useUploadMediaFromBlobURL } from '../utils/hooks';
|
|
31
32
|
import Image from './image';
|
|
32
33
|
|
|
33
34
|
/**
|
|
@@ -116,7 +117,9 @@ export function ImageEdit( {
|
|
|
116
117
|
align,
|
|
117
118
|
metadata,
|
|
118
119
|
} = attributes;
|
|
119
|
-
const [ temporaryURL, setTemporaryURL ] = useState()
|
|
120
|
+
const [ temporaryURL, setTemporaryURL ] = useState( () => {
|
|
121
|
+
return isTemporaryImage( id, url ) ? url : undefined;
|
|
122
|
+
} );
|
|
120
123
|
|
|
121
124
|
const altRef = useRef();
|
|
122
125
|
useEffect( () => {
|
|
@@ -267,44 +270,12 @@ export function ImageEdit( {
|
|
|
267
270
|
}
|
|
268
271
|
}
|
|
269
272
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
const file = getBlobByURL( url );
|
|
279
|
-
|
|
280
|
-
if ( file ) {
|
|
281
|
-
const { mediaUpload } = getSettings();
|
|
282
|
-
if ( ! mediaUpload ) {
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
mediaUpload( {
|
|
286
|
-
filesList: [ file ],
|
|
287
|
-
onFileChange: ( [ img ] ) => {
|
|
288
|
-
onSelectImage( img );
|
|
289
|
-
},
|
|
290
|
-
allowedTypes: ALLOWED_MEDIA_TYPES,
|
|
291
|
-
onError: ( message ) => {
|
|
292
|
-
isTemp = false;
|
|
293
|
-
onUploadError( message );
|
|
294
|
-
},
|
|
295
|
-
} );
|
|
296
|
-
}
|
|
297
|
-
}, [] );
|
|
298
|
-
|
|
299
|
-
// If an image is temporary, revoke the Blob url when it is uploaded (and is
|
|
300
|
-
// no longer temporary).
|
|
301
|
-
useEffect( () => {
|
|
302
|
-
if ( isTemp ) {
|
|
303
|
-
setTemporaryURL( url );
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
revokeBlobURL( temporaryURL );
|
|
307
|
-
}, [ isTemp, url ] );
|
|
273
|
+
useUploadMediaFromBlobURL( {
|
|
274
|
+
url,
|
|
275
|
+
allowedTypes: ALLOWED_MEDIA_TYPES,
|
|
276
|
+
onChange: onSelectImage,
|
|
277
|
+
onError: onUploadError,
|
|
278
|
+
} );
|
|
308
279
|
|
|
309
280
|
const isExternal = isExternalImage( id, url );
|
|
310
281
|
const src = isExternal ? url : undefined;
|
package/src/image/editor.scss
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Provide special styling for the placeholder.
|
|
2
|
-
// @todo
|
|
2
|
+
// @todo this particular minimal style of placeholder could be componentized further.
|
|
3
3
|
.wp-block-image.wp-block-image {
|
|
4
4
|
|
|
5
5
|
// Show Placeholder style on-select.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// Disable any duotone filter applied in the selected state.
|
|
14
14
|
filter: none !important;
|
|
15
15
|
|
|
16
|
-
// @todo
|
|
16
|
+
// @todo this should eventually be overridden by a custom border-radius set in the inspector.
|
|
17
17
|
border-radius: $radius-block-ui;
|
|
18
18
|
|
|
19
19
|
> svg {
|
package/src/image/image.js
CHANGED
|
@@ -83,8 +83,7 @@ const ImageWrapper = ( { href, children } ) => {
|
|
|
83
83
|
// When the Image block is linked,
|
|
84
84
|
// it's wrapped with a disabled <a /> tag.
|
|
85
85
|
// Restore cursor style so it doesn't appear 'clickable'
|
|
86
|
-
//
|
|
87
|
-
pointerEvents: 'none',
|
|
86
|
+
// Safari needs the display property.
|
|
88
87
|
cursor: 'default',
|
|
89
88
|
display: 'inline',
|
|
90
89
|
} }
|
|
@@ -274,6 +273,22 @@ export default function Image( {
|
|
|
274
273
|
}
|
|
275
274
|
}
|
|
276
275
|
|
|
276
|
+
function resetLightbox() {
|
|
277
|
+
// When deleting a link from an image while lightbox settings
|
|
278
|
+
// are enabled by default, we should disable the lightbox,
|
|
279
|
+
// otherwise the resulting UX looks like a mistake.
|
|
280
|
+
// See https://github.com/WordPress/gutenberg/pull/59890/files#r1532286123.
|
|
281
|
+
if ( lightboxSetting?.enabled && lightboxSetting?.allowEditing ) {
|
|
282
|
+
setAttributes( {
|
|
283
|
+
lightbox: { enabled: false },
|
|
284
|
+
} );
|
|
285
|
+
} else {
|
|
286
|
+
setAttributes( {
|
|
287
|
+
lightbox: undefined,
|
|
288
|
+
} );
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
277
292
|
function onSetTitle( value ) {
|
|
278
293
|
// This is the HTML title attribute, separate from the media object
|
|
279
294
|
// title.
|
|
@@ -348,7 +363,10 @@ export default function Image( {
|
|
|
348
363
|
const [ lightboxSetting ] = useSettings( 'lightbox' );
|
|
349
364
|
|
|
350
365
|
const showLightboxSetting =
|
|
351
|
-
|
|
366
|
+
// If a block-level override is set, we should give users the option to
|
|
367
|
+
// remove that override, even if the lightbox UI is disabled in the settings.
|
|
368
|
+
( !! lightbox && lightbox?.enabled !== lightboxSetting?.enabled ) ||
|
|
369
|
+
lightboxSetting?.allowEditing;
|
|
352
370
|
|
|
353
371
|
const lightboxChecked =
|
|
354
372
|
!! lightbox?.enabled || ( ! lightbox && !! lightboxSetting?.enabled );
|
|
@@ -498,6 +516,7 @@ export default function Image( {
|
|
|
498
516
|
showLightboxSetting={ showLightboxSetting }
|
|
499
517
|
lightboxEnabled={ lightboxChecked }
|
|
500
518
|
onSetLightbox={ onSetLightbox }
|
|
519
|
+
resetLightbox={ resetLightbox }
|
|
501
520
|
/>
|
|
502
521
|
) }
|
|
503
522
|
{ allowCrop && (
|
|
@@ -692,6 +711,7 @@ export default function Image( {
|
|
|
692
711
|
<InspectorControls group="advanced">
|
|
693
712
|
<TextControl
|
|
694
713
|
__nextHasNoMarginBottom
|
|
714
|
+
__next40pxDefaultSize
|
|
695
715
|
label={ __( 'Title attribute' ) }
|
|
696
716
|
value={ title || '' }
|
|
697
717
|
onChange={ onSetTitle }
|
|
@@ -913,9 +933,7 @@ export default function Image( {
|
|
|
913
933
|
|
|
914
934
|
return (
|
|
915
935
|
<>
|
|
916
|
-
{
|
|
917
|
-
which causes duplicated image upload. */ }
|
|
918
|
-
{ ! temporaryURL && controls }
|
|
936
|
+
{ controls }
|
|
919
937
|
{ img }
|
|
920
938
|
|
|
921
939
|
<Caption
|
|
@@ -925,7 +943,7 @@ export default function Image( {
|
|
|
925
943
|
insertBlocksAfter={ insertBlocksAfter }
|
|
926
944
|
label={ __( 'Image caption text' ) }
|
|
927
945
|
showToolbarButton={ isSingleSelected && hasNonContentControls }
|
|
928
|
-
|
|
946
|
+
readOnly={ lockCaption }
|
|
929
947
|
/>
|
|
930
948
|
</>
|
|
931
949
|
);
|
package/src/image/theme.scss
CHANGED
package/src/navigation/index.php
CHANGED
|
@@ -1520,6 +1520,14 @@ function block_core_navigation_update_ignore_hooked_blocks_meta( $post ) {
|
|
|
1520
1520
|
return $post;
|
|
1521
1521
|
}
|
|
1522
1522
|
|
|
1523
|
+
/**
|
|
1524
|
+
* Skip meta generation when consumers intentionally update specific Navigation fields
|
|
1525
|
+
* and omit the content update.
|
|
1526
|
+
*/
|
|
1527
|
+
if ( ! isset( $post->post_content ) ) {
|
|
1528
|
+
return $post;
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1523
1531
|
/*
|
|
1524
1532
|
* We run the Block Hooks mechanism to inject the `metadata.ignoredHookedBlocks` attribute into
|
|
1525
1533
|
* all anchor blocks. For the root level, we create a mock Navigation and extract them from there.
|
package/src/navigation/view.js
CHANGED
|
@@ -62,11 +62,20 @@ const { state, actions } = store(
|
|
|
62
62
|
// Only open on hover if the overlay is closed.
|
|
63
63
|
Object.values( overlayOpenedBy || {} ).filter( Boolean )
|
|
64
64
|
.length === 0
|
|
65
|
-
)
|
|
65
|
+
) {
|
|
66
66
|
actions.openMenu( 'hover' );
|
|
67
|
+
}
|
|
67
68
|
},
|
|
68
69
|
closeMenuOnHover() {
|
|
69
|
-
|
|
70
|
+
const { type, overlayOpenedBy } = getContext();
|
|
71
|
+
if (
|
|
72
|
+
type === 'submenu' &&
|
|
73
|
+
// Only close on hover if the overlay is closed.
|
|
74
|
+
Object.values( overlayOpenedBy || {} ).filter( Boolean )
|
|
75
|
+
.length === 0
|
|
76
|
+
) {
|
|
77
|
+
actions.closeMenu( 'hover' );
|
|
78
|
+
}
|
|
70
79
|
},
|
|
71
80
|
openMenuOnClick() {
|
|
72
81
|
const ctx = getContext();
|
|
@@ -29,14 +29,11 @@ import {
|
|
|
29
29
|
} from '@wordpress/block-editor';
|
|
30
30
|
import { isURL, prependHTTP, safeDecodeURI } from '@wordpress/url';
|
|
31
31
|
import { useState, useEffect, useRef } from '@wordpress/element';
|
|
32
|
-
import {
|
|
33
|
-
placeCaretAtHorizontalEdge,
|
|
34
|
-
__unstableStripHTML as stripHTML,
|
|
35
|
-
} from '@wordpress/dom';
|
|
32
|
+
import { __unstableStripHTML as stripHTML } from '@wordpress/dom';
|
|
36
33
|
import { decodeEntities } from '@wordpress/html-entities';
|
|
37
34
|
import { link as linkIcon, addSubmenu } from '@wordpress/icons';
|
|
38
35
|
import { store as coreStore } from '@wordpress/core-data';
|
|
39
|
-
import { useMergeRefs } from '@wordpress/compose';
|
|
36
|
+
import { useMergeRefs, usePrevious } from '@wordpress/compose';
|
|
40
37
|
|
|
41
38
|
/**
|
|
42
39
|
* Internal dependencies
|
|
@@ -93,7 +90,7 @@ const useIsDraggingWithin = ( elementRef ) => {
|
|
|
93
90
|
ownerDocument.removeEventListener( 'dragend', handleDragEnd );
|
|
94
91
|
ownerDocument.removeEventListener( 'dragenter', handleDragEnter );
|
|
95
92
|
};
|
|
96
|
-
}, [] );
|
|
93
|
+
}, [ elementRef ] );
|
|
97
94
|
|
|
98
95
|
return isDraggingWithin;
|
|
99
96
|
};
|
|
@@ -171,9 +168,14 @@ export default function NavigationLinkEdit( {
|
|
|
171
168
|
const [ isInvalid, isDraft ] = useIsInvalidLink( kind, type, id );
|
|
172
169
|
const { maxNestingLevel } = context;
|
|
173
170
|
|
|
174
|
-
const {
|
|
175
|
-
|
|
171
|
+
const {
|
|
172
|
+
replaceBlock,
|
|
173
|
+
__unstableMarkNextChangeAsNotPersistent,
|
|
174
|
+
selectPreviousBlock,
|
|
175
|
+
} = useDispatch( blockEditorStore );
|
|
176
176
|
const [ isLinkOpen, setIsLinkOpen ] = useState( false );
|
|
177
|
+
// Store what element opened the popover, so we know where to return focus to (toolbar button vs navigation link text)
|
|
178
|
+
const [ openedBy, setOpenedBy ] = useState( null );
|
|
177
179
|
// Use internal state instead of a ref to make sure that the component
|
|
178
180
|
// re-renders when the popover's anchor updates.
|
|
179
181
|
const [ popoverAnchor, setPopoverAnchor ] = useState( null );
|
|
@@ -181,6 +183,7 @@ export default function NavigationLinkEdit( {
|
|
|
181
183
|
const isDraggingWithin = useIsDraggingWithin( listItemRef );
|
|
182
184
|
const itemLabelPlaceholder = __( 'Add label…' );
|
|
183
185
|
const ref = useRef();
|
|
186
|
+
const prevUrl = usePrevious( url );
|
|
184
187
|
|
|
185
188
|
// Change the label using inspector causes rich text to change focus on firefox.
|
|
186
189
|
// This is a workaround to keep the focus on the label field when label filed is focused we don't render the rich text.
|
|
@@ -226,7 +229,7 @@ export default function NavigationLinkEdit( {
|
|
|
226
229
|
/**
|
|
227
230
|
* Transform to submenu block.
|
|
228
231
|
*/
|
|
229
|
-
|
|
232
|
+
const transformToSubmenu = () => {
|
|
230
233
|
const newSubmenu = createBlock(
|
|
231
234
|
'core/navigation-submenu',
|
|
232
235
|
attributes,
|
|
@@ -235,7 +238,7 @@ export default function NavigationLinkEdit( {
|
|
|
235
238
|
: [ createBlock( 'core/navigation-link' ) ]
|
|
236
239
|
);
|
|
237
240
|
replaceBlock( clientId, newSubmenu );
|
|
238
|
-
}
|
|
241
|
+
};
|
|
239
242
|
|
|
240
243
|
useEffect( () => {
|
|
241
244
|
// Show the LinkControl on mount if the URL is empty
|
|
@@ -269,20 +272,18 @@ export default function NavigationLinkEdit( {
|
|
|
269
272
|
|
|
270
273
|
// If the LinkControl popover is open and the URL has changed, close the LinkControl and focus the label text.
|
|
271
274
|
useEffect( () => {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
)
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
placeCaretAtHorizontalEdge( ref.current, true );
|
|
283
|
-
}
|
|
275
|
+
// We only want to do this when the URL has gone from nothing to a new URL AND the label looks like a URL
|
|
276
|
+
if (
|
|
277
|
+
! prevUrl &&
|
|
278
|
+
url &&
|
|
279
|
+
isLinkOpen &&
|
|
280
|
+
isURL( prependHTTP( label ) ) &&
|
|
281
|
+
/^.+\.[a-z]+/.test( label )
|
|
282
|
+
) {
|
|
283
|
+
// Focus and select the label text.
|
|
284
|
+
selectLabelText();
|
|
284
285
|
}
|
|
285
|
-
}, [ url, isLinkOpen, label ] );
|
|
286
|
+
}, [ prevUrl, url, isLinkOpen, label ] );
|
|
286
287
|
|
|
287
288
|
/**
|
|
288
289
|
* Focus the Link label text and select it.
|
|
@@ -334,7 +335,10 @@ export default function NavigationLinkEdit( {
|
|
|
334
335
|
// as it shares the CMD+K shortcut.
|
|
335
336
|
// See https://github.com/WordPress/gutenberg/pull/59845.
|
|
336
337
|
event.preventDefault();
|
|
338
|
+
// If this link is a child of a parent submenu item, the parent submenu item event will also open, closing this popover
|
|
339
|
+
event.stopPropagation();
|
|
337
340
|
setIsLinkOpen( true );
|
|
341
|
+
setOpenedBy( ref.current );
|
|
338
342
|
}
|
|
339
343
|
}
|
|
340
344
|
|
|
@@ -373,6 +377,7 @@ export default function NavigationLinkEdit( {
|
|
|
373
377
|
if ( ! url || isInvalid || isDraft ) {
|
|
374
378
|
blockProps.onClick = () => {
|
|
375
379
|
setIsLinkOpen( true );
|
|
380
|
+
setOpenedBy( ref.current );
|
|
376
381
|
};
|
|
377
382
|
}
|
|
378
383
|
|
|
@@ -399,7 +404,10 @@ export default function NavigationLinkEdit( {
|
|
|
399
404
|
icon={ linkIcon }
|
|
400
405
|
title={ __( 'Link' ) }
|
|
401
406
|
shortcut={ displayShortcut.primary( 'k' ) }
|
|
402
|
-
onClick={ () =>
|
|
407
|
+
onClick={ ( event ) => {
|
|
408
|
+
setIsLinkOpen( true );
|
|
409
|
+
setOpenedBy( event.currentTarget );
|
|
410
|
+
} }
|
|
403
411
|
/>
|
|
404
412
|
{ ! isAtMaxNesting && (
|
|
405
413
|
<ToolbarButton
|
|
@@ -416,17 +424,19 @@ export default function NavigationLinkEdit( {
|
|
|
416
424
|
<PanelBody title={ __( 'Settings' ) }>
|
|
417
425
|
<TextControl
|
|
418
426
|
__nextHasNoMarginBottom
|
|
427
|
+
__next40pxDefaultSize
|
|
419
428
|
value={ label ? stripHTML( label ) : '' }
|
|
420
429
|
onChange={ ( labelValue ) => {
|
|
421
430
|
setAttributes( { label: labelValue } );
|
|
422
431
|
} }
|
|
423
|
-
label={ __( '
|
|
432
|
+
label={ __( 'Text' ) }
|
|
424
433
|
autoComplete="off"
|
|
425
434
|
onFocus={ () => setIsLabelFieldFocused( true ) }
|
|
426
435
|
onBlur={ () => setIsLabelFieldFocused( false ) }
|
|
427
436
|
/>
|
|
428
437
|
<TextControl
|
|
429
438
|
__nextHasNoMarginBottom
|
|
439
|
+
__next40pxDefaultSize
|
|
430
440
|
value={ url ? safeDecodeURI( url ) : '' }
|
|
431
441
|
onChange={ ( urlValue ) => {
|
|
432
442
|
updateAttributes(
|
|
@@ -435,7 +445,7 @@ export default function NavigationLinkEdit( {
|
|
|
435
445
|
attributes
|
|
436
446
|
);
|
|
437
447
|
} }
|
|
438
|
-
label={ __( '
|
|
448
|
+
label={ __( 'Link' ) }
|
|
439
449
|
autoComplete="off"
|
|
440
450
|
/>
|
|
441
451
|
<TextareaControl
|
|
@@ -451,6 +461,7 @@ export default function NavigationLinkEdit( {
|
|
|
451
461
|
/>
|
|
452
462
|
<TextControl
|
|
453
463
|
__nextHasNoMarginBottom
|
|
464
|
+
__next40pxDefaultSize
|
|
454
465
|
value={ title || '' }
|
|
455
466
|
onChange={ ( titleValue ) => {
|
|
456
467
|
setAttributes( { title: titleValue } );
|
|
@@ -463,6 +474,7 @@ export default function NavigationLinkEdit( {
|
|
|
463
474
|
/>
|
|
464
475
|
<TextControl
|
|
465
476
|
__nextHasNoMarginBottom
|
|
477
|
+
__next40pxDefaultSize
|
|
466
478
|
value={ rel || '' }
|
|
467
479
|
onChange={ ( relValue ) => {
|
|
468
480
|
setAttributes( { rel: relValue } );
|
|
@@ -565,10 +577,24 @@ export default function NavigationLinkEdit( {
|
|
|
565
577
|
// If there is no link then remove the auto-inserted block.
|
|
566
578
|
// This avoids empty blocks which can provided a poor UX.
|
|
567
579
|
if ( ! url ) {
|
|
568
|
-
//
|
|
580
|
+
// Select the previous block to keep focus nearby
|
|
581
|
+
selectPreviousBlock( clientId, true );
|
|
582
|
+
// Remove the link.
|
|
569
583
|
onReplace( [] );
|
|
584
|
+
return;
|
|
570
585
|
}
|
|
586
|
+
|
|
571
587
|
setIsLinkOpen( false );
|
|
588
|
+
if ( openedBy ) {
|
|
589
|
+
openedBy.focus();
|
|
590
|
+
setOpenedBy( null );
|
|
591
|
+
} else if ( ref.current ) {
|
|
592
|
+
// select the ref when adding a new link
|
|
593
|
+
ref.current.focus();
|
|
594
|
+
} else {
|
|
595
|
+
// Fallback
|
|
596
|
+
selectPreviousBlock( clientId, true );
|
|
597
|
+
}
|
|
572
598
|
} }
|
|
573
599
|
anchor={ popoverAnchor }
|
|
574
600
|
onRemove={ removeLink }
|
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
} from '@wordpress/block-editor';
|
|
29
29
|
import { isURL, prependHTTP } from '@wordpress/url';
|
|
30
30
|
import { useState, useEffect, useRef } from '@wordpress/element';
|
|
31
|
-
import { placeCaretAtHorizontalEdge } from '@wordpress/dom';
|
|
32
31
|
import { link as linkIcon, removeSubmenu } from '@wordpress/icons';
|
|
33
32
|
import { useResourcePermissions } from '@wordpress/core-data';
|
|
34
33
|
import { speak } from '@wordpress/a11y';
|
|
@@ -139,9 +138,14 @@ export default function NavigationSubmenuEdit( {
|
|
|
139
138
|
|
|
140
139
|
const { showSubmenuIcon, maxNestingLevel, openSubmenusOnClick } = context;
|
|
141
140
|
|
|
142
|
-
const {
|
|
143
|
-
|
|
141
|
+
const {
|
|
142
|
+
__unstableMarkNextChangeAsNotPersistent,
|
|
143
|
+
replaceBlock,
|
|
144
|
+
selectBlock,
|
|
145
|
+
} = useDispatch( blockEditorStore );
|
|
144
146
|
const [ isLinkOpen, setIsLinkOpen ] = useState( false );
|
|
147
|
+
// Store what element opened the popover, so we know where to return focus to (toolbar button vs navigation link text)
|
|
148
|
+
const [ openedBy, setOpenedBy ] = useState( null );
|
|
145
149
|
// Use internal state instead of a ref to make sure that the component
|
|
146
150
|
// re-renders when the popover's anchor updates.
|
|
147
151
|
const [ popoverAnchor, setPopoverAnchor ] = useState( null );
|
|
@@ -241,9 +245,6 @@ export default function NavigationSubmenuEdit( {
|
|
|
241
245
|
) {
|
|
242
246
|
// Focus and select the label text.
|
|
243
247
|
selectLabelText();
|
|
244
|
-
} else {
|
|
245
|
-
// Focus it (but do not select).
|
|
246
|
-
placeCaretAtHorizontalEdge( ref.current, true );
|
|
247
248
|
}
|
|
248
249
|
}
|
|
249
250
|
}, [ url ] );
|
|
@@ -283,7 +284,10 @@ export default function NavigationSubmenuEdit( {
|
|
|
283
284
|
// as it shares the CMD+K shortcut.
|
|
284
285
|
// See https://github.com/WordPress/gutenberg/pull/59845.
|
|
285
286
|
event.preventDefault();
|
|
287
|
+
// If we don't stop propogation, this event bubbles up to the parent submenu item
|
|
288
|
+
event.stopPropagation();
|
|
286
289
|
setIsLinkOpen( true );
|
|
290
|
+
setOpenedBy( ref.current );
|
|
287
291
|
}
|
|
288
292
|
}
|
|
289
293
|
|
|
@@ -370,7 +374,10 @@ export default function NavigationSubmenuEdit( {
|
|
|
370
374
|
icon={ linkIcon }
|
|
371
375
|
title={ __( 'Link' ) }
|
|
372
376
|
shortcut={ displayShortcut.primary( 'k' ) }
|
|
373
|
-
onClick={ () =>
|
|
377
|
+
onClick={ ( event ) => {
|
|
378
|
+
setIsLinkOpen( true );
|
|
379
|
+
setOpenedBy( event.currentTarget );
|
|
380
|
+
} }
|
|
374
381
|
/>
|
|
375
382
|
) }
|
|
376
383
|
|
|
@@ -389,20 +396,22 @@ export default function NavigationSubmenuEdit( {
|
|
|
389
396
|
<PanelBody title={ __( 'Settings' ) }>
|
|
390
397
|
<TextControl
|
|
391
398
|
__nextHasNoMarginBottom
|
|
399
|
+
__next40pxDefaultSize
|
|
392
400
|
value={ label || '' }
|
|
393
401
|
onChange={ ( labelValue ) => {
|
|
394
402
|
setAttributes( { label: labelValue } );
|
|
395
403
|
} }
|
|
396
|
-
label={ __( '
|
|
404
|
+
label={ __( 'Text' ) }
|
|
397
405
|
autoComplete="off"
|
|
398
406
|
/>
|
|
399
407
|
<TextControl
|
|
400
408
|
__nextHasNoMarginBottom
|
|
409
|
+
__next40pxDefaultSize
|
|
401
410
|
value={ url || '' }
|
|
402
411
|
onChange={ ( urlValue ) => {
|
|
403
412
|
setAttributes( { url: urlValue } );
|
|
404
413
|
} }
|
|
405
|
-
label={ __( '
|
|
414
|
+
label={ __( 'Link' ) }
|
|
406
415
|
autoComplete="off"
|
|
407
416
|
/>
|
|
408
417
|
<TextareaControl
|
|
@@ -420,6 +429,7 @@ export default function NavigationSubmenuEdit( {
|
|
|
420
429
|
/>
|
|
421
430
|
<TextControl
|
|
422
431
|
__nextHasNoMarginBottom
|
|
432
|
+
__next40pxDefaultSize
|
|
423
433
|
value={ title || '' }
|
|
424
434
|
onChange={ ( titleValue ) => {
|
|
425
435
|
setAttributes( { title: titleValue } );
|
|
@@ -432,6 +442,7 @@ export default function NavigationSubmenuEdit( {
|
|
|
432
442
|
/>
|
|
433
443
|
<TextControl
|
|
434
444
|
__nextHasNoMarginBottom
|
|
445
|
+
__next40pxDefaultSize
|
|
435
446
|
value={ rel || '' }
|
|
436
447
|
onChange={ ( relValue ) => {
|
|
437
448
|
setAttributes( { rel: relValue } );
|
|
@@ -471,6 +482,7 @@ export default function NavigationSubmenuEdit( {
|
|
|
471
482
|
onClick={ () => {
|
|
472
483
|
if ( ! openSubmenusOnClick && ! url ) {
|
|
473
484
|
setIsLinkOpen( true );
|
|
485
|
+
setOpenedBy( ref.current );
|
|
474
486
|
}
|
|
475
487
|
} }
|
|
476
488
|
/>
|
|
@@ -479,7 +491,15 @@ export default function NavigationSubmenuEdit( {
|
|
|
479
491
|
<LinkUI
|
|
480
492
|
clientId={ clientId }
|
|
481
493
|
link={ attributes }
|
|
482
|
-
onClose={ () =>
|
|
494
|
+
onClose={ () => {
|
|
495
|
+
setIsLinkOpen( false );
|
|
496
|
+
if ( openedBy ) {
|
|
497
|
+
openedBy.focus();
|
|
498
|
+
setOpenedBy( null );
|
|
499
|
+
} else {
|
|
500
|
+
selectBlock( clientId );
|
|
501
|
+
}
|
|
502
|
+
} }
|
|
483
503
|
anchor={ popoverAnchor }
|
|
484
504
|
hasCreateSuggestion={ userCanCreate }
|
|
485
505
|
onRemove={ () => {
|
package/src/pattern/edit.js
CHANGED
|
@@ -108,6 +108,10 @@ const PatternEdit = ( { attributes, clientId } ) => {
|
|
|
108
108
|
metadata: {
|
|
109
109
|
...clonedBlocks[ 0 ].attributes.metadata,
|
|
110
110
|
categories: selectedPattern.categories,
|
|
111
|
+
patternName: selectedPattern.name,
|
|
112
|
+
name:
|
|
113
|
+
clonedBlocks[ 0 ].attributes.metadata.name ||
|
|
114
|
+
selectedPattern.title,
|
|
111
115
|
},
|
|
112
116
|
};
|
|
113
117
|
}
|