@wordpress/block-library 8.24.1 → 8.25.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/audio/edit.js +7 -52
- package/build/audio/edit.js.map +1 -1
- package/build/audio/edit.native.js +1 -1
- package/build/audio/edit.native.js.map +1 -1
- package/build/audio/index.js +2 -2
- package/build/block/edit.js +102 -11
- package/build/block/edit.js.map +1 -1
- package/build/block/index.js +3 -2
- package/build/block/index.js.map +1 -1
- package/build/block/v1/edit.js +116 -0
- package/build/block/v1/edit.js.map +1 -0
- package/build/block/{edit.native.js → v1/edit.native.js} +2 -2
- package/build/block/v1/edit.native.js.map +1 -0
- package/build/button/index.js +2 -2
- package/build/button/save.js +1 -1
- package/build/button/save.js.map +1 -1
- package/build/code/edit.native.js +13 -14
- package/build/code/edit.native.js.map +1 -1
- package/build/code/index.js +2 -2
- package/build/code/save.js +6 -2
- package/build/code/save.js.map +1 -1
- package/build/details/index.js +2 -2
- package/build/embed/deprecated.js +2 -2
- package/build/embed/embed-preview.native.js +1 -1
- package/build/embed/embed-preview.native.js.map +1 -1
- package/build/embed/icons.js +1 -1
- package/build/embed/icons.js.map +1 -1
- package/build/embed/index.js +2 -2
- package/build/embed/transforms.js +2 -2
- package/build/embed/util.js +2 -2
- package/build/file/edit.js +1 -1
- package/build/file/edit.js.map +1 -1
- package/build/file/edit.native.js +1 -1
- package/build/file/edit.native.js.map +1 -1
- package/build/file/index.js +4 -4
- package/build/file/save.js +4 -1
- package/build/file/save.js.map +1 -1
- package/build/form-input/deprecated.js +147 -0
- package/build/form-input/deprecated.js.map +1 -0
- package/build/form-input/edit.js +1 -1
- package/build/form-input/edit.js.map +1 -1
- package/build/form-input/index.js +4 -2
- package/build/form-input/index.js.map +1 -1
- package/build/form-input/save.js +7 -9
- package/build/form-input/save.js.map +1 -1
- package/build/gallery/edit.js +2 -41
- package/build/gallery/edit.js.map +1 -1
- package/build/gallery/gallery.js +18 -24
- package/build/gallery/gallery.js.map +1 -1
- package/build/gallery/gallery.native.js +1 -1
- package/build/gallery/gallery.native.js.map +1 -1
- package/build/gallery/index.js +4 -4
- package/build/gallery/v1/gallery.native.js +1 -1
- package/build/gallery/v1/gallery.native.js.map +1 -1
- package/build/group/edit.js +6 -1
- package/build/group/edit.js.map +1 -1
- package/build/heading/index.js +3 -6
- package/build/heading/index.js.map +1 -1
- package/build/image/edit.native.js +1 -1
- package/build/image/edit.native.js.map +1 -1
- package/build/image/image.js +14 -51
- package/build/image/image.js.map +1 -1
- package/build/image/index.js +2 -2
- package/build/image/save.js +3 -1
- package/build/image/save.js.map +1 -1
- package/build/list-item/index.js +10 -3
- package/build/list-item/index.js.map +1 -1
- package/build/navigation/edit/index.js +1 -1
- package/build/navigation/edit/index.js.map +1 -1
- package/build/page-list/convert-to-links-modal.js +2 -2
- package/build/page-list/convert-to-links-modal.js.map +1 -1
- package/build/paragraph/edit.js +54 -32
- package/build/paragraph/edit.js.map +1 -1
- package/build/paragraph/index.js +2 -3
- package/build/paragraph/index.js.map +1 -1
- package/build/paragraph/transforms.js +2 -3
- package/build/paragraph/transforms.js.map +1 -1
- package/build/post-title/index.js +1 -3
- package/build/post-title/index.js.map +1 -1
- package/build/preformatted/index.js +2 -3
- package/build/preformatted/index.js.map +1 -1
- package/build/pullquote/index.js +5 -7
- package/build/pullquote/index.js.map +1 -1
- package/build/query/edit/inspector-controls/taxonomy-controls.js +2 -0
- package/build/query/edit/inspector-controls/taxonomy-controls.js.map +1 -1
- package/build/query-title/index.js +1 -3
- package/build/query-title/index.js.map +1 -1
- package/build/quote/index.js +3 -5
- package/build/quote/index.js.map +1 -1
- package/build/quote/transforms.js +7 -6
- package/build/quote/transforms.js.map +1 -1
- package/build/site-title/index.js +1 -5
- package/build/site-title/index.js.map +1 -1
- package/build/social-link/icons/gravatar.js +22 -0
- package/build/social-link/icons/gravatar.js.map +1 -0
- package/build/social-link/icons/index.js +11 -0
- package/build/social-link/icons/index.js.map +1 -1
- package/build/social-link/variations.js +7 -0
- package/build/social-link/variations.js.map +1 -1
- package/build/table/edit.js +3 -1
- package/build/table/edit.js.map +1 -1
- package/build/table/index.js +9 -10
- package/build/table/index.js.map +1 -1
- package/build/table-of-contents/edit.js +2 -2
- package/build/table-of-contents/edit.js.map +1 -1
- package/build/table-of-contents/index.js +5 -2
- package/build/table-of-contents/index.js.map +1 -1
- package/build/utils/caption.js +90 -0
- package/build/utils/caption.js.map +1 -0
- package/build/utils/remove-anchor-tag.js +2 -1
- package/build/utils/remove-anchor-tag.js.map +1 -1
- package/build/verse/index.js +3 -5
- package/build/verse/index.js.map +1 -1
- package/build/video/deprecated.js +2 -2
- package/build/video/edit.js +8 -52
- package/build/video/edit.js.map +1 -1
- package/build/video/edit.native.js +1 -1
- package/build/video/edit.native.js.map +1 -1
- package/build/video/index.js +2 -2
- package/build-module/audio/edit.js +11 -56
- package/build-module/audio/edit.js.map +1 -1
- package/build-module/audio/edit.native.js +2 -2
- package/build-module/audio/edit.native.js.map +1 -1
- package/build-module/audio/index.js +2 -2
- package/build-module/block/edit.js +104 -13
- package/build-module/block/edit.js.map +1 -1
- package/build-module/block/index.js +3 -2
- package/build-module/block/index.js.map +1 -1
- package/build-module/block/v1/edit.js +108 -0
- package/build-module/block/v1/edit.js.map +1 -0
- package/build-module/block/{edit.native.js → v1/edit.native.js} +2 -2
- package/build-module/block/v1/edit.native.js.map +1 -0
- package/build-module/button/index.js +2 -2
- package/build-module/button/save.js +1 -1
- package/build-module/button/save.js.map +1 -1
- package/build-module/code/edit.native.js +14 -16
- package/build-module/code/edit.native.js.map +1 -1
- package/build-module/code/index.js +2 -2
- package/build-module/code/save.js +6 -2
- package/build-module/code/save.js.map +1 -1
- package/build-module/details/index.js +2 -2
- package/build-module/embed/deprecated.js +2 -2
- package/build-module/embed/embed-preview.native.js +2 -2
- package/build-module/embed/embed-preview.native.js.map +1 -1
- package/build-module/embed/icons.js +1 -1
- package/build-module/embed/icons.js.map +1 -1
- package/build-module/embed/index.js +2 -2
- package/build-module/embed/transforms.js +2 -2
- package/build-module/embed/util.js +2 -2
- package/build-module/file/edit.js +1 -1
- package/build-module/file/edit.js.map +1 -1
- package/build-module/file/edit.native.js +1 -1
- package/build-module/file/edit.native.js.map +1 -1
- package/build-module/file/index.js +4 -4
- package/build-module/file/save.js +4 -1
- package/build-module/file/save.js.map +1 -1
- package/build-module/form-input/deprecated.js +138 -0
- package/build-module/form-input/deprecated.js.map +1 -0
- package/build-module/form-input/edit.js +1 -1
- package/build-module/form-input/edit.js.map +1 -1
- package/build-module/form-input/index.js +4 -2
- package/build-module/form-input/index.js.map +1 -1
- package/build-module/form-input/save.js +8 -10
- package/build-module/form-input/save.js.map +1 -1
- package/build-module/gallery/edit.js +5 -44
- package/build-module/gallery/edit.js.map +1 -1
- package/build-module/gallery/gallery.js +17 -21
- package/build-module/gallery/gallery.js.map +1 -1
- package/build-module/gallery/gallery.native.js +2 -2
- package/build-module/gallery/gallery.native.js.map +1 -1
- package/build-module/gallery/index.js +4 -4
- package/build-module/gallery/v1/gallery.native.js +2 -2
- package/build-module/gallery/v1/gallery.native.js.map +1 -1
- package/build-module/group/edit.js +6 -1
- package/build-module/group/edit.js.map +1 -1
- package/build-module/heading/index.js +3 -6
- package/build-module/heading/index.js.map +1 -1
- package/build-module/image/edit.native.js +2 -2
- package/build-module/image/edit.native.js.map +1 -1
- package/build-module/image/image.js +19 -56
- package/build-module/image/image.js.map +1 -1
- package/build-module/image/index.js +2 -2
- package/build-module/image/save.js +3 -1
- package/build-module/image/save.js.map +1 -1
- package/build-module/list-item/index.js +10 -3
- package/build-module/list-item/index.js.map +1 -1
- package/build-module/navigation/edit/index.js +2 -2
- package/build-module/navigation/edit/index.js.map +1 -1
- package/build-module/page-list/convert-to-links-modal.js +2 -2
- package/build-module/page-list/convert-to-links-modal.js.map +1 -1
- package/build-module/paragraph/edit.js +54 -32
- package/build-module/paragraph/edit.js.map +1 -1
- package/build-module/paragraph/index.js +2 -3
- package/build-module/paragraph/index.js.map +1 -1
- package/build-module/paragraph/transforms.js +2 -3
- package/build-module/paragraph/transforms.js.map +1 -1
- package/build-module/post-title/index.js +1 -3
- package/build-module/post-title/index.js.map +1 -1
- package/build-module/preformatted/index.js +2 -3
- package/build-module/preformatted/index.js.map +1 -1
- package/build-module/pullquote/index.js +5 -7
- package/build-module/pullquote/index.js.map +1 -1
- package/build-module/query/edit/inspector-controls/taxonomy-controls.js +2 -0
- package/build-module/query/edit/inspector-controls/taxonomy-controls.js.map +1 -1
- package/build-module/query-title/index.js +1 -3
- package/build-module/query-title/index.js.map +1 -1
- package/build-module/quote/index.js +3 -5
- package/build-module/quote/index.js.map +1 -1
- package/build-module/quote/transforms.js +7 -6
- package/build-module/quote/transforms.js.map +1 -1
- package/build-module/site-title/index.js +1 -5
- package/build-module/site-title/index.js.map +1 -1
- package/build-module/social-link/icons/gravatar.js +14 -0
- package/build-module/social-link/icons/gravatar.js.map +1 -0
- package/build-module/social-link/icons/index.js +1 -0
- package/build-module/social-link/icons/index.js.map +1 -1
- package/build-module/social-link/variations.js +8 -1
- package/build-module/social-link/variations.js.map +1 -1
- package/build-module/table/edit.js +3 -1
- package/build-module/table/edit.js.map +1 -1
- package/build-module/table/index.js +9 -10
- package/build-module/table/index.js.map +1 -1
- package/build-module/table-of-contents/edit.js +1 -1
- package/build-module/table-of-contents/edit.js.map +1 -1
- package/build-module/table-of-contents/index.js +5 -1
- package/build-module/table-of-contents/index.js.map +1 -1
- package/build-module/utils/caption.js +82 -0
- package/build-module/utils/caption.js.map +1 -0
- package/build-module/utils/remove-anchor-tag.js +2 -1
- package/build-module/utils/remove-anchor-tag.js.map +1 -1
- package/build-module/verse/index.js +3 -5
- package/build-module/verse/index.js.map +1 -1
- package/build-module/video/deprecated.js +2 -2
- package/build-module/video/edit.js +13 -57
- package/build-module/video/edit.js.map +1 -1
- package/build-module/video/edit.native.js +2 -2
- package/build-module/video/edit.native.js.map +1 -1
- package/build-module/video/index.js +2 -2
- package/build-style/editor-rtl.css +1 -11
- package/build-style/editor.css +1 -11
- package/build-style/social-links/style-rtl.css +14 -2
- package/build-style/social-links/style.css +14 -2
- package/build-style/style-rtl.css +14 -2
- package/build-style/style.css +14 -2
- package/build-style/table/editor-rtl.css +1 -11
- package/build-style/table/editor.css +1 -11
- package/package.json +32 -32
- package/src/audio/block.json +2 -2
- package/src/audio/edit.js +11 -74
- package/src/audio/edit.native.js +2 -1
- package/src/block/edit.js +143 -16
- package/src/block/index.js +3 -2
- package/src/block/index.php +48 -0
- package/src/block/v1/edit.js +163 -0
- package/src/block/{edit.native.js → v1/edit.native.js} +2 -2
- package/src/button/block.json +2 -2
- package/src/button/save.js +1 -1
- package/src/code/block.json +2 -2
- package/src/code/edit.native.js +11 -13
- package/src/code/save.js +4 -1
- package/src/code/test/edit.native.js +2 -2
- package/src/cover/test/edit.native.js +7 -1
- package/src/details/block.json +2 -2
- package/src/embed/block.json +2 -2
- package/src/embed/embed-preview.native.js +2 -1
- package/src/embed/icons.js +1 -1
- package/src/file/block.json +4 -4
- package/src/file/edit.js +1 -1
- package/src/file/edit.native.js +1 -1
- package/src/file/save.js +5 -1
- package/src/form-input/block.json +2 -2
- package/src/form-input/deprecated.js +142 -0
- package/src/form-input/edit.js +1 -1
- package/src/form-input/index.js +2 -0
- package/src/form-input/save.js +27 -24
- package/src/gallery/block.json +4 -4
- package/src/gallery/edit.js +4 -59
- package/src/gallery/gallery.js +19 -36
- package/src/gallery/gallery.native.js +6 -2
- package/src/gallery/v1/gallery.native.js +2 -1
- package/src/group/edit.js +4 -1
- package/src/heading/block.json +3 -6
- package/src/image/block.json +2 -2
- package/src/image/edit.native.js +2 -3
- package/src/image/image.js +24 -93
- package/src/image/save.js +3 -1
- package/src/list-item/block.json +10 -3
- package/src/navigation/edit/index.js +7 -2
- package/src/navigation/index.php +1 -1
- package/src/navigation-link/test/__snapshots__/hooks.js.snap +6 -3
- package/src/page-list/convert-to-links-modal.js +2 -2
- package/src/paragraph/block.json +2 -3
- package/src/paragraph/edit.js +53 -40
- package/src/post-title/block.json +1 -3
- package/src/preformatted/block.json +2 -3
- package/src/pullquote/block.json +5 -7
- package/src/query/edit/inspector-controls/taxonomy-controls.js +2 -0
- package/src/query-title/block.json +1 -3
- package/src/quote/block.json +3 -5
- package/src/quote/transforms.js +12 -11
- package/src/site-title/block.json +1 -5
- package/src/social-link/icons/gravatar.js +10 -0
- package/src/social-link/icons/index.js +1 -0
- package/src/social-link/index.php +4 -0
- package/src/social-link/socials-with-bg.scss +5 -0
- package/src/social-link/socials-without-bg.scss +4 -0
- package/src/social-link/variations.js +7 -0
- package/src/social-links/style.scss +14 -8
- package/src/table/block.json +9 -10
- package/src/table/edit.js +3 -1
- package/src/table/editor.scss +1 -14
- package/src/table-of-contents/edit.js +1 -1
- package/src/table-of-contents/index.js +5 -1
- package/src/utils/caption.js +108 -0
- package/src/utils/remove-anchor-tag.js +2 -1
- package/src/verse/block.json +3 -5
- package/src/video/block.json +2 -2
- package/src/video/edit.js +12 -74
- package/src/video/edit.native.js +2 -1
- package/build/block/edit.native.js.map +0 -1
- package/build/table-of-contents/icon.js +0 -22
- package/build/table-of-contents/icon.js.map +0 -1
- package/build-module/block/edit.native.js.map +0 -1
- package/build-module/table-of-contents/icon.js +0 -15
- package/build-module/table-of-contents/icon.js.map +0 -1
- package/src/table-of-contents/icon.js +0 -18
package/src/audio/edit.js
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
SelectControl,
|
|
14
14
|
Spinner,
|
|
15
15
|
ToggleControl,
|
|
16
|
-
ToolbarButton,
|
|
17
16
|
} from '@wordpress/components';
|
|
18
17
|
import {
|
|
19
18
|
BlockControls,
|
|
@@ -21,23 +20,20 @@ import {
|
|
|
21
20
|
InspectorControls,
|
|
22
21
|
MediaPlaceholder,
|
|
23
22
|
MediaReplaceFlow,
|
|
24
|
-
RichText,
|
|
25
23
|
useBlockProps,
|
|
26
24
|
store as blockEditorStore,
|
|
27
|
-
__experimentalGetElementClassName,
|
|
28
25
|
} from '@wordpress/block-editor';
|
|
29
|
-
import { useEffect
|
|
26
|
+
import { useEffect } from '@wordpress/element';
|
|
30
27
|
import { __, _x } from '@wordpress/i18n';
|
|
31
28
|
import { useDispatch, useSelect } from '@wordpress/data';
|
|
32
|
-
import { audio as icon
|
|
33
|
-
import { createBlock, getDefaultBlockName } from '@wordpress/blocks';
|
|
29
|
+
import { audio as icon } from '@wordpress/icons';
|
|
34
30
|
import { store as noticesStore } from '@wordpress/notices';
|
|
35
|
-
import { usePrevious } from '@wordpress/compose';
|
|
36
31
|
|
|
37
32
|
/**
|
|
38
33
|
* Internal dependencies
|
|
39
34
|
*/
|
|
40
35
|
import { createUpgradedEmbedBlock } from '../embed/util';
|
|
36
|
+
import { Caption } from '../utils/caption';
|
|
41
37
|
|
|
42
38
|
const ALLOWED_MEDIA_TYPES = [ 'audio' ];
|
|
43
39
|
|
|
@@ -49,9 +45,7 @@ function AudioEdit( {
|
|
|
49
45
|
isSelected,
|
|
50
46
|
insertBlocksAfter,
|
|
51
47
|
} ) {
|
|
52
|
-
const { id, autoplay,
|
|
53
|
-
const prevCaption = usePrevious( caption );
|
|
54
|
-
const [ showCaption, setShowCaption ] = useState( !! caption );
|
|
48
|
+
const { id, autoplay, loop, preload, src } = attributes;
|
|
55
49
|
const isTemporaryAudio = ! id && isBlobURL( src );
|
|
56
50
|
const mediaUpload = useSelect( ( select ) => {
|
|
57
51
|
const { getSettings } = select( blockEditorStore );
|
|
@@ -73,30 +67,6 @@ function AudioEdit( {
|
|
|
73
67
|
}
|
|
74
68
|
}, [] );
|
|
75
69
|
|
|
76
|
-
// We need to show the caption when changes come from
|
|
77
|
-
// history navigation(undo/redo).
|
|
78
|
-
useEffect( () => {
|
|
79
|
-
if ( caption && ! prevCaption ) {
|
|
80
|
-
setShowCaption( true );
|
|
81
|
-
}
|
|
82
|
-
}, [ caption, prevCaption ] );
|
|
83
|
-
|
|
84
|
-
// Focus the caption when we click to add one.
|
|
85
|
-
const captionRef = useCallback(
|
|
86
|
-
( node ) => {
|
|
87
|
-
if ( node && ! caption ) {
|
|
88
|
-
node.focus();
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
[ caption ]
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
useEffect( () => {
|
|
95
|
-
if ( ! isSelected && ! caption ) {
|
|
96
|
-
setShowCaption( false );
|
|
97
|
-
}
|
|
98
|
-
}, [ isSelected, caption ] );
|
|
99
|
-
|
|
100
70
|
function toggleAttribute( attribute ) {
|
|
101
71
|
return ( newValue ) => {
|
|
102
72
|
setAttributes( { [ attribute ]: newValue } );
|
|
@@ -176,23 +146,6 @@ function AudioEdit( {
|
|
|
176
146
|
|
|
177
147
|
return (
|
|
178
148
|
<>
|
|
179
|
-
<BlockControls group="block">
|
|
180
|
-
<ToolbarButton
|
|
181
|
-
onClick={ () => {
|
|
182
|
-
setShowCaption( ! showCaption );
|
|
183
|
-
if ( showCaption && caption ) {
|
|
184
|
-
setAttributes( { caption: undefined } );
|
|
185
|
-
}
|
|
186
|
-
} }
|
|
187
|
-
icon={ captionIcon }
|
|
188
|
-
isPressed={ showCaption }
|
|
189
|
-
label={
|
|
190
|
-
showCaption
|
|
191
|
-
? __( 'Remove caption' )
|
|
192
|
-
: __( 'Add caption' )
|
|
193
|
-
}
|
|
194
|
-
/>
|
|
195
|
-
</BlockControls>
|
|
196
149
|
<BlockControls group="other">
|
|
197
150
|
<MediaReplaceFlow
|
|
198
151
|
mediaId={ id }
|
|
@@ -251,29 +204,13 @@ function AudioEdit( {
|
|
|
251
204
|
<audio controls="controls" src={ src } />
|
|
252
205
|
</Disabled>
|
|
253
206
|
{ isTemporaryAudio && <Spinner /> }
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
) }
|
|
262
|
-
ref={ captionRef }
|
|
263
|
-
aria-label={ __( 'Audio caption text' ) }
|
|
264
|
-
placeholder={ __( 'Add caption' ) }
|
|
265
|
-
value={ caption }
|
|
266
|
-
onChange={ ( value ) =>
|
|
267
|
-
setAttributes( { caption: value } )
|
|
268
|
-
}
|
|
269
|
-
inlineToolbar
|
|
270
|
-
__unstableOnSplitAtEnd={ () =>
|
|
271
|
-
insertBlocksAfter(
|
|
272
|
-
createBlock( getDefaultBlockName() )
|
|
273
|
-
)
|
|
274
|
-
}
|
|
275
|
-
/>
|
|
276
|
-
) }
|
|
207
|
+
<Caption
|
|
208
|
+
attributes={ attributes }
|
|
209
|
+
setAttributes={ setAttributes }
|
|
210
|
+
isSelected={ isSelected }
|
|
211
|
+
insertBlocksAfter={ insertBlocksAfter }
|
|
212
|
+
label={ __( 'Audio caption text' ) }
|
|
213
|
+
/>
|
|
277
214
|
</figure>
|
|
278
215
|
</>
|
|
279
216
|
);
|
package/src/audio/edit.native.js
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
MediaPlaceholder,
|
|
24
24
|
MediaUpload,
|
|
25
25
|
MediaUploadProgress,
|
|
26
|
+
RichText,
|
|
26
27
|
store as blockEditorStore,
|
|
27
28
|
} from '@wordpress/block-editor';
|
|
28
29
|
import { __, _x, sprintf } from '@wordpress/i18n';
|
|
@@ -227,7 +228,7 @@ function AudioEdit( {
|
|
|
227
228
|
<BlockCaption
|
|
228
229
|
accessible={ true }
|
|
229
230
|
accessibilityLabelCreator={ ( caption ) =>
|
|
230
|
-
|
|
231
|
+
RichText.isEmpty( caption )
|
|
231
232
|
? /* translators: accessibility text. Empty Audio caption. */
|
|
232
233
|
__( 'Audio caption. Empty' )
|
|
233
234
|
: sprintf(
|
package/src/block/edit.js
CHANGED
|
@@ -6,11 +6,9 @@ import classnames from 'classnames';
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
useEntityRecord,
|
|
13
|
-
} from '@wordpress/core-data';
|
|
9
|
+
import { useRegistry, useSelect, useDispatch } from '@wordpress/data';
|
|
10
|
+
import { useRef, useMemo, useEffect } from '@wordpress/element';
|
|
11
|
+
import { useEntityProp, useEntityRecord } from '@wordpress/core-data';
|
|
14
12
|
import {
|
|
15
13
|
Placeholder,
|
|
16
14
|
Spinner,
|
|
@@ -27,8 +25,9 @@ import {
|
|
|
27
25
|
useBlockProps,
|
|
28
26
|
Warning,
|
|
29
27
|
privateApis as blockEditorPrivateApis,
|
|
28
|
+
store as blockEditorStore,
|
|
30
29
|
} from '@wordpress/block-editor';
|
|
31
|
-
import {
|
|
30
|
+
import { getBlockSupport, parse } from '@wordpress/blocks';
|
|
32
31
|
|
|
33
32
|
/**
|
|
34
33
|
* Internal dependencies
|
|
@@ -36,6 +35,24 @@ import { useRef, useMemo } from '@wordpress/element';
|
|
|
36
35
|
import { unlock } from '../lock-unlock';
|
|
37
36
|
|
|
38
37
|
const { useLayoutClasses } = unlock( blockEditorPrivateApis );
|
|
38
|
+
|
|
39
|
+
function isPartiallySynced( block ) {
|
|
40
|
+
return (
|
|
41
|
+
!! getBlockSupport( block.name, '__experimentalConnections', false ) &&
|
|
42
|
+
!! block.attributes.connections?.attributes &&
|
|
43
|
+
Object.values( block.attributes.connections.attributes ).some(
|
|
44
|
+
( connection ) => connection.source === 'pattern_attributes'
|
|
45
|
+
)
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
function getPartiallySyncedAttributes( block ) {
|
|
49
|
+
return Object.entries( block.attributes.connections.attributes )
|
|
50
|
+
.filter(
|
|
51
|
+
( [ , connection ] ) => connection.source === 'pattern_attributes'
|
|
52
|
+
)
|
|
53
|
+
.map( ( [ attributeKey ] ) => attributeKey );
|
|
54
|
+
}
|
|
55
|
+
|
|
39
56
|
const fullAlignments = [ 'full', 'wide', 'left', 'right' ];
|
|
40
57
|
|
|
41
58
|
const useInferredLayout = ( blocks, parentLayout ) => {
|
|
@@ -67,11 +84,61 @@ const useInferredLayout = ( blocks, parentLayout ) => {
|
|
|
67
84
|
}, [ blocks, parentLayout ] );
|
|
68
85
|
};
|
|
69
86
|
|
|
87
|
+
function applyInitialOverrides( blocks, overrides = {}, defaultValues ) {
|
|
88
|
+
return blocks.map( ( block ) => {
|
|
89
|
+
const innerBlocks = applyInitialOverrides(
|
|
90
|
+
block.innerBlocks,
|
|
91
|
+
overrides,
|
|
92
|
+
defaultValues
|
|
93
|
+
);
|
|
94
|
+
const blockId = block.attributes.metadata?.id;
|
|
95
|
+
if ( ! isPartiallySynced( block ) || ! blockId )
|
|
96
|
+
return { ...block, innerBlocks };
|
|
97
|
+
const attributes = getPartiallySyncedAttributes( block );
|
|
98
|
+
const newAttributes = { ...block.attributes };
|
|
99
|
+
for ( const attributeKey of attributes ) {
|
|
100
|
+
defaultValues[ blockId ] = block.attributes[ attributeKey ];
|
|
101
|
+
if ( overrides[ blockId ] ) {
|
|
102
|
+
newAttributes[ attributeKey ] = overrides[ blockId ];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
...block,
|
|
107
|
+
attributes: newAttributes,
|
|
108
|
+
innerBlocks,
|
|
109
|
+
};
|
|
110
|
+
} );
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function getOverridesFromBlocks( blocks, defaultValues ) {
|
|
114
|
+
/** @type {Record<string, unknown>} */
|
|
115
|
+
const overrides = {};
|
|
116
|
+
for ( const block of blocks ) {
|
|
117
|
+
Object.assign(
|
|
118
|
+
overrides,
|
|
119
|
+
getOverridesFromBlocks( block.innerBlocks, defaultValues )
|
|
120
|
+
);
|
|
121
|
+
const blockId = block.attributes.metadata?.id;
|
|
122
|
+
if ( ! isPartiallySynced( block ) || ! blockId ) continue;
|
|
123
|
+
const attributes = getPartiallySyncedAttributes( block );
|
|
124
|
+
for ( const attributeKey of attributes ) {
|
|
125
|
+
if (
|
|
126
|
+
block.attributes[ attributeKey ] !== defaultValues[ blockId ]
|
|
127
|
+
) {
|
|
128
|
+
overrides[ blockId ] = block.attributes[ attributeKey ];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return Object.keys( overrides ).length > 0 ? overrides : undefined;
|
|
133
|
+
}
|
|
134
|
+
|
|
70
135
|
export default function ReusableBlockEdit( {
|
|
71
136
|
name,
|
|
72
|
-
attributes: { ref },
|
|
137
|
+
attributes: { ref, overrides },
|
|
73
138
|
__unstableParentLayout: parentLayout,
|
|
139
|
+
clientId: patternClientId,
|
|
74
140
|
} ) {
|
|
141
|
+
const registry = useRegistry();
|
|
75
142
|
const hasAlreadyRendered = useHasRecursion( ref );
|
|
76
143
|
const { record, hasResolved } = useEntityRecord(
|
|
77
144
|
'postType',
|
|
@@ -79,11 +146,46 @@ export default function ReusableBlockEdit( {
|
|
|
79
146
|
ref
|
|
80
147
|
);
|
|
81
148
|
const isMissing = hasResolved && ! record;
|
|
149
|
+
const initialOverrides = useRef( overrides );
|
|
150
|
+
const defaultValuesRef = useRef( {} );
|
|
151
|
+
const {
|
|
152
|
+
replaceInnerBlocks,
|
|
153
|
+
__unstableMarkNextChangeAsNotPersistent,
|
|
154
|
+
setBlockEditingMode,
|
|
155
|
+
} = useDispatch( blockEditorStore );
|
|
156
|
+
const { getBlockEditingMode } = useSelect( blockEditorStore );
|
|
82
157
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
158
|
+
useEffect( () => {
|
|
159
|
+
if ( ! record?.content?.raw ) return;
|
|
160
|
+
const initialBlocks = parse( record.content.raw );
|
|
161
|
+
|
|
162
|
+
const editingMode = getBlockEditingMode( patternClientId );
|
|
163
|
+
registry.batch( () => {
|
|
164
|
+
setBlockEditingMode( patternClientId, 'default' );
|
|
165
|
+
__unstableMarkNextChangeAsNotPersistent();
|
|
166
|
+
replaceInnerBlocks(
|
|
167
|
+
patternClientId,
|
|
168
|
+
applyInitialOverrides(
|
|
169
|
+
initialBlocks,
|
|
170
|
+
initialOverrides.current,
|
|
171
|
+
defaultValuesRef.current
|
|
172
|
+
)
|
|
173
|
+
);
|
|
174
|
+
setBlockEditingMode( patternClientId, editingMode );
|
|
175
|
+
} );
|
|
176
|
+
}, [
|
|
177
|
+
__unstableMarkNextChangeAsNotPersistent,
|
|
178
|
+
patternClientId,
|
|
179
|
+
record,
|
|
180
|
+
replaceInnerBlocks,
|
|
181
|
+
registry,
|
|
182
|
+
getBlockEditingMode,
|
|
183
|
+
setBlockEditingMode,
|
|
184
|
+
] );
|
|
185
|
+
|
|
186
|
+
const innerBlocks = useSelect(
|
|
187
|
+
( select ) => select( blockEditorStore ).getBlocks( patternClientId ),
|
|
188
|
+
[ patternClientId ]
|
|
87
189
|
);
|
|
88
190
|
|
|
89
191
|
const [ title, setTitle ] = useEntityProp(
|
|
@@ -93,7 +195,10 @@ export default function ReusableBlockEdit( {
|
|
|
93
195
|
ref
|
|
94
196
|
);
|
|
95
197
|
|
|
96
|
-
const { alignment, layout } = useInferredLayout(
|
|
198
|
+
const { alignment, layout } = useInferredLayout(
|
|
199
|
+
innerBlocks,
|
|
200
|
+
parentLayout
|
|
201
|
+
);
|
|
97
202
|
const layoutClasses = useLayoutClasses( { layout }, name );
|
|
98
203
|
|
|
99
204
|
const blockProps = useBlockProps( {
|
|
@@ -105,16 +210,38 @@ export default function ReusableBlockEdit( {
|
|
|
105
210
|
} );
|
|
106
211
|
|
|
107
212
|
const innerBlocksProps = useInnerBlocksProps( blockProps, {
|
|
108
|
-
value: blocks,
|
|
109
213
|
layout,
|
|
110
|
-
|
|
111
|
-
onChange,
|
|
112
|
-
renderAppender: blocks?.length
|
|
214
|
+
renderAppender: innerBlocks?.length
|
|
113
215
|
? undefined
|
|
114
216
|
: InnerBlocks.ButtonBlockAppender,
|
|
115
217
|
} );
|
|
116
218
|
|
|
219
|
+
// Sync the `overrides` attribute from the updated blocks.
|
|
220
|
+
// `syncDerivedBlockAttributes` is an action that just like `updateBlockAttributes`
|
|
221
|
+
// but won't create an undo level.
|
|
222
|
+
// This can be abstracted into a `useSyncDerivedAttributes` hook if needed.
|
|
223
|
+
useEffect( () => {
|
|
224
|
+
const { getBlocks } = registry.select( blockEditorStore );
|
|
225
|
+
const { syncDerivedBlockAttributes } = unlock(
|
|
226
|
+
registry.dispatch( blockEditorStore )
|
|
227
|
+
);
|
|
228
|
+
let prevBlocks = getBlocks( patternClientId );
|
|
229
|
+
return registry.subscribe( () => {
|
|
230
|
+
const blocks = getBlocks( patternClientId );
|
|
231
|
+
if ( blocks !== prevBlocks ) {
|
|
232
|
+
prevBlocks = blocks;
|
|
233
|
+
syncDerivedBlockAttributes( patternClientId, {
|
|
234
|
+
overrides: getOverridesFromBlocks(
|
|
235
|
+
blocks,
|
|
236
|
+
defaultValuesRef.current
|
|
237
|
+
),
|
|
238
|
+
} );
|
|
239
|
+
}
|
|
240
|
+
}, blockEditorStore );
|
|
241
|
+
}, [ patternClientId, registry ] );
|
|
242
|
+
|
|
117
243
|
let children = null;
|
|
244
|
+
|
|
118
245
|
if ( hasAlreadyRendered ) {
|
|
119
246
|
children = (
|
|
120
247
|
<Warning>
|
package/src/block/index.js
CHANGED
|
@@ -8,14 +8,15 @@ import { symbol as icon } from '@wordpress/icons';
|
|
|
8
8
|
*/
|
|
9
9
|
import initBlock from '../utils/init-block';
|
|
10
10
|
import metadata from './block.json';
|
|
11
|
-
import
|
|
11
|
+
import editV1 from './v1/edit';
|
|
12
|
+
import editV2 from './edit';
|
|
12
13
|
|
|
13
14
|
const { name } = metadata;
|
|
14
15
|
|
|
15
16
|
export { metadata, name };
|
|
16
17
|
|
|
17
18
|
export const settings = {
|
|
18
|
-
edit,
|
|
19
|
+
edit: window.__experimentalPatternPartialSyncing ? editV2 : editV1,
|
|
19
20
|
icon,
|
|
20
21
|
};
|
|
21
22
|
|
package/src/block/index.php
CHANGED
|
@@ -46,8 +46,31 @@ function render_block_core_block( $attributes ) {
|
|
|
46
46
|
$content = $wp_embed->run_shortcode( $reusable_block->post_content );
|
|
47
47
|
$content = $wp_embed->autoembed( $content );
|
|
48
48
|
|
|
49
|
+
$gutenberg_experiments = get_option( 'gutenberg-experiments' );
|
|
50
|
+
$has_partial_synced_overrides = $gutenberg_experiments
|
|
51
|
+
&& array_key_exists( 'gutenberg-pattern-partial-syncing', $gutenberg_experiments )
|
|
52
|
+
&& isset( $attributes['overrides'] );
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* We set the `pattern/overrides` context through the `render_block_context`
|
|
56
|
+
* filter so that it is available when a pattern's inner blocks are
|
|
57
|
+
* rendering via do_blocks given it only receives the inner content.
|
|
58
|
+
*/
|
|
59
|
+
if ( $has_partial_synced_overrides ) {
|
|
60
|
+
$filter_block_context = static function ( $context ) use ( $attributes ) {
|
|
61
|
+
$context['pattern/overrides'] = $attributes['overrides'];
|
|
62
|
+
return $context;
|
|
63
|
+
};
|
|
64
|
+
add_filter( 'render_block_context', $filter_block_context, 1 );
|
|
65
|
+
}
|
|
66
|
+
|
|
49
67
|
$content = do_blocks( $content );
|
|
50
68
|
unset( $seen_refs[ $attributes['ref'] ] );
|
|
69
|
+
|
|
70
|
+
if ( $has_partial_synced_overrides ) {
|
|
71
|
+
remove_filter( 'render_block_context', $filter_block_context, 1 );
|
|
72
|
+
}
|
|
73
|
+
|
|
51
74
|
return $content;
|
|
52
75
|
}
|
|
53
76
|
|
|
@@ -63,3 +86,28 @@ function register_block_core_block() {
|
|
|
63
86
|
);
|
|
64
87
|
}
|
|
65
88
|
add_action( 'init', 'register_block_core_block' );
|
|
89
|
+
|
|
90
|
+
$gutenberg_experiments = get_option( 'gutenberg-experiments' );
|
|
91
|
+
if ( $gutenberg_experiments && array_key_exists( 'gutenberg-pattern-partial-syncing', $gutenberg_experiments ) ) {
|
|
92
|
+
/**
|
|
93
|
+
* Registers the overrides attribute for core/block.
|
|
94
|
+
*
|
|
95
|
+
* @param array $args Array of arguments for registering a block type.
|
|
96
|
+
* @param string $block_name Block name including namespace.
|
|
97
|
+
* @return array $args
|
|
98
|
+
*/
|
|
99
|
+
function register_block_core_block_args( $args, $block_name ) {
|
|
100
|
+
if ( 'core/block' === $block_name ) {
|
|
101
|
+
$args['attributes'] = array_merge(
|
|
102
|
+
$args['attributes'],
|
|
103
|
+
array(
|
|
104
|
+
'overrides' => array(
|
|
105
|
+
'type' => 'object',
|
|
106
|
+
),
|
|
107
|
+
)
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
return $args;
|
|
111
|
+
}
|
|
112
|
+
add_filter( 'register_block_type_args', 'register_block_core_block_args', 10, 2 );
|
|
113
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import classnames from 'classnames';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import {
|
|
10
|
+
useEntityBlockEditor,
|
|
11
|
+
useEntityProp,
|
|
12
|
+
useEntityRecord,
|
|
13
|
+
} from '@wordpress/core-data';
|
|
14
|
+
import {
|
|
15
|
+
Placeholder,
|
|
16
|
+
Spinner,
|
|
17
|
+
TextControl,
|
|
18
|
+
PanelBody,
|
|
19
|
+
} from '@wordpress/components';
|
|
20
|
+
import { __ } from '@wordpress/i18n';
|
|
21
|
+
import {
|
|
22
|
+
useInnerBlocksProps,
|
|
23
|
+
__experimentalRecursionProvider as RecursionProvider,
|
|
24
|
+
__experimentalUseHasRecursion as useHasRecursion,
|
|
25
|
+
InnerBlocks,
|
|
26
|
+
InspectorControls,
|
|
27
|
+
useBlockProps,
|
|
28
|
+
Warning,
|
|
29
|
+
privateApis as blockEditorPrivateApis,
|
|
30
|
+
} from '@wordpress/block-editor';
|
|
31
|
+
import { useRef, useMemo } from '@wordpress/element';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Internal dependencies
|
|
35
|
+
*/
|
|
36
|
+
import { unlock } from '../../lock-unlock';
|
|
37
|
+
|
|
38
|
+
const { useLayoutClasses } = unlock( blockEditorPrivateApis );
|
|
39
|
+
const fullAlignments = [ 'full', 'wide', 'left', 'right' ];
|
|
40
|
+
|
|
41
|
+
const useInferredLayout = ( blocks, parentLayout ) => {
|
|
42
|
+
const initialInferredAlignmentRef = useRef();
|
|
43
|
+
|
|
44
|
+
return useMemo( () => {
|
|
45
|
+
// Exit early if the pattern's blocks haven't loaded yet.
|
|
46
|
+
if ( ! blocks?.length ) {
|
|
47
|
+
return {};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let alignment = initialInferredAlignmentRef.current;
|
|
51
|
+
|
|
52
|
+
// Only track the initial alignment so that temporarily removed
|
|
53
|
+
// alignments can be reapplied.
|
|
54
|
+
if ( alignment === undefined ) {
|
|
55
|
+
const isConstrained = parentLayout?.type === 'constrained';
|
|
56
|
+
const hasFullAlignment = blocks.some( ( block ) =>
|
|
57
|
+
fullAlignments.includes( block.attributes.align )
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
alignment = isConstrained && hasFullAlignment ? 'full' : null;
|
|
61
|
+
initialInferredAlignmentRef.current = alignment;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const layout = alignment ? parentLayout : undefined;
|
|
65
|
+
|
|
66
|
+
return { alignment, layout };
|
|
67
|
+
}, [ blocks, parentLayout ] );
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default function ReusableBlockEdit( {
|
|
71
|
+
name,
|
|
72
|
+
attributes: { ref },
|
|
73
|
+
__unstableParentLayout: parentLayout,
|
|
74
|
+
} ) {
|
|
75
|
+
const hasAlreadyRendered = useHasRecursion( ref );
|
|
76
|
+
const { record, hasResolved } = useEntityRecord(
|
|
77
|
+
'postType',
|
|
78
|
+
'wp_block',
|
|
79
|
+
ref
|
|
80
|
+
);
|
|
81
|
+
const isMissing = hasResolved && ! record;
|
|
82
|
+
|
|
83
|
+
const [ blocks, onInput, onChange ] = useEntityBlockEditor(
|
|
84
|
+
'postType',
|
|
85
|
+
'wp_block',
|
|
86
|
+
{ id: ref }
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const [ title, setTitle ] = useEntityProp(
|
|
90
|
+
'postType',
|
|
91
|
+
'wp_block',
|
|
92
|
+
'title',
|
|
93
|
+
ref
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const { alignment, layout } = useInferredLayout( blocks, parentLayout );
|
|
97
|
+
const layoutClasses = useLayoutClasses( { layout }, name );
|
|
98
|
+
|
|
99
|
+
const blockProps = useBlockProps( {
|
|
100
|
+
className: classnames(
|
|
101
|
+
'block-library-block__reusable-block-container',
|
|
102
|
+
layout && layoutClasses,
|
|
103
|
+
{ [ `align${ alignment }` ]: alignment }
|
|
104
|
+
),
|
|
105
|
+
} );
|
|
106
|
+
|
|
107
|
+
const innerBlocksProps = useInnerBlocksProps( blockProps, {
|
|
108
|
+
value: blocks,
|
|
109
|
+
layout,
|
|
110
|
+
onInput,
|
|
111
|
+
onChange,
|
|
112
|
+
renderAppender: blocks?.length
|
|
113
|
+
? undefined
|
|
114
|
+
: InnerBlocks.ButtonBlockAppender,
|
|
115
|
+
} );
|
|
116
|
+
|
|
117
|
+
let children = null;
|
|
118
|
+
|
|
119
|
+
if ( hasAlreadyRendered ) {
|
|
120
|
+
children = (
|
|
121
|
+
<Warning>
|
|
122
|
+
{ __( 'Block cannot be rendered inside itself.' ) }
|
|
123
|
+
</Warning>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if ( isMissing ) {
|
|
128
|
+
children = (
|
|
129
|
+
<Warning>
|
|
130
|
+
{ __( 'Block has been deleted or is unavailable.' ) }
|
|
131
|
+
</Warning>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if ( ! hasResolved ) {
|
|
136
|
+
children = (
|
|
137
|
+
<Placeholder>
|
|
138
|
+
<Spinner />
|
|
139
|
+
</Placeholder>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<RecursionProvider uniqueId={ ref }>
|
|
145
|
+
<InspectorControls>
|
|
146
|
+
<PanelBody>
|
|
147
|
+
<TextControl
|
|
148
|
+
label={ __( 'Name' ) }
|
|
149
|
+
value={ title }
|
|
150
|
+
onChange={ setTitle }
|
|
151
|
+
__nextHasNoMarginBottom
|
|
152
|
+
__next40pxDefaultSize
|
|
153
|
+
/>
|
|
154
|
+
</PanelBody>
|
|
155
|
+
</InspectorControls>
|
|
156
|
+
{ children === null ? (
|
|
157
|
+
<div { ...innerBlocksProps } />
|
|
158
|
+
) : (
|
|
159
|
+
<div { ...blockProps }>{ children }</div>
|
|
160
|
+
) }
|
|
161
|
+
</RecursionProvider>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
@@ -42,8 +42,8 @@ import { store as noticesStore } from '@wordpress/notices';
|
|
|
42
42
|
/**
|
|
43
43
|
* Internal dependencies
|
|
44
44
|
*/
|
|
45
|
-
import styles from '
|
|
46
|
-
import EditTitle from '
|
|
45
|
+
import styles from '../editor.scss';
|
|
46
|
+
import EditTitle from '../edit-title';
|
|
47
47
|
|
|
48
48
|
export default function ReusableBlockEdit( {
|
|
49
49
|
attributes: { ref },
|
package/src/button/block.json
CHANGED
package/src/button/save.js
CHANGED