@wordpress/block-library 7.18.0 → 7.19.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/button/deprecated.js +16 -2
- package/build/button/deprecated.js.map +1 -1
- package/build/button/edit.js +13 -7
- package/build/button/edit.js.map +1 -1
- package/build/button/index.js +4 -1
- package/build/button/index.js.map +1 -1
- package/build/button/save.js +2 -0
- package/build/button/save.js.map +1 -1
- package/build/columns/transforms.js +5 -0
- package/build/columns/transforms.js.map +1 -1
- package/build/cover/edit/index.js +3 -1
- package/build/cover/edit/index.js.map +1 -1
- package/build/gallery/v1/edit.js +4 -2
- package/build/gallery/v1/edit.js.map +1 -1
- package/build/group/edit.js +98 -45
- package/build/group/edit.js.map +1 -1
- package/build/group/index.js +3 -0
- package/build/group/index.js.map +1 -1
- package/build/group/placeholder.js +168 -0
- package/build/group/placeholder.js.map +1 -0
- package/build/group/variations.js +3 -3
- package/build/group/variations.js.map +1 -1
- package/build/latest-comments/edit.js +2 -1
- package/build/latest-comments/edit.js.map +1 -1
- package/build/latest-comments/index.js +5 -1
- package/build/latest-comments/index.js.map +1 -1
- package/build/latest-posts/deprecated.js +13 -0
- package/build/latest-posts/deprecated.js.map +1 -1
- package/build/latest-posts/index.js +13 -0
- package/build/latest-posts/index.js.map +1 -1
- package/build/list-item/edit.js +2 -1
- package/build/list-item/edit.js.map +1 -1
- package/build/navigation/edit/index.js +82 -92
- package/build/navigation/edit/index.js.map +1 -1
- package/build/navigation/edit/manage-menus-button.js +36 -0
- package/build/navigation/edit/manage-menus-button.js.map +1 -0
- package/build/navigation/edit/navigation-menu-selector.js +12 -5
- package/build/navigation/edit/navigation-menu-selector.js.map +1 -1
- package/build/navigation/edit/responsive-wrapper.js +2 -6
- package/build/navigation/edit/responsive-wrapper.js.map +1 -1
- package/build/navigation/edit/unsaved-inner-blocks.js +5 -19
- package/build/navigation/edit/unsaved-inner-blocks.js.map +1 -1
- package/build/navigation-link/edit.js +10 -1
- package/build/navigation-link/edit.js.map +1 -1
- package/build/post-author/edit.js +35 -20
- package/build/post-author/edit.js.map +1 -1
- package/build/post-content/index.js +3 -0
- package/build/post-content/index.js.map +1 -1
- package/build/site-logo/edit.js +1 -1
- package/build/site-logo/edit.js.map +1 -1
- package/build/template-part/variations.js +5 -0
- package/build/template-part/variations.js.map +1 -1
- package/build-module/button/deprecated.js +16 -2
- package/build-module/button/deprecated.js.map +1 -1
- package/build-module/button/edit.js +15 -9
- package/build-module/button/edit.js.map +1 -1
- package/build-module/button/index.js +4 -1
- package/build-module/button/index.js.map +1 -1
- package/build-module/button/save.js +2 -0
- package/build-module/button/save.js.map +1 -1
- package/build-module/columns/transforms.js +5 -0
- package/build-module/columns/transforms.js.map +1 -1
- package/build-module/cover/edit/index.js +3 -1
- package/build-module/cover/edit/index.js.map +1 -1
- package/build-module/gallery/v1/edit.js +5 -3
- package/build-module/gallery/v1/edit.js.map +1 -1
- package/build-module/group/edit.js +94 -45
- package/build-module/group/edit.js.map +1 -1
- package/build-module/group/index.js +3 -0
- package/build-module/group/index.js.map +1 -1
- package/build-module/group/placeholder.js +154 -0
- package/build-module/group/placeholder.js.map +1 -0
- package/build-module/group/variations.js +3 -3
- package/build-module/group/variations.js.map +1 -1
- package/build-module/latest-comments/edit.js +2 -1
- package/build-module/latest-comments/edit.js.map +1 -1
- package/build-module/latest-comments/index.js +5 -1
- package/build-module/latest-comments/index.js.map +1 -1
- package/build-module/latest-posts/deprecated.js +13 -0
- package/build-module/latest-posts/deprecated.js.map +1 -1
- package/build-module/latest-posts/index.js +13 -0
- package/build-module/latest-posts/index.js.map +1 -1
- package/build-module/list-item/edit.js +2 -1
- package/build-module/list-item/edit.js.map +1 -1
- package/build-module/navigation/edit/index.js +84 -94
- package/build-module/navigation/edit/index.js.map +1 -1
- package/build-module/navigation/edit/manage-menus-button.js +26 -0
- package/build-module/navigation/edit/manage-menus-button.js.map +1 -0
- package/build-module/navigation/edit/navigation-menu-selector.js +13 -6
- package/build-module/navigation/edit/navigation-menu-selector.js.map +1 -1
- package/build-module/navigation/edit/responsive-wrapper.js +2 -6
- package/build-module/navigation/edit/responsive-wrapper.js.map +1 -1
- package/build-module/navigation/edit/unsaved-inner-blocks.js +7 -20
- package/build-module/navigation/edit/unsaved-inner-blocks.js.map +1 -1
- package/build-module/navigation-link/edit.js +10 -1
- package/build-module/navigation-link/edit.js.map +1 -1
- package/build-module/post-author/edit.js +35 -21
- package/build-module/post-author/edit.js.map +1 -1
- package/build-module/post-content/index.js +3 -0
- package/build-module/post-content/index.js.map +1 -1
- package/build-module/site-logo/edit.js +1 -1
- package/build-module/site-logo/edit.js.map +1 -1
- package/build-module/template-part/variations.js +5 -0
- package/build-module/template-part/variations.js.map +1 -1
- package/build-style/editor-rtl.css +76 -1
- package/build-style/editor.css +76 -1
- package/build-style/group/editor-rtl.css +44 -0
- package/build-style/group/editor.css +44 -0
- package/build-style/latest-comments/style-rtl.css +1 -0
- package/build-style/latest-comments/style.css +1 -0
- package/build-style/latest-posts/style-rtl.css +3 -0
- package/build-style/latest-posts/style.css +3 -0
- package/build-style/navigation/editor-rtl.css +23 -0
- package/build-style/navigation/editor.css +23 -0
- package/build-style/navigation/style-rtl.css +10 -0
- package/build-style/navigation/style.css +10 -0
- package/build-style/navigation-link/editor-rtl.css +8 -1
- package/build-style/navigation-link/editor.css +8 -1
- package/build-style/query/editor-rtl.css +1 -1
- package/build-style/query/editor.css +1 -1
- package/build-style/query-pagination/style-rtl.css +1 -1
- package/build-style/query-pagination/style.css +1 -1
- package/build-style/style-rtl.css +20 -1
- package/build-style/style.css +20 -1
- package/build-style/table/editor-rtl.css +1 -0
- package/build-style/table/editor.css +1 -0
- package/build-style/table/style-rtl.css +5 -0
- package/build-style/table/style.css +5 -0
- package/build-style/table/theme-rtl.css +1 -3
- package/build-style/table/theme.css +1 -3
- package/build-style/theme-rtl.css +1 -3
- package/build-style/theme.css +1 -3
- package/package.json +28 -28
- package/src/avatar/index.php +1 -1
- package/src/block/test/edit.native.js +8 -8
- package/src/button/block.json +4 -1
- package/src/button/deprecated.js +18 -2
- package/src/button/edit.js +11 -9
- package/src/button/save.js +12 -2
- package/src/buttons/test/edit.native.js +19 -19
- package/src/columns/test/edit.native.js +32 -32
- package/src/columns/transforms.js +8 -0
- package/src/cover/edit/index.js +3 -1
- package/src/cover/test/edit.native.js +26 -26
- package/src/embed/test/index.native.js +43 -43
- package/src/gallery/test/index.native.js +11 -11
- package/src/gallery/v1/edit.js +19 -24
- package/src/group/block.json +3 -0
- package/src/group/edit.js +95 -44
- package/src/group/editor.scss +48 -0
- package/src/group/placeholder.js +187 -0
- package/src/group/test/edit.native.js +3 -3
- package/src/group/test/placeholder.js +78 -0
- package/src/group/variations.js +3 -3
- package/src/image/test/edit.native.js +17 -17
- package/src/latest-comments/block.json +5 -1
- package/src/latest-comments/edit.js +1 -0
- package/src/latest-comments/style.scss +3 -0
- package/src/latest-posts/block.json +13 -0
- package/src/latest-posts/style.scss +3 -0
- package/src/list/test/edit.native.js +36 -36
- package/src/list-item/edit.js +1 -0
- package/src/missing/test/edit-integration.native.js +5 -5
- package/src/navigation/edit/index.js +173 -146
- package/src/navigation/edit/manage-menus-button.js +21 -0
- package/src/navigation/edit/navigation-menu-selector.js +20 -5
- package/src/navigation/edit/responsive-wrapper.js +2 -10
- package/src/navigation/edit/unsaved-inner-blocks.js +5 -29
- package/src/navigation/editor.scss +25 -0
- package/src/navigation/style.scss +16 -0
- package/src/navigation-link/edit.js +8 -0
- package/src/navigation-link/editor.scss +8 -0
- package/src/post-author/edit.js +44 -20
- package/src/post-content/block.json +3 -0
- package/src/query/editor.scss +1 -1
- package/src/query-pagination/style.scss +1 -1
- package/src/read-more/index.php +9 -2
- package/src/shortcode/test/edit.native.js +5 -5
- package/src/site-logo/edit.js +1 -1
- package/src/social-link/test/index.native.js +10 -10
- package/src/social-links/test/edit.native.js +4 -4
- package/src/spacer/test/index.native.js +17 -17
- package/src/table/editor.scss +1 -0
- package/src/table/style.scss +7 -0
- package/src/table/theme.scss +1 -3
- package/src/template-part/index.php +5 -0
- package/src/template-part/variations.js +4 -0
package/src/gallery/v1/edit.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { filter, find, get, isEmpty, map
|
|
4
|
+
import { filter, find, get, isEmpty, map } from 'lodash';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
@@ -98,34 +98,29 @@ function GalleryEdit( props ) {
|
|
|
98
98
|
|
|
99
99
|
const resizedImages = useMemo( () => {
|
|
100
100
|
if ( isSelected ) {
|
|
101
|
-
return reduce(
|
|
102
|
-
attributes.ids,
|
|
101
|
+
return ( attributes.ids ?? [] ).reduce(
|
|
103
102
|
( currentResizedImages, id ) => {
|
|
104
103
|
if ( ! id ) {
|
|
105
104
|
return currentResizedImages;
|
|
106
105
|
}
|
|
107
106
|
const image = getMedia( id );
|
|
108
|
-
const sizes = reduce(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
};
|
|
126
|
-
},
|
|
127
|
-
{}
|
|
128
|
-
);
|
|
107
|
+
const sizes = imageSizes.reduce( ( currentSizes, size ) => {
|
|
108
|
+
const defaultUrl = get( image, [
|
|
109
|
+
'sizes',
|
|
110
|
+
size.slug,
|
|
111
|
+
'url',
|
|
112
|
+
] );
|
|
113
|
+
const mediaDetailsUrl = get( image, [
|
|
114
|
+
'media_details',
|
|
115
|
+
'sizes',
|
|
116
|
+
size.slug,
|
|
117
|
+
'source_url',
|
|
118
|
+
] );
|
|
119
|
+
return {
|
|
120
|
+
...currentSizes,
|
|
121
|
+
[ size.slug ]: defaultUrl || mediaDetailsUrl,
|
|
122
|
+
};
|
|
123
|
+
}, {} );
|
|
129
124
|
return {
|
|
130
125
|
...currentResizedImages,
|
|
131
126
|
[ parseInt( id, 10 ) ]: sizes,
|
package/src/group/block.json
CHANGED
package/src/group/edit.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { useSelect } from '@wordpress/data';
|
|
5
|
-
|
|
4
|
+
import { useDispatch, useSelect } from '@wordpress/data';
|
|
6
5
|
import {
|
|
7
6
|
InnerBlocks,
|
|
8
7
|
useBlockProps,
|
|
@@ -13,30 +12,67 @@ import {
|
|
|
13
12
|
} from '@wordpress/block-editor';
|
|
14
13
|
import { SelectControl } from '@wordpress/components';
|
|
15
14
|
import { __ } from '@wordpress/i18n';
|
|
15
|
+
import { useCallback } from '@wordpress/element';
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Internal dependencies
|
|
19
|
+
*/
|
|
20
|
+
import GroupPlaceHolder, { useShouldShowPlaceHolder } from './placeholder';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Render inspector controls for the Group block.
|
|
24
|
+
*
|
|
25
|
+
* @param {Object} props Component props.
|
|
26
|
+
* @param {string} props.tagName The HTML tag name.
|
|
27
|
+
* @param {Function} props.onSelectTagName onChange function for the SelectControl.
|
|
28
|
+
*
|
|
29
|
+
* @return {JSX.Element} The control group.
|
|
30
|
+
*/
|
|
31
|
+
function GroupEditControls( { tagName, onSelectTagName } ) {
|
|
32
|
+
const htmlElementMessages = {
|
|
33
|
+
header: __(
|
|
34
|
+
'The <header> element should represent introductory content, typically a group of introductory or navigational aids.'
|
|
35
|
+
),
|
|
36
|
+
main: __(
|
|
37
|
+
'The <main> element should be used for the primary content of your document only. '
|
|
38
|
+
),
|
|
39
|
+
section: __(
|
|
40
|
+
"The <section> element should represent a standalone portion of the document that can't be better represented by another element."
|
|
41
|
+
),
|
|
42
|
+
article: __(
|
|
43
|
+
'The <article> element should represent a self-contained, syndicatable portion of the document.'
|
|
44
|
+
),
|
|
45
|
+
aside: __(
|
|
46
|
+
"The <aside> element should represent a portion of a document whose content is only indirectly related to the document's main content."
|
|
47
|
+
),
|
|
48
|
+
footer: __(
|
|
49
|
+
'The <footer> element should represent a footer for its nearest sectioning element (e.g.: <section>, <article>, <main> etc.).'
|
|
50
|
+
),
|
|
51
|
+
};
|
|
52
|
+
return (
|
|
53
|
+
<InspectorControls __experimentalGroup="advanced">
|
|
54
|
+
<SelectControl
|
|
55
|
+
label={ __( 'HTML element' ) }
|
|
56
|
+
options={ [
|
|
57
|
+
{ label: __( 'Default (<div>)' ), value: 'div' },
|
|
58
|
+
{ label: '<header>', value: 'header' },
|
|
59
|
+
{ label: '<main>', value: 'main' },
|
|
60
|
+
{ label: '<section>', value: 'section' },
|
|
61
|
+
{ label: '<article>', value: 'article' },
|
|
62
|
+
{ label: '<aside>', value: 'aside' },
|
|
63
|
+
{ label: '<footer>', value: 'footer' },
|
|
64
|
+
] }
|
|
65
|
+
value={ tagName }
|
|
66
|
+
onChange={ onSelectTagName }
|
|
67
|
+
help={ htmlElementMessages[ tagName ] }
|
|
68
|
+
/>
|
|
69
|
+
</InspectorControls>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
37
72
|
|
|
38
73
|
function GroupEdit( {
|
|
39
74
|
attributes,
|
|
75
|
+
name,
|
|
40
76
|
setAttributes,
|
|
41
77
|
clientId,
|
|
42
78
|
__unstableLayoutClassNames: layoutClassNames,
|
|
@@ -52,18 +88,26 @@ function GroupEdit( {
|
|
|
52
88
|
},
|
|
53
89
|
[ clientId ]
|
|
54
90
|
);
|
|
55
|
-
|
|
91
|
+
|
|
56
92
|
const { tagName: TagName = 'div', templateLock, layout = {} } = attributes;
|
|
93
|
+
|
|
94
|
+
// Layout settings.
|
|
95
|
+
const defaultLayout = useSetting( 'layout' ) || {};
|
|
57
96
|
const usedLayout = ! layout?.type
|
|
58
97
|
? { ...defaultLayout, ...layout, type: 'default' }
|
|
59
98
|
: { ...defaultLayout, ...layout };
|
|
60
99
|
const { type = 'default' } = usedLayout;
|
|
61
100
|
const layoutSupportEnabled = themeSupportsLayout || type === 'flex';
|
|
62
101
|
|
|
102
|
+
// Hooks.
|
|
63
103
|
const blockProps = useBlockProps( {
|
|
64
104
|
className: ! layoutSupportEnabled ? layoutClassNames : null,
|
|
65
105
|
} );
|
|
66
|
-
|
|
106
|
+
const [ showPlaceholder, setShowPlaceholder ] = useShouldShowPlaceHolder( {
|
|
107
|
+
attributes,
|
|
108
|
+
usedLayoutType: usedLayout?.type,
|
|
109
|
+
hasInnerBlocks,
|
|
110
|
+
} );
|
|
67
111
|
const innerBlocksProps = useInnerBlocksProps(
|
|
68
112
|
layoutSupportEnabled
|
|
69
113
|
? blockProps
|
|
@@ -78,31 +122,38 @@ function GroupEdit( {
|
|
|
78
122
|
}
|
|
79
123
|
);
|
|
80
124
|
|
|
125
|
+
const { selectBlock } = useDispatch( blockEditorStore );
|
|
126
|
+
const updateSelection = useCallback(
|
|
127
|
+
( newClientId ) => selectBlock( newClientId, -1 ),
|
|
128
|
+
[ selectBlock ]
|
|
129
|
+
);
|
|
130
|
+
const selectVariation = ( nextVariation ) => {
|
|
131
|
+
setAttributes( nextVariation.attributes );
|
|
132
|
+
updateSelection( clientId );
|
|
133
|
+
setShowPlaceholder( false );
|
|
134
|
+
};
|
|
135
|
+
|
|
81
136
|
return (
|
|
82
137
|
<>
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
] }
|
|
95
|
-
value={ TagName }
|
|
96
|
-
onChange={ ( value ) =>
|
|
97
|
-
setAttributes( { tagName: value } )
|
|
98
|
-
}
|
|
99
|
-
help={ htmlElementMessages[ TagName ] }
|
|
138
|
+
<GroupEditControls
|
|
139
|
+
tagName={ TagName }
|
|
140
|
+
onSelectTagName={ ( value ) =>
|
|
141
|
+
setAttributes( { tagName: value } )
|
|
142
|
+
}
|
|
143
|
+
/>
|
|
144
|
+
{ showPlaceholder && (
|
|
145
|
+
<GroupPlaceHolder
|
|
146
|
+
clientId={ clientId }
|
|
147
|
+
name={ name }
|
|
148
|
+
onSelect={ selectVariation }
|
|
100
149
|
/>
|
|
101
|
-
|
|
102
|
-
{ layoutSupportEnabled &&
|
|
150
|
+
) }
|
|
151
|
+
{ layoutSupportEnabled && ! showPlaceholder && (
|
|
152
|
+
<TagName { ...innerBlocksProps } />
|
|
153
|
+
) }
|
|
103
154
|
{ /* Ideally this is not needed but it's there for backward compatibility reason
|
|
104
155
|
to keep this div for themes that might rely on its presence */ }
|
|
105
|
-
{ ! layoutSupportEnabled && (
|
|
156
|
+
{ ! layoutSupportEnabled && ! showPlaceholder && (
|
|
106
157
|
<TagName { ...blockProps }>
|
|
107
158
|
<div { ...innerBlocksProps } />
|
|
108
159
|
</TagName>
|
package/src/group/editor.scss
CHANGED
|
@@ -52,3 +52,51 @@
|
|
|
52
52
|
pointer-events: all;
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
+
|
|
56
|
+
.wp-block-group__placeholder {
|
|
57
|
+
.wp-block-group-placeholder__variations {
|
|
58
|
+
list-style: none;
|
|
59
|
+
display: flex;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
flex-direction: row;
|
|
62
|
+
flex-wrap: wrap;
|
|
63
|
+
width: 100%;
|
|
64
|
+
padding: 0;
|
|
65
|
+
margin: 0;
|
|
66
|
+
}
|
|
67
|
+
.components-placeholder__instructions {
|
|
68
|
+
text-align: center;
|
|
69
|
+
margin-bottom: 18px;
|
|
70
|
+
}
|
|
71
|
+
.wp-block-group-placeholder__variations svg {
|
|
72
|
+
fill: $gray-400 !important;
|
|
73
|
+
}
|
|
74
|
+
.wp-block-group-placeholder__variations svg:hover {
|
|
75
|
+
fill: var(--wp-admin-theme-color) !important;
|
|
76
|
+
}
|
|
77
|
+
.wp-block-group-placeholder__variations > li {
|
|
78
|
+
margin: 0 $grid-unit-15 $grid-unit-15 $grid-unit-15;
|
|
79
|
+
width: auto;
|
|
80
|
+
display: flex;
|
|
81
|
+
flex-direction: column;
|
|
82
|
+
align-items: center;
|
|
83
|
+
}
|
|
84
|
+
.wp-block-group-placeholder__variations li > .wp-block-group-placeholder__variation-button {
|
|
85
|
+
width: 44px;
|
|
86
|
+
height: 32px;
|
|
87
|
+
padding: 0;
|
|
88
|
+
&:hover {
|
|
89
|
+
box-shadow: none;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
.components-placeholder {
|
|
93
|
+
min-height: auto;
|
|
94
|
+
padding: $grid-unit-30;
|
|
95
|
+
}
|
|
96
|
+
.is-small,
|
|
97
|
+
.is-medium {
|
|
98
|
+
.wp-block-group-placeholder__variations > li {
|
|
99
|
+
margin: $grid-unit-15;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useSelect } from '@wordpress/data';
|
|
5
|
+
import { useBlockProps } from '@wordpress/block-editor';
|
|
6
|
+
import { __ } from '@wordpress/i18n';
|
|
7
|
+
import { store as blocksStore } from '@wordpress/blocks';
|
|
8
|
+
import { Path, SVG, Button, Placeholder } from '@wordpress/components';
|
|
9
|
+
import { useState, useEffect } from '@wordpress/element';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Returns a custom variation icon.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} name The block variation name.
|
|
15
|
+
*
|
|
16
|
+
* @return {JSX.Element} The SVG element.
|
|
17
|
+
*/
|
|
18
|
+
const getGroupPlaceholderIcons = ( name = 'group' ) => {
|
|
19
|
+
const icons = {
|
|
20
|
+
group: (
|
|
21
|
+
<SVG
|
|
22
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
23
|
+
width="44"
|
|
24
|
+
height="32"
|
|
25
|
+
viewBox="0 0 44 32"
|
|
26
|
+
>
|
|
27
|
+
<Path
|
|
28
|
+
d="M42 0H2C.9 0 0 .9 0 2v28c0 1.1.9 2 2 2h40c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2z"
|
|
29
|
+
// style="fill:#ccc"
|
|
30
|
+
/>
|
|
31
|
+
</SVG>
|
|
32
|
+
),
|
|
33
|
+
'group-row': (
|
|
34
|
+
<SVG
|
|
35
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
36
|
+
width="44"
|
|
37
|
+
height="32"
|
|
38
|
+
viewBox="0 0 44 32"
|
|
39
|
+
>
|
|
40
|
+
<Path
|
|
41
|
+
d="M42 0H23.5c-.6 0-1 .4-1 1v30c0 .6.4 1 1 1H42c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2zM20.5 0H2C.9 0 0 .9 0 2v28c0 1.1.9 2 2 2h18.5c.6 0 1-.4 1-1V1c0-.6-.4-1-1-1z"
|
|
42
|
+
// style="fill:#ccc"
|
|
43
|
+
/>
|
|
44
|
+
</SVG>
|
|
45
|
+
),
|
|
46
|
+
'group-stack': (
|
|
47
|
+
<SVG
|
|
48
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
49
|
+
width="44"
|
|
50
|
+
height="32"
|
|
51
|
+
viewBox="0 0 44 32"
|
|
52
|
+
>
|
|
53
|
+
<Path
|
|
54
|
+
d="M42 0H2C.9 0 0 .9 0 2v12.5c0 .6.4 1 1 1h42c.6 0 1-.4 1-1V2c0-1.1-.9-2-2-2zm1 16.5H1c-.6 0-1 .4-1 1V30c0 1.1.9 2 2 2h40c1.1 0 2-.9 2-2V17.5c0-.6-.4-1-1-1z"
|
|
55
|
+
// style="fill:#ccc"
|
|
56
|
+
/>
|
|
57
|
+
</SVG>
|
|
58
|
+
),
|
|
59
|
+
};
|
|
60
|
+
return icons?.[ name ];
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A custom hook to tell the Group block whether to show the variation placeholder.
|
|
65
|
+
*
|
|
66
|
+
* @param {Object} props Arguments to pass to hook.
|
|
67
|
+
* @param {Object} [props.attributes] The block's attributes.
|
|
68
|
+
* @param {string} [props.usedLayoutType] The block's current layout type.
|
|
69
|
+
* @param {boolean} [props.hasInnerBlocks] Whether the block has inner blocks.
|
|
70
|
+
*
|
|
71
|
+
* @return {[boolean, Function]} A state value and setter function.
|
|
72
|
+
*/
|
|
73
|
+
export function useShouldShowPlaceHolder( {
|
|
74
|
+
attributes = {
|
|
75
|
+
style: undefined,
|
|
76
|
+
backgroundColor: undefined,
|
|
77
|
+
textColor: undefined,
|
|
78
|
+
fontSize: undefined,
|
|
79
|
+
},
|
|
80
|
+
usedLayoutType = '',
|
|
81
|
+
hasInnerBlocks = false,
|
|
82
|
+
} ) {
|
|
83
|
+
const { style, backgroundColor, textColor, fontSize } = attributes;
|
|
84
|
+
/*
|
|
85
|
+
* Shows the placeholder when no known styles are set,
|
|
86
|
+
* or when a non-default layout has been selected.
|
|
87
|
+
* Should the Group block support more style presets in the
|
|
88
|
+
* future, e.g., attributes.spacingSize, we can add them to the
|
|
89
|
+
* condition.
|
|
90
|
+
*/
|
|
91
|
+
const [ showPlaceholder, setShowPlaceholder ] = useState(
|
|
92
|
+
! hasInnerBlocks &&
|
|
93
|
+
! backgroundColor &&
|
|
94
|
+
! fontSize &&
|
|
95
|
+
! textColor &&
|
|
96
|
+
! style &&
|
|
97
|
+
usedLayoutType !== 'flex'
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
useEffect( () => {
|
|
101
|
+
if (
|
|
102
|
+
!! hasInnerBlocks ||
|
|
103
|
+
!! backgroundColor ||
|
|
104
|
+
!! fontSize ||
|
|
105
|
+
!! textColor ||
|
|
106
|
+
!! style ||
|
|
107
|
+
usedLayoutType === 'flex'
|
|
108
|
+
) {
|
|
109
|
+
setShowPlaceholder( false );
|
|
110
|
+
}
|
|
111
|
+
}, [
|
|
112
|
+
backgroundColor,
|
|
113
|
+
fontSize,
|
|
114
|
+
textColor,
|
|
115
|
+
style,
|
|
116
|
+
usedLayoutType,
|
|
117
|
+
hasInnerBlocks,
|
|
118
|
+
] );
|
|
119
|
+
|
|
120
|
+
return [ showPlaceholder, setShowPlaceholder ];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Display group variations if none is selected.
|
|
125
|
+
*
|
|
126
|
+
* @param {Object} props Component props.
|
|
127
|
+
* @param {string} props.name The block's name.
|
|
128
|
+
* @param {Function} props.onSelect Function to set block's attributes.
|
|
129
|
+
*
|
|
130
|
+
* @return {JSX.Element} The placeholder.
|
|
131
|
+
*/
|
|
132
|
+
function GroupPlaceHolder( { name, onSelect } ) {
|
|
133
|
+
const { defaultVariation, variations } = useSelect(
|
|
134
|
+
( select ) => {
|
|
135
|
+
const { getBlockVariations, getDefaultBlockVariation } =
|
|
136
|
+
select( blocksStore );
|
|
137
|
+
return {
|
|
138
|
+
defaultVariation: getDefaultBlockVariation( name, 'block' ),
|
|
139
|
+
variations: getBlockVariations( name, 'block' ) || [],
|
|
140
|
+
};
|
|
141
|
+
},
|
|
142
|
+
[ name ]
|
|
143
|
+
);
|
|
144
|
+
const blockProps = useBlockProps( {
|
|
145
|
+
className: 'wp-block-group__placeholder',
|
|
146
|
+
} );
|
|
147
|
+
const selectVariation = ( nextVariation = defaultVariation ) =>
|
|
148
|
+
onSelect( nextVariation );
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<div { ...blockProps }>
|
|
152
|
+
<Placeholder
|
|
153
|
+
instructions={ __( 'Group blocks together. Select a layout:' ) }
|
|
154
|
+
>
|
|
155
|
+
{ /*
|
|
156
|
+
* Taken from BlockVariationPicker component.
|
|
157
|
+
* Disable reason: The `list` ARIA role is redundant but
|
|
158
|
+
* Safari+VoiceOver won't announce the list otherwise.
|
|
159
|
+
*/
|
|
160
|
+
/* eslint-disable jsx-a11y/no-redundant-roles */ }
|
|
161
|
+
<ul
|
|
162
|
+
role="list"
|
|
163
|
+
className="wp-block-group-placeholder__variations"
|
|
164
|
+
aria-label={ __( 'Block variations' ) }
|
|
165
|
+
>
|
|
166
|
+
{ variations.map( ( variation ) => (
|
|
167
|
+
<li key={ variation.name }>
|
|
168
|
+
<Button
|
|
169
|
+
variant="tertiary"
|
|
170
|
+
icon={ getGroupPlaceholderIcons(
|
|
171
|
+
variation.name
|
|
172
|
+
) }
|
|
173
|
+
iconSize={ 44 }
|
|
174
|
+
onClick={ () => selectVariation( variation ) }
|
|
175
|
+
className="wp-block-group-placeholder__variation-button"
|
|
176
|
+
label={ `${ variation.title }: ${ variation.description }` }
|
|
177
|
+
/>
|
|
178
|
+
</li>
|
|
179
|
+
) ) }
|
|
180
|
+
</ul>
|
|
181
|
+
{ /* eslint-enable jsx-a11y/no-redundant-roles */ }
|
|
182
|
+
</Placeholder>
|
|
183
|
+
</div>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export default GroupPlaceHolder;
|
|
@@ -79,14 +79,14 @@ describe( 'Group block', () => {
|
|
|
79
79
|
const screen = await initializeEditor( {
|
|
80
80
|
initialHtml: NESTED_GROUP_BLOCK,
|
|
81
81
|
} );
|
|
82
|
-
const {
|
|
82
|
+
const { getByLabelText } = screen;
|
|
83
83
|
|
|
84
84
|
// Get block
|
|
85
85
|
let groupBlock = await getBlock( screen, 'Group' );
|
|
86
86
|
fireEvent.press( groupBlock );
|
|
87
87
|
|
|
88
88
|
// Get Ungroup button
|
|
89
|
-
let ungroupButton =
|
|
89
|
+
let ungroupButton = getByLabelText( /Ungroup/ );
|
|
90
90
|
fireEvent.press( ungroupButton );
|
|
91
91
|
|
|
92
92
|
// Press Group block again
|
|
@@ -94,7 +94,7 @@ describe( 'Group block', () => {
|
|
|
94
94
|
fireEvent.press( groupBlock );
|
|
95
95
|
|
|
96
96
|
// Ungroup last block
|
|
97
|
-
ungroupButton =
|
|
97
|
+
ungroupButton = getByLabelText( /Ungroup/ );
|
|
98
98
|
fireEvent.press( ungroupButton );
|
|
99
99
|
|
|
100
100
|
expect( getEditorHtml() ).toMatchSnapshot();
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { render } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { useShouldShowPlaceHolder } from '../placeholder';
|
|
10
|
+
|
|
11
|
+
describe( 'useShouldShowPlaceHolder', () => {
|
|
12
|
+
function renderTestComponent( ...props ) {
|
|
13
|
+
let returnVal = [];
|
|
14
|
+
function TestComponent() {
|
|
15
|
+
returnVal = returnVal.concat(
|
|
16
|
+
useShouldShowPlaceHolder( ...props )
|
|
17
|
+
);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
render( <TestComponent /> );
|
|
21
|
+
return returnVal;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
test.each( [
|
|
25
|
+
{
|
|
26
|
+
attributes: {},
|
|
27
|
+
usedLayoutType: undefined,
|
|
28
|
+
hasInnerBlocks: undefined,
|
|
29
|
+
expectedValue: true,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
attributes: { style: { something: 'something' } },
|
|
33
|
+
usedLayoutType: undefined,
|
|
34
|
+
hasInnerBlocks: undefined,
|
|
35
|
+
expectedValue: false,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
attributes: { backgroundColor: 'red' },
|
|
39
|
+
usedLayoutType: undefined,
|
|
40
|
+
hasInnerBlocks: true,
|
|
41
|
+
expectedValue: false,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
attributes: { fontSize: 'big' },
|
|
45
|
+
usedLayoutType: undefined,
|
|
46
|
+
hasInnerBlocks: true,
|
|
47
|
+
expectedValue: false,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
attributes: { textColor: 'yellow' },
|
|
51
|
+
usedLayoutType: undefined,
|
|
52
|
+
hasInnerBlocks: true,
|
|
53
|
+
expectedValue: false,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
attributes: undefined,
|
|
57
|
+
usedLayoutType: 'flex',
|
|
58
|
+
hasInnerBlocks: undefined,
|
|
59
|
+
expectedValue: false,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
attributes: undefined,
|
|
63
|
+
usedLayoutType: undefined,
|
|
64
|
+
hasInnerBlocks: true,
|
|
65
|
+
expectedValue: false,
|
|
66
|
+
},
|
|
67
|
+
] )(
|
|
68
|
+
'should return $expectedValue for `showPlaceholder` when hasInnerBlocks is $hasInnerBlocks, usedLayoutType is $usedLayoutType and attributes is $attributes',
|
|
69
|
+
( { hasInnerBlocks, usedLayoutType, attributes, expectedValue } ) => {
|
|
70
|
+
const [ showPlaceholder ] = renderTestComponent( {
|
|
71
|
+
hasInnerBlocks,
|
|
72
|
+
usedLayoutType,
|
|
73
|
+
attributes,
|
|
74
|
+
} );
|
|
75
|
+
expect( showPlaceholder ).toBe( expectedValue );
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
} );
|
package/src/group/variations.js
CHANGED
|
@@ -11,7 +11,7 @@ const variations = [
|
|
|
11
11
|
description: __( 'Gather blocks in a container.' ),
|
|
12
12
|
attributes: { layout: { type: 'constrained' } },
|
|
13
13
|
isDefault: true,
|
|
14
|
-
scope: [ 'inserter', 'transform' ],
|
|
14
|
+
scope: [ 'block', 'inserter', 'transform' ],
|
|
15
15
|
isActive: ( blockAttributes ) =>
|
|
16
16
|
! blockAttributes.layout ||
|
|
17
17
|
! blockAttributes.layout?.type ||
|
|
@@ -24,7 +24,7 @@ const variations = [
|
|
|
24
24
|
title: _x( 'Row', 'single horizontal line' ),
|
|
25
25
|
description: __( 'Arrange blocks horizontally.' ),
|
|
26
26
|
attributes: { layout: { type: 'flex', flexWrap: 'nowrap' } },
|
|
27
|
-
scope: [ 'inserter', 'transform' ],
|
|
27
|
+
scope: [ 'block', 'inserter', 'transform' ],
|
|
28
28
|
isActive: ( blockAttributes ) =>
|
|
29
29
|
blockAttributes.layout?.type === 'flex' &&
|
|
30
30
|
( ! blockAttributes.layout?.orientation ||
|
|
@@ -36,7 +36,7 @@ const variations = [
|
|
|
36
36
|
title: __( 'Stack' ),
|
|
37
37
|
description: __( 'Arrange blocks vertically.' ),
|
|
38
38
|
attributes: { layout: { type: 'flex', orientation: 'vertical' } },
|
|
39
|
-
scope: [ 'inserter', 'transform' ],
|
|
39
|
+
scope: [ 'block', 'inserter', 'transform' ],
|
|
40
40
|
isActive: ( blockAttributes ) =>
|
|
41
41
|
blockAttributes.layout?.type === 'flex' &&
|
|
42
42
|
blockAttributes.layout?.orientation === 'vertical',
|