@wordpress/block-library 9.38.1-next.v.0 → 9.39.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/index.cjs +3 -0
- package/build/button/index.cjs.map +2 -2
- package/build/comments-title/block.json +1 -3
- package/build/comments-title/deprecated.cjs +148 -24
- package/build/comments-title/deprecated.cjs.map +3 -3
- package/build/comments-title/edit.cjs +17 -31
- package/build/comments-title/edit.cjs.map +3 -3
- package/build/cover/edit/block-controls.cjs +10 -2
- package/build/cover/edit/block-controls.cjs.map +2 -2
- package/build/cover/edit/embed-video-url-input.cjs +6 -2
- package/build/cover/edit/embed-video-url-input.cjs.map +2 -2
- package/build/details/index.cjs +3 -0
- package/build/details/index.cjs.map +2 -2
- package/build/heading/index.cjs +3 -0
- package/build/heading/index.cjs.map +2 -2
- package/build/image/index.cjs +1 -1
- package/build/image/index.cjs.map +2 -2
- package/build/index.cjs +6 -0
- package/build/index.cjs.map +2 -2
- package/build/list-item/index.cjs +3 -0
- package/build/list-item/index.cjs.map +2 -2
- package/build/more/index.cjs +1 -1
- package/build/more/index.cjs.map +2 -2
- package/build/navigation/edit/index.cjs +23 -2
- package/build/navigation/edit/index.cjs.map +2 -2
- package/build/navigation-submenu/index.cjs +2 -2
- package/build/navigation-submenu/index.cjs.map +2 -2
- package/build/paragraph/index.cjs +1 -1
- package/build/paragraph/index.cjs.map +2 -2
- package/build/post-excerpt/edit.cjs +1 -1
- package/build/post-excerpt/edit.cjs.map +2 -2
- package/build/tab/add-tab-toolbar-control.cjs +31 -9
- package/build/tab/add-tab-toolbar-control.cjs.map +2 -2
- package/build/tab/block.json +18 -4
- package/build/tab/controls.cjs +4 -8
- package/build/tab/controls.cjs.map +3 -3
- package/build/tab/edit.cjs +46 -118
- package/build/tab/edit.cjs.map +3 -3
- package/build/tab/remove-tab-toolbar-control.cjs +91 -0
- package/build/tab/remove-tab-toolbar-control.cjs.map +7 -0
- package/build/tab/save.cjs +2 -2
- package/build/tab/save.cjs.map +2 -2
- package/build/tab-panels/block.json +70 -0
- package/build/tab-panels/edit.cjs +63 -0
- package/build/tab-panels/edit.cjs.map +7 -0
- package/build/tab-panels/icon.cjs +29 -0
- package/build/tab-panels/icon.cjs.map +7 -0
- package/build/tab-panels/index.cjs +58 -0
- package/build/tab-panels/index.cjs.map +7 -0
- package/build/tab-panels/save.cjs +33 -0
- package/build/tab-panels/save.cjs.map +7 -0
- package/build/tabs/block.json +61 -90
- package/build/tabs/controls.cjs +19 -221
- package/build/tabs/controls.cjs.map +3 -3
- package/build/tabs/deprecated.cjs +179 -0
- package/build/tabs/deprecated.cjs.map +7 -0
- package/build/tabs/edit.cjs +84 -62
- package/build/tabs/edit.cjs.map +3 -3
- package/build/tabs/index.cjs +3 -1
- package/build/tabs/index.cjs.map +3 -3
- package/build/tabs/save.cjs +6 -9
- package/build/tabs/save.cjs.map +2 -2
- package/build/tabs-menu/block.json +77 -0
- package/build/tabs-menu/edit.cjs +204 -0
- package/build/tabs-menu/edit.cjs.map +7 -0
- package/build/tabs-menu/icon.cjs +29 -0
- package/build/tabs-menu/icon.cjs.map +7 -0
- package/build/tabs-menu/index.cjs +58 -0
- package/build/tabs-menu/index.cjs.map +7 -0
- package/build/tabs-menu/save.cjs +35 -0
- package/build/tabs-menu/save.cjs.map +7 -0
- package/build/tabs-menu-item/block.json +98 -0
- package/build/tabs-menu-item/controls.cjs +247 -0
- package/build/tabs-menu-item/controls.cjs.map +7 -0
- package/build/tabs-menu-item/edit.cjs +272 -0
- package/build/tabs-menu-item/edit.cjs.map +7 -0
- package/build/tabs-menu-item/icon.cjs +29 -0
- package/build/tabs-menu-item/icon.cjs.map +7 -0
- package/build/tabs-menu-item/index.cjs +58 -0
- package/build/tabs-menu-item/index.cjs.map +7 -0
- package/build/tabs-menu-item/save.cjs +50 -0
- package/build/tabs-menu-item/save.cjs.map +7 -0
- package/build/template-part/edit/index.cjs +1 -1
- package/build/template-part/edit/index.cjs.map +2 -2
- package/build/utils/caption.cjs +4 -6
- package/build/utils/caption.cjs.map +3 -3
- package/build/video/edit.cjs +4 -2
- package/build/video/edit.cjs.map +2 -2
- package/build-module/button/index.mjs +3 -0
- package/build-module/button/index.mjs.map +2 -2
- package/build-module/comments-title/block.json +1 -3
- package/build-module/comments-title/deprecated.mjs +148 -24
- package/build-module/comments-title/deprecated.mjs.map +2 -2
- package/build-module/comments-title/edit.mjs +17 -32
- package/build-module/comments-title/edit.mjs.map +2 -2
- package/build-module/cover/edit/block-controls.mjs +11 -3
- package/build-module/cover/edit/block-controls.mjs.map +2 -2
- package/build-module/cover/edit/embed-video-url-input.mjs +6 -2
- package/build-module/cover/edit/embed-video-url-input.mjs.map +2 -2
- package/build-module/details/index.mjs +3 -0
- package/build-module/details/index.mjs.map +2 -2
- package/build-module/heading/index.mjs +3 -0
- package/build-module/heading/index.mjs.map +2 -2
- package/build-module/image/index.mjs +1 -1
- package/build-module/image/index.mjs.map +2 -2
- package/build-module/index.mjs +6 -0
- package/build-module/index.mjs.map +2 -2
- package/build-module/list-item/index.mjs +3 -0
- package/build-module/list-item/index.mjs.map +2 -2
- package/build-module/more/index.mjs +1 -1
- package/build-module/more/index.mjs.map +2 -2
- package/build-module/navigation/edit/index.mjs +23 -2
- package/build-module/navigation/edit/index.mjs.map +2 -2
- package/build-module/navigation-submenu/index.mjs +2 -2
- package/build-module/navigation-submenu/index.mjs.map +2 -2
- package/build-module/paragraph/index.mjs +1 -1
- package/build-module/paragraph/index.mjs.map +2 -2
- package/build-module/post-excerpt/edit.mjs +1 -1
- package/build-module/post-excerpt/edit.mjs.map +2 -2
- package/build-module/tab/add-tab-toolbar-control.mjs +32 -10
- package/build-module/tab/add-tab-toolbar-control.mjs.map +2 -2
- package/build-module/tab/block.json +18 -4
- package/build-module/tab/controls.mjs +4 -8
- package/build-module/tab/controls.mjs.map +2 -2
- package/build-module/tab/edit.mjs +48 -128
- package/build-module/tab/edit.mjs.map +2 -2
- package/build-module/tab/remove-tab-toolbar-control.mjs +73 -0
- package/build-module/tab/remove-tab-toolbar-control.mjs.map +7 -0
- package/build-module/tab/save.mjs +2 -2
- package/build-module/tab/save.mjs.map +2 -2
- package/build-module/tab-panels/block.json +70 -0
- package/build-module/tab-panels/edit.mjs +36 -0
- package/build-module/tab-panels/edit.mjs.map +7 -0
- package/build-module/tab-panels/icon.mjs +8 -0
- package/build-module/tab-panels/icon.mjs.map +7 -0
- package/build-module/tab-panels/index.mjs +20 -0
- package/build-module/tab-panels/index.mjs.map +7 -0
- package/build-module/tab-panels/save.mjs +12 -0
- package/build-module/tab-panels/save.mjs.map +7 -0
- package/build-module/tabs/block.json +61 -90
- package/build-module/tabs/controls.mjs +21 -228
- package/build-module/tabs/controls.mjs.map +2 -2
- package/build-module/tabs/deprecated.mjs +158 -0
- package/build-module/tabs/deprecated.mjs.map +7 -0
- package/build-module/tabs/edit.mjs +87 -64
- package/build-module/tabs/edit.mjs.map +2 -2
- package/build-module/tabs/index.mjs +3 -1
- package/build-module/tabs/index.mjs.map +2 -2
- package/build-module/tabs/save.mjs +7 -10
- package/build-module/tabs/save.mjs.map +2 -2
- package/build-module/tabs-menu/block.json +77 -0
- package/build-module/tabs-menu/edit.mjs +186 -0
- package/build-module/tabs-menu/edit.mjs.map +7 -0
- package/build-module/tabs-menu/icon.mjs +8 -0
- package/build-module/tabs-menu/icon.mjs.map +7 -0
- package/build-module/tabs-menu/index.mjs +20 -0
- package/build-module/tabs-menu/index.mjs.map +7 -0
- package/build-module/tabs-menu/save.mjs +14 -0
- package/build-module/tabs-menu/save.mjs.map +7 -0
- package/build-module/tabs-menu-item/block.json +98 -0
- package/build-module/tabs-menu-item/controls.mjs +227 -0
- package/build-module/tabs-menu-item/controls.mjs.map +7 -0
- package/build-module/tabs-menu-item/edit.mjs +253 -0
- package/build-module/tabs-menu-item/edit.mjs.map +7 -0
- package/build-module/tabs-menu-item/icon.mjs +8 -0
- package/build-module/tabs-menu-item/icon.mjs.map +7 -0
- package/build-module/tabs-menu-item/index.mjs +20 -0
- package/build-module/tabs-menu-item/index.mjs.map +7 -0
- package/build-module/tabs-menu-item/save.mjs +29 -0
- package/build-module/tabs-menu-item/save.mjs.map +7 -0
- package/build-module/template-part/edit/index.mjs +1 -1
- package/build-module/template-part/edit/index.mjs.map +2 -2
- package/build-module/utils/caption.mjs +1 -3
- package/build-module/utils/caption.mjs.map +2 -2
- package/build-module/video/edit.mjs +4 -2
- package/build-module/video/edit.mjs.map +2 -2
- package/build-style/editor-rtl.css +16 -21
- package/build-style/editor.css +16 -21
- package/build-style/gallery/style-rtl.css +1 -1
- package/build-style/gallery/style.css +1 -1
- package/build-style/style-rtl.css +42 -153
- package/build-style/style.css +42 -153
- package/build-style/tab/style-rtl.css +7 -1
- package/build-style/tab/style.css +7 -1
- package/build-style/tab-panels/style-rtl.css +4 -0
- package/build-style/tab-panels/style.css +4 -0
- package/build-style/tabs/style-rtl.css +1 -167
- package/build-style/tabs/style.css +1 -167
- package/build-style/tabs-menu/editor-rtl.css +4 -0
- package/build-style/tabs-menu/editor.css +4 -0
- package/build-style/tabs-menu/style-rtl.css +8 -0
- package/build-style/tabs-menu/style.css +8 -0
- package/build-style/tabs-menu-item/editor-rtl.css +16 -0
- package/build-style/tabs-menu-item/editor.css +16 -0
- package/build-style/tabs-menu-item/style-rtl.css +34 -0
- package/build-style/tabs-menu-item/style.css +34 -0
- package/package.json +37 -37
- package/src/button/index.js +4 -0
- package/src/comments-title/block.json +1 -3
- package/src/comments-title/deprecated.js +153 -23
- package/src/comments-title/edit.js +9 -25
- package/src/cover/edit/block-controls.js +14 -3
- package/src/cover/edit/embed-video-url-input.js +6 -2
- package/src/details/index.js +4 -0
- package/src/editor.scss +2 -1
- package/src/gallery/style.scss +1 -1
- package/src/heading/index.js +4 -0
- package/src/image/index.js +4 -1
- package/src/index.js +6 -0
- package/src/list-item/index.js +4 -0
- package/src/more/index.js +4 -1
- package/src/navigation/edit/index.js +28 -4
- package/src/navigation-submenu/index.js +6 -3
- package/src/paragraph/index.js +4 -1
- package/src/post-excerpt/edit.js +1 -1
- package/src/post-excerpt/index.php +39 -16
- package/src/style.scss +3 -0
- package/src/tab/add-tab-toolbar-control.js +36 -11
- package/src/tab/block.json +18 -4
- package/src/tab/controls.js +4 -5
- package/src/tab/edit.js +75 -150
- package/src/tab/index.php +5 -63
- package/src/tab/remove-tab-toolbar-control.js +103 -0
- package/src/tab/save.js +1 -3
- package/src/tab/style.scss +8 -1
- package/src/tab-panels/block.json +70 -0
- package/src/tab-panels/edit.js +44 -0
- package/src/tab-panels/icon.js +10 -0
- package/src/tab-panels/index.js +21 -0
- package/src/tab-panels/save.js +11 -0
- package/src/tab-panels/style.scss +4 -0
- package/src/tabs/block.json +61 -90
- package/src/tabs/controls.js +7 -221
- package/src/tabs/deprecated.js +214 -0
- package/src/tabs/edit.js +108 -68
- package/src/tabs/index.js +2 -0
- package/src/tabs/index.php +86 -191
- package/src/tabs/save.js +6 -13
- package/src/tabs/style.scss +1 -187
- package/src/tabs-menu/block.json +77 -0
- package/src/tabs-menu/edit.js +251 -0
- package/src/tabs-menu/editor.scss +6 -0
- package/src/tabs-menu/icon.js +10 -0
- package/src/tabs-menu/index.js +21 -0
- package/src/tabs-menu/index.php +74 -0
- package/src/tabs-menu/save.js +18 -0
- package/src/tabs-menu/style.scss +8 -0
- package/src/tabs-menu-item/block.json +98 -0
- package/src/tabs-menu-item/controls.js +262 -0
- package/src/tabs-menu-item/edit.js +322 -0
- package/src/tabs-menu-item/editor.scss +20 -0
- package/src/tabs-menu-item/icon.js +10 -0
- package/src/tabs-menu-item/index.js +21 -0
- package/src/tabs-menu-item/index.php +82 -0
- package/src/tabs-menu-item/save.js +44 -0
- package/src/tabs-menu-item/style.scss +42 -0
- package/src/template-part/edit/index.js +1 -3
- package/src/utils/caption.js +1 -7
- package/src/video/edit.js +4 -2
- package/build/tab/tabs-list.cjs +0 -132
- package/build/tab/tabs-list.cjs.map +0 -7
- package/build/tabs/style-engine.cjs +0 -119
- package/build/tabs/style-engine.cjs.map +0 -7
- package/build-module/tab/tabs-list.mjs +0 -101
- package/build-module/tab/tabs-list.mjs.map +0 -7
- package/build-module/tabs/style-engine.mjs +0 -101
- package/build-module/tabs/style-engine.mjs.map +0 -7
- package/build-style/tabs/editor-rtl.css +0 -26
- package/build-style/tabs/editor.css +0 -26
- package/src/tab/tabs-list.js +0 -122
- package/src/tabs/editor.scss +0 -30
- package/src/tabs/style-engine.js +0 -164
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { __, isRTL } from '@wordpress/i18n';
|
|
10
|
+
import {
|
|
11
|
+
BlockControls,
|
|
12
|
+
InspectorControls,
|
|
13
|
+
store as blockEditorStore,
|
|
14
|
+
__experimentalColorGradientSettingsDropdown as ColorGradientSettingsDropdown,
|
|
15
|
+
__experimentalUseMultipleOriginColorsAndGradients as useMultipleOriginColorsAndGradients,
|
|
16
|
+
} from '@wordpress/block-editor';
|
|
17
|
+
import { ToolbarGroup, ToolbarItem, Button } from '@wordpress/components';
|
|
18
|
+
import {
|
|
19
|
+
chevronLeft,
|
|
20
|
+
chevronRight,
|
|
21
|
+
chevronUp,
|
|
22
|
+
chevronDown,
|
|
23
|
+
} from '@wordpress/icons';
|
|
24
|
+
import { useDispatch, useSelect } from '@wordpress/data';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Internal dependencies
|
|
28
|
+
*/
|
|
29
|
+
import AddTabToolbarControl from '../tab/add-tab-toolbar-control';
|
|
30
|
+
import RemoveTabToolbarControl from '../tab/remove-tab-toolbar-control';
|
|
31
|
+
|
|
32
|
+
function TabBlockMover( {
|
|
33
|
+
tabClientId,
|
|
34
|
+
tabIndex,
|
|
35
|
+
tabsCount,
|
|
36
|
+
tabsMenuClientId,
|
|
37
|
+
tabsClientId,
|
|
38
|
+
} ) {
|
|
39
|
+
const {
|
|
40
|
+
moveBlocksUp,
|
|
41
|
+
moveBlocksDown,
|
|
42
|
+
updateBlockAttributes,
|
|
43
|
+
__unstableMarkNextChangeAsNotPersistent,
|
|
44
|
+
} = useDispatch( blockEditorStore );
|
|
45
|
+
|
|
46
|
+
const { tabPanelsClientId, orientation } = useSelect(
|
|
47
|
+
( select ) => {
|
|
48
|
+
const { getBlockRootClientId, getBlockAttributes } =
|
|
49
|
+
select( blockEditorStore );
|
|
50
|
+
// Get orientation directly from the tabs-menu block's layout attribute.
|
|
51
|
+
// This is more reliable than getBlockListSettings which is set asynchronously.
|
|
52
|
+
const tabsMenuAttributes = tabsMenuClientId
|
|
53
|
+
? getBlockAttributes( tabsMenuClientId )
|
|
54
|
+
: null;
|
|
55
|
+
return {
|
|
56
|
+
tabPanelsClientId: getBlockRootClientId( tabClientId ),
|
|
57
|
+
orientation:
|
|
58
|
+
tabsMenuAttributes?.layout?.orientation || 'horizontal',
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
[ tabClientId, tabsMenuClientId ]
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const isFirst = tabIndex === 0;
|
|
65
|
+
const isLast = tabIndex === tabsCount - 1;
|
|
66
|
+
const isHorizontal = orientation === 'horizontal';
|
|
67
|
+
|
|
68
|
+
// Icons and labels based on orientation (respects RTL for horizontal)
|
|
69
|
+
let upIcon, downIcon, upLabel, downLabel;
|
|
70
|
+
if ( isHorizontal ) {
|
|
71
|
+
if ( isRTL() ) {
|
|
72
|
+
upIcon = chevronRight;
|
|
73
|
+
downIcon = chevronLeft;
|
|
74
|
+
upLabel = __( 'Move tab right' );
|
|
75
|
+
downLabel = __( 'Move tab left' );
|
|
76
|
+
} else {
|
|
77
|
+
upIcon = chevronLeft;
|
|
78
|
+
downIcon = chevronRight;
|
|
79
|
+
upLabel = __( 'Move tab left' );
|
|
80
|
+
downLabel = __( 'Move tab right' );
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
upIcon = chevronUp;
|
|
84
|
+
downIcon = chevronDown;
|
|
85
|
+
upLabel = __( 'Move tab up' );
|
|
86
|
+
downLabel = __( 'Move tab down' );
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Handle moving tab and updating active index to follow the moved tab
|
|
90
|
+
const handleMoveUp = () => {
|
|
91
|
+
moveBlocksUp( [ tabClientId ], tabPanelsClientId );
|
|
92
|
+
// Update editorActiveTabIndex to follow the moved tab
|
|
93
|
+
if ( tabsClientId ) {
|
|
94
|
+
__unstableMarkNextChangeAsNotPersistent();
|
|
95
|
+
updateBlockAttributes( tabsClientId, {
|
|
96
|
+
editorActiveTabIndex: tabIndex - 1,
|
|
97
|
+
} );
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const handleMoveDown = () => {
|
|
102
|
+
moveBlocksDown( [ tabClientId ], tabPanelsClientId );
|
|
103
|
+
// Update editorActiveTabIndex to follow the moved tab
|
|
104
|
+
if ( tabsClientId ) {
|
|
105
|
+
__unstableMarkNextChangeAsNotPersistent();
|
|
106
|
+
updateBlockAttributes( tabsClientId, {
|
|
107
|
+
editorActiveTabIndex: tabIndex + 1,
|
|
108
|
+
} );
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Don't render if only one tab
|
|
113
|
+
if ( tabsCount <= 1 ) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<BlockControls group="parent">
|
|
119
|
+
<ToolbarGroup
|
|
120
|
+
className={ clsx( 'block-editor-block-mover', {
|
|
121
|
+
'is-horizontal': isHorizontal,
|
|
122
|
+
} ) }
|
|
123
|
+
>
|
|
124
|
+
<div className="block-editor-block-mover__move-button-container">
|
|
125
|
+
<ToolbarItem>
|
|
126
|
+
{ ( itemProps ) => (
|
|
127
|
+
<Button
|
|
128
|
+
className={ clsx(
|
|
129
|
+
'block-editor-block-mover-button',
|
|
130
|
+
'is-up-button'
|
|
131
|
+
) }
|
|
132
|
+
icon={ upIcon }
|
|
133
|
+
label={ upLabel }
|
|
134
|
+
disabled={ isFirst }
|
|
135
|
+
accessibleWhenDisabled
|
|
136
|
+
onClick={ handleMoveUp }
|
|
137
|
+
__next40pxDefaultSize
|
|
138
|
+
{ ...itemProps }
|
|
139
|
+
/>
|
|
140
|
+
) }
|
|
141
|
+
</ToolbarItem>
|
|
142
|
+
<ToolbarItem>
|
|
143
|
+
{ ( itemProps ) => (
|
|
144
|
+
<Button
|
|
145
|
+
className={ clsx(
|
|
146
|
+
'block-editor-block-mover-button',
|
|
147
|
+
'is-down-button'
|
|
148
|
+
) }
|
|
149
|
+
icon={ downIcon }
|
|
150
|
+
label={ downLabel }
|
|
151
|
+
disabled={ isLast }
|
|
152
|
+
accessibleWhenDisabled
|
|
153
|
+
onClick={ handleMoveDown }
|
|
154
|
+
__next40pxDefaultSize
|
|
155
|
+
{ ...itemProps }
|
|
156
|
+
/>
|
|
157
|
+
) }
|
|
158
|
+
</ToolbarItem>
|
|
159
|
+
</div>
|
|
160
|
+
</ToolbarGroup>
|
|
161
|
+
</BlockControls>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export default function Controls( {
|
|
166
|
+
attributes,
|
|
167
|
+
setAttributes,
|
|
168
|
+
clientId,
|
|
169
|
+
tabsClientId,
|
|
170
|
+
tabClientId,
|
|
171
|
+
tabIndex,
|
|
172
|
+
tabsCount,
|
|
173
|
+
tabsMenuClientId,
|
|
174
|
+
activeBackgroundColor,
|
|
175
|
+
setActiveBackgroundColor,
|
|
176
|
+
activeTextColor,
|
|
177
|
+
setActiveTextColor,
|
|
178
|
+
hoverBackgroundColor,
|
|
179
|
+
setHoverBackgroundColor,
|
|
180
|
+
hoverTextColor,
|
|
181
|
+
setHoverTextColor,
|
|
182
|
+
} ) {
|
|
183
|
+
const {
|
|
184
|
+
customActiveBackgroundColor,
|
|
185
|
+
customActiveTextColor,
|
|
186
|
+
customHoverBackgroundColor,
|
|
187
|
+
customHoverTextColor,
|
|
188
|
+
} = attributes;
|
|
189
|
+
|
|
190
|
+
const colorSettings = useMultipleOriginColorsAndGradients();
|
|
191
|
+
|
|
192
|
+
return (
|
|
193
|
+
<>
|
|
194
|
+
<TabBlockMover
|
|
195
|
+
tabClientId={ tabClientId }
|
|
196
|
+
tabIndex={ tabIndex }
|
|
197
|
+
tabsCount={ tabsCount }
|
|
198
|
+
tabsMenuClientId={ tabsMenuClientId }
|
|
199
|
+
tabsClientId={ tabsClientId }
|
|
200
|
+
/>
|
|
201
|
+
<AddTabToolbarControl tabsClientId={ tabsClientId } />
|
|
202
|
+
<RemoveTabToolbarControl tabsClientId={ tabsClientId } />
|
|
203
|
+
<InspectorControls group="color">
|
|
204
|
+
<ColorGradientSettingsDropdown
|
|
205
|
+
settings={ [
|
|
206
|
+
{
|
|
207
|
+
label: __( 'Active Background' ),
|
|
208
|
+
colorValue:
|
|
209
|
+
activeBackgroundColor?.color ??
|
|
210
|
+
customActiveBackgroundColor,
|
|
211
|
+
onColorChange: ( value ) => {
|
|
212
|
+
setActiveBackgroundColor( value );
|
|
213
|
+
setAttributes( {
|
|
214
|
+
customActiveBackgroundColor: value,
|
|
215
|
+
} );
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
label: __( 'Active Text' ),
|
|
220
|
+
colorValue:
|
|
221
|
+
activeTextColor?.color ?? customActiveTextColor,
|
|
222
|
+
onColorChange: ( value ) => {
|
|
223
|
+
setActiveTextColor( value );
|
|
224
|
+
setAttributes( {
|
|
225
|
+
customActiveTextColor: value,
|
|
226
|
+
} );
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
label: __( 'Hover Background' ),
|
|
231
|
+
colorValue:
|
|
232
|
+
hoverBackgroundColor?.color ??
|
|
233
|
+
customHoverBackgroundColor,
|
|
234
|
+
onColorChange: ( value ) => {
|
|
235
|
+
setHoverBackgroundColor( value );
|
|
236
|
+
setAttributes( {
|
|
237
|
+
customHoverBackgroundColor: value,
|
|
238
|
+
} );
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
label: __( 'Hover Text' ),
|
|
243
|
+
colorValue:
|
|
244
|
+
hoverTextColor?.color ?? customHoverTextColor,
|
|
245
|
+
onColorChange: ( value ) => {
|
|
246
|
+
setHoverTextColor( value );
|
|
247
|
+
setAttributes( {
|
|
248
|
+
customHoverTextColor: value,
|
|
249
|
+
} );
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
] }
|
|
253
|
+
panelId={ clientId }
|
|
254
|
+
disableCustomColors={ false }
|
|
255
|
+
__experimentalIsRenderedInSidebar
|
|
256
|
+
__next40pxDefaultSize
|
|
257
|
+
{ ...colorSettings }
|
|
258
|
+
/>
|
|
259
|
+
</InspectorControls>
|
|
260
|
+
</>
|
|
261
|
+
);
|
|
262
|
+
}
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
10
|
+
import {
|
|
11
|
+
useBlockProps,
|
|
12
|
+
withColors,
|
|
13
|
+
store as blockEditorStore,
|
|
14
|
+
RichText,
|
|
15
|
+
} from '@wordpress/block-editor';
|
|
16
|
+
import { useSelect, useDispatch } from '@wordpress/data';
|
|
17
|
+
import { decodeEntities } from '@wordpress/html-entities';
|
|
18
|
+
import {
|
|
19
|
+
RawHTML,
|
|
20
|
+
useRef,
|
|
21
|
+
useCallback,
|
|
22
|
+
useState,
|
|
23
|
+
useEffect,
|
|
24
|
+
useMemo,
|
|
25
|
+
} from '@wordpress/element';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Internal dependencies
|
|
29
|
+
*/
|
|
30
|
+
import slugFromLabel from '../tab/slug-from-label';
|
|
31
|
+
import Controls from './controls';
|
|
32
|
+
|
|
33
|
+
const { requestAnimationFrame, cancelAnimationFrame } = window;
|
|
34
|
+
|
|
35
|
+
function StaticLabel( { label, index } ) {
|
|
36
|
+
if ( label ) {
|
|
37
|
+
return (
|
|
38
|
+
<span>
|
|
39
|
+
<RawHTML>{ decodeEntities( label ) }</RawHTML>
|
|
40
|
+
</span>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return (
|
|
44
|
+
<span>
|
|
45
|
+
{ sprintf(
|
|
46
|
+
/* translators: %d is the tab index + 1 */
|
|
47
|
+
__( 'Tab %d' ),
|
|
48
|
+
index + 1
|
|
49
|
+
) }
|
|
50
|
+
</span>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function Edit( {
|
|
55
|
+
attributes,
|
|
56
|
+
setAttributes,
|
|
57
|
+
context,
|
|
58
|
+
clientId,
|
|
59
|
+
activeBackgroundColor,
|
|
60
|
+
setActiveBackgroundColor,
|
|
61
|
+
activeTextColor,
|
|
62
|
+
setActiveTextColor,
|
|
63
|
+
hoverBackgroundColor,
|
|
64
|
+
setHoverBackgroundColor,
|
|
65
|
+
hoverTextColor,
|
|
66
|
+
setHoverTextColor,
|
|
67
|
+
__unstableLayoutClassNames: layoutClassNames,
|
|
68
|
+
} ) {
|
|
69
|
+
// Context from tabs-menu (per-item context via BlockContextProvider)
|
|
70
|
+
const tabIndex = context[ 'core/tabs-menu-item-index' ] ?? 0;
|
|
71
|
+
const tabId = context[ 'core/tabs-menu-item-id' ] ?? '';
|
|
72
|
+
const tabLabel = context[ 'core/tabs-menu-item-label' ] ?? '';
|
|
73
|
+
const tabClientId = context[ 'core/tabs-menu-item-clientId' ] ?? '';
|
|
74
|
+
|
|
75
|
+
// Context from parent tabs block, memoized to prevent unnecessary re-renders.
|
|
76
|
+
const contextTabsList = context[ 'core/tabs-list' ];
|
|
77
|
+
const tabsList = useMemo(
|
|
78
|
+
() => contextTabsList || [],
|
|
79
|
+
[ contextTabsList ]
|
|
80
|
+
);
|
|
81
|
+
const activeTabIndex = context[ 'core/tabs-activeTabIndex' ] ?? 0;
|
|
82
|
+
const editorActiveTabIndex = context[ 'core/tabs-editorActiveTabIndex' ];
|
|
83
|
+
|
|
84
|
+
// Memoize effectiveActiveIndex to ensure it updates when context changes
|
|
85
|
+
const effectiveActiveIndex = useMemo( () => {
|
|
86
|
+
return editorActiveTabIndex ?? activeTabIndex;
|
|
87
|
+
}, [ editorActiveTabIndex, activeTabIndex ] );
|
|
88
|
+
|
|
89
|
+
const isActiveTab = tabIndex === effectiveActiveIndex;
|
|
90
|
+
|
|
91
|
+
const { __unstableMarkNextChangeAsNotPersistent } =
|
|
92
|
+
useDispatch( blockEditorStore );
|
|
93
|
+
const focusRef = useRef();
|
|
94
|
+
const labelElementRef = useRef( null );
|
|
95
|
+
const [ isEditing, setIsEditing ] = useState( false );
|
|
96
|
+
const [ editingLabel, setEditingLabel ] = useState( '' );
|
|
97
|
+
|
|
98
|
+
// Get parent tabs clientId for updating editorActiveTabIndex
|
|
99
|
+
const { tabsClientId, tabsMenuClientId, selectedTabClientId } = useSelect(
|
|
100
|
+
( select ) => {
|
|
101
|
+
const {
|
|
102
|
+
getBlockRootClientId,
|
|
103
|
+
getSelectedBlockClientIds,
|
|
104
|
+
hasSelectedInnerBlock,
|
|
105
|
+
} = select( blockEditorStore );
|
|
106
|
+
// tabs-menu-item -> tabs-menu -> tabs
|
|
107
|
+
const _tabsMenuClientId = getBlockRootClientId( clientId );
|
|
108
|
+
const _tabsClientId = _tabsMenuClientId
|
|
109
|
+
? getBlockRootClientId( _tabsMenuClientId )
|
|
110
|
+
: null;
|
|
111
|
+
|
|
112
|
+
const selectedIds = getSelectedBlockClientIds();
|
|
113
|
+
|
|
114
|
+
// Find if any tab is selected
|
|
115
|
+
let selectedTab = null;
|
|
116
|
+
for ( const tab of tabsList ) {
|
|
117
|
+
if (
|
|
118
|
+
selectedIds.includes( tab.clientId ) ||
|
|
119
|
+
hasSelectedInnerBlock( tab.clientId, true )
|
|
120
|
+
) {
|
|
121
|
+
selectedTab = tab.clientId;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
tabsClientId: _tabsClientId,
|
|
128
|
+
tabsMenuClientId: _tabsMenuClientId,
|
|
129
|
+
selectedTabClientId: selectedTab,
|
|
130
|
+
};
|
|
131
|
+
},
|
|
132
|
+
[ clientId, tabsList ]
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
const isSelectedTab = tabClientId === selectedTabClientId;
|
|
136
|
+
|
|
137
|
+
// Update tab label in the tab block
|
|
138
|
+
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
139
|
+
|
|
140
|
+
const handleLabelChange = useCallback(
|
|
141
|
+
( newLabel ) => {
|
|
142
|
+
if ( tabClientId ) {
|
|
143
|
+
updateBlockAttributes( tabClientId, {
|
|
144
|
+
label: newLabel,
|
|
145
|
+
anchor: slugFromLabel( newLabel, tabIndex ),
|
|
146
|
+
} );
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
[ updateBlockAttributes, tabClientId, tabIndex ]
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
// Update editor active tab index on parent tabs block when tab is clicked
|
|
153
|
+
const handleTabClick = useCallback(
|
|
154
|
+
( event ) => {
|
|
155
|
+
event.preventDefault();
|
|
156
|
+
|
|
157
|
+
// Update the parent tabs block's editorActiveTabIndex (ephemeral, not persisted)
|
|
158
|
+
if ( tabsClientId && tabIndex !== effectiveActiveIndex ) {
|
|
159
|
+
__unstableMarkNextChangeAsNotPersistent();
|
|
160
|
+
updateBlockAttributes( tabsClientId, {
|
|
161
|
+
editorActiveTabIndex: tabIndex,
|
|
162
|
+
} );
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Don't select block if we're editing this tab's label
|
|
166
|
+
if ( isEditing ) {
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
[
|
|
170
|
+
isEditing,
|
|
171
|
+
tabsClientId,
|
|
172
|
+
tabIndex,
|
|
173
|
+
effectiveActiveIndex,
|
|
174
|
+
updateBlockAttributes,
|
|
175
|
+
__unstableMarkNextChangeAsNotPersistent,
|
|
176
|
+
]
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// Callback ref for label RichText
|
|
180
|
+
const labelRef = useCallback(
|
|
181
|
+
( node ) => {
|
|
182
|
+
labelElementRef.current = node;
|
|
183
|
+
if ( node && isEditing ) {
|
|
184
|
+
const animationId = requestAnimationFrame( () => {
|
|
185
|
+
if ( node ) {
|
|
186
|
+
node.focus();
|
|
187
|
+
}
|
|
188
|
+
} );
|
|
189
|
+
focusRef.current = animationId;
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
[ isEditing ]
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
// Cleanup animation frames
|
|
196
|
+
useEffect( () => {
|
|
197
|
+
return () => {
|
|
198
|
+
if ( focusRef.current ) {
|
|
199
|
+
cancelAnimationFrame( focusRef.current );
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
}, [] );
|
|
203
|
+
|
|
204
|
+
// Build CSS custom properties for active/hover color states
|
|
205
|
+
const customColorStyles = useMemo( () => {
|
|
206
|
+
const styles = {};
|
|
207
|
+
|
|
208
|
+
// Active/hover colors from custom attributes
|
|
209
|
+
const activeBg =
|
|
210
|
+
activeBackgroundColor?.color ||
|
|
211
|
+
attributes.customActiveBackgroundColor;
|
|
212
|
+
const activeText =
|
|
213
|
+
activeTextColor?.color || attributes.customActiveTextColor;
|
|
214
|
+
const hoverBg =
|
|
215
|
+
hoverBackgroundColor?.color ||
|
|
216
|
+
attributes.customHoverBackgroundColor;
|
|
217
|
+
const hoverText =
|
|
218
|
+
hoverTextColor?.color || attributes.customHoverTextColor;
|
|
219
|
+
|
|
220
|
+
if ( activeBg ) {
|
|
221
|
+
styles[ '--custom-tab-active-color' ] = activeBg;
|
|
222
|
+
}
|
|
223
|
+
if ( activeText ) {
|
|
224
|
+
styles[ '--custom-tab-active-text-color' ] = activeText;
|
|
225
|
+
}
|
|
226
|
+
if ( hoverBg ) {
|
|
227
|
+
styles[ '--custom-tab-hover-color' ] = hoverBg;
|
|
228
|
+
}
|
|
229
|
+
if ( hoverText ) {
|
|
230
|
+
styles[ '--custom-tab-hover-text-color' ] = hoverText;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return styles;
|
|
234
|
+
}, [
|
|
235
|
+
activeBackgroundColor?.color,
|
|
236
|
+
attributes.customActiveBackgroundColor,
|
|
237
|
+
activeTextColor?.color,
|
|
238
|
+
attributes.customActiveTextColor,
|
|
239
|
+
hoverBackgroundColor?.color,
|
|
240
|
+
attributes.customHoverBackgroundColor,
|
|
241
|
+
hoverTextColor?.color,
|
|
242
|
+
attributes.customHoverTextColor,
|
|
243
|
+
] );
|
|
244
|
+
|
|
245
|
+
const tabPanelId = tabId || `tab-${ tabIndex }`;
|
|
246
|
+
const tabLabelId = `${ tabPanelId }--tab`;
|
|
247
|
+
|
|
248
|
+
// Use blockProps for core style engine support
|
|
249
|
+
const blockProps = useBlockProps( {
|
|
250
|
+
className: clsx( layoutClassNames, {
|
|
251
|
+
'is-active': isActiveTab,
|
|
252
|
+
'is-selected': isSelectedTab,
|
|
253
|
+
} ),
|
|
254
|
+
style: customColorStyles,
|
|
255
|
+
'aria-controls': tabPanelId,
|
|
256
|
+
'aria-selected': isActiveTab,
|
|
257
|
+
id: tabLabelId,
|
|
258
|
+
role: 'tab',
|
|
259
|
+
tabIndex: isActiveTab ? 0 : -1,
|
|
260
|
+
onClick: handleTabClick,
|
|
261
|
+
onDoubleClick: () => {
|
|
262
|
+
setIsEditing( true );
|
|
263
|
+
setEditingLabel( tabLabel || '' );
|
|
264
|
+
},
|
|
265
|
+
} );
|
|
266
|
+
|
|
267
|
+
return (
|
|
268
|
+
<>
|
|
269
|
+
<Controls
|
|
270
|
+
{ ...{
|
|
271
|
+
attributes,
|
|
272
|
+
setAttributes,
|
|
273
|
+
clientId,
|
|
274
|
+
tabsClientId,
|
|
275
|
+
tabClientId,
|
|
276
|
+
tabIndex,
|
|
277
|
+
tabsCount: tabsList.length,
|
|
278
|
+
tabsMenuClientId,
|
|
279
|
+
activeBackgroundColor,
|
|
280
|
+
setActiveBackgroundColor,
|
|
281
|
+
activeTextColor,
|
|
282
|
+
setActiveTextColor,
|
|
283
|
+
hoverBackgroundColor,
|
|
284
|
+
setHoverBackgroundColor,
|
|
285
|
+
hoverTextColor,
|
|
286
|
+
setHoverTextColor,
|
|
287
|
+
} }
|
|
288
|
+
/>
|
|
289
|
+
<div { ...blockProps }>
|
|
290
|
+
{ isEditing ? (
|
|
291
|
+
<RichText
|
|
292
|
+
ref={ labelRef }
|
|
293
|
+
tagName="span"
|
|
294
|
+
withoutInteractiveFormatting
|
|
295
|
+
placeholder={ sprintf(
|
|
296
|
+
/* translators: %d is the tab index + 1 */
|
|
297
|
+
__( 'Tab %d…' ),
|
|
298
|
+
tabIndex + 1
|
|
299
|
+
) }
|
|
300
|
+
value={ decodeEntities( editingLabel ) }
|
|
301
|
+
onChange={ ( value ) => {
|
|
302
|
+
setEditingLabel( value );
|
|
303
|
+
handleLabelChange( value );
|
|
304
|
+
} }
|
|
305
|
+
onBlur={ () => {
|
|
306
|
+
setIsEditing( false );
|
|
307
|
+
} }
|
|
308
|
+
/>
|
|
309
|
+
) : (
|
|
310
|
+
<StaticLabel label={ tabLabel } index={ tabIndex } />
|
|
311
|
+
) }
|
|
312
|
+
</div>
|
|
313
|
+
</>
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export default withColors(
|
|
318
|
+
'activeBackgroundColor',
|
|
319
|
+
'activeTextColor',
|
|
320
|
+
'hoverBackgroundColor',
|
|
321
|
+
'hoverTextColor'
|
|
322
|
+
)( Edit );
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.wp-block-tabs-menu-item {
|
|
2
|
+
&.is-selected {
|
|
3
|
+
outline: 2px solid var(--wp-admin-theme-color, #007cba);
|
|
4
|
+
outline-offset: 2px;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.block-editor-block-preview__live-content:has(.wp-block-tabs-menu-item) {
|
|
9
|
+
flex-basis: inherit !important;
|
|
10
|
+
flex-grow: inherit !important;
|
|
11
|
+
|
|
12
|
+
.wp-block-tabs-menu-item {
|
|
13
|
+
flex-basis: 100% !important;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&:hover > .wp-block-tabs-menu-item {
|
|
17
|
+
background-color: var(--custom-tab-hover-color, #eaeaea) !important;
|
|
18
|
+
color: var(--custom-tab-hover-text-color, #000) !important;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { Path, SVG } from '@wordpress/primitives';
|
|
5
|
+
|
|
6
|
+
export default (
|
|
7
|
+
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
8
|
+
<Path d="M4 6h5v2H4V6zm0 4h5v2H4v-2zm0 4h5v2H4v-2zm10-8h6v2h-6V6zm0 4h6v2h-6v-2zm0 4h6v2h-6v-2z" />
|
|
9
|
+
</SVG>
|
|
10
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import initBlock from '../utils/init-block';
|
|
5
|
+
import edit from './edit';
|
|
6
|
+
import save from './save';
|
|
7
|
+
import icon from './icon';
|
|
8
|
+
|
|
9
|
+
import metadata from './block.json';
|
|
10
|
+
|
|
11
|
+
const { name } = metadata;
|
|
12
|
+
|
|
13
|
+
export { metadata, name };
|
|
14
|
+
|
|
15
|
+
export const settings = {
|
|
16
|
+
icon,
|
|
17
|
+
edit,
|
|
18
|
+
save,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const init = () => initBlock( { name, metadata, settings } );
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* Tabs Menu Item Block
|
|
4
|
+
*
|
|
5
|
+
* @package WordPress
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Render callback for core/tabs-menu-item.
|
|
10
|
+
*
|
|
11
|
+
* Applies IAPI directives and tab-specific attributes to the saved content.
|
|
12
|
+
*
|
|
13
|
+
* @param array $attributes Block attributes.
|
|
14
|
+
* @param string $content Block content.
|
|
15
|
+
* @param \WP_Block $block WP_Block instance.
|
|
16
|
+
*
|
|
17
|
+
* @return string Updated HTML.
|
|
18
|
+
*/
|
|
19
|
+
function block_core_tabs_menu_item_render_callback( array $attributes, string $content, \WP_Block $block ): string {
|
|
20
|
+
// Get tab-specific context
|
|
21
|
+
$tab_index = $block->context['core/tabs-menu-item-index'] ?? 0;
|
|
22
|
+
$tab_id = $block->context['core/tabs-menu-item-id'] ?? '';
|
|
23
|
+
$tab_label = $block->context['core/tabs-menu-item-label'] ?? '';
|
|
24
|
+
|
|
25
|
+
if ( empty( $tab_id ) ) {
|
|
26
|
+
$tab_id = 'tab-' . $tab_index;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Process the content to add IAPI directives
|
|
30
|
+
$tag_processor = new WP_HTML_Tag_Processor( $content );
|
|
31
|
+
|
|
32
|
+
if ( $tag_processor->next_tag() ) {
|
|
33
|
+
// Remove hidden attribute and template class (from save.js)
|
|
34
|
+
$tag_processor->remove_attribute( 'hidden' );
|
|
35
|
+
|
|
36
|
+
// Set tab-specific attributes
|
|
37
|
+
$tag_processor->set_attribute( 'id', 'tab__' . $tab_id );
|
|
38
|
+
$tag_processor->set_attribute( 'href', '#' . $tab_id );
|
|
39
|
+
$tag_processor->set_attribute( 'role', 'tab' );
|
|
40
|
+
$tag_processor->set_attribute( 'aria-controls', $tab_id );
|
|
41
|
+
|
|
42
|
+
// Add IAPI directives
|
|
43
|
+
$tag_processor->set_attribute( 'data-wp-on--click', 'actions.handleTabClick' );
|
|
44
|
+
$tag_processor->set_attribute( 'data-wp-on--keydown', 'actions.handleTabKeyDown' );
|
|
45
|
+
$tag_processor->set_attribute( 'data-wp-bind--aria-selected', 'state.isActiveTab' );
|
|
46
|
+
$tag_processor->set_attribute( 'data-wp-bind--tabindex', 'state.tabIndexAttribute' );
|
|
47
|
+
|
|
48
|
+
// Add context for this specific tab item
|
|
49
|
+
$tag_processor->set_attribute(
|
|
50
|
+
'data-wp-context',
|
|
51
|
+
wp_json_encode( array( 'tabIndex' => $tab_index ) )
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Get updated HTML and inject the label
|
|
56
|
+
$output = $tag_processor->get_updated_html();
|
|
57
|
+
|
|
58
|
+
// The save.js outputs <a><span class="screen-reader-text">...</span></a>
|
|
59
|
+
// Replace the anchor content with the actual tab label
|
|
60
|
+
$output = preg_replace(
|
|
61
|
+
'/(<a[^>]*>).*?(<\/a>)/s',
|
|
62
|
+
'$1' . '<span>' . esc_html( html_entity_decode( $tab_label ) ) . '</span>' . '$2',
|
|
63
|
+
$output
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return $output;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Registers the `core/tabs-menu-item` block on the server.
|
|
71
|
+
*
|
|
72
|
+
* @since 6.9.0
|
|
73
|
+
*/
|
|
74
|
+
function register_block_core_tabs_menu_item() {
|
|
75
|
+
register_block_type_from_metadata(
|
|
76
|
+
__DIR__ . '/tabs-menu-item',
|
|
77
|
+
array(
|
|
78
|
+
'render_callback' => 'block_core_tabs_menu_item_render_callback',
|
|
79
|
+
)
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
add_action( 'init', 'register_block_core_tabs_menu_item' );
|