@wordpress/block-library 9.41.1-next.v.202603102151.0 → 9.42.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/cover/edit/cover-placeholder.cjs +7 -0
- package/build/cover/edit/cover-placeholder.cjs.map +2 -2
- package/build/html/modal.cjs +151 -229
- package/build/html/modal.cjs.map +2 -2
- package/build/image/edit.cjs +7 -0
- package/build/image/edit.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 +5 -4
- package/build/navigation/edit/index.cjs.map +2 -2
- 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/playlist-track/block.json +0 -0
- package/build/post-date/block.json +1 -3
- package/build/post-date/deprecated.cjs +82 -6
- package/build/post-date/deprecated.cjs.map +3 -3
- package/build/post-date/edit.cjs +49 -62
- package/build/post-date/edit.cjs.map +3 -3
- package/build/site-logo/edit.cjs +1 -3
- package/build/site-logo/edit.cjs.map +2 -2
- package/build/site-title/index.cjs +5 -1
- package/build/site-title/index.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/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/modal.mjs +151 -229
- package/build-module/html/modal.mjs.map +2 -2
- package/build-module/image/edit.mjs +7 -0
- package/build-module/image/edit.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 +5 -4
- package/build-module/navigation/edit/index.mjs.map +2 -2
- 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/playlist-track/block.json +0 -0
- package/build-module/post-date/block.json +1 -3
- package/build-module/post-date/deprecated.mjs +82 -6
- package/build-module/post-date/deprecated.mjs.map +2 -2
- package/build-module/post-date/edit.mjs +49 -63
- package/build-module/post-date/edit.mjs.map +2 -2
- package/build-module/site-logo/edit.mjs +1 -3
- package/build-module/site-logo/edit.mjs.map +2 -2
- package/build-module/site-title/index.mjs +5 -1
- package/build-module/site-title/index.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/utils/media-control.mjs +73 -30
- package/build-module/utils/media-control.mjs.map +2 -2
- package/build-style/editor-rtl.css +45 -11
- package/build-style/editor.css +45 -11
- package/build-style/navigation/style-rtl.css +4 -0
- package/build-style/navigation/style.css +4 -0
- package/build-style/navigation-overlay-close/style-rtl.css +3 -3
- package/build-style/navigation-overlay-close/style.css +3 -3
- package/build-style/style-rtl.css +7 -3
- package/build-style/style.css +7 -3
- 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/cover/edit/cover-placeholder.js +8 -0
- package/src/html/modal.js +6 -77
- package/src/image/edit.js +8 -0
- package/src/media-text/media-container.js +8 -1
- package/src/navigation/edit/index.js +6 -4
- package/src/navigation/index.php +24 -17
- package/src/navigation/style.scss +10 -0
- package/src/navigation-link/index.php +9 -9
- 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/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-date/block.json +1 -3
- package/src/post-date/deprecated.js +86 -6
- package/src/post-date/edit.js +65 -82
- package/src/site-logo/edit.js +1 -3
- package/src/site-title/index.js +5 -1
- 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/utils/media-control.js +61 -21
- package/src/utils/media-control.scss +54 -18
|
@@ -10,12 +10,13 @@ import { useDispatch, useSelect } from "@wordpress/data";
|
|
|
10
10
|
import { jsx } from "react/jsx-runtime";
|
|
11
11
|
function AddTabToolbarControl({ tabsClientId }) {
|
|
12
12
|
const { insertBlock } = useDispatch(blockEditorStore);
|
|
13
|
-
const { tabPanelClientId,
|
|
13
|
+
const { tabPanelClientId, tabsMenuClientId, tabCount, existingAnchors } = useSelect(
|
|
14
14
|
(select) => {
|
|
15
15
|
if (!tabsClientId) {
|
|
16
16
|
return {
|
|
17
17
|
tabPanelClientId: null,
|
|
18
|
-
|
|
18
|
+
tabsMenuClientId: null,
|
|
19
|
+
existingAnchors: []
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
22
|
const { getBlocks } = select(blockEditorStore);
|
|
@@ -23,9 +24,14 @@ function AddTabToolbarControl({ tabsClientId }) {
|
|
|
23
24
|
const tabPanel = innerBlocks.find(
|
|
24
25
|
(block) => block.name === "core/tab-panel"
|
|
25
26
|
);
|
|
27
|
+
const tabsMenu = innerBlocks.find(
|
|
28
|
+
(block) => block.name === "core/tabs-menu"
|
|
29
|
+
);
|
|
26
30
|
return {
|
|
27
31
|
tabPanelClientId: tabPanel?.clientId || null,
|
|
28
|
-
|
|
32
|
+
tabsMenuClientId: tabsMenu?.clientId || null,
|
|
33
|
+
tabCount: tabPanel?.innerBlocks?.length || 0,
|
|
34
|
+
existingAnchors: (tabPanel?.innerBlocks || []).map((block) => block.attributes.anchor).filter(Boolean)
|
|
29
35
|
};
|
|
30
36
|
},
|
|
31
37
|
[tabsClientId]
|
|
@@ -34,12 +40,23 @@ function AddTabToolbarControl({ tabsClientId }) {
|
|
|
34
40
|
if (!tabPanelClientId) {
|
|
35
41
|
return;
|
|
36
42
|
}
|
|
43
|
+
const existingAnchorSet = new Set(existingAnchors);
|
|
44
|
+
let tabNumber = tabCount + 1;
|
|
45
|
+
while (existingAnchorSet.has(`tab-${tabNumber}`)) {
|
|
46
|
+
tabNumber++;
|
|
47
|
+
}
|
|
37
48
|
const newTabBlock = createBlock("core/tab", {
|
|
38
|
-
anchor:
|
|
49
|
+
anchor: `tab-${tabNumber}`,
|
|
39
50
|
/* translators: %d: tab number */
|
|
40
|
-
label: sprintf(__("Tab %d"),
|
|
51
|
+
label: sprintf(__("Tab %d"), tabNumber)
|
|
41
52
|
});
|
|
42
53
|
insertBlock(newTabBlock, void 0, tabPanelClientId);
|
|
54
|
+
if (tabsMenuClientId) {
|
|
55
|
+
const newMenuItemBlock = createBlock("core/tabs-menu-item", {
|
|
56
|
+
anchor: `tab-${tabNumber}-button`
|
|
57
|
+
});
|
|
58
|
+
insertBlock(newMenuItemBlock, void 0, tabsMenuClientId);
|
|
59
|
+
}
|
|
43
60
|
};
|
|
44
61
|
return /* @__PURE__ */ jsx(BlockControls, { group: "other", children: /* @__PURE__ */ jsx(ToolbarGroup, { children: /* @__PURE__ */ jsx(
|
|
45
62
|
ToolbarButton,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/tab/add-tab-toolbar-control.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { sprintf, __ } from '@wordpress/i18n';\nimport { createBlock } from '@wordpress/blocks';\nimport {\n\tBlockControls,\n\tstore as blockEditorStore,\n} from '@wordpress/block-editor';\nimport { ToolbarGroup, ToolbarButton } from '@wordpress/components';\nimport { useDispatch, useSelect } from '@wordpress/data';\n\n/**\n * \"Add tab\" button in the block toolbar for the tab block.\n * Inserts new
|
|
5
|
-
"mappings": ";AAGA,SAAS,SAAS,UAAU;AAC5B,SAAS,mBAAmB;AAC5B;AAAA,EACC;AAAA,EACA,SAAS;AAAA,OACH;AACP,SAAS,cAAc,qBAAqB;AAC5C,SAAS,aAAa,iBAAiB;
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { sprintf, __ } from '@wordpress/i18n';\nimport { createBlock } from '@wordpress/blocks';\nimport {\n\tBlockControls,\n\tstore as blockEditorStore,\n} from '@wordpress/block-editor';\nimport { ToolbarGroup, ToolbarButton } from '@wordpress/components';\nimport { useDispatch, useSelect } from '@wordpress/data';\n\n/**\n * \"Add tab\" button in the block toolbar for the tab block.\n * Inserts a new core/tab into the tab-panel and a new core/tabs-menu-item\n * into the tabs-menu, keeping both in sync.\n *\n * @param {Object} props\n * @param {string} props.tabsClientId The client ID of the parent tabs block.\n * @return {React.JSX.Element} The toolbar control element.\n */\nexport default function AddTabToolbarControl( { tabsClientId } ) {\n\tconst { insertBlock } = useDispatch( blockEditorStore );\n\n\tconst { tabPanelClientId, tabsMenuClientId, tabCount, existingAnchors } =\n\t\tuseSelect(\n\t\t\t( select ) => {\n\t\t\t\tif ( ! tabsClientId ) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttabPanelClientId: null,\n\t\t\t\t\t\ttabsMenuClientId: null,\n\t\t\t\t\t\texistingAnchors: [],\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst { getBlocks } = select( blockEditorStore );\n\t\t\t\tconst innerBlocks = getBlocks( tabsClientId );\n\t\t\t\tconst tabPanel = innerBlocks.find(\n\t\t\t\t\t( block ) => block.name === 'core/tab-panel'\n\t\t\t\t);\n\t\t\t\tconst tabsMenu = innerBlocks.find(\n\t\t\t\t\t( block ) => block.name === 'core/tabs-menu'\n\t\t\t\t);\n\t\t\t\treturn {\n\t\t\t\t\ttabPanelClientId: tabPanel?.clientId || null,\n\t\t\t\t\ttabsMenuClientId: tabsMenu?.clientId || null,\n\t\t\t\t\ttabCount: tabPanel?.innerBlocks?.length || 0,\n\t\t\t\t\texistingAnchors: ( tabPanel?.innerBlocks || [] )\n\t\t\t\t\t\t.map( ( block ) => block.attributes.anchor )\n\t\t\t\t\t\t.filter( Boolean ),\n\t\t\t\t};\n\t\t\t},\n\t\t\t[ tabsClientId ]\n\t\t);\n\n\tconst addTab = () => {\n\t\tif ( ! tabPanelClientId ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Start from count + 1 so the label stays sequential, then increment\n\t\t// until the anchor slot is free.\n\t\tconst existingAnchorSet = new Set( existingAnchors );\n\t\tlet tabNumber = tabCount + 1;\n\t\twhile ( existingAnchorSet.has( `tab-${ tabNumber }` ) ) {\n\t\t\ttabNumber++;\n\t\t}\n\n\t\tconst newTabBlock = createBlock( 'core/tab', {\n\t\t\tanchor: `tab-${ tabNumber }`,\n\t\t\t/* translators: %d: tab number */\n\t\t\tlabel: sprintf( __( 'Tab %d' ), tabNumber ),\n\t\t} );\n\t\tinsertBlock( newTabBlock, undefined, tabPanelClientId );\n\n\t\t// Insert a corresponding menu item into the tabs-menu.\n\t\tif ( tabsMenuClientId ) {\n\t\t\tconst newMenuItemBlock = createBlock( 'core/tabs-menu-item', {\n\t\t\t\tanchor: `tab-${ tabNumber }-button`,\n\t\t\t} );\n\t\t\tinsertBlock( newMenuItemBlock, undefined, tabsMenuClientId );\n\t\t}\n\t};\n\n\treturn (\n\t\t<BlockControls group=\"other\">\n\t\t\t<ToolbarGroup>\n\t\t\t\t<ToolbarButton\n\t\t\t\t\tclassName=\"components-toolbar__control\"\n\t\t\t\t\tonClick={ addTab }\n\t\t\t\t\ttext={ __( 'Add tab' ) }\n\t\t\t\t/>\n\t\t\t</ToolbarGroup>\n\t\t</BlockControls>\n\t);\n}\n"],
|
|
5
|
+
"mappings": ";AAGA,SAAS,SAAS,UAAU;AAC5B,SAAS,mBAAmB;AAC5B;AAAA,EACC;AAAA,EACA,SAAS;AAAA,OACH;AACP,SAAS,cAAc,qBAAqB;AAC5C,SAAS,aAAa,iBAAiB;AA4EnC;AAjEW,SAAR,qBAAuC,EAAE,aAAa,GAAI;AAChE,QAAM,EAAE,YAAY,IAAI,YAAa,gBAAiB;AAEtD,QAAM,EAAE,kBAAkB,kBAAkB,UAAU,gBAAgB,IACrE;AAAA,IACC,CAAE,WAAY;AACb,UAAK,CAAE,cAAe;AACrB,eAAO;AAAA,UACN,kBAAkB;AAAA,UAClB,kBAAkB;AAAA,UAClB,iBAAiB,CAAC;AAAA,QACnB;AAAA,MACD;AACA,YAAM,EAAE,UAAU,IAAI,OAAQ,gBAAiB;AAC/C,YAAM,cAAc,UAAW,YAAa;AAC5C,YAAM,WAAW,YAAY;AAAA,QAC5B,CAAE,UAAW,MAAM,SAAS;AAAA,MAC7B;AACA,YAAM,WAAW,YAAY;AAAA,QAC5B,CAAE,UAAW,MAAM,SAAS;AAAA,MAC7B;AACA,aAAO;AAAA,QACN,kBAAkB,UAAU,YAAY;AAAA,QACxC,kBAAkB,UAAU,YAAY;AAAA,QACxC,UAAU,UAAU,aAAa,UAAU;AAAA,QAC3C,kBAAmB,UAAU,eAAe,CAAC,GAC3C,IAAK,CAAE,UAAW,MAAM,WAAW,MAAO,EAC1C,OAAQ,OAAQ;AAAA,MACnB;AAAA,IACD;AAAA,IACA,CAAE,YAAa;AAAA,EAChB;AAED,QAAM,SAAS,MAAM;AACpB,QAAK,CAAE,kBAAmB;AACzB;AAAA,IACD;AAIA,UAAM,oBAAoB,IAAI,IAAK,eAAgB;AACnD,QAAI,YAAY,WAAW;AAC3B,WAAQ,kBAAkB,IAAK,OAAQ,SAAU,EAAG,GAAI;AACvD;AAAA,IACD;AAEA,UAAM,cAAc,YAAa,YAAY;AAAA,MAC5C,QAAQ,OAAQ,SAAU;AAAA;AAAA,MAE1B,OAAO,QAAS,GAAI,QAAS,GAAG,SAAU;AAAA,IAC3C,CAAE;AACF,gBAAa,aAAa,QAAW,gBAAiB;AAGtD,QAAK,kBAAmB;AACvB,YAAM,mBAAmB,YAAa,uBAAuB;AAAA,QAC5D,QAAQ,OAAQ,SAAU;AAAA,MAC3B,CAAE;AACF,kBAAa,kBAAkB,QAAW,gBAAiB;AAAA,IAC5D;AAAA,EACD;AAEA,SACC,oBAAC,iBAAc,OAAM,SACpB,8BAAC,gBACA;AAAA,IAAC;AAAA;AAAA,MACA,WAAU;AAAA,MACV,SAAU;AAAA,MACV,MAAO,GAAI,SAAU;AAAA;AAAA,EACtB,GACD,GACD;AAEF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -14,11 +14,17 @@ function RemoveTabToolbarControl({ tabsClientId }) {
|
|
|
14
14
|
selectBlock,
|
|
15
15
|
__unstableMarkNextChangeAsNotPersistent
|
|
16
16
|
} = useDispatch(blockEditorStore);
|
|
17
|
-
const {
|
|
17
|
+
const {
|
|
18
|
+
activeTabClientId,
|
|
19
|
+
activeMenuItemClientId,
|
|
20
|
+
tabCount,
|
|
21
|
+
editorActiveTabIndex
|
|
22
|
+
} = useSelect(
|
|
18
23
|
(select) => {
|
|
19
24
|
if (!tabsClientId) {
|
|
20
25
|
return {
|
|
21
26
|
activeTabClientId: null,
|
|
27
|
+
activeMenuItemClientId: null,
|
|
22
28
|
tabCount: 0,
|
|
23
29
|
editorActiveTabIndex: 0
|
|
24
30
|
};
|
|
@@ -30,10 +36,19 @@ function RemoveTabToolbarControl({ tabsClientId }) {
|
|
|
30
36
|
const tabPanel = innerBlocks.find(
|
|
31
37
|
(block) => block.name === "core/tab-panel"
|
|
32
38
|
);
|
|
39
|
+
const tabsMenu = innerBlocks.find(
|
|
40
|
+
(block) => block.name === "core/tabs-menu"
|
|
41
|
+
);
|
|
33
42
|
const tabs = tabPanel?.innerBlocks || [];
|
|
43
|
+
const menuItems = tabsMenu?.innerBlocks || [];
|
|
34
44
|
const activeTab = tabs[activeIndex];
|
|
45
|
+
const expectedMenuAnchor = activeTab?.attributes?.anchor ? `${activeTab.attributes.anchor}-button` : null;
|
|
46
|
+
const activeMenuItem = expectedMenuAnchor ? menuItems.find(
|
|
47
|
+
(m) => m.attributes?.anchor === expectedMenuAnchor
|
|
48
|
+
) : menuItems[activeIndex];
|
|
35
49
|
return {
|
|
36
50
|
activeTabClientId: activeTab?.clientId || null,
|
|
51
|
+
activeMenuItemClientId: activeMenuItem?.clientId || null,
|
|
37
52
|
tabCount: tabs.length,
|
|
38
53
|
editorActiveTabIndex: activeIndex
|
|
39
54
|
};
|
|
@@ -50,6 +65,9 @@ function RemoveTabToolbarControl({ tabsClientId }) {
|
|
|
50
65
|
editorActiveTabIndex: newActiveIndex
|
|
51
66
|
});
|
|
52
67
|
removeBlock(activeTabClientId, false);
|
|
68
|
+
if (activeMenuItemClientId) {
|
|
69
|
+
removeBlock(activeMenuItemClientId, false);
|
|
70
|
+
}
|
|
53
71
|
if (tabsClientId) {
|
|
54
72
|
selectBlock(tabsClientId);
|
|
55
73
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/tab/remove-tab-toolbar-control.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tBlockControls,\n\tstore as blockEditorStore,\n} from '@wordpress/block-editor';\nimport { ToolbarGroup, ToolbarButton } from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\nimport { useDispatch, useSelect } from '@wordpress/data';\n\n/**\n * \"Remove Tab\" button in the block toolbar for the tab block.\n * Removes the currently active tab
|
|
5
|
-
"mappings": ";AAGA;AAAA,EACC;AAAA,EACA,SAAS;AAAA,OACH;AACP,SAAS,cAAc,qBAAqB;AAC5C,SAAS,UAAU;AACnB,SAAS,aAAa,iBAAiB;
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tBlockControls,\n\tstore as blockEditorStore,\n} from '@wordpress/block-editor';\nimport { ToolbarGroup, ToolbarButton } from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\nimport { useDispatch, useSelect } from '@wordpress/data';\n\n/**\n * \"Remove Tab\" button in the block toolbar for the tab block.\n * Removes the currently active core/tab and its corresponding\n * core/tabs-menu-item, keeping both in sync.\n *\n * @param {Object} props\n * @param {string} props.tabsClientId The client ID of the parent tabs block.\n * @return {React.JSX.Element} The toolbar control element.\n */\nexport default function RemoveTabToolbarControl( { tabsClientId } ) {\n\tconst {\n\t\tremoveBlock,\n\t\tupdateBlockAttributes,\n\t\tselectBlock,\n\t\t__unstableMarkNextChangeAsNotPersistent,\n\t} = useDispatch( blockEditorStore );\n\n\tconst {\n\t\tactiveTabClientId,\n\t\tactiveMenuItemClientId,\n\t\ttabCount,\n\t\teditorActiveTabIndex,\n\t} = useSelect(\n\t\t( select ) => {\n\t\t\tif ( ! tabsClientId ) {\n\t\t\t\treturn {\n\t\t\t\t\tactiveTabClientId: null,\n\t\t\t\t\tactiveMenuItemClientId: null,\n\t\t\t\t\ttabCount: 0,\n\t\t\t\t\teditorActiveTabIndex: 0,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst { getBlocks, getBlockAttributes } =\n\t\t\t\tselect( blockEditorStore );\n\t\t\tconst tabsAttributes = getBlockAttributes( tabsClientId );\n\t\t\tconst activeIndex =\n\t\t\t\ttabsAttributes?.editorActiveTabIndex ??\n\t\t\t\ttabsAttributes?.activeTabIndex ??\n\t\t\t\t0;\n\t\t\tconst innerBlocks = getBlocks( tabsClientId );\n\t\t\tconst tabPanel = innerBlocks.find(\n\t\t\t\t( block ) => block.name === 'core/tab-panel'\n\t\t\t);\n\t\t\tconst tabsMenu = innerBlocks.find(\n\t\t\t\t( block ) => block.name === 'core/tabs-menu'\n\t\t\t);\n\t\t\tconst tabs = tabPanel?.innerBlocks || [];\n\t\t\tconst menuItems = tabsMenu?.innerBlocks || [];\n\t\t\tconst activeTab = tabs[ activeIndex ];\n\t\t\t// Match menu item by anchor (e.g. \"tab-1\" \u2192 \"tab-1-button\").\n\t\t\tconst expectedMenuAnchor = activeTab?.attributes?.anchor\n\t\t\t\t? `${ activeTab.attributes.anchor }-button`\n\t\t\t\t: null;\n\t\t\tconst activeMenuItem = expectedMenuAnchor\n\t\t\t\t? menuItems.find(\n\t\t\t\t\t\t( m ) => m.attributes?.anchor === expectedMenuAnchor\n\t\t\t\t )\n\t\t\t\t: menuItems[ activeIndex ];\n\t\t\treturn {\n\t\t\t\tactiveTabClientId: activeTab?.clientId || null,\n\t\t\t\tactiveMenuItemClientId: activeMenuItem?.clientId || null,\n\t\t\t\ttabCount: tabs.length,\n\t\t\t\teditorActiveTabIndex: activeIndex,\n\t\t\t};\n\t\t},\n\t\t[ tabsClientId ]\n\t);\n\n\tconst removeTab = () => {\n\t\tif ( ! activeTabClientId || tabCount <= 1 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Calculate new active index after removal.\n\t\tconst newActiveIndex =\n\t\t\teditorActiveTabIndex >= tabCount - 1\n\t\t\t\t? tabCount - 2\n\t\t\t\t: editorActiveTabIndex;\n\n\t\t__unstableMarkNextChangeAsNotPersistent();\n\t\tupdateBlockAttributes( tabsClientId, {\n\t\t\teditorActiveTabIndex: newActiveIndex,\n\t\t} );\n\n\t\t// Remove the tab content block and the corresponding menu item.\n\t\tremoveBlock( activeTabClientId, false );\n\t\tif ( activeMenuItemClientId ) {\n\t\t\tremoveBlock( activeMenuItemClientId, false );\n\t\t}\n\n\t\tif ( tabsClientId ) {\n\t\t\tselectBlock( tabsClientId );\n\t\t}\n\t};\n\n\tconst isDisabled = tabCount <= 1 || ! activeTabClientId;\n\n\treturn (\n\t\t<BlockControls group=\"other\">\n\t\t\t<ToolbarGroup>\n\t\t\t\t<ToolbarButton\n\t\t\t\t\tclassName=\"components-toolbar__control\"\n\t\t\t\t\tonClick={ removeTab }\n\t\t\t\t\ttext={ __( 'Remove tab' ) }\n\t\t\t\t\tdisabled={ isDisabled }\n\t\t\t\t/>\n\t\t\t</ToolbarGroup>\n\t\t</BlockControls>\n\t);\n}\n"],
|
|
5
|
+
"mappings": ";AAGA;AAAA,EACC;AAAA,EACA,SAAS;AAAA,OACH;AACP,SAAS,cAAc,qBAAqB;AAC5C,SAAS,UAAU;AACnB,SAAS,aAAa,iBAAiB;AAsGnC;AA3FW,SAAR,wBAA0C,EAAE,aAAa,GAAI;AACnE,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI,YAAa,gBAAiB;AAElC,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI;AAAA,IACH,CAAE,WAAY;AACb,UAAK,CAAE,cAAe;AACrB,eAAO;AAAA,UACN,mBAAmB;AAAA,UACnB,wBAAwB;AAAA,UACxB,UAAU;AAAA,UACV,sBAAsB;AAAA,QACvB;AAAA,MACD;AACA,YAAM,EAAE,WAAW,mBAAmB,IACrC,OAAQ,gBAAiB;AAC1B,YAAM,iBAAiB,mBAAoB,YAAa;AACxD,YAAM,cACL,gBAAgB,wBAChB,gBAAgB,kBAChB;AACD,YAAM,cAAc,UAAW,YAAa;AAC5C,YAAM,WAAW,YAAY;AAAA,QAC5B,CAAE,UAAW,MAAM,SAAS;AAAA,MAC7B;AACA,YAAM,WAAW,YAAY;AAAA,QAC5B,CAAE,UAAW,MAAM,SAAS;AAAA,MAC7B;AACA,YAAM,OAAO,UAAU,eAAe,CAAC;AACvC,YAAM,YAAY,UAAU,eAAe,CAAC;AAC5C,YAAM,YAAY,KAAM,WAAY;AAEpC,YAAM,qBAAqB,WAAW,YAAY,SAC/C,GAAI,UAAU,WAAW,MAAO,YAChC;AACH,YAAM,iBAAiB,qBACpB,UAAU;AAAA,QACV,CAAE,MAAO,EAAE,YAAY,WAAW;AAAA,MAClC,IACA,UAAW,WAAY;AAC1B,aAAO;AAAA,QACN,mBAAmB,WAAW,YAAY;AAAA,QAC1C,wBAAwB,gBAAgB,YAAY;AAAA,QACpD,UAAU,KAAK;AAAA,QACf,sBAAsB;AAAA,MACvB;AAAA,IACD;AAAA,IACA,CAAE,YAAa;AAAA,EAChB;AAEA,QAAM,YAAY,MAAM;AACvB,QAAK,CAAE,qBAAqB,YAAY,GAAI;AAC3C;AAAA,IACD;AAGA,UAAM,iBACL,wBAAwB,WAAW,IAChC,WAAW,IACX;AAEJ,4CAAwC;AACxC,0BAAuB,cAAc;AAAA,MACpC,sBAAsB;AAAA,IACvB,CAAE;AAGF,gBAAa,mBAAmB,KAAM;AACtC,QAAK,wBAAyB;AAC7B,kBAAa,wBAAwB,KAAM;AAAA,IAC5C;AAEA,QAAK,cAAe;AACnB,kBAAa,YAAa;AAAA,IAC3B;AAAA,EACD;AAEA,QAAM,aAAa,YAAY,KAAK,CAAE;AAEtC,SACC,oBAAC,iBAAc,OAAM,SACpB,8BAAC,gBACA;AAAA,IAAC;AAAA;AAAA,MACA,WAAU;AAAA,MACV,SAAU;AAAA,MACV,MAAO,GAAI,YAAa;AAAA,MACxB,UAAW;AAAA;AAAA,EACZ,GACD,GACD;AAEF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
BlockContextProvider,
|
|
6
6
|
store as blockEditorStore
|
|
7
7
|
} from "@wordpress/block-editor";
|
|
8
|
-
import { useSelect } from "@wordpress/data";
|
|
9
|
-
import { useMemo, useEffect } from "@wordpress/element";
|
|
8
|
+
import { useSelect, useDispatch } from "@wordpress/data";
|
|
9
|
+
import { useMemo, useEffect, useRef } from "@wordpress/element";
|
|
10
10
|
import Controls from "./controls.mjs";
|
|
11
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
12
|
var TABS_TEMPLATE = [
|
|
@@ -16,7 +16,11 @@ var TABS_TEMPLATE = [
|
|
|
16
16
|
lock: {
|
|
17
17
|
remove: true
|
|
18
18
|
}
|
|
19
|
-
}
|
|
19
|
+
},
|
|
20
|
+
[
|
|
21
|
+
["core/tabs-menu-item", { anchor: "tab-1-button" }],
|
|
22
|
+
["core/tabs-menu-item", { anchor: "tab-2-button" }]
|
|
23
|
+
]
|
|
20
24
|
],
|
|
21
25
|
[
|
|
22
26
|
"core/tab-panel",
|
|
@@ -33,6 +37,14 @@ var TABS_TEMPLATE = [
|
|
|
33
37
|
label: "Tab 1"
|
|
34
38
|
},
|
|
35
39
|
[["core/paragraph"]]
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
"core/tab",
|
|
43
|
+
{
|
|
44
|
+
anchor: "tab-2",
|
|
45
|
+
label: "Tab 2"
|
|
46
|
+
},
|
|
47
|
+
[["core/paragraph"]]
|
|
36
48
|
]
|
|
37
49
|
]
|
|
38
50
|
]
|
|
@@ -49,22 +61,88 @@ function Edit({
|
|
|
49
61
|
setAttributes({ editorActiveTabIndex: activeTabIndex });
|
|
50
62
|
}
|
|
51
63
|
}, []);
|
|
52
|
-
const
|
|
64
|
+
const { removeBlock } = useDispatch(blockEditorStore);
|
|
65
|
+
const { tabs, menuItems } = useSelect(
|
|
53
66
|
(select) => {
|
|
54
67
|
const { getBlocks } = select(blockEditorStore);
|
|
55
68
|
const innerBlocks = getBlocks(clientId);
|
|
56
69
|
const tabPanel = innerBlocks.find(
|
|
57
70
|
(block) => block.name === "core/tab-panel"
|
|
58
71
|
);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
return tabPanel.innerBlocks.filter(
|
|
63
|
-
(block) => block.name === "core/tab"
|
|
72
|
+
const tabsMenu = innerBlocks.find(
|
|
73
|
+
(block) => block.name === "core/tabs-menu"
|
|
64
74
|
);
|
|
75
|
+
return {
|
|
76
|
+
tabs: tabPanel ? tabPanel.innerBlocks.filter(
|
|
77
|
+
(block) => block.name === "core/tab"
|
|
78
|
+
) : [],
|
|
79
|
+
menuItems: tabsMenu ? getBlocks(tabsMenu.clientId).filter((b) => b.name === "core/tabs-menu-item").map((b) => ({
|
|
80
|
+
clientId: b.clientId,
|
|
81
|
+
anchor: b.attributes.anchor ?? ""
|
|
82
|
+
})) : []
|
|
83
|
+
};
|
|
65
84
|
},
|
|
66
85
|
[clientId]
|
|
67
86
|
);
|
|
87
|
+
const prevSyncStateRef = useRef(null);
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
const currentTabs = tabs.map((tab) => ({
|
|
90
|
+
clientId: tab.clientId,
|
|
91
|
+
anchor: tab.attributes.anchor ?? ""
|
|
92
|
+
}));
|
|
93
|
+
if (prevSyncStateRef.current === null) {
|
|
94
|
+
prevSyncStateRef.current = {
|
|
95
|
+
tabs: currentTabs,
|
|
96
|
+
menuItems: [...menuItems]
|
|
97
|
+
};
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const { tabs: prevTabs, menuItems: prevMenuItems } = prevSyncStateRef.current;
|
|
101
|
+
const tabsRemoved = currentTabs.length < prevTabs.length;
|
|
102
|
+
const menuItemsRemoved = menuItems.length < prevMenuItems.length;
|
|
103
|
+
prevSyncStateRef.current = {
|
|
104
|
+
tabs: currentTabs,
|
|
105
|
+
menuItems: [...menuItems]
|
|
106
|
+
};
|
|
107
|
+
if (!tabsRemoved && !menuItemsRemoved || tabsRemoved && menuItemsRemoved) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const currentTabIds = new Set(currentTabs.map((t) => t.clientId));
|
|
111
|
+
const currentMenuItemIds = new Set(
|
|
112
|
+
menuItems.map((m) => m.clientId)
|
|
113
|
+
);
|
|
114
|
+
if (tabsRemoved) {
|
|
115
|
+
prevTabs.forEach((prevTab) => {
|
|
116
|
+
if (currentTabIds.has(prevTab.clientId)) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const expectedMenuAnchor = prevTab.anchor ? `${prevTab.anchor}-button` : null;
|
|
120
|
+
const menuItemToRemove = expectedMenuAnchor ? menuItems.find((m) => m.anchor === expectedMenuAnchor) : null;
|
|
121
|
+
if (menuItemToRemove) {
|
|
122
|
+
removeBlock(menuItemToRemove.clientId, false);
|
|
123
|
+
prevSyncStateRef.current.menuItems = prevSyncStateRef.current.menuItems.filter(
|
|
124
|
+
(m) => m.clientId !== menuItemToRemove.clientId
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
} else {
|
|
129
|
+
prevMenuItems.forEach((prevItem) => {
|
|
130
|
+
if (currentMenuItemIds.has(prevItem.clientId)) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const expectedTabAnchor = prevItem.anchor?.replace(/-button$/, "") ?? "";
|
|
134
|
+
const tabToRemove = tabs.find(
|
|
135
|
+
(tab) => (tab.attributes.anchor ?? "") === expectedTabAnchor
|
|
136
|
+
);
|
|
137
|
+
if (tabToRemove) {
|
|
138
|
+
removeBlock(tabToRemove.clientId, false);
|
|
139
|
+
prevSyncStateRef.current.tabs = prevSyncStateRef.current.tabs.filter(
|
|
140
|
+
(t) => t.clientId !== tabToRemove.clientId
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}, [tabs, menuItems, removeBlock]);
|
|
68
146
|
const contextValue = useMemo(() => {
|
|
69
147
|
const tabList = tabs.map((tab, index) => ({
|
|
70
148
|
id: tab.attributes.anchor || `tab-${index}`,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/tabs/edit.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tuseBlockProps,\n\tuseInnerBlocksProps,\n\tBlockContextProvider,\n\tstore as blockEditorStore,\n} from '@wordpress/block-editor';\nimport { useSelect } from '@wordpress/data';\nimport { useMemo, useEffect } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport Controls from './controls';\n\nconst TABS_TEMPLATE = [\n\t[\n\t\t'core/tabs-menu',\n\t\t{\n\t\t\tlock: {\n\t\t\t\tremove: true,\n\t\t\t},\n\t\t},\n\t],\n\t[\n\t\t'core/tab-panel',\n\t\t{\n\t\t\tlock: {\n\t\t\t\tremove: true,\n\t\t\t},\n\t\t},\n\t\t[\n\t\t\t[\n\t\t\t\t'core/tab',\n\t\t\t\t{\n\t\t\t\t\tanchor: 'tab-1',\n\t\t\t\t\tlabel: 'Tab 1',\n\t\t\t\t},\n\t\t\t\t[ [ 'core/paragraph' ] ],\n\t\t\t],\n\t\t],\n\t],\n];\n\nfunction Edit( {\n\tclientId,\n\tattributes,\n\tsetAttributes,\n\t__unstableLayoutClassNames: layoutClassNames,\n} ) {\n\tconst { anchor, activeTabIndex, editorActiveTabIndex } = attributes;\n\n\t/**\n\t * Initialize editorActiveTabIndex to activeTabIndex on mount.\n\t * This ensures the ephemeral editor state starts at the persisted default.\n\t */\n\tuseEffect( () => {\n\t\tif ( editorActiveTabIndex === undefined ) {\n\t\t\tsetAttributes( { editorActiveTabIndex: activeTabIndex } );\n\t\t}\n\t}, [] ); // eslint-disable-line react-hooks/exhaustive-deps\n\n\t/**\n\t * Construct a list of core/tab blocks, used to create tabs-list context.\n\t */\n\tconst tabs = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getBlocks } = select( blockEditorStore );\n\t\t\tconst innerBlocks = getBlocks( clientId );\n\n\t\t\t// Find tab-panel block and extract tab data
|
|
5
|
-
"mappings": ";AAGA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,OACH;AACP,SAAS,
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tuseBlockProps,\n\tuseInnerBlocksProps,\n\tBlockContextProvider,\n\tstore as blockEditorStore,\n} from '@wordpress/block-editor';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { useMemo, useEffect, useRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport Controls from './controls';\n\nconst TABS_TEMPLATE = [\n\t[\n\t\t'core/tabs-menu',\n\t\t{\n\t\t\tlock: {\n\t\t\t\tremove: true,\n\t\t\t},\n\t\t},\n\t\t[\n\t\t\t[ 'core/tabs-menu-item', { anchor: 'tab-1-button' } ],\n\t\t\t[ 'core/tabs-menu-item', { anchor: 'tab-2-button' } ],\n\t\t],\n\t],\n\t[\n\t\t'core/tab-panel',\n\t\t{\n\t\t\tlock: {\n\t\t\t\tremove: true,\n\t\t\t},\n\t\t},\n\t\t[\n\t\t\t[\n\t\t\t\t'core/tab',\n\t\t\t\t{\n\t\t\t\t\tanchor: 'tab-1',\n\t\t\t\t\tlabel: 'Tab 1',\n\t\t\t\t},\n\t\t\t\t[ [ 'core/paragraph' ] ],\n\t\t\t],\n\t\t\t[\n\t\t\t\t'core/tab',\n\t\t\t\t{\n\t\t\t\t\tanchor: 'tab-2',\n\t\t\t\t\tlabel: 'Tab 2',\n\t\t\t\t},\n\t\t\t\t[ [ 'core/paragraph' ] ],\n\t\t\t],\n\t\t],\n\t],\n];\n\nfunction Edit( {\n\tclientId,\n\tattributes,\n\tsetAttributes,\n\t__unstableLayoutClassNames: layoutClassNames,\n} ) {\n\tconst { anchor, activeTabIndex, editorActiveTabIndex } = attributes;\n\n\t/**\n\t * Initialize editorActiveTabIndex to activeTabIndex on mount.\n\t * This ensures the ephemeral editor state starts at the persisted default.\n\t */\n\tuseEffect( () => {\n\t\tif ( editorActiveTabIndex === undefined ) {\n\t\t\tsetAttributes( { editorActiveTabIndex: activeTabIndex } );\n\t\t}\n\t}, [] ); // eslint-disable-line react-hooks/exhaustive-deps\n\n\tconst { removeBlock } = useDispatch( blockEditorStore );\n\n\t/**\n\t * Construct a list of core/tab blocks, used to create tabs-list context.\n\t * Also select menu items with their anchors for anchor-based deletion sync.\n\t */\n\tconst { tabs, menuItems } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getBlocks } = select( blockEditorStore );\n\t\t\tconst innerBlocks = getBlocks( clientId );\n\n\t\t\t// Find tab-panel block and extract tab data.\n\t\t\tconst tabPanel = innerBlocks.find(\n\t\t\t\t( block ) => block.name === 'core/tab-panel'\n\t\t\t);\n\n\t\t\t// Find tabs-menu block and get its children with their anchors.\n\t\t\tconst tabsMenu = innerBlocks.find(\n\t\t\t\t( block ) => block.name === 'core/tabs-menu'\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\ttabs: tabPanel\n\t\t\t\t\t? tabPanel.innerBlocks.filter(\n\t\t\t\t\t\t\t( block ) => block.name === 'core/tab'\n\t\t\t\t\t )\n\t\t\t\t\t: [],\n\t\t\t\tmenuItems: tabsMenu\n\t\t\t\t\t? getBlocks( tabsMenu.clientId )\n\t\t\t\t\t\t\t.filter( ( b ) => b.name === 'core/tabs-menu-item' )\n\t\t\t\t\t\t\t.map( ( b ) => ( {\n\t\t\t\t\t\t\t\tclientId: b.clientId,\n\t\t\t\t\t\t\t\tanchor: b.attributes.anchor ?? '',\n\t\t\t\t\t\t\t} ) )\n\t\t\t\t\t: [],\n\t\t\t};\n\t\t},\n\t\t[ clientId ]\n\t);\n\n\t/**\n\t * Keep tabs and menu items in sync when either is deleted directly (e.g.\n\t * via the Backspace key or List View).\n\t *\n\t * TODO: This effect only handles deletions. The two lists can get out of\n\t * sync in other cases: if a user pastes a core/tab block into the tab-panel\n\t * (or duplicates one), no corresponding tabs-menu-item is created; if a\n\t * user drags and drops a tabs-menu-item, the tab panel is not copied with\n\t * it. We should extend this effect to handle insertions, detecting when\n\t * tabs.length > menuItems.length and inserting the missing menu\n\t * item(s) at the correct index.\n\t */\n\tconst prevSyncStateRef = useRef( null );\n\tuseEffect( () => {\n\t\tconst currentTabs = tabs.map( ( tab ) => ( {\n\t\t\tclientId: tab.clientId,\n\t\t\tanchor: tab.attributes.anchor ?? '',\n\t\t} ) );\n\n\t\tif ( prevSyncStateRef.current === null ) {\n\t\t\tprevSyncStateRef.current = {\n\t\t\t\ttabs: currentTabs,\n\t\t\t\tmenuItems: [ ...menuItems ],\n\t\t\t};\n\t\t\treturn;\n\t\t}\n\n\t\tconst { tabs: prevTabs, menuItems: prevMenuItems } =\n\t\t\tprevSyncStateRef.current;\n\n\t\tconst tabsRemoved = currentTabs.length < prevTabs.length;\n\t\tconst menuItemsRemoved = menuItems.length < prevMenuItems.length;\n\n\t\t// Update snapshot to the current state.\n\t\t// Snapshot is updated eagerly; post-removal mutations keep it consistent\n\t\t// so the next effect invocation sees a stable baseline.\n\t\tprevSyncStateRef.current = {\n\t\t\ttabs: currentTabs,\n\t\t\tmenuItems: [ ...menuItems ],\n\t\t};\n\n\t\t// Lists are in sync, nothing changed, or toolbar already removed both.\n\t\tif (\n\t\t\t( ! tabsRemoved && ! menuItemsRemoved ) ||\n\t\t\t( tabsRemoved && menuItemsRemoved )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentTabIds = new Set( currentTabs.map( ( t ) => t.clientId ) );\n\t\tconst currentMenuItemIds = new Set(\n\t\t\tmenuItems.map( ( m ) => m.clientId )\n\t\t);\n\n\t\tif ( tabsRemoved ) {\n\t\t\tprevTabs.forEach( ( prevTab ) => {\n\t\t\t\tif ( currentTabIds.has( prevTab.clientId ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst expectedMenuAnchor = prevTab.anchor\n\t\t\t\t\t? `${ prevTab.anchor }-button`\n\t\t\t\t\t: null;\n\t\t\t\tconst menuItemToRemove = expectedMenuAnchor\n\t\t\t\t\t? menuItems.find( ( m ) => m.anchor === expectedMenuAnchor )\n\t\t\t\t\t: null;\n\t\t\t\tif ( menuItemToRemove ) {\n\t\t\t\t\tremoveBlock( menuItemToRemove.clientId, false );\n\t\t\t\t\tprevSyncStateRef.current.menuItems =\n\t\t\t\t\t\tprevSyncStateRef.current.menuItems.filter(\n\t\t\t\t\t\t\t( m ) => m.clientId !== menuItemToRemove.clientId\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} );\n\t\t} else {\n\t\t\tprevMenuItems.forEach( ( prevItem ) => {\n\t\t\t\tif ( currentMenuItemIds.has( prevItem.clientId ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst expectedTabAnchor =\n\t\t\t\t\tprevItem.anchor?.replace( /-button$/, '' ) ?? '';\n\t\t\t\tconst tabToRemove = tabs.find(\n\t\t\t\t\t( tab ) =>\n\t\t\t\t\t\t( tab.attributes.anchor ?? '' ) === expectedTabAnchor\n\t\t\t\t);\n\t\t\t\tif ( tabToRemove ) {\n\t\t\t\t\tremoveBlock( tabToRemove.clientId, false );\n\t\t\t\t\tprevSyncStateRef.current.tabs =\n\t\t\t\t\t\tprevSyncStateRef.current.tabs.filter(\n\t\t\t\t\t\t\t( t ) => t.clientId !== tabToRemove.clientId\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}, [ tabs, menuItems, removeBlock ] );\n\n\t/**\n\t * Memoize context value to prevent unnecessary re-renders.\n\t */\n\tconst contextValue = useMemo( () => {\n\t\t/**\n\t\t * Compute tabs list from innerblocks to provide via context.\n\t\t * This traverses the tab-panel block to find all tab blocks\n\t\t * and extracts their label and anchor for the tabs-menu to consume.\n\t\t */\n\t\tconst tabList = tabs.map( ( tab, index ) => ( {\n\t\t\tid: tab.attributes.anchor || `tab-${ index }`,\n\t\t\tlabel: tab.attributes.label || '',\n\t\t\tclientId: tab.clientId,\n\t\t\tindex,\n\t\t} ) );\n\n\t\treturn {\n\t\t\t'core/tabs-list': tabList,\n\t\t\t'core/tabs-id': anchor,\n\t\t\t'core/tabs-activeTabIndex': activeTabIndex,\n\t\t\t'core/tabs-editorActiveTabIndex': editorActiveTabIndex,\n\t\t};\n\t}, [ tabs, anchor, activeTabIndex, editorActiveTabIndex ] );\n\n\t/**\n\t * Block props for the tabs container.\n\t */\n\tconst blockProps = useBlockProps( {\n\t\tclassName: layoutClassNames,\n\t} );\n\n\t/**\n\t * Innerblocks props for the tabs container.\n\t */\n\tconst innerBlockProps = useInnerBlocksProps( blockProps, {\n\t\t__experimentalCaptureToolbars: true,\n\t\ttemplate: TABS_TEMPLATE,\n\t\ttemplateLock: false,\n\t\trenderAppender: false,\n\t} );\n\n\treturn (\n\t\t<BlockContextProvider value={ contextValue }>\n\t\t\t<div { ...innerBlockProps }>\n\t\t\t\t<Controls\n\t\t\t\t\tclientId={ clientId }\n\t\t\t\t\tattributes={ attributes }\n\t\t\t\t\tsetAttributes={ setAttributes }\n\t\t\t\t/>\n\t\t\t\t{ innerBlockProps.children }\n\t\t\t</div>\n\t\t</BlockContextProvider>\n\t);\n}\n\nexport default Edit;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -12,13 +12,23 @@ var settings = {
|
|
|
12
12
|
innerBlocks: [
|
|
13
13
|
{
|
|
14
14
|
name: "core/tabs-menu",
|
|
15
|
-
innerBlocks: [
|
|
15
|
+
innerBlocks: [
|
|
16
|
+
{
|
|
17
|
+
name: "core/tabs-menu-item",
|
|
18
|
+
attributes: { anchor: "tab-1-button" }
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "core/tabs-menu-item",
|
|
22
|
+
attributes: { anchor: "tab-2-button" }
|
|
23
|
+
}
|
|
24
|
+
]
|
|
16
25
|
},
|
|
17
26
|
{
|
|
18
27
|
name: "core/tab-panel",
|
|
19
|
-
innerBlocks: [1, 2
|
|
28
|
+
innerBlocks: [1, 2].map((index) => ({
|
|
20
29
|
name: "core/tab",
|
|
21
30
|
attributes: {
|
|
31
|
+
anchor: `tab-${index}`,
|
|
22
32
|
label: sprintf(
|
|
23
33
|
/** translators: %s: tab index number */
|
|
24
34
|
__("Tab %s"),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/tabs/index.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { __, sprintf } from '@wordpress/i18n';\nimport { tabs as icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies\n */\nimport initBlock from '../utils/init-block';\nimport edit from './edit';\nimport save from './save';\nimport metadata from './block.json';\n\nconst { name } = metadata;\n\nexport { metadata, name };\n\nexport const settings = {\n\ticon,\n\texample: {\n\t\tinnerBlocks: [\n\t\t\t{\n\t\t\t\tname: 'core/tabs-menu',\n\t\t\t\tinnerBlocks: [ {
|
|
5
|
-
"mappings": ";AAGA,SAAS,IAAI,eAAe;AAC5B,SAAS,QAAQ,YAAY;AAK7B,OAAO,eAAe;AACtB,OAAO,UAAU;AACjB,OAAO,UAAU;AACjB,OAAO,cAAc;AAErB,IAAM,EAAE,KAAK,IAAI;AAIV,IAAM,WAAW;AAAA,EACvB;AAAA,EACA,SAAS;AAAA,IACR,aAAa;AAAA,MACZ;AAAA,QACC,MAAM;AAAA,QACN,aAAa,
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { __, sprintf } from '@wordpress/i18n';\nimport { tabs as icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies\n */\nimport initBlock from '../utils/init-block';\nimport edit from './edit';\nimport save from './save';\nimport metadata from './block.json';\n\nconst { name } = metadata;\n\nexport { metadata, name };\n\nexport const settings = {\n\ticon,\n\texample: {\n\t\tinnerBlocks: [\n\t\t\t{\n\t\t\t\tname: 'core/tabs-menu',\n\t\t\t\tinnerBlocks: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'core/tabs-menu-item',\n\t\t\t\t\t\tattributes: { anchor: 'tab-1-button' },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'core/tabs-menu-item',\n\t\t\t\t\t\tattributes: { anchor: 'tab-2-button' },\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'core/tab-panel',\n\t\t\t\tinnerBlocks: [ 1, 2 ].map( ( index ) => ( {\n\t\t\t\t\tname: 'core/tab',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tanchor: `tab-${ index }`,\n\t\t\t\t\t\tlabel: sprintf(\n\t\t\t\t\t\t\t/** translators: %s: tab index number */\n\t\t\t\t\t\t\t__( 'Tab %s' ),\n\t\t\t\t\t\t\tindex\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\tinnerBlocks: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'core/paragraph',\n\t\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t\tcontent: __(\n\t\t\t\t\t\t\t\t\t'In a village of La Mancha, the name of which I have no desire to call to mind, there lived not long since one of those gentlemen that keep a lance in the lance-rack, an old buckler, a lean hack, and a greyhound for coursing.'\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t} ) ),\n\t\t\t},\n\t\t],\n\t},\n\tedit,\n\tsave,\n};\n\nexport const init = () => initBlock( { name, metadata, settings } );\n"],
|
|
5
|
+
"mappings": ";AAGA,SAAS,IAAI,eAAe;AAC5B,SAAS,QAAQ,YAAY;AAK7B,OAAO,eAAe;AACtB,OAAO,UAAU;AACjB,OAAO,UAAU;AACjB,OAAO,cAAc;AAErB,IAAM,EAAE,KAAK,IAAI;AAIV,IAAM,WAAW;AAAA,EACvB;AAAA,EACA,SAAS;AAAA,IACR,aAAa;AAAA,MACZ;AAAA,QACC,MAAM;AAAA,QACN,aAAa;AAAA,UACZ;AAAA,YACC,MAAM;AAAA,YACN,YAAY,EAAE,QAAQ,eAAe;AAAA,UACtC;AAAA,UACA;AAAA,YACC,MAAM;AAAA,YACN,YAAY,EAAE,QAAQ,eAAe;AAAA,UACtC;AAAA,QACD;AAAA,MACD;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,aAAa,CAAE,GAAG,CAAE,EAAE,IAAK,CAAE,WAAa;AAAA,UACzC,MAAM;AAAA,UACN,YAAY;AAAA,YACX,QAAQ,OAAQ,KAAM;AAAA,YACtB,OAAO;AAAA;AAAA,cAEN,GAAI,QAAS;AAAA,cACb;AAAA,YACD;AAAA,UACD;AAAA,UACA,aAAa;AAAA,YACZ;AAAA,cACC,MAAM;AAAA,cACN,YAAY;AAAA,gBACX,SAAS;AAAA,kBACR;AAAA,gBACD;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,QACD,EAAI;AAAA,MACL;AAAA,IACD;AAAA,EACD;AAAA,EACA;AAAA,EACA;AACD;AAEO,IAAM,OAAO,MAAM,UAAW,EAAE,MAAM,UAAU,SAAS,CAAE;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -10,12 +10,7 @@
|
|
|
10
10
|
"textdomain": "default",
|
|
11
11
|
"parent": [ "core/tabs" ],
|
|
12
12
|
"allowedBlocks": [ "core/tabs-menu-item" ],
|
|
13
|
-
"usesContext": [
|
|
14
|
-
"core/tabs-list",
|
|
15
|
-
"core/tabs-id",
|
|
16
|
-
"core/tabs-activeTabIndex",
|
|
17
|
-
"core/tabs-editorActiveTabIndex"
|
|
18
|
-
],
|
|
13
|
+
"usesContext": [ "core/tabs-list" ],
|
|
19
14
|
"attributes": {},
|
|
20
15
|
"supports": {
|
|
21
16
|
"html": false,
|
|
@@ -1,183 +1,34 @@
|
|
|
1
1
|
// packages/block-library/src/tabs-menu/edit.js
|
|
2
2
|
import clsx from "clsx";
|
|
3
|
-
import { __ } from "@wordpress/i18n";
|
|
4
3
|
import {
|
|
5
4
|
useBlockProps,
|
|
6
5
|
useInnerBlocksProps,
|
|
7
|
-
|
|
8
|
-
__experimentalUseBlockPreview as useBlockPreview,
|
|
9
|
-
store as blockEditorStore,
|
|
10
|
-
useBlockEditContext
|
|
6
|
+
store as blockEditorStore
|
|
11
7
|
} from "@wordpress/block-editor";
|
|
12
|
-
import { useSelect
|
|
13
|
-
import {
|
|
14
|
-
memo,
|
|
15
|
-
useMemo,
|
|
16
|
-
useState,
|
|
17
|
-
useEffect,
|
|
18
|
-
useCallback
|
|
19
|
-
} from "@wordpress/element";
|
|
8
|
+
import { useSelect } from "@wordpress/data";
|
|
20
9
|
import AddTabToolbarControl from "../tab/add-tab-toolbar-control.mjs";
|
|
21
10
|
import RemoveTabToolbarControl from "../tab/remove-tab-toolbar-control.mjs";
|
|
22
11
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
isHidden,
|
|
29
|
-
setActiveBlockContextId
|
|
30
|
-
}) {
|
|
31
|
-
const blockPreviewProps = useBlockPreview({ blocks });
|
|
32
|
-
const handleOnClick = () => {
|
|
33
|
-
setActiveBlockContextId(blockContextId);
|
|
34
|
-
};
|
|
35
|
-
const style = {
|
|
36
|
-
display: isHidden ? "none" : "flex"
|
|
37
|
-
};
|
|
38
|
-
return /* @__PURE__ */ jsx(
|
|
39
|
-
"div",
|
|
40
|
-
{
|
|
41
|
-
...blockPreviewProps,
|
|
42
|
-
tabIndex: 0,
|
|
43
|
-
role: "button",
|
|
44
|
-
onClick: handleOnClick,
|
|
45
|
-
onKeyDown: handleOnClick,
|
|
46
|
-
style
|
|
47
|
-
}
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
var MemoizedTabsMenuItemPreview = memo(TabsMenuItemPreview);
|
|
51
|
-
function TabsMenuItemTemplateBlocks({ wrapperProps = {}, layout }) {
|
|
52
|
-
const innerBlocksProps = useInnerBlocksProps(wrapperProps, {
|
|
53
|
-
template: TABS_MENU_ITEM_TEMPLATE,
|
|
54
|
-
templateLock: "all",
|
|
55
|
-
renderAppender: false,
|
|
56
|
-
layout
|
|
57
|
-
});
|
|
58
|
-
return innerBlocksProps.children;
|
|
59
|
-
}
|
|
60
|
-
function Edit({
|
|
61
|
-
context,
|
|
62
|
-
clientId,
|
|
63
|
-
__unstableLayoutClassNames: layoutClassNames
|
|
64
|
-
}) {
|
|
65
|
-
const { layout } = useBlockEditContext();
|
|
66
|
-
const tabsId = context["core/tabs-id"] || null;
|
|
67
|
-
const tabsList = context["core/tabs-list"] || EMPTY_ARRAY;
|
|
68
|
-
const activeTabIndex = context["core/tabs-activeTabIndex"] ?? 0;
|
|
69
|
-
const editorActiveTabIndex = context["core/tabs-editorActiveTabIndex"];
|
|
70
|
-
const effectiveActiveIndex = useMemo(() => {
|
|
71
|
-
return editorActiveTabIndex ?? activeTabIndex;
|
|
72
|
-
}, [editorActiveTabIndex, activeTabIndex]);
|
|
73
|
-
const { __unstableMarkNextChangeAsNotPersistent } = useDispatch(blockEditorStore);
|
|
74
|
-
const { updateBlockAttributes } = useDispatch(blockEditorStore);
|
|
75
|
-
const [activeBlockContextId, setActiveBlockContextId] = useState(null);
|
|
76
|
-
const { blocks, tabsClientId } = useSelect(
|
|
77
|
-
(select) => {
|
|
78
|
-
const { getBlocks, getBlockRootClientId } = select(blockEditorStore);
|
|
79
|
-
return {
|
|
80
|
-
blocks: getBlocks(clientId),
|
|
81
|
-
tabsClientId: getBlockRootClientId(clientId)
|
|
82
|
-
};
|
|
83
|
-
},
|
|
12
|
+
function Edit({ clientId, __unstableLayoutClassNames: layoutClassNames }) {
|
|
13
|
+
const { tabsClientId } = useSelect(
|
|
14
|
+
(select) => ({
|
|
15
|
+
tabsClientId: select(blockEditorStore).getBlockRootClientId(clientId)
|
|
16
|
+
}),
|
|
84
17
|
[clientId]
|
|
85
18
|
);
|
|
86
|
-
const blockContexts = useMemo(() => {
|
|
87
|
-
return tabsList.map((tab, index) => ({
|
|
88
|
-
"core/tabs-menu-item-index": index,
|
|
89
|
-
"core/tabs-menu-item-id": tab.id || `tab-${index}`,
|
|
90
|
-
"core/tabs-menu-item-label": tab.label || "",
|
|
91
|
-
"core/tabs-menu-item-clientId": tab.clientId,
|
|
92
|
-
// Pass through parent context
|
|
93
|
-
"core/tabs-id": tabsId,
|
|
94
|
-
"core/tabs-list": tabsList,
|
|
95
|
-
"core/tabs-activeTabIndex": activeTabIndex,
|
|
96
|
-
"core/tabs-editorActiveTabIndex": editorActiveTabIndex
|
|
97
|
-
}));
|
|
98
|
-
}, [tabsList, tabsId, activeTabIndex, editorActiveTabIndex]);
|
|
99
|
-
const getContextId = useCallback((blockContext) => {
|
|
100
|
-
return `tab-context-${blockContext["core/tabs-menu-item-index"]}`;
|
|
101
|
-
}, []);
|
|
102
|
-
useEffect(() => {
|
|
103
|
-
if (blockContexts.length > 0 && activeBlockContextId === null) {
|
|
104
|
-
setActiveBlockContextId(getContextId(blockContexts[0]));
|
|
105
|
-
}
|
|
106
|
-
}, [blockContexts, activeBlockContextId, getContextId]);
|
|
107
|
-
useEffect(() => {
|
|
108
|
-
if (blockContexts.length > 0 && effectiveActiveIndex < blockContexts.length) {
|
|
109
|
-
const newContextId = getContextId(
|
|
110
|
-
blockContexts[effectiveActiveIndex]
|
|
111
|
-
);
|
|
112
|
-
setActiveBlockContextId(
|
|
113
|
-
(prevId) => prevId !== newContextId ? newContextId : prevId
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
}, [effectiveActiveIndex, blockContexts, getContextId]);
|
|
117
|
-
const handleTabContextClick = useCallback(
|
|
118
|
-
(index) => {
|
|
119
|
-
if (tabsClientId && index !== effectiveActiveIndex) {
|
|
120
|
-
__unstableMarkNextChangeAsNotPersistent();
|
|
121
|
-
updateBlockAttributes(tabsClientId, {
|
|
122
|
-
editorActiveTabIndex: index
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
[
|
|
127
|
-
tabsClientId,
|
|
128
|
-
effectiveActiveIndex,
|
|
129
|
-
updateBlockAttributes,
|
|
130
|
-
__unstableMarkNextChangeAsNotPersistent
|
|
131
|
-
]
|
|
132
|
-
);
|
|
133
19
|
const blockProps = useBlockProps({
|
|
134
20
|
className: clsx(layoutClassNames),
|
|
135
21
|
role: "tablist"
|
|
136
22
|
});
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
] });
|
|
143
|
-
}
|
|
23
|
+
const innerBlocksProps = useInnerBlocksProps(blockProps, {
|
|
24
|
+
allowedBlocks: ["core/tabs-menu-item"],
|
|
25
|
+
orientation: "horizontal",
|
|
26
|
+
renderAppender: false
|
|
27
|
+
});
|
|
144
28
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
145
29
|
/* @__PURE__ */ jsx(AddTabToolbarControl, { tabsClientId }),
|
|
146
30
|
/* @__PURE__ */ jsx(RemoveTabToolbarControl, { tabsClientId }),
|
|
147
|
-
/* @__PURE__ */ jsx("div", { ...
|
|
148
|
-
const contextId = getContextId(blockContext);
|
|
149
|
-
const isVisible = contextId === activeBlockContextId;
|
|
150
|
-
return /* @__PURE__ */ jsxs(
|
|
151
|
-
BlockContextProvider,
|
|
152
|
-
{
|
|
153
|
-
value: blockContext,
|
|
154
|
-
children: [
|
|
155
|
-
isVisible ? /* @__PURE__ */ jsx(
|
|
156
|
-
TabsMenuItemTemplateBlocks,
|
|
157
|
-
{
|
|
158
|
-
wrapperProps: {
|
|
159
|
-
onClick: () => handleTabContextClick(index)
|
|
160
|
-
},
|
|
161
|
-
layout
|
|
162
|
-
}
|
|
163
|
-
) : null,
|
|
164
|
-
/* @__PURE__ */ jsx(
|
|
165
|
-
MemoizedTabsMenuItemPreview,
|
|
166
|
-
{
|
|
167
|
-
blocks,
|
|
168
|
-
blockContextId: contextId,
|
|
169
|
-
setActiveBlockContextId: (id) => {
|
|
170
|
-
setActiveBlockContextId(id);
|
|
171
|
-
handleTabContextClick(index);
|
|
172
|
-
},
|
|
173
|
-
isHidden: isVisible
|
|
174
|
-
}
|
|
175
|
-
)
|
|
176
|
-
]
|
|
177
|
-
},
|
|
178
|
-
contextId
|
|
179
|
-
);
|
|
180
|
-
}) })
|
|
31
|
+
/* @__PURE__ */ jsx("div", { ...innerBlocksProps })
|
|
181
32
|
] });
|
|
182
33
|
}
|
|
183
34
|
var edit_default = Edit;
|