@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,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { __ } from '@wordpress/i18n';
|
|
10
|
+
import {
|
|
11
|
+
useBlockProps,
|
|
12
|
+
useInnerBlocksProps,
|
|
13
|
+
BlockContextProvider,
|
|
14
|
+
__experimentalUseBlockPreview as useBlockPreview,
|
|
15
|
+
store as blockEditorStore,
|
|
16
|
+
useBlockEditContext,
|
|
17
|
+
} from '@wordpress/block-editor';
|
|
18
|
+
import { useSelect, useDispatch } from '@wordpress/data';
|
|
19
|
+
import {
|
|
20
|
+
memo,
|
|
21
|
+
useMemo,
|
|
22
|
+
useState,
|
|
23
|
+
useEffect,
|
|
24
|
+
useCallback,
|
|
25
|
+
} from '@wordpress/element';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Internal dependencies
|
|
29
|
+
*/
|
|
30
|
+
import AddTabToolbarControl from '../tab/add-tab-toolbar-control';
|
|
31
|
+
import RemoveTabToolbarControl from '../tab/remove-tab-toolbar-control';
|
|
32
|
+
|
|
33
|
+
const TABS_MENU_ITEM_TEMPLATE = [ [ 'core/tabs-menu-item', {} ] ];
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Preview component for non-active tab menu items.
|
|
37
|
+
* Uses useBlockPreview to cache the rendering.
|
|
38
|
+
*
|
|
39
|
+
* @param {Object} props Component props.
|
|
40
|
+
* @param {Array} props.blocks The blocks to preview.
|
|
41
|
+
* @param {string} props.blockContextId The context ID for this block.
|
|
42
|
+
* @param {boolean} props.isHidden Whether the preview is hidden.
|
|
43
|
+
* @param {Function} props.setActiveBlockContextId Callback to set the active context ID.
|
|
44
|
+
*/
|
|
45
|
+
function TabsMenuItemPreview( {
|
|
46
|
+
blocks,
|
|
47
|
+
blockContextId,
|
|
48
|
+
isHidden,
|
|
49
|
+
setActiveBlockContextId,
|
|
50
|
+
} ) {
|
|
51
|
+
const blockPreviewProps = useBlockPreview( { blocks } );
|
|
52
|
+
|
|
53
|
+
const handleOnClick = () => {
|
|
54
|
+
setActiveBlockContextId( blockContextId );
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const style = {
|
|
58
|
+
display: isHidden ? 'none' : 'flex',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<div
|
|
63
|
+
{ ...blockPreviewProps }
|
|
64
|
+
tabIndex={ 0 }
|
|
65
|
+
role="button"
|
|
66
|
+
onClick={ handleOnClick }
|
|
67
|
+
onKeyDown={ handleOnClick }
|
|
68
|
+
style={ style }
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const MemoizedTabsMenuItemPreview = memo( TabsMenuItemPreview );
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The actual editable inner blocks for the active tab item.
|
|
77
|
+
*
|
|
78
|
+
* @param {Object} props Component props.
|
|
79
|
+
* @param {Object} props.wrapperProps Props to pass to the wrapper element.
|
|
80
|
+
* @param {Object} props.layout The layout object to pass to inner blocks.
|
|
81
|
+
*/
|
|
82
|
+
function TabsMenuItemTemplateBlocks( { wrapperProps = {}, layout } ) {
|
|
83
|
+
const innerBlocksProps = useInnerBlocksProps( wrapperProps, {
|
|
84
|
+
template: TABS_MENU_ITEM_TEMPLATE,
|
|
85
|
+
templateLock: 'all',
|
|
86
|
+
renderAppender: false,
|
|
87
|
+
layout,
|
|
88
|
+
} );
|
|
89
|
+
return innerBlocksProps.children;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function Edit( {
|
|
93
|
+
context,
|
|
94
|
+
clientId,
|
|
95
|
+
__unstableLayoutClassNames: layoutClassNames,
|
|
96
|
+
} ) {
|
|
97
|
+
// Get the layout from block edit context to pass to inner blocks.
|
|
98
|
+
// This ensures the correct orientation is used from the start.
|
|
99
|
+
const { layout } = useBlockEditContext();
|
|
100
|
+
|
|
101
|
+
const tabsId = context[ 'core/tabs-id' ] || null;
|
|
102
|
+
const tabsList = context[ 'core/tabs-list' ] || [];
|
|
103
|
+
const activeTabIndex = context[ 'core/tabs-activeTabIndex' ] ?? 0;
|
|
104
|
+
const editorActiveTabIndex = context[ 'core/tabs-editorActiveTabIndex' ];
|
|
105
|
+
|
|
106
|
+
// Memoize effectiveActiveIndex to ensure it updates when context changes
|
|
107
|
+
const effectiveActiveIndex = useMemo( () => {
|
|
108
|
+
return editorActiveTabIndex ?? activeTabIndex;
|
|
109
|
+
}, [ editorActiveTabIndex, activeTabIndex ] );
|
|
110
|
+
|
|
111
|
+
const { __unstableMarkNextChangeAsNotPersistent } =
|
|
112
|
+
useDispatch( blockEditorStore );
|
|
113
|
+
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
114
|
+
|
|
115
|
+
// Track which tab context is "active" for editing (shows real inner blocks)
|
|
116
|
+
const [ activeBlockContextId, setActiveBlockContextId ] = useState( null );
|
|
117
|
+
|
|
118
|
+
// Get the inner blocks (the single tabs-menu-item template)
|
|
119
|
+
const { blocks, tabsClientId } = useSelect(
|
|
120
|
+
( select ) => {
|
|
121
|
+
const { getBlocks, getBlockRootClientId } =
|
|
122
|
+
select( blockEditorStore );
|
|
123
|
+
return {
|
|
124
|
+
blocks: getBlocks( clientId ),
|
|
125
|
+
tabsClientId: getBlockRootClientId( clientId ),
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
[ clientId ]
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
// Build block contexts for each tab
|
|
132
|
+
const blockContexts = useMemo( () => {
|
|
133
|
+
return tabsList.map( ( tab, index ) => ( {
|
|
134
|
+
'core/tabs-menu-item-index': index,
|
|
135
|
+
'core/tabs-menu-item-id': tab.id || `tab-${ index }`,
|
|
136
|
+
'core/tabs-menu-item-label': tab.label || '',
|
|
137
|
+
'core/tabs-menu-item-clientId': tab.clientId,
|
|
138
|
+
// Pass through parent context
|
|
139
|
+
'core/tabs-id': tabsId,
|
|
140
|
+
'core/tabs-list': tabsList,
|
|
141
|
+
'core/tabs-activeTabIndex': activeTabIndex,
|
|
142
|
+
'core/tabs-editorActiveTabIndex': editorActiveTabIndex,
|
|
143
|
+
} ) );
|
|
144
|
+
}, [ tabsList, tabsId, activeTabIndex, editorActiveTabIndex ] );
|
|
145
|
+
|
|
146
|
+
// Generate a unique ID for each block context
|
|
147
|
+
const getContextId = useCallback( ( blockContext ) => {
|
|
148
|
+
return `tab-context-${ blockContext[ 'core/tabs-menu-item-index' ] }`;
|
|
149
|
+
}, [] );
|
|
150
|
+
|
|
151
|
+
// Set the first tab as active by default
|
|
152
|
+
useEffect( () => {
|
|
153
|
+
if ( blockContexts.length > 0 && activeBlockContextId === null ) {
|
|
154
|
+
setActiveBlockContextId( getContextId( blockContexts[ 0 ] ) );
|
|
155
|
+
}
|
|
156
|
+
}, [ blockContexts, activeBlockContextId, getContextId ] );
|
|
157
|
+
|
|
158
|
+
// Update active context when editorActiveTabIndex changes
|
|
159
|
+
useEffect( () => {
|
|
160
|
+
if (
|
|
161
|
+
blockContexts.length > 0 &&
|
|
162
|
+
effectiveActiveIndex < blockContexts.length
|
|
163
|
+
) {
|
|
164
|
+
const newContextId = getContextId(
|
|
165
|
+
blockContexts[ effectiveActiveIndex ]
|
|
166
|
+
);
|
|
167
|
+
setActiveBlockContextId( ( prevId ) =>
|
|
168
|
+
prevId !== newContextId ? newContextId : prevId
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}, [ effectiveActiveIndex, blockContexts, getContextId ] );
|
|
172
|
+
|
|
173
|
+
// Handle tab click to update parent tabs block's editorActiveTabIndex
|
|
174
|
+
const handleTabContextClick = useCallback(
|
|
175
|
+
( index ) => {
|
|
176
|
+
if ( tabsClientId && index !== effectiveActiveIndex ) {
|
|
177
|
+
__unstableMarkNextChangeAsNotPersistent();
|
|
178
|
+
updateBlockAttributes( tabsClientId, {
|
|
179
|
+
editorActiveTabIndex: index,
|
|
180
|
+
} );
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
[
|
|
184
|
+
tabsClientId,
|
|
185
|
+
effectiveActiveIndex,
|
|
186
|
+
updateBlockAttributes,
|
|
187
|
+
__unstableMarkNextChangeAsNotPersistent,
|
|
188
|
+
]
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
const blockProps = useBlockProps( {
|
|
192
|
+
className: clsx( layoutClassNames ),
|
|
193
|
+
role: 'tablist',
|
|
194
|
+
} );
|
|
195
|
+
|
|
196
|
+
// If no tabs exist yet, show placeholder
|
|
197
|
+
if ( tabsList.length === 0 ) {
|
|
198
|
+
return (
|
|
199
|
+
<>
|
|
200
|
+
<AddTabToolbarControl tabsClientId={ tabsClientId } />
|
|
201
|
+
<RemoveTabToolbarControl tabsClientId={ tabsClientId } />
|
|
202
|
+
<div { ...blockProps }>
|
|
203
|
+
<span className="tabs__tab-label tabs__tab-label--placeholder">
|
|
204
|
+
{ __( 'Add tabs to display menu' ) }
|
|
205
|
+
</span>
|
|
206
|
+
</div>
|
|
207
|
+
</>
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<>
|
|
213
|
+
<AddTabToolbarControl tabsClientId={ tabsClientId } />
|
|
214
|
+
<RemoveTabToolbarControl tabsClientId={ tabsClientId } />
|
|
215
|
+
<div { ...blockProps }>
|
|
216
|
+
{ blockContexts.map( ( blockContext, index ) => {
|
|
217
|
+
const contextId = getContextId( blockContext );
|
|
218
|
+
const isVisible = contextId === activeBlockContextId;
|
|
219
|
+
|
|
220
|
+
return (
|
|
221
|
+
<BlockContextProvider
|
|
222
|
+
key={ contextId }
|
|
223
|
+
value={ blockContext }
|
|
224
|
+
>
|
|
225
|
+
{ isVisible ? (
|
|
226
|
+
<TabsMenuItemTemplateBlocks
|
|
227
|
+
wrapperProps={ {
|
|
228
|
+
onClick: () =>
|
|
229
|
+
handleTabContextClick( index ),
|
|
230
|
+
} }
|
|
231
|
+
layout={ layout }
|
|
232
|
+
/>
|
|
233
|
+
) : null }
|
|
234
|
+
<MemoizedTabsMenuItemPreview
|
|
235
|
+
blocks={ blocks }
|
|
236
|
+
blockContextId={ contextId }
|
|
237
|
+
setActiveBlockContextId={ ( id ) => {
|
|
238
|
+
setActiveBlockContextId( id );
|
|
239
|
+
handleTabContextClick( index );
|
|
240
|
+
} }
|
|
241
|
+
isHidden={ isVisible }
|
|
242
|
+
/>
|
|
243
|
+
</BlockContextProvider>
|
|
244
|
+
);
|
|
245
|
+
} ) }
|
|
246
|
+
</div>
|
|
247
|
+
</>
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export default Edit;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { SVG, Path } 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 5.5H20V7H4V5.5ZM4 11.5H12V13H4V11.5ZM20 11.5H14V13H20V11.5ZM4 17.5H20V19H4V17.5Z" />
|
|
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,74 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* Tabs Menu Block
|
|
4
|
+
*
|
|
5
|
+
* @package WordPress
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Render callback for core/tabs-menu.
|
|
10
|
+
*
|
|
11
|
+
* @param array $attributes Block attributes.
|
|
12
|
+
* @param string $content Block content (contains the tabs-menu-item template).
|
|
13
|
+
* @param \WP_Block $block WP_Block instance.
|
|
14
|
+
*
|
|
15
|
+
* @return string Updated HTML.
|
|
16
|
+
*/
|
|
17
|
+
function block_core_tabs_menu_render_callback( array $attributes, string $content, \WP_Block $block ): string {
|
|
18
|
+
$tabs_list = $block->context['core/tabs-list'] ?? array();
|
|
19
|
+
|
|
20
|
+
if ( empty( $tabs_list ) ) {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Get the first inner block as template (tabs-menu-item)
|
|
25
|
+
$inner_blocks = $block->parsed_block['innerBlocks'] ?? array();
|
|
26
|
+
if ( empty( $inner_blocks ) ) {
|
|
27
|
+
return '';
|
|
28
|
+
}
|
|
29
|
+
$template_block = $inner_blocks[0];
|
|
30
|
+
|
|
31
|
+
// Build rendered tab items
|
|
32
|
+
$tabs_markup = '';
|
|
33
|
+
foreach ( $tabs_list as $index => $tab ) {
|
|
34
|
+
// Create context for this specific tab
|
|
35
|
+
$tab_context = array_merge(
|
|
36
|
+
$block->context,
|
|
37
|
+
array(
|
|
38
|
+
'core/tabs-menu-item-index' => $index,
|
|
39
|
+
'core/tabs-menu-item-id' => $tab['id'] ?? '',
|
|
40
|
+
'core/tabs-menu-item-label' => $tab['label'] ?? '',
|
|
41
|
+
)
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// Create new WP_Block instance with template and context
|
|
45
|
+
$tab_block = new WP_Block( $template_block, $tab_context );
|
|
46
|
+
|
|
47
|
+
// Render the block
|
|
48
|
+
$tabs_markup .= $tab_block->render();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Find the template block and replace it in $content with $tabs_markup
|
|
52
|
+
$content = preg_replace(
|
|
53
|
+
'/<a\b[^>]*\bwp-block-tabs-menu-item__template\b[^>]*>.*?<\/a>/si',
|
|
54
|
+
$tabs_markup,
|
|
55
|
+
$content
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
return $content;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Registers the `core/tabs-menu` block on the server.
|
|
63
|
+
*
|
|
64
|
+
* @since 6.9.0
|
|
65
|
+
*/
|
|
66
|
+
function register_block_core_tabs_menu() {
|
|
67
|
+
register_block_type_from_metadata(
|
|
68
|
+
__DIR__ . '/tabs-menu',
|
|
69
|
+
array(
|
|
70
|
+
'render_callback' => 'block_core_tabs_menu_render_callback',
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
add_action( 'init', 'register_block_core_tabs_menu' );
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* WordPress dependencies
|
|
7
|
+
*/
|
|
8
|
+
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
|
|
9
|
+
|
|
10
|
+
export default function save() {
|
|
11
|
+
const blockProps = useBlockProps.save( {
|
|
12
|
+
role: 'tablist',
|
|
13
|
+
} );
|
|
14
|
+
|
|
15
|
+
const innerBlocksProps = useInnerBlocksProps.save( blockProps );
|
|
16
|
+
|
|
17
|
+
return <div { ...innerBlocksProps } />;
|
|
18
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://schemas.wp.org/trunk/block.json",
|
|
3
|
+
"__experimental": true,
|
|
4
|
+
"apiVersion": 3,
|
|
5
|
+
"name": "core/tabs-menu-item",
|
|
6
|
+
"title": "Tab Menu Item",
|
|
7
|
+
"description": "A single tab button in the tabs menu. Used as a template for styling all tab buttons.",
|
|
8
|
+
"version": "1.0.0",
|
|
9
|
+
"category": "design",
|
|
10
|
+
"textdomain": "default",
|
|
11
|
+
"parent": [
|
|
12
|
+
"core/tabs-menu"
|
|
13
|
+
],
|
|
14
|
+
"usesContext": [
|
|
15
|
+
"core/tabs-menu-item-index",
|
|
16
|
+
"core/tabs-menu-item-id",
|
|
17
|
+
"core/tabs-menu-item-label",
|
|
18
|
+
"core/tabs-menu-item-clientId",
|
|
19
|
+
"core/tabs-list",
|
|
20
|
+
"core/tabs-activeTabIndex",
|
|
21
|
+
"core/tabs-editorActiveTabIndex"
|
|
22
|
+
],
|
|
23
|
+
"attributes": {
|
|
24
|
+
"activeBackgroundColor": {
|
|
25
|
+
"type": "string"
|
|
26
|
+
},
|
|
27
|
+
"customActiveBackgroundColor": {
|
|
28
|
+
"type": "string"
|
|
29
|
+
},
|
|
30
|
+
"activeTextColor": {
|
|
31
|
+
"type": "string"
|
|
32
|
+
},
|
|
33
|
+
"customActiveTextColor": {
|
|
34
|
+
"type": "string"
|
|
35
|
+
},
|
|
36
|
+
"hoverBackgroundColor": {
|
|
37
|
+
"type": "string"
|
|
38
|
+
},
|
|
39
|
+
"customHoverBackgroundColor": {
|
|
40
|
+
"type": "string"
|
|
41
|
+
},
|
|
42
|
+
"hoverTextColor": {
|
|
43
|
+
"type": "string"
|
|
44
|
+
},
|
|
45
|
+
"customHoverTextColor": {
|
|
46
|
+
"type": "string"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"supports": {
|
|
50
|
+
"html": false,
|
|
51
|
+
"reusable": false,
|
|
52
|
+
"lock": false,
|
|
53
|
+
"color": {
|
|
54
|
+
"background": true,
|
|
55
|
+
"text": true,
|
|
56
|
+
"__experimentalDefaultControls": {
|
|
57
|
+
"background": true,
|
|
58
|
+
"text": true
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"shadow": true,
|
|
62
|
+
"typography": {
|
|
63
|
+
"fontSize": true,
|
|
64
|
+
"__experimentalFontFamily": true,
|
|
65
|
+
"textAlign": true,
|
|
66
|
+
"__experimentalDefaultControls": {
|
|
67
|
+
"fontSize": true
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"layout": {
|
|
71
|
+
"default": {
|
|
72
|
+
"type": "flex",
|
|
73
|
+
"orientation": "vertical",
|
|
74
|
+
"flexWrap": "nowrap"
|
|
75
|
+
},
|
|
76
|
+
"allowVerticalAlignment": true,
|
|
77
|
+
"allowJustification": true,
|
|
78
|
+
"allowSwitching": false,
|
|
79
|
+
"allowOrientation": false,
|
|
80
|
+
"allowWrap": false
|
|
81
|
+
},
|
|
82
|
+
"spacing": {
|
|
83
|
+
"padding": true,
|
|
84
|
+
"__experimentalDefaultControls": {
|
|
85
|
+
"padding": true
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"__experimentalBorder": {
|
|
89
|
+
"radius": true,
|
|
90
|
+
"color": true,
|
|
91
|
+
"width": true,
|
|
92
|
+
"style": true
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"editorScript": "file:./index.js",
|
|
96
|
+
"editorStyle": "file:./editor.css",
|
|
97
|
+
"style": "file:./style-index.css"
|
|
98
|
+
}
|