@wordpress/block-library 9.41.0 → 9.41.1-next.v.202603161435.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/build/cover/edit/cover-placeholder.cjs +7 -0
- package/build/cover/edit/cover-placeholder.cjs.map +2 -2
- package/build/html/block.json +2 -1
- package/build/html/modal.cjs +142 -147
- package/build/html/modal.cjs.map +3 -3
- package/build/icon/block.json +3 -12
- package/build/image/edit.cjs +7 -0
- package/build/image/edit.cjs.map +2 -2
- package/build/image/image.cjs +5 -9
- package/build/image/image.cjs.map +2 -2
- package/build/media-text/media-container.cjs +6 -0
- package/build/media-text/media-container.cjs.map +2 -2
- package/build/navigation/edit/index.cjs +21 -14
- package/build/navigation/edit/index.cjs.map +3 -3
- package/build/navigation/view.cjs +9 -2
- package/build/navigation/view.cjs.map +2 -2
- package/build/navigation-link/block.json +5 -0
- package/build/navigation-link/shared/use-link-preview.cjs +29 -0
- package/build/navigation-link/shared/use-link-preview.cjs.map +2 -2
- package/build/nextpage/block.json +0 -1
- package/build/paragraph/edit.cjs +1 -1
- package/build/paragraph/edit.cjs.map +1 -1
- package/build/playlist/edit.cjs +3 -23
- package/build/playlist/edit.cjs.map +3 -3
- package/build/playlist/utils.cjs +48 -0
- package/build/playlist/utils.cjs.map +7 -0
- package/build/playlist-track/block.json +0 -0
- package/build/post-excerpt/block.json +1 -3
- package/build/post-excerpt/deprecated.cjs +112 -0
- package/build/post-excerpt/deprecated.cjs.map +7 -0
- package/build/post-excerpt/edit.cjs +11 -30
- package/build/post-excerpt/edit.cjs.map +3 -3
- package/build/post-excerpt/index.cjs +3 -1
- package/build/post-excerpt/index.cjs.map +3 -3
- package/build/private-apis.cjs +3 -1
- package/build/private-apis.cjs.map +2 -2
- package/build/shortcode/block.json +2 -1
- package/build/site-logo/edit.cjs +1 -3
- package/build/site-logo/edit.cjs.map +2 -2
- package/build/tab/add-tab-toolbar-control.cjs +22 -5
- package/build/tab/add-tab-toolbar-control.cjs.map +2 -2
- package/build/tab/remove-tab-toolbar-control.cjs +19 -1
- package/build/tab/remove-tab-toolbar-control.cjs.map +2 -2
- package/build/tabs/edit.cjs +85 -7
- package/build/tabs/edit.cjs.map +2 -2
- package/build/tabs/index.cjs +12 -2
- package/build/tabs/index.cjs.map +2 -2
- package/build/tabs-menu/block.json +1 -6
- package/build/tabs-menu/edit.cjs +11 -151
- package/build/tabs-menu/edit.cjs.map +3 -3
- package/build/tabs-menu/save.cjs.map +2 -2
- package/build/tabs-menu-item/block.json +14 -11
- package/build/tabs-menu-item/controls.cjs +2 -133
- package/build/tabs-menu-item/controls.cjs.map +3 -3
- package/build/tabs-menu-item/edit.cjs +44 -56
- package/build/tabs-menu-item/edit.cjs.map +3 -3
- package/build/tabs-menu-item/save.cjs +0 -1
- package/build/tabs-menu-item/save.cjs.map +2 -2
- package/build/template-part/edit/index.cjs +6 -4
- package/build/template-part/edit/index.cjs.map +2 -2
- package/build/utils/media-control.cjs +72 -29
- package/build/utils/media-control.cjs.map +3 -3
- package/build-module/cover/edit/cover-placeholder.mjs +7 -0
- package/build-module/cover/edit/cover-placeholder.mjs.map +2 -2
- package/build-module/html/block.json +2 -1
- package/build-module/html/modal.mjs +144 -149
- package/build-module/html/modal.mjs.map +2 -2
- package/build-module/icon/block.json +3 -12
- package/build-module/image/edit.mjs +7 -0
- package/build-module/image/edit.mjs.map +2 -2
- package/build-module/image/image.mjs +5 -9
- package/build-module/image/image.mjs.map +2 -2
- package/build-module/media-text/media-container.mjs +7 -1
- package/build-module/media-text/media-container.mjs.map +2 -2
- package/build-module/navigation/edit/index.mjs +22 -14
- package/build-module/navigation/edit/index.mjs.map +2 -2
- package/build-module/navigation/view.mjs +9 -2
- package/build-module/navigation/view.mjs.map +2 -2
- package/build-module/navigation-link/block.json +5 -0
- package/build-module/navigation-link/shared/use-link-preview.mjs +28 -0
- package/build-module/navigation-link/shared/use-link-preview.mjs.map +2 -2
- package/build-module/nextpage/block.json +0 -1
- package/build-module/paragraph/edit.mjs +2 -2
- package/build-module/paragraph/edit.mjs.map +1 -1
- package/build-module/playlist/edit.mjs +2 -18
- package/build-module/playlist/edit.mjs.map +2 -2
- package/build-module/playlist/utils.mjs +23 -0
- package/build-module/playlist/utils.mjs.map +7 -0
- package/build-module/playlist-track/block.json +0 -0
- package/build-module/post-excerpt/block.json +1 -3
- package/build-module/post-excerpt/deprecated.mjs +81 -0
- package/build-module/post-excerpt/deprecated.mjs.map +7 -0
- package/build-module/post-excerpt/edit.mjs +12 -34
- package/build-module/post-excerpt/edit.mjs.map +2 -2
- package/build-module/post-excerpt/index.mjs +3 -1
- package/build-module/post-excerpt/index.mjs.map +2 -2
- package/build-module/private-apis.mjs +3 -1
- package/build-module/private-apis.mjs.map +2 -2
- package/build-module/shortcode/block.json +2 -1
- package/build-module/site-logo/edit.mjs +1 -3
- package/build-module/site-logo/edit.mjs.map +2 -2
- package/build-module/tab/add-tab-toolbar-control.mjs +22 -5
- package/build-module/tab/add-tab-toolbar-control.mjs.map +2 -2
- package/build-module/tab/remove-tab-toolbar-control.mjs +19 -1
- package/build-module/tab/remove-tab-toolbar-control.mjs.map +2 -2
- package/build-module/tabs/edit.mjs +87 -9
- package/build-module/tabs/edit.mjs.map +2 -2
- package/build-module/tabs/index.mjs +12 -2
- package/build-module/tabs/index.mjs.map +2 -2
- package/build-module/tabs-menu/block.json +1 -6
- package/build-module/tabs-menu/edit.mjs +13 -162
- package/build-module/tabs-menu/edit.mjs.map +2 -2
- package/build-module/tabs-menu/save.mjs.map +2 -2
- package/build-module/tabs-menu-item/block.json +14 -11
- package/build-module/tabs-menu-item/controls.mjs +4 -143
- package/build-module/tabs-menu-item/controls.mjs.map +2 -2
- package/build-module/tabs-menu-item/edit.mjs +45 -57
- package/build-module/tabs-menu-item/edit.mjs.map +3 -3
- package/build-module/tabs-menu-item/save.mjs +0 -1
- package/build-module/tabs-menu-item/save.mjs.map +2 -2
- package/build-module/template-part/edit/index.mjs +6 -4
- package/build-module/template-part/edit/index.mjs.map +2 -2
- package/build-module/utils/media-control.mjs +73 -30
- package/build-module/utils/media-control.mjs.map +2 -2
- package/build-style/common-rtl.css +1 -0
- package/build-style/common.css +1 -0
- package/build-style/editor-rtl.css +55 -17
- package/build-style/editor.css +55 -17
- package/build-style/html/editor-rtl.css +10 -6
- package/build-style/html/editor.css +10 -6
- package/build-style/navigation/style-rtl.css +15 -1
- package/build-style/navigation/style.css +15 -1
- package/build-style/navigation-overlay-close/style-rtl.css +3 -3
- package/build-style/navigation-overlay-close/style.css +3 -3
- package/build-style/playlist/style-rtl.css +4 -0
- package/build-style/playlist/style.css +4 -0
- package/build-style/style-rtl.css +23 -4
- package/build-style/style.css +23 -4
- package/build-style/tabs-menu/editor-rtl.css +5 -3
- package/build-style/tabs-menu/editor.css +5 -3
- package/package.json +38 -38
- package/src/accordion-item/index.php +17 -5
- package/src/common.scss +1 -0
- package/src/cover/edit/cover-placeholder.js +8 -0
- package/src/cover/index.php +8 -0
- package/src/details/index.php +47 -0
- package/src/html/block.json +2 -1
- package/src/html/editor.scss +15 -5
- package/src/html/modal.js +26 -22
- package/src/icon/block.json +3 -12
- package/src/image/edit.js +8 -0
- package/src/image/image.js +8 -13
- package/src/media-text/media-container.js +8 -1
- package/src/navigation/edit/index.js +26 -14
- package/src/navigation/index.php +27 -13
- package/src/navigation/style.scss +17 -1
- package/src/navigation/view.js +14 -2
- package/src/navigation-link/block.json +5 -0
- package/src/navigation-link/index.php +10 -10
- package/src/navigation-link/shared/test/use-link-preview.test.js +149 -0
- package/src/navigation-link/shared/use-link-preview.js +43 -1
- package/src/navigation-overlay-close/style.scss +3 -3
- package/src/navigation-submenu/index.php +17 -11
- package/src/nextpage/block.json +0 -1
- package/src/paragraph/edit.js +2 -2
- package/src/playlist/edit.js +1 -34
- package/src/playlist/style.scss +5 -0
- package/src/playlist/test/edit.js +1 -1
- package/src/playlist/utils.js +42 -0
- package/src/playlist-track/block.json +0 -0
- package/src/playlist-track/edit.js +0 -0
- package/src/playlist-track/index.js +0 -0
- package/src/playlist-track/index.php +0 -0
- package/src/playlist-track/init.js +0 -0
- package/src/playlist-track/style.scss +0 -0
- package/src/post-excerpt/block.json +1 -3
- package/src/post-excerpt/deprecated.js +84 -0
- package/src/post-excerpt/edit.js +14 -39
- package/src/post-excerpt/index.js +2 -0
- package/src/private-apis.js +2 -0
- package/src/shortcode/block.json +2 -1
- package/src/site-logo/edit.js +1 -3
- package/src/tab/add-tab-toolbar-control.js +48 -23
- package/src/tab/remove-tab-toolbar-control.js +30 -10
- package/src/tabs/edit.js +133 -10
- package/src/tabs/index.js +12 -2
- package/src/tabs-menu/block.json +1 -6
- package/src/tabs-menu/edit.js +13 -214
- package/src/tabs-menu/editor.scss +7 -3
- package/src/tabs-menu/index.php +42 -27
- package/src/tabs-menu/save.js +0 -4
- package/src/tabs-menu-item/block.json +14 -11
- package/src/tabs-menu-item/controls.js +4 -167
- package/src/tabs-menu-item/edit.js +60 -69
- package/src/tabs-menu-item/index.php +11 -23
- package/src/tabs-menu-item/save.js +0 -1
- package/src/template-part/edit/index.js +5 -1
- package/src/utils/media-control.js +61 -21
- package/src/utils/media-control.scss +54 -18
package/src/tabs-menu/save.js
CHANGED
|
@@ -4,21 +4,25 @@
|
|
|
4
4
|
"apiVersion": 3,
|
|
5
5
|
"name": "core/tabs-menu-item",
|
|
6
6
|
"title": "Tab Menu Item",
|
|
7
|
-
"description": "A single tab button in the tabs menu.
|
|
7
|
+
"description": "A single tab button in the tabs menu.",
|
|
8
8
|
"version": "1.0.0",
|
|
9
9
|
"category": "design",
|
|
10
10
|
"textdomain": "default",
|
|
11
11
|
"parent": [ "core/tabs-menu" ],
|
|
12
12
|
"usesContext": [
|
|
13
|
-
"core/tabs-menu-item-index",
|
|
14
|
-
"core/tabs-menu-item-id",
|
|
15
|
-
"core/tabs-menu-item-label",
|
|
16
|
-
"core/tabs-menu-item-clientId",
|
|
17
13
|
"core/tabs-list",
|
|
18
14
|
"core/tabs-activeTabIndex",
|
|
19
|
-
"core/tabs-editorActiveTabIndex"
|
|
15
|
+
"core/tabs-editorActiveTabIndex",
|
|
16
|
+
"core/tabs-menu-item-index",
|
|
17
|
+
"core/tabs-menu-item-id",
|
|
18
|
+
"core/tabs-menu-item-label"
|
|
20
19
|
],
|
|
21
|
-
"attributes": {
|
|
20
|
+
"attributes": {
|
|
21
|
+
"anchor": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"default": ""
|
|
24
|
+
}
|
|
25
|
+
},
|
|
22
26
|
"supports": {
|
|
23
27
|
"html": false,
|
|
24
28
|
"reusable": false,
|
|
@@ -31,7 +35,6 @@
|
|
|
31
35
|
"text": true
|
|
32
36
|
}
|
|
33
37
|
},
|
|
34
|
-
"shadow": true,
|
|
35
38
|
"typography": {
|
|
36
39
|
"fontSize": true,
|
|
37
40
|
"__experimentalFontFamily": true,
|
|
@@ -40,9 +43,6 @@
|
|
|
40
43
|
"fontSize": true
|
|
41
44
|
}
|
|
42
45
|
},
|
|
43
|
-
"layout": {
|
|
44
|
-
"allowEditing": false
|
|
45
|
-
},
|
|
46
46
|
"spacing": {
|
|
47
47
|
"padding": true,
|
|
48
48
|
"__experimentalDefaultControls": {
|
|
@@ -54,6 +54,9 @@
|
|
|
54
54
|
"color": true,
|
|
55
55
|
"width": true,
|
|
56
56
|
"style": true
|
|
57
|
+
},
|
|
58
|
+
"layout": {
|
|
59
|
+
"allowEditing": false
|
|
57
60
|
}
|
|
58
61
|
},
|
|
59
62
|
"editorScript": "file:./index.js",
|
|
@@ -1,24 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import clsx from 'clsx';
|
|
5
|
-
|
|
6
1
|
/**
|
|
7
2
|
* WordPress dependencies
|
|
8
3
|
*/
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
BlockControls,
|
|
12
|
-
store as blockEditorStore,
|
|
13
|
-
} from '@wordpress/block-editor';
|
|
14
|
-
import { ToolbarGroup, ToolbarItem, Button } from '@wordpress/components';
|
|
15
|
-
import {
|
|
16
|
-
chevronLeft,
|
|
17
|
-
chevronRight,
|
|
18
|
-
chevronUp,
|
|
19
|
-
chevronDown,
|
|
20
|
-
} from '@wordpress/icons';
|
|
21
|
-
import { useDispatch, useSelect } from '@wordpress/data';
|
|
4
|
+
import { BlockControls } from '@wordpress/block-editor';
|
|
22
5
|
|
|
23
6
|
/**
|
|
24
7
|
* Internal dependencies
|
|
@@ -26,157 +9,11 @@ import { useDispatch, useSelect } from '@wordpress/data';
|
|
|
26
9
|
import AddTabToolbarControl from '../tab/add-tab-toolbar-control';
|
|
27
10
|
import RemoveTabToolbarControl from '../tab/remove-tab-toolbar-control';
|
|
28
11
|
|
|
29
|
-
function
|
|
30
|
-
tabClientId,
|
|
31
|
-
tabIndex,
|
|
32
|
-
tabsCount,
|
|
33
|
-
tabsMenuClientId,
|
|
34
|
-
tabsClientId,
|
|
35
|
-
} ) {
|
|
36
|
-
const {
|
|
37
|
-
moveBlocksUp,
|
|
38
|
-
moveBlocksDown,
|
|
39
|
-
updateBlockAttributes,
|
|
40
|
-
__unstableMarkNextChangeAsNotPersistent,
|
|
41
|
-
} = useDispatch( blockEditorStore );
|
|
42
|
-
|
|
43
|
-
const { tabPanelClientId, orientation } = useSelect(
|
|
44
|
-
( select ) => {
|
|
45
|
-
const { getBlockRootClientId, getBlockAttributes } =
|
|
46
|
-
select( blockEditorStore );
|
|
47
|
-
// Get orientation directly from the tabs-menu block's layout attribute.
|
|
48
|
-
// This is more reliable than getBlockListSettings which is set asynchronously.
|
|
49
|
-
const tabsMenuAttributes = tabsMenuClientId
|
|
50
|
-
? getBlockAttributes( tabsMenuClientId )
|
|
51
|
-
: null;
|
|
52
|
-
return {
|
|
53
|
-
tabPanelClientId: getBlockRootClientId( tabClientId ),
|
|
54
|
-
orientation:
|
|
55
|
-
tabsMenuAttributes?.layout?.orientation || 'horizontal',
|
|
56
|
-
};
|
|
57
|
-
},
|
|
58
|
-
[ tabClientId, tabsMenuClientId ]
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
const isFirst = tabIndex === 0;
|
|
62
|
-
const isLast = tabIndex === tabsCount - 1;
|
|
63
|
-
const isHorizontal = orientation === 'horizontal';
|
|
64
|
-
|
|
65
|
-
// Icons and labels based on orientation (respects RTL for horizontal)
|
|
66
|
-
let upIcon, downIcon, upLabel, downLabel;
|
|
67
|
-
if ( isHorizontal ) {
|
|
68
|
-
if ( isRTL() ) {
|
|
69
|
-
upIcon = chevronRight;
|
|
70
|
-
downIcon = chevronLeft;
|
|
71
|
-
upLabel = __( 'Move tab right' );
|
|
72
|
-
downLabel = __( 'Move tab left' );
|
|
73
|
-
} else {
|
|
74
|
-
upIcon = chevronLeft;
|
|
75
|
-
downIcon = chevronRight;
|
|
76
|
-
upLabel = __( 'Move tab left' );
|
|
77
|
-
downLabel = __( 'Move tab right' );
|
|
78
|
-
}
|
|
79
|
-
} else {
|
|
80
|
-
upIcon = chevronUp;
|
|
81
|
-
downIcon = chevronDown;
|
|
82
|
-
upLabel = __( 'Move tab up' );
|
|
83
|
-
downLabel = __( 'Move tab down' );
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Handle moving tab and updating active index to follow the moved tab
|
|
87
|
-
const handleMoveUp = () => {
|
|
88
|
-
moveBlocksUp( [ tabClientId ], tabPanelClientId );
|
|
89
|
-
// Update editorActiveTabIndex to follow the moved tab
|
|
90
|
-
if ( tabsClientId ) {
|
|
91
|
-
__unstableMarkNextChangeAsNotPersistent();
|
|
92
|
-
updateBlockAttributes( tabsClientId, {
|
|
93
|
-
editorActiveTabIndex: tabIndex - 1,
|
|
94
|
-
} );
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const handleMoveDown = () => {
|
|
99
|
-
moveBlocksDown( [ tabClientId ], tabPanelClientId );
|
|
100
|
-
// Update editorActiveTabIndex to follow the moved tab
|
|
101
|
-
if ( tabsClientId ) {
|
|
102
|
-
__unstableMarkNextChangeAsNotPersistent();
|
|
103
|
-
updateBlockAttributes( tabsClientId, {
|
|
104
|
-
editorActiveTabIndex: tabIndex + 1,
|
|
105
|
-
} );
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
// Don't render if only one tab
|
|
110
|
-
if ( tabsCount <= 1 ) {
|
|
111
|
-
return null;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return (
|
|
115
|
-
<BlockControls group="parent">
|
|
116
|
-
<ToolbarGroup
|
|
117
|
-
className={ clsx( 'block-editor-block-mover', {
|
|
118
|
-
'is-horizontal': isHorizontal,
|
|
119
|
-
} ) }
|
|
120
|
-
>
|
|
121
|
-
<div className="block-editor-block-mover__move-button-container">
|
|
122
|
-
<ToolbarItem>
|
|
123
|
-
{ ( itemProps ) => (
|
|
124
|
-
<Button
|
|
125
|
-
className={ clsx(
|
|
126
|
-
'block-editor-block-mover-button',
|
|
127
|
-
'is-up-button'
|
|
128
|
-
) }
|
|
129
|
-
icon={ upIcon }
|
|
130
|
-
label={ upLabel }
|
|
131
|
-
disabled={ isFirst }
|
|
132
|
-
accessibleWhenDisabled
|
|
133
|
-
onClick={ handleMoveUp }
|
|
134
|
-
__next40pxDefaultSize
|
|
135
|
-
{ ...itemProps }
|
|
136
|
-
/>
|
|
137
|
-
) }
|
|
138
|
-
</ToolbarItem>
|
|
139
|
-
<ToolbarItem>
|
|
140
|
-
{ ( itemProps ) => (
|
|
141
|
-
<Button
|
|
142
|
-
className={ clsx(
|
|
143
|
-
'block-editor-block-mover-button',
|
|
144
|
-
'is-down-button'
|
|
145
|
-
) }
|
|
146
|
-
icon={ downIcon }
|
|
147
|
-
label={ downLabel }
|
|
148
|
-
disabled={ isLast }
|
|
149
|
-
accessibleWhenDisabled
|
|
150
|
-
onClick={ handleMoveDown }
|
|
151
|
-
__next40pxDefaultSize
|
|
152
|
-
{ ...itemProps }
|
|
153
|
-
/>
|
|
154
|
-
) }
|
|
155
|
-
</ToolbarItem>
|
|
156
|
-
</div>
|
|
157
|
-
</ToolbarGroup>
|
|
158
|
-
</BlockControls>
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
export default function Controls( {
|
|
163
|
-
tabsClientId,
|
|
164
|
-
tabClientId,
|
|
165
|
-
tabIndex,
|
|
166
|
-
tabsCount,
|
|
167
|
-
tabsMenuClientId,
|
|
168
|
-
} ) {
|
|
12
|
+
export default function Controls( { tabsClientId } ) {
|
|
169
13
|
return (
|
|
170
|
-
|
|
171
|
-
<TabBlockMover
|
|
172
|
-
tabClientId={ tabClientId }
|
|
173
|
-
tabIndex={ tabIndex }
|
|
174
|
-
tabsCount={ tabsCount }
|
|
175
|
-
tabsMenuClientId={ tabsMenuClientId }
|
|
176
|
-
tabsClientId={ tabsClientId }
|
|
177
|
-
/>
|
|
14
|
+
<BlockControls>
|
|
178
15
|
<AddTabToolbarControl tabsClientId={ tabsClientId } />
|
|
179
16
|
<RemoveTabToolbarControl tabsClientId={ tabsClientId } />
|
|
180
|
-
|
|
17
|
+
</BlockControls>
|
|
181
18
|
);
|
|
182
19
|
}
|
|
@@ -13,132 +13,127 @@ import {
|
|
|
13
13
|
RichText,
|
|
14
14
|
} from '@wordpress/block-editor';
|
|
15
15
|
import { useSelect, useDispatch } from '@wordpress/data';
|
|
16
|
-
import {
|
|
16
|
+
import { useMemo, useCallback } from '@wordpress/element';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Internal dependencies
|
|
20
20
|
*/
|
|
21
|
-
import slugFromLabel from '../tab/slug-from-label';
|
|
22
21
|
import Controls from './controls';
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
const EMPTY_ARRAY = [];
|
|
24
|
+
|
|
25
|
+
function Edit( {
|
|
26
|
+
attributes,
|
|
25
27
|
context,
|
|
26
28
|
clientId,
|
|
27
29
|
__unstableLayoutClassNames: layoutClassNames,
|
|
28
30
|
} ) {
|
|
29
|
-
|
|
30
|
-
const tabIndex = context[ 'core/tabs-menu-item-index' ] ?? 0;
|
|
31
|
-
const tabId = context[ 'core/tabs-menu-item-id' ] ?? '';
|
|
32
|
-
const tabLabel = context[ 'core/tabs-menu-item-label' ] ?? '';
|
|
33
|
-
const tabClientId = context[ 'core/tabs-menu-item-clientId' ] ?? '';
|
|
34
|
-
|
|
35
|
-
// Context from parent tabs block, memoized to prevent unnecessary re-renders.
|
|
36
|
-
const contextTabsList = context[ 'core/tabs-list' ];
|
|
37
|
-
const tabsList = useMemo(
|
|
38
|
-
() => contextTabsList || [],
|
|
39
|
-
[ contextTabsList ]
|
|
40
|
-
);
|
|
31
|
+
const tabsList = context[ 'core/tabs-list' ] || EMPTY_ARRAY;
|
|
41
32
|
const activeTabIndex = context[ 'core/tabs-activeTabIndex' ] ?? 0;
|
|
42
33
|
const editorActiveTabIndex = context[ 'core/tabs-editorActiveTabIndex' ];
|
|
43
34
|
|
|
44
|
-
// Memoize effectiveActiveIndex to ensure it updates when context changes
|
|
45
35
|
const effectiveActiveIndex = useMemo( () => {
|
|
46
36
|
return editorActiveTabIndex ?? activeTabIndex;
|
|
47
37
|
}, [ editorActiveTabIndex, activeTabIndex ] );
|
|
48
38
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const { __unstableMarkNextChangeAsNotPersistent } =
|
|
52
|
-
useDispatch( blockEditorStore );
|
|
53
|
-
|
|
54
|
-
// Get parent tabs clientId for updating editorActiveTabIndex
|
|
55
|
-
const { tabsClientId, tabsMenuClientId, selectedTabClientId } = useSelect(
|
|
39
|
+
const { menuItemIndex, tabsClientId, selectedTabClientId } = useSelect(
|
|
56
40
|
( select ) => {
|
|
57
41
|
const {
|
|
42
|
+
getBlockOrder,
|
|
58
43
|
getBlockRootClientId,
|
|
59
44
|
getSelectedBlockClientIds,
|
|
60
45
|
hasSelectedInnerBlock,
|
|
61
46
|
} = select( blockEditorStore );
|
|
62
|
-
|
|
47
|
+
|
|
63
48
|
const _tabsMenuClientId = getBlockRootClientId( clientId );
|
|
64
49
|
const _tabsClientId = _tabsMenuClientId
|
|
65
50
|
? getBlockRootClientId( _tabsMenuClientId )
|
|
66
51
|
: null;
|
|
67
52
|
|
|
68
|
-
const
|
|
53
|
+
const siblings = getBlockOrder( _tabsMenuClientId );
|
|
54
|
+
const _menuItemIndex = siblings.indexOf( clientId );
|
|
69
55
|
|
|
70
|
-
// Find
|
|
71
|
-
|
|
56
|
+
// Find which tab panel block is currently selected.
|
|
57
|
+
const selectedIds = getSelectedBlockClientIds();
|
|
58
|
+
let _selectedTabClientId = null;
|
|
72
59
|
for ( const tab of tabsList ) {
|
|
73
60
|
if (
|
|
74
61
|
selectedIds.includes( tab.clientId ) ||
|
|
75
62
|
hasSelectedInnerBlock( tab.clientId, true )
|
|
76
63
|
) {
|
|
77
|
-
|
|
64
|
+
_selectedTabClientId = tab.clientId;
|
|
78
65
|
break;
|
|
79
66
|
}
|
|
80
67
|
}
|
|
81
68
|
|
|
82
69
|
return {
|
|
70
|
+
menuItemIndex: _menuItemIndex,
|
|
83
71
|
tabsClientId: _tabsClientId,
|
|
84
|
-
|
|
85
|
-
selectedTabClientId: selectedTab,
|
|
72
|
+
selectedTabClientId: _selectedTabClientId,
|
|
86
73
|
};
|
|
87
74
|
},
|
|
88
75
|
[ clientId, tabsList ]
|
|
89
76
|
);
|
|
90
77
|
|
|
91
|
-
|
|
78
|
+
// Find the corresponding tab's anchor from this menu item's anchor
|
|
79
|
+
// attribute (e.g., "tab-1-button" → "tab-1"), then look it up in tabsList.
|
|
80
|
+
// Falls back to positional lookup when no anchor is set.
|
|
81
|
+
const tabAnchor = attributes.anchor?.replace( /-button$/, '' ) ?? '';
|
|
82
|
+
const tab =
|
|
83
|
+
( tabAnchor && tabsList.find( ( t ) => t.id === tabAnchor ) ) ||
|
|
84
|
+
tabsList[ menuItemIndex ] ||
|
|
85
|
+
{};
|
|
92
86
|
|
|
93
|
-
//
|
|
94
|
-
|
|
87
|
+
// tabListIndex is the tab's position in tabsList, used for active-state
|
|
88
|
+
// checks and click handling.
|
|
89
|
+
const tabListIndex = tab.index ?? menuItemIndex;
|
|
95
90
|
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
[ updateBlockAttributes, tabClientId, tabIndex ]
|
|
106
|
-
);
|
|
91
|
+
const tabId = tab.id || `tab-${ menuItemIndex }`;
|
|
92
|
+
const tabClientId = tab.clientId || '';
|
|
93
|
+
const label = tab.label || '';
|
|
94
|
+
|
|
95
|
+
const isActive = tabListIndex === effectiveActiveIndex;
|
|
96
|
+
const isSelected = tabClientId === selectedTabClientId;
|
|
97
|
+
|
|
98
|
+
const { __unstableMarkNextChangeAsNotPersistent, updateBlockAttributes } =
|
|
99
|
+
useDispatch( blockEditorStore );
|
|
107
100
|
|
|
108
|
-
// Update editor active tab index on parent tabs block when tab is clicked
|
|
109
101
|
const handleTabClick = useCallback(
|
|
110
102
|
( event ) => {
|
|
111
103
|
event.preventDefault();
|
|
112
|
-
|
|
113
|
-
// Update the parent tabs block's editorActiveTabIndex (ephemeral, not persisted)
|
|
114
|
-
if ( tabsClientId && tabIndex !== effectiveActiveIndex ) {
|
|
104
|
+
if ( tabsClientId && tabListIndex !== effectiveActiveIndex ) {
|
|
115
105
|
__unstableMarkNextChangeAsNotPersistent();
|
|
116
106
|
updateBlockAttributes( tabsClientId, {
|
|
117
|
-
editorActiveTabIndex:
|
|
107
|
+
editorActiveTabIndex: tabListIndex,
|
|
118
108
|
} );
|
|
119
109
|
}
|
|
120
110
|
},
|
|
121
111
|
[
|
|
122
112
|
tabsClientId,
|
|
123
|
-
|
|
113
|
+
tabListIndex,
|
|
124
114
|
effectiveActiveIndex,
|
|
125
115
|
updateBlockAttributes,
|
|
126
116
|
__unstableMarkNextChangeAsNotPersistent,
|
|
127
117
|
]
|
|
128
118
|
);
|
|
129
119
|
|
|
130
|
-
const
|
|
131
|
-
|
|
120
|
+
const handleLabelChange = useCallback(
|
|
121
|
+
( newLabel ) => {
|
|
122
|
+
if ( tabClientId ) {
|
|
123
|
+
updateBlockAttributes( tabClientId, { label: newLabel } );
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
[ tabClientId, updateBlockAttributes ]
|
|
127
|
+
);
|
|
132
128
|
|
|
133
|
-
// Use blockProps for core style engine support
|
|
134
129
|
const blockProps = useBlockProps( {
|
|
135
130
|
className: clsx( layoutClassNames, {
|
|
136
|
-
'is-active':
|
|
137
|
-
'is-selected':
|
|
131
|
+
'is-active': isActive,
|
|
132
|
+
'is-selected': isSelected,
|
|
138
133
|
} ),
|
|
139
|
-
'aria-controls':
|
|
140
|
-
'aria-selected':
|
|
141
|
-
id:
|
|
134
|
+
'aria-controls': tabId,
|
|
135
|
+
'aria-selected': isActive,
|
|
136
|
+
id: `${ tabId }--tab`,
|
|
142
137
|
role: 'tab',
|
|
143
138
|
tabIndex: -1,
|
|
144
139
|
onClick: handleTabClick,
|
|
@@ -146,26 +141,22 @@ export default function Edit( {
|
|
|
146
141
|
|
|
147
142
|
return (
|
|
148
143
|
<>
|
|
149
|
-
<Controls
|
|
150
|
-
|
|
151
|
-
tabClientId={ tabClientId }
|
|
152
|
-
tabIndex={ tabIndex }
|
|
153
|
-
tabsCount={ tabsList.length }
|
|
154
|
-
tabsMenuClientId={ tabsMenuClientId }
|
|
155
|
-
/>
|
|
156
|
-
<div { ...blockProps }>
|
|
144
|
+
<Controls tabsClientId={ tabsClientId } />
|
|
145
|
+
<button { ...blockProps } type="button">
|
|
157
146
|
<RichText
|
|
158
147
|
tagName="span"
|
|
159
148
|
withoutInteractiveFormatting
|
|
160
149
|
placeholder={ sprintf(
|
|
161
150
|
/* translators: %d is the tab index + 1 */
|
|
162
151
|
__( 'Tab title %d' ),
|
|
163
|
-
|
|
152
|
+
menuItemIndex + 1
|
|
164
153
|
) }
|
|
165
|
-
value={
|
|
154
|
+
value={ label }
|
|
166
155
|
onChange={ handleLabelChange }
|
|
167
156
|
/>
|
|
168
|
-
</
|
|
157
|
+
</button>
|
|
169
158
|
</>
|
|
170
159
|
);
|
|
171
160
|
}
|
|
161
|
+
|
|
162
|
+
export default Edit;
|
|
@@ -8,18 +8,19 @@
|
|
|
8
8
|
/**
|
|
9
9
|
* Render callback for core/tabs-menu-item.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* Injects the tab label and IAPI directives into the saved button HTML.
|
|
12
|
+
* Per-item context (index, id, label) is provided by the parent tabs-menu
|
|
13
|
+
* render callback before this is called.
|
|
12
14
|
*
|
|
13
15
|
* @since 7.0.0
|
|
14
16
|
*
|
|
15
17
|
* @param array $attributes Block attributes.
|
|
16
|
-
* @param string $content Block content.
|
|
18
|
+
* @param string $content Block content (styled button from save.js).
|
|
17
19
|
* @param \WP_Block $block WP_Block instance.
|
|
18
20
|
*
|
|
19
21
|
* @return string Updated HTML.
|
|
20
22
|
*/
|
|
21
23
|
function block_core_tabs_menu_item_render_callback( array $attributes, string $content, \WP_Block $block ): string {
|
|
22
|
-
// Get tab-specific context
|
|
23
24
|
$tab_index = $block->context['core/tabs-menu-item-index'] ?? 0;
|
|
24
25
|
$tab_id = $block->context['core/tabs-menu-item-id'] ?? '';
|
|
25
26
|
$tab_label = $block->context['core/tabs-menu-item-label'] ?? '';
|
|
@@ -28,42 +29,29 @@ function block_core_tabs_menu_item_render_callback( array $attributes, string $c
|
|
|
28
29
|
$tab_id = 'tab-' . $tab_index;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
//
|
|
32
|
+
// Add Interactivity API directives and tab-specific attributes to the button.
|
|
32
33
|
$tag_processor = new WP_HTML_Tag_Processor( $content );
|
|
33
34
|
|
|
34
35
|
if ( $tag_processor->next_tag() ) {
|
|
35
|
-
// Remove hidden attribute and template class (from save.js)
|
|
36
|
-
$tag_processor->remove_attribute( 'hidden' );
|
|
37
|
-
|
|
38
|
-
// Set tab-specific attributes
|
|
39
36
|
$tag_processor->set_attribute( 'id', 'tab__' . $tab_id );
|
|
40
37
|
$tag_processor->set_attribute( 'aria-controls', $tab_id );
|
|
41
|
-
|
|
42
|
-
// Add IAPI directives
|
|
43
38
|
$tag_processor->set_attribute( 'data-wp-on--click', 'actions.handleTabClick' );
|
|
44
39
|
$tag_processor->set_attribute( 'data-wp-on--keydown', 'actions.handleTabKeyDown' );
|
|
45
40
|
$tag_processor->set_attribute( 'data-wp-bind--aria-selected', 'state.isActiveTab' );
|
|
46
41
|
$tag_processor->set_attribute( 'data-wp-bind--tabindex', 'state.tabIndexAttribute' );
|
|
47
|
-
|
|
48
|
-
// Add context for this specific tab item
|
|
49
42
|
$tag_processor->set_attribute(
|
|
50
43
|
'data-wp-context',
|
|
51
44
|
wp_json_encode( array( 'tabIndex' => $tab_index ) )
|
|
52
45
|
);
|
|
53
46
|
}
|
|
54
47
|
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
'/(<button[^>]*>).*?(<\/button>)/s',
|
|
62
|
-
'$1' . '<span>' . wp_kses_post( $tab_label ) . '</span>' . '$2',
|
|
63
|
-
$output
|
|
48
|
+
// Inject the tab label into the button.
|
|
49
|
+
return preg_replace(
|
|
50
|
+
'/(<button\b[^>]*>).*?(<\/button>)/s',
|
|
51
|
+
'$1<span>' . wp_kses_post( $tab_label ) . '</span>$2',
|
|
52
|
+
$tag_processor->get_updated_html(),
|
|
53
|
+
1
|
|
64
54
|
);
|
|
65
|
-
|
|
66
|
-
return $output;
|
|
67
55
|
}
|
|
68
56
|
|
|
69
57
|
/**
|
|
@@ -128,11 +128,13 @@ export default function TemplatePartEdit( {
|
|
|
128
128
|
onNavigateToEntityRecord,
|
|
129
129
|
title,
|
|
130
130
|
canUserEdit,
|
|
131
|
+
canUserEditBlock,
|
|
131
132
|
} = useSelect(
|
|
132
133
|
( select ) => {
|
|
133
134
|
const { getEditedEntityRecord, hasFinishedResolution } =
|
|
134
135
|
select( coreStore );
|
|
135
|
-
const { getBlockCount, getSettings } =
|
|
136
|
+
const { getBlockCount, getSettings, canEditBlock } =
|
|
137
|
+
select( blockEditorStore );
|
|
136
138
|
|
|
137
139
|
const getEntityArgs = [
|
|
138
140
|
'postType',
|
|
@@ -170,6 +172,7 @@ export default function TemplatePartEdit( {
|
|
|
170
172
|
getSettings().onNavigateToEntityRecord,
|
|
171
173
|
title: entityRecord?.title,
|
|
172
174
|
canUserEdit: !! _canUserEdit,
|
|
175
|
+
canUserEditBlock: canEditBlock( clientId ),
|
|
173
176
|
};
|
|
174
177
|
},
|
|
175
178
|
[ templatePartId, attributes.area, clientId ]
|
|
@@ -284,6 +287,7 @@ export default function TemplatePartEdit( {
|
|
|
284
287
|
// Only enable for single selection that matches the current block.
|
|
285
288
|
// Ensures menu item doesn't render multiple times.
|
|
286
289
|
if (
|
|
290
|
+
! canUserEditBlock ||
|
|
287
291
|
! (
|
|
288
292
|
selectedClientIds.length === 1 &&
|
|
289
293
|
clientId === selectedClientIds[ 0 ]
|