@wordpress/block-library 9.40.2-next.v.202602241322.0 → 9.41.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/accordion/view.cjs +0 -34
- package/build/accordion/view.cjs.map +2 -2
- package/build/button/block.json +11 -3
- package/build/button/deprecated.cjs +246 -13
- package/build/button/deprecated.cjs.map +2 -2
- package/build/button/edit.cjs +45 -58
- package/build/button/edit.cjs.map +3 -3
- package/build/button/save.cjs +3 -7
- package/build/button/save.cjs.map +2 -2
- package/build/button/utils.cjs +59 -0
- package/build/button/utils.cjs.map +7 -0
- package/build/image/image.cjs +1 -1
- package/build/image/image.cjs.map +2 -2
- package/build/navigation/edit/index.cjs +4 -2
- package/build/navigation/edit/index.cjs.map +3 -3
- package/build/navigation/edit/leaf-more-menu.cjs +68 -6
- package/build/navigation/edit/leaf-more-menu.cjs.map +3 -3
- package/build/navigation/edit/menu-inspector-controls.cjs +20 -91
- package/build/navigation/edit/menu-inspector-controls.cjs.map +3 -3
- package/build/navigation/edit/navigation-link-ui.cjs +97 -0
- package/build/navigation/edit/navigation-link-ui.cjs.map +7 -0
- package/build/navigation/edit/navigation-list-view-header.cjs +86 -0
- package/build/navigation/edit/navigation-list-view-header.cjs.map +7 -0
- package/build/navigation/edit/navigation-menu-selector.cjs +4 -2
- package/build/navigation/edit/navigation-menu-selector.cjs.map +3 -3
- package/build/navigation/edit/placeholder/index.cjs +2 -2
- package/build/navigation/edit/placeholder/index.cjs.map +3 -3
- package/build/navigation-link/shared/controls.cjs +29 -52
- package/build/navigation-link/shared/controls.cjs.map +3 -3
- package/build/navigation-link/shared/use-link-preview.cjs +8 -9
- package/build/navigation-link/shared/use-link-preview.cjs.map +2 -2
- package/build/page-list-item/edit.cjs +6 -3
- package/build/page-list-item/edit.cjs.map +2 -2
- package/build/playlist/edit.cjs +43 -136
- package/build/playlist/edit.cjs.map +3 -3
- package/build/playlist/view.cjs +56 -38
- package/build/playlist/view.cjs.map +2 -2
- package/build/playlist-track/edit.cjs +0 -1
- package/build/playlist-track/edit.cjs.map +2 -2
- package/build/post-title/block.json +3 -0
- package/build/post-title/edit.cjs +2 -2
- package/build/post-title/edit.cjs.map +2 -2
- package/build/utils/waveform-player.cjs +68 -0
- package/build/utils/waveform-player.cjs.map +7 -0
- package/build/utils/waveform-utils.cjs +171 -0
- package/build/utils/waveform-utils.cjs.map +7 -0
- package/build-module/accordion/view.mjs +1 -35
- package/build-module/accordion/view.mjs.map +2 -2
- package/build-module/button/block.json +11 -3
- package/build-module/button/deprecated.mjs +246 -13
- package/build-module/button/deprecated.mjs.map +2 -2
- package/build-module/button/edit.mjs +47 -63
- package/build-module/button/edit.mjs.map +2 -2
- package/build-module/button/save.mjs +3 -7
- package/build-module/button/save.mjs.map +2 -2
- package/build-module/button/utils.mjs +33 -0
- package/build-module/button/utils.mjs.map +7 -0
- package/build-module/image/image.mjs +1 -1
- package/build-module/image/image.mjs.map +2 -2
- package/build-module/navigation/edit/index.mjs +4 -2
- package/build-module/navigation/edit/index.mjs.map +2 -2
- package/build-module/navigation/edit/leaf-more-menu.mjs +73 -7
- package/build-module/navigation/edit/leaf-more-menu.mjs.map +2 -2
- package/build-module/navigation/edit/menu-inspector-controls.mjs +21 -101
- package/build-module/navigation/edit/menu-inspector-controls.mjs.map +2 -2
- package/build-module/navigation/edit/navigation-link-ui.mjs +76 -0
- package/build-module/navigation/edit/navigation-link-ui.mjs.map +7 -0
- package/build-module/navigation/edit/navigation-list-view-header.mjs +58 -0
- package/build-module/navigation/edit/navigation-list-view-header.mjs.map +7 -0
- package/build-module/navigation/edit/navigation-menu-selector.mjs +5 -3
- package/build-module/navigation/edit/navigation-menu-selector.mjs.map +2 -2
- package/build-module/navigation/edit/placeholder/index.mjs +2 -2
- package/build-module/navigation/edit/placeholder/index.mjs.map +2 -2
- package/build-module/navigation-link/shared/controls.mjs +29 -53
- package/build-module/navigation-link/shared/controls.mjs.map +2 -2
- package/build-module/navigation-link/shared/use-link-preview.mjs +8 -9
- package/build-module/navigation-link/shared/use-link-preview.mjs.map +2 -2
- package/build-module/page-list-item/edit.mjs +6 -3
- package/build-module/page-list-item/edit.mjs.map +2 -2
- package/build-module/playlist/edit.mjs +41 -139
- package/build-module/playlist/edit.mjs.map +2 -2
- package/build-module/playlist/view.mjs +56 -38
- package/build-module/playlist/view.mjs.map +2 -2
- package/build-module/playlist-track/edit.mjs +0 -1
- package/build-module/playlist-track/edit.mjs.map +2 -2
- package/build-module/post-title/block.json +3 -0
- package/build-module/post-title/edit.mjs +2 -2
- package/build-module/post-title/edit.mjs.map +2 -2
- package/build-module/utils/waveform-player.mjs +43 -0
- package/build-module/utils/waveform-player.mjs.map +7 -0
- package/build-module/utils/waveform-utils.mjs +131 -0
- package/build-module/utils/waveform-utils.mjs.map +7 -0
- package/build-style/button/style-rtl.css +6 -0
- package/build-style/button/style.css +6 -0
- package/build-style/editor-rtl.css +13 -3
- package/build-style/editor.css +13 -3
- package/build-style/navigation-link/editor-rtl.css +10 -0
- package/build-style/navigation-link/editor.css +10 -0
- package/build-style/playlist/editor-rtl.css +3 -3
- package/build-style/playlist/editor.css +3 -3
- package/build-style/playlist/style-rtl.css +351 -17
- package/build-style/playlist/style.css +351 -17
- package/build-style/style-rtl.css +357 -17
- package/build-style/style.css +357 -17
- package/package.json +39 -38
- package/src/accordion/view.js +1 -44
- package/src/accordion-item/index.php +0 -1
- package/src/button/block.json +11 -3
- package/src/button/deprecated.js +254 -16
- package/src/button/edit.js +50 -61
- package/src/button/index.php +68 -0
- package/src/button/save.js +2 -8
- package/src/button/style.scss +49 -7
- package/src/button/test/utils.js +84 -0
- package/src/button/utils.js +42 -0
- package/src/cover/index.php +4 -4
- package/src/image/image.js +14 -15
- package/src/image/index.php +3 -1
- package/src/navigation/edit/index.js +4 -2
- package/src/navigation/edit/leaf-more-menu.js +86 -11
- package/src/navigation/edit/menu-inspector-controls.js +23 -142
- package/src/navigation/edit/navigation-link-ui.js +115 -0
- package/src/navigation/edit/navigation-list-view-header.js +62 -0
- package/src/navigation/edit/navigation-menu-selector.js +5 -3
- package/src/navigation/edit/placeholder/index.js +3 -2
- package/src/navigation/edit/test/navigation-menu-selector.js +23 -20
- package/src/navigation-link/editor.scss +18 -0
- package/src/navigation-link/shared/controls.js +35 -62
- package/src/navigation-link/shared/test/controls.js +5 -5
- package/src/navigation-link/shared/test/use-link-preview.test.js +19 -1
- package/src/navigation-link/shared/use-link-preview.js +14 -15
- package/src/page-list/index.php +1 -1
- package/src/page-list-item/edit.js +8 -7
- package/src/playlist/edit.js +60 -154
- package/src/playlist/editor.scss +3 -3
- package/src/playlist/index.php +15 -40
- package/src/playlist/style.scss +34 -27
- package/src/playlist/test/edit.js +137 -0
- package/src/playlist/view.js +97 -40
- package/src/playlist-track/edit.js +0 -1
- package/src/post-title/block.json +3 -0
- package/src/post-title/edit.js +4 -2
- package/src/query-title/index.php +1 -1
- package/src/search/index.php +1 -1
- package/src/utils/test/waveform-utils.js +328 -0
- package/src/utils/waveform-player.js +77 -0
- package/src/utils/waveform-utils.js +232 -0
- package/build/navigation/use-navigation-entities.cjs +0 -67
- package/build/navigation/use-navigation-entities.cjs.map +0 -7
- package/build-module/navigation/use-navigation-entities.mjs +0 -46
- package/build-module/navigation/use-navigation-entities.mjs.map +0 -7
- package/src/navigation/use-navigation-entities.js +0 -72
package/src/button/style.scss
CHANGED
|
@@ -55,16 +55,41 @@ $blocks-block__margin: 0.5em;
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
&[class*="wp-block-button__width"] {
|
|
59
|
+
width:
|
|
60
|
+
calc(var(--wp--block-button--width) * 1% -
|
|
61
|
+
(
|
|
62
|
+
var(--wp--style--block-gap, #{$blocks-block__margin}) *
|
|
63
|
+
( 1 - var(--wp--block-button--width) / 100 )
|
|
64
|
+
));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Legacy width classes for backwards compatibility.
|
|
58
68
|
&.wp-block-button__width-25 {
|
|
59
|
-
width:
|
|
69
|
+
width:
|
|
70
|
+
calc(25% -
|
|
71
|
+
(
|
|
72
|
+
var(--wp--style--block-gap, #{$blocks-block__margin}) *
|
|
73
|
+
0.75
|
|
74
|
+
));
|
|
60
75
|
}
|
|
61
76
|
|
|
62
77
|
&.wp-block-button__width-50 {
|
|
63
|
-
width:
|
|
78
|
+
width:
|
|
79
|
+
calc(50% -
|
|
80
|
+
(
|
|
81
|
+
var(--wp--style--block-gap, #{$blocks-block__margin}) *
|
|
82
|
+
0.5
|
|
83
|
+
));
|
|
64
84
|
}
|
|
65
85
|
|
|
66
86
|
&.wp-block-button__width-75 {
|
|
67
|
-
width:
|
|
87
|
+
width:
|
|
88
|
+
calc(75% -
|
|
89
|
+
(
|
|
90
|
+
var(--wp--style--block-gap, #{$blocks-block__margin}) *
|
|
91
|
+
0.25
|
|
92
|
+
));
|
|
68
93
|
}
|
|
69
94
|
|
|
70
95
|
&.wp-block-button__width-100 {
|
|
@@ -75,6 +100,11 @@ $blocks-block__margin: 0.5em;
|
|
|
75
100
|
|
|
76
101
|
// For vertical buttons, gap is not factored into width calculations.
|
|
77
102
|
.wp-block-buttons.is-vertical > .wp-block-button {
|
|
103
|
+
&[class*="wp-block-button__width"] {
|
|
104
|
+
width: calc(var(--wp--block-button--width) * 1%);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Legacy width classes for backwards compatibility.
|
|
78
108
|
&.wp-block-button__width-25 {
|
|
79
109
|
width: 25%;
|
|
80
110
|
}
|
|
@@ -110,13 +140,25 @@ $blocks-block__margin: 0.5em;
|
|
|
110
140
|
padding: 0.667em 1.333em;
|
|
111
141
|
}
|
|
112
142
|
|
|
113
|
-
:where(
|
|
114
|
-
|
|
143
|
+
:where(
|
|
144
|
+
.wp-block-button.is-style-outline
|
|
145
|
+
> .wp-block-button__link:not(.has-text-color)
|
|
146
|
+
),
|
|
147
|
+
:where(
|
|
148
|
+
.wp-block-button
|
|
149
|
+
.wp-block-button__link.is-style-outline:not(.has-text-color)
|
|
150
|
+
) {
|
|
115
151
|
color: currentColor;
|
|
116
152
|
}
|
|
117
153
|
|
|
118
|
-
:where(
|
|
119
|
-
|
|
154
|
+
:where(
|
|
155
|
+
.wp-block-button.is-style-outline
|
|
156
|
+
> .wp-block-button__link:not(.has-background)
|
|
157
|
+
),
|
|
158
|
+
:where(
|
|
159
|
+
.wp-block-button
|
|
160
|
+
.wp-block-button__link.is-style-outline:not(.has-background)
|
|
161
|
+
) {
|
|
120
162
|
background-color: transparent;
|
|
121
163
|
// background-image is required to overwrite a gradient background
|
|
122
164
|
background-image: none;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { getWidthClasses, isPercentageWidth } from '../utils';
|
|
5
|
+
|
|
6
|
+
describe( 'isPercentageWidth', () => {
|
|
7
|
+
it( 'should return true for percentage values', () => {
|
|
8
|
+
expect( isPercentageWidth( '50%' ) ).toBe( true );
|
|
9
|
+
expect( isPercentageWidth( '100%' ) ).toBe( true );
|
|
10
|
+
expect( isPercentageWidth( '33.5%' ) ).toBe( true );
|
|
11
|
+
} );
|
|
12
|
+
|
|
13
|
+
it( 'should return false for non-percentage values', () => {
|
|
14
|
+
expect( isPercentageWidth( '200px' ) ).toBe( false );
|
|
15
|
+
expect( isPercentageWidth( '10em' ) ).toBe( false );
|
|
16
|
+
expect( isPercentageWidth( undefined ) ).toBe( false );
|
|
17
|
+
expect( isPercentageWidth( null ) ).toBe( false );
|
|
18
|
+
} );
|
|
19
|
+
|
|
20
|
+
it( 'should return false for preset strings', () => {
|
|
21
|
+
expect( isPercentageWidth( 'var:preset|dimension|custom-width' ) ).toBe(
|
|
22
|
+
false
|
|
23
|
+
);
|
|
24
|
+
} );
|
|
25
|
+
} );
|
|
26
|
+
|
|
27
|
+
describe( 'getWidthClasses', () => {
|
|
28
|
+
it( 'should return empty object when no width is provided', () => {
|
|
29
|
+
expect( getWidthClasses( undefined ) ).toEqual( {} );
|
|
30
|
+
expect( getWidthClasses( '' ) ).toEqual( {} );
|
|
31
|
+
expect( getWidthClasses( null ) ).toEqual( {} );
|
|
32
|
+
} );
|
|
33
|
+
|
|
34
|
+
it( 'should return percentage classes for standard percentage widths', () => {
|
|
35
|
+
expect( getWidthClasses( '25%' ) ).toEqual( {
|
|
36
|
+
'has-custom-width': true,
|
|
37
|
+
'wp-block-button__width': true,
|
|
38
|
+
'wp-block-button__width-25': true,
|
|
39
|
+
} );
|
|
40
|
+
|
|
41
|
+
expect( getWidthClasses( '50%' ) ).toEqual( {
|
|
42
|
+
'has-custom-width': true,
|
|
43
|
+
'wp-block-button__width': true,
|
|
44
|
+
'wp-block-button__width-50': true,
|
|
45
|
+
} );
|
|
46
|
+
|
|
47
|
+
expect( getWidthClasses( '75%' ) ).toEqual( {
|
|
48
|
+
'has-custom-width': true,
|
|
49
|
+
'wp-block-button__width': true,
|
|
50
|
+
'wp-block-button__width-75': true,
|
|
51
|
+
} );
|
|
52
|
+
|
|
53
|
+
expect( getWidthClasses( '100%' ) ).toEqual( {
|
|
54
|
+
'has-custom-width': true,
|
|
55
|
+
'wp-block-button__width': true,
|
|
56
|
+
'wp-block-button__width-100': true,
|
|
57
|
+
} );
|
|
58
|
+
} );
|
|
59
|
+
|
|
60
|
+
it( 'should return generic percentage classes for non-standard percentage widths', () => {
|
|
61
|
+
expect( getWidthClasses( '33%' ) ).toEqual( {
|
|
62
|
+
'has-custom-width': true,
|
|
63
|
+
'wp-block-button__width': true,
|
|
64
|
+
} );
|
|
65
|
+
} );
|
|
66
|
+
|
|
67
|
+
it( 'should return only has-custom-width for non-percentage values', () => {
|
|
68
|
+
expect( getWidthClasses( '200px' ) ).toEqual( {
|
|
69
|
+
'has-custom-width': true,
|
|
70
|
+
} );
|
|
71
|
+
|
|
72
|
+
expect( getWidthClasses( '10em' ) ).toEqual( {
|
|
73
|
+
'has-custom-width': true,
|
|
74
|
+
} );
|
|
75
|
+
} );
|
|
76
|
+
|
|
77
|
+
it( 'should return only has-custom-width for resolved non-percentage preset values', () => {
|
|
78
|
+
// When a preset resolves to a non-percentage value (e.g., 200px),
|
|
79
|
+
// the resolved value is passed to getWidthClasses, not the preset string.
|
|
80
|
+
expect( getWidthClasses( '300px' ) ).toEqual( {
|
|
81
|
+
'has-custom-width': true,
|
|
82
|
+
} );
|
|
83
|
+
} );
|
|
84
|
+
} );
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns whether the given width value is a percentage.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} width - The width value.
|
|
5
|
+
* @return {boolean} True if the width is a percentage value.
|
|
6
|
+
*/
|
|
7
|
+
export function isPercentageWidth( width ) {
|
|
8
|
+
return typeof width === 'string' && width.endsWith( '%' );
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Returns the width classes for the button based on the width attribute.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} width - The width value (e.g., '25%', '50%', '75%', '100%', or custom value).
|
|
15
|
+
* @return {Object} Object with width-related class names as keys and true as values.
|
|
16
|
+
*/
|
|
17
|
+
export function getWidthClasses( width ) {
|
|
18
|
+
if ( ! width ) {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if ( isPercentageWidth( width ) ) {
|
|
23
|
+
const legacyWidthClasses = {
|
|
24
|
+
'25%': 'wp-block-button__width-25',
|
|
25
|
+
'50%': 'wp-block-button__width-50',
|
|
26
|
+
'75%': 'wp-block-button__width-75',
|
|
27
|
+
'100%': 'wp-block-button__width-100',
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
'has-custom-width': true,
|
|
31
|
+
'wp-block-button__width': true,
|
|
32
|
+
// Maintain legacy class for backwards compatibility.
|
|
33
|
+
...( legacyWidthClasses[ width ] && {
|
|
34
|
+
[ legacyWidthClasses[ width ] ]: true,
|
|
35
|
+
} ),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
'has-custom-width': true,
|
|
41
|
+
};
|
|
42
|
+
}
|
package/src/cover/index.php
CHANGED
|
@@ -39,13 +39,13 @@ function render_block_core_cover( $attributes, $content ) {
|
|
|
39
39
|
$lower_src = strtolower( $iframe_src );
|
|
40
40
|
$provider = null;
|
|
41
41
|
|
|
42
|
-
if (
|
|
42
|
+
if ( str_contains( $lower_src, 'youtube.com' ) || str_contains( $lower_src, 'youtu.be' ) ) {
|
|
43
43
|
$provider = 'youtube';
|
|
44
|
-
} elseif (
|
|
44
|
+
} elseif ( str_contains( $lower_src, 'vimeo.com' ) ) {
|
|
45
45
|
$provider = 'vimeo';
|
|
46
|
-
} elseif (
|
|
46
|
+
} elseif ( str_contains( $lower_src, 'videopress.com' ) ) {
|
|
47
47
|
$provider = 'videopress';
|
|
48
|
-
} elseif (
|
|
48
|
+
} elseif ( str_contains( $lower_src, 'wordpress.tv' ) ) {
|
|
49
49
|
$provider = 'wordpress-tv';
|
|
50
50
|
}
|
|
51
51
|
|
package/src/image/image.js
CHANGED
|
@@ -1241,21 +1241,20 @@ export default function Image( {
|
|
|
1241
1241
|
} );
|
|
1242
1242
|
};
|
|
1243
1243
|
|
|
1244
|
-
const featuredImageControl =
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
selectedClientIds
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
);
|
|
1244
|
+
const featuredImageControl =
|
|
1245
|
+
! isDescendentOfQueryLoop && postId && id ? (
|
|
1246
|
+
<BlockSettingsMenuControls>
|
|
1247
|
+
{ ( { canEdit, selectedClientIds } ) =>
|
|
1248
|
+
canEdit &&
|
|
1249
|
+
selectedClientIds.length === 1 &&
|
|
1250
|
+
clientId === selectedClientIds[ 0 ] && (
|
|
1251
|
+
<MenuItem onClick={ setPostFeatureImage }>
|
|
1252
|
+
{ __( 'Set as featured image' ) }
|
|
1253
|
+
</MenuItem>
|
|
1254
|
+
)
|
|
1255
|
+
}
|
|
1256
|
+
</BlockSettingsMenuControls>
|
|
1257
|
+
) : null;
|
|
1259
1258
|
|
|
1260
1259
|
return (
|
|
1261
1260
|
<>
|
package/src/image/index.php
CHANGED
|
@@ -218,7 +218,9 @@ function block_core_image_render_lightbox( $block_content, $block, $block_instan
|
|
|
218
218
|
if ( isset( $block['attrs']['id'] ) ) {
|
|
219
219
|
$img_uploaded_src = wp_get_attachment_url( $block['attrs']['id'] );
|
|
220
220
|
$img_metadata = wp_get_attachment_metadata( $block['attrs']['id'] );
|
|
221
|
-
$
|
|
221
|
+
$has_dimensions = ( $img_metadata['width'] ?? '' ) && ( $img_metadata['height'] ?? '' );
|
|
222
|
+
$srcset_size = $has_dimensions ? array( $img_metadata['width'], $img_metadata['height'] ) : 'large';
|
|
223
|
+
$img_srcset = wp_get_attachment_image_srcset( $block['attrs']['id'], $srcset_size );
|
|
222
224
|
$img_width = $img_metadata['width'] ?? 'none';
|
|
223
225
|
$img_height = $img_metadata['height'] ?? 'none';
|
|
224
226
|
}
|
|
@@ -55,7 +55,6 @@ import { useInstanceId } from '@wordpress/compose';
|
|
|
55
55
|
* Internal dependencies
|
|
56
56
|
*/
|
|
57
57
|
import useNavigationMenu from '../use-navigation-menu';
|
|
58
|
-
import useNavigationEntities from '../use-navigation-entities';
|
|
59
58
|
import Placeholder from './placeholder';
|
|
60
59
|
import ResponsiveWrapper from './responsive-wrapper';
|
|
61
60
|
import NavigationInnerBlocks from './inner-blocks';
|
|
@@ -339,7 +338,10 @@ function Navigation( {
|
|
|
339
338
|
|
|
340
339
|
// Preload classic menus, so that they don't suddenly pop-in when viewing
|
|
341
340
|
// the Select Menu dropdown.
|
|
342
|
-
const {
|
|
341
|
+
const { records: classicMenus } = useEntityRecords( 'root', 'menu', {
|
|
342
|
+
per_page: -1,
|
|
343
|
+
context: 'view',
|
|
344
|
+
} );
|
|
343
345
|
|
|
344
346
|
const [ showNavigationMenuStatusNotice, hideNavigationMenuStatusNotice ] =
|
|
345
347
|
useNavigationNotice( {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
createBlock,
|
|
6
|
+
hasBlockSupport,
|
|
7
|
+
store as blocksStore,
|
|
8
|
+
} from '@wordpress/blocks';
|
|
5
9
|
import {
|
|
6
10
|
addSubmenu,
|
|
7
11
|
chevronUp,
|
|
@@ -103,8 +107,14 @@ export default function LeafMoreMenu( props ) {
|
|
|
103
107
|
const { block } = props;
|
|
104
108
|
const { clientId } = block;
|
|
105
109
|
|
|
106
|
-
const {
|
|
107
|
-
|
|
110
|
+
const {
|
|
111
|
+
moveBlocksDown,
|
|
112
|
+
moveBlocksUp,
|
|
113
|
+
removeBlocks,
|
|
114
|
+
duplicateBlocks,
|
|
115
|
+
insertBeforeBlock,
|
|
116
|
+
insertAfterBlock,
|
|
117
|
+
} = useDispatch( blockEditorStore );
|
|
108
118
|
|
|
109
119
|
const removeLabel = sprintf(
|
|
110
120
|
/* translators: %s: block name */
|
|
@@ -112,14 +122,45 @@ export default function LeafMoreMenu( props ) {
|
|
|
112
122
|
BlockTitle( { clientId, maximumLength: 25 } )
|
|
113
123
|
);
|
|
114
124
|
|
|
115
|
-
const rootClientId =
|
|
116
|
-
(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
125
|
+
const { rootClientId, canDuplicate, canInsertBlock, isFirst, isLast } =
|
|
126
|
+
useSelect(
|
|
127
|
+
( select ) => {
|
|
128
|
+
const {
|
|
129
|
+
getBlockRootClientId,
|
|
130
|
+
canInsertBlockType,
|
|
131
|
+
getDirectInsertBlock,
|
|
132
|
+
getBlockIndex,
|
|
133
|
+
getBlockCount,
|
|
134
|
+
} = select( blockEditorStore );
|
|
135
|
+
const { getDefaultBlockName } = select( blocksStore );
|
|
136
|
+
|
|
137
|
+
const _rootClientId = getBlockRootClientId( clientId );
|
|
138
|
+
const canInsertDefaultBlock = canInsertBlockType(
|
|
139
|
+
getDefaultBlockName(),
|
|
140
|
+
_rootClientId
|
|
141
|
+
);
|
|
142
|
+
const directInsertBlock = _rootClientId
|
|
143
|
+
? getDirectInsertBlock( _rootClientId )
|
|
144
|
+
: null;
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
rootClientId: _rootClientId,
|
|
148
|
+
canDuplicate:
|
|
149
|
+
!! block &&
|
|
150
|
+
hasBlockSupport( block.name, 'multiple', true ) &&
|
|
151
|
+
canInsertBlockType( block.name, _rootClientId ),
|
|
152
|
+
canInsertBlock:
|
|
153
|
+
( canInsertDefaultBlock || !! directInsertBlock ) &&
|
|
154
|
+
!! block &&
|
|
155
|
+
canInsertBlockType( block.name, _rootClientId ),
|
|
156
|
+
isFirst: getBlockIndex( clientId ) === 0,
|
|
157
|
+
isLast:
|
|
158
|
+
getBlockIndex( clientId ) ===
|
|
159
|
+
getBlockCount( _rootClientId ) - 1,
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
[ clientId, block ]
|
|
163
|
+
);
|
|
123
164
|
|
|
124
165
|
return (
|
|
125
166
|
<DropdownMenu
|
|
@@ -135,6 +176,8 @@ export default function LeafMoreMenu( props ) {
|
|
|
135
176
|
<MenuGroup>
|
|
136
177
|
<MenuItem
|
|
137
178
|
icon={ chevronUp }
|
|
179
|
+
disabled={ isFirst }
|
|
180
|
+
accessibleWhenDisabled
|
|
138
181
|
onClick={ () => {
|
|
139
182
|
moveBlocksUp( [ clientId ], rootClientId );
|
|
140
183
|
onClose();
|
|
@@ -144,6 +187,8 @@ export default function LeafMoreMenu( props ) {
|
|
|
144
187
|
</MenuItem>
|
|
145
188
|
<MenuItem
|
|
146
189
|
icon={ chevronDown }
|
|
190
|
+
disabled={ isLast }
|
|
191
|
+
accessibleWhenDisabled
|
|
147
192
|
onClick={ () => {
|
|
148
193
|
moveBlocksDown( [ clientId ], rootClientId );
|
|
149
194
|
onClose();
|
|
@@ -158,6 +203,36 @@ export default function LeafMoreMenu( props ) {
|
|
|
158
203
|
expand={ props.expand }
|
|
159
204
|
setInsertedBlock={ props.setInsertedBlock }
|
|
160
205
|
/>
|
|
206
|
+
{ canDuplicate && (
|
|
207
|
+
<MenuItem
|
|
208
|
+
onClick={ () => {
|
|
209
|
+
duplicateBlocks( [ clientId ] );
|
|
210
|
+
onClose();
|
|
211
|
+
} }
|
|
212
|
+
>
|
|
213
|
+
{ __( 'Duplicate' ) }
|
|
214
|
+
</MenuItem>
|
|
215
|
+
) }
|
|
216
|
+
{ canInsertBlock && (
|
|
217
|
+
<>
|
|
218
|
+
<MenuItem
|
|
219
|
+
onClick={ () => {
|
|
220
|
+
insertBeforeBlock( clientId );
|
|
221
|
+
onClose();
|
|
222
|
+
} }
|
|
223
|
+
>
|
|
224
|
+
{ __( 'Add before' ) }
|
|
225
|
+
</MenuItem>
|
|
226
|
+
<MenuItem
|
|
227
|
+
onClick={ () => {
|
|
228
|
+
insertAfterBlock( clientId );
|
|
229
|
+
onClose();
|
|
230
|
+
} }
|
|
231
|
+
>
|
|
232
|
+
{ __( 'Add after' ) }
|
|
233
|
+
</MenuItem>
|
|
234
|
+
</>
|
|
235
|
+
) }
|
|
161
236
|
</MenuGroup>
|
|
162
237
|
<MenuGroup>
|
|
163
238
|
<MenuItem
|
|
@@ -6,12 +6,7 @@ import {
|
|
|
6
6
|
InspectorControls,
|
|
7
7
|
store as blockEditorStore,
|
|
8
8
|
} from '@wordpress/block-editor';
|
|
9
|
-
import {
|
|
10
|
-
PanelBody,
|
|
11
|
-
Spinner,
|
|
12
|
-
__experimentalHStack as HStack,
|
|
13
|
-
__experimentalHeading as Heading,
|
|
14
|
-
} from '@wordpress/components';
|
|
9
|
+
import { PanelBody, Spinner } from '@wordpress/components';
|
|
15
10
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
16
11
|
import { __, sprintf } from '@wordpress/i18n';
|
|
17
12
|
import { useContext } from '@wordpress/element';
|
|
@@ -24,121 +19,18 @@ import { unlock } from '../../lock-unlock';
|
|
|
24
19
|
import DeletedNavigationWarning from './deleted-navigation-warning';
|
|
25
20
|
import useNavigationMenu from '../use-navigation-menu';
|
|
26
21
|
import LeafMoreMenu from './leaf-more-menu';
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
updateAttributes,
|
|
30
|
-
useEntityBinding,
|
|
31
|
-
} from '../../navigation-link/shared';
|
|
22
|
+
import { NavigationLinkUI } from './navigation-link-ui';
|
|
23
|
+
import NavigationListViewHeader from './navigation-list-view-header';
|
|
32
24
|
|
|
33
25
|
const actionLabel =
|
|
34
26
|
/* translators: %s: The name of a menu. */ __( "Switch to '%s'" );
|
|
35
|
-
const BLOCKS_WITH_LINK_UI_SUPPORT = [
|
|
36
|
-
'core/navigation-link',
|
|
37
|
-
'core/navigation-submenu',
|
|
38
|
-
];
|
|
39
27
|
const {
|
|
40
28
|
PrivateListView,
|
|
41
|
-
useBlockDisplayTitle,
|
|
42
29
|
PrivateBlockContext,
|
|
43
30
|
useListViewPanelState,
|
|
31
|
+
useBlockDisplayTitle,
|
|
44
32
|
} = unlock( blockEditorPrivateApis );
|
|
45
33
|
|
|
46
|
-
function AdditionalBlockContent( { block, insertedBlock, setInsertedBlock } ) {
|
|
47
|
-
const { updateBlockAttributes, removeBlock } =
|
|
48
|
-
useDispatch( blockEditorStore );
|
|
49
|
-
|
|
50
|
-
const supportsLinkControls = BLOCKS_WITH_LINK_UI_SUPPORT?.includes(
|
|
51
|
-
insertedBlock?.name
|
|
52
|
-
);
|
|
53
|
-
const blockWasJustInserted = insertedBlock?.clientId === block.clientId;
|
|
54
|
-
const showLinkControls = supportsLinkControls && blockWasJustInserted;
|
|
55
|
-
|
|
56
|
-
// Get binding utilities for the inserted block
|
|
57
|
-
const { createBinding, clearBinding } = useEntityBinding( {
|
|
58
|
-
clientId: insertedBlock?.clientId,
|
|
59
|
-
attributes: insertedBlock?.attributes || {},
|
|
60
|
-
} );
|
|
61
|
-
|
|
62
|
-
if ( ! showLinkControls ) {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Cleanup function for auto-inserted Navigation Link blocks.
|
|
68
|
-
*
|
|
69
|
-
* Removes the block if it has no URL and clears the inserted block state.
|
|
70
|
-
* This ensures consistent cleanup behavior across different contexts.
|
|
71
|
-
*/
|
|
72
|
-
const cleanupInsertedBlock = () => {
|
|
73
|
-
// Prevent automatic block selection when removing blocks in list view context
|
|
74
|
-
// This avoids focus stealing that would close the list view and switch to canvas
|
|
75
|
-
const shouldAutoSelectBlock = false;
|
|
76
|
-
|
|
77
|
-
// Follows the exact same pattern as Navigation Link block's onClose handler
|
|
78
|
-
// If there is no URL then remove the auto-inserted block to avoid empty blocks
|
|
79
|
-
if ( ! insertedBlock?.attributes?.url && insertedBlock?.clientId ) {
|
|
80
|
-
// Remove the block entirely to avoid poor UX
|
|
81
|
-
// This matches the Navigation Link block's behavior
|
|
82
|
-
removeBlock( insertedBlock.clientId, shouldAutoSelectBlock );
|
|
83
|
-
}
|
|
84
|
-
setInsertedBlock( null );
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const setInsertedBlockAttributes =
|
|
88
|
-
( _insertedBlockClientId ) => ( _updatedAttributes ) => {
|
|
89
|
-
if ( ! _insertedBlockClientId ) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
updateBlockAttributes( _insertedBlockClientId, _updatedAttributes );
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
// Wrapper function to clean up original block when a new block is selected
|
|
96
|
-
const handleSetInsertedBlock = ( newBlock ) => {
|
|
97
|
-
// Prevent automatic block selection when removing blocks in list view context
|
|
98
|
-
// This avoids focus stealing that would close the list view and switch to canvas
|
|
99
|
-
const shouldAutoSelectBlock = false;
|
|
100
|
-
|
|
101
|
-
// If we have an existing inserted block and a new block is being set,
|
|
102
|
-
// remove the original block to avoid duplicates
|
|
103
|
-
if ( insertedBlock?.clientId && newBlock ) {
|
|
104
|
-
removeBlock( insertedBlock.clientId, shouldAutoSelectBlock );
|
|
105
|
-
}
|
|
106
|
-
setInsertedBlock( newBlock );
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
return (
|
|
110
|
-
<LinkUI
|
|
111
|
-
clientId={ insertedBlock?.clientId }
|
|
112
|
-
link={ insertedBlock?.attributes }
|
|
113
|
-
onBlockInsert={ handleSetInsertedBlock }
|
|
114
|
-
onClose={ () => {
|
|
115
|
-
// Use cleanup function
|
|
116
|
-
cleanupInsertedBlock();
|
|
117
|
-
} }
|
|
118
|
-
onChange={ ( updatedValue ) => {
|
|
119
|
-
// updateAttributes determines the final state and returns metadata
|
|
120
|
-
const { isEntityLink, attributes: updatedAttributes } =
|
|
121
|
-
updateAttributes(
|
|
122
|
-
updatedValue,
|
|
123
|
-
setInsertedBlockAttributes( insertedBlock?.clientId ),
|
|
124
|
-
insertedBlock?.attributes
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
// Handle URL binding based on the final computed state
|
|
128
|
-
// Only create bindings for entity links (posts, pages, taxonomies)
|
|
129
|
-
// Never create bindings for custom links (manual URLs)
|
|
130
|
-
if ( isEntityLink ) {
|
|
131
|
-
createBinding( updatedAttributes );
|
|
132
|
-
} else {
|
|
133
|
-
clearBinding();
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
setInsertedBlock( null );
|
|
137
|
-
} }
|
|
138
|
-
/>
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
34
|
const MainContent = ( {
|
|
143
35
|
clientId,
|
|
144
36
|
currentMenuId,
|
|
@@ -194,7 +86,7 @@ const MainContent = ( {
|
|
|
194
86
|
description={ description }
|
|
195
87
|
showAppender
|
|
196
88
|
blockSettingsMenu={ LeafMoreMenu }
|
|
197
|
-
additionalBlockContent={
|
|
89
|
+
additionalBlockContent={ NavigationLinkUI }
|
|
198
90
|
onSelect={ openListViewContentPanel }
|
|
199
91
|
/>
|
|
200
92
|
</div>
|
|
@@ -232,34 +124,23 @@ const MenuInspectorControls = ( props ) => {
|
|
|
232
124
|
return (
|
|
233
125
|
<InspectorControls group="list">
|
|
234
126
|
<PanelBody title={ null }>
|
|
235
|
-
<
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
{
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
createNavigationMenuIsError={
|
|
254
|
-
createNavigationMenuIsError
|
|
255
|
-
}
|
|
256
|
-
actionLabel={ actionLabel }
|
|
257
|
-
isManageMenusButtonDisabled={
|
|
258
|
-
isManageMenusButtonDisabled
|
|
259
|
-
}
|
|
260
|
-
/>
|
|
261
|
-
) }
|
|
262
|
-
</HStack>
|
|
127
|
+
<NavigationListViewHeader
|
|
128
|
+
clientId={ clientId }
|
|
129
|
+
blockEditingMode={ blockEditingMode }
|
|
130
|
+
currentMenuId={ currentMenuId }
|
|
131
|
+
onSelectClassicMenu={ onSelectClassicMenu }
|
|
132
|
+
onSelectNavigationMenu={ onSelectNavigationMenu }
|
|
133
|
+
onCreateNew={ onCreateNew }
|
|
134
|
+
createNavigationMenuIsSuccess={
|
|
135
|
+
createNavigationMenuIsSuccess
|
|
136
|
+
}
|
|
137
|
+
createNavigationMenuIsError={
|
|
138
|
+
createNavigationMenuIsError
|
|
139
|
+
}
|
|
140
|
+
isManageMenusButtonDisabled={
|
|
141
|
+
isManageMenusButtonDisabled
|
|
142
|
+
}
|
|
143
|
+
/>
|
|
263
144
|
<MainContent
|
|
264
145
|
{ ...props }
|
|
265
146
|
expandRevision={ expandRevision }
|
|
@@ -273,7 +154,7 @@ const MenuInspectorControls = ( props ) => {
|
|
|
273
154
|
return (
|
|
274
155
|
<InspectorControls group="list">
|
|
275
156
|
<PanelBody
|
|
276
|
-
title={
|
|
157
|
+
title={ blockTitle }
|
|
277
158
|
opened={ isOpened }
|
|
278
159
|
onToggle={ handleToggle }
|
|
279
160
|
>
|