@wordpress/block-editor
Version:
182 lines (181 loc) • 5.97 kB
JavaScript
// packages/block-editor/src/hooks/block-hooks.js
import { __ } from "@wordpress/i18n";
import { Fragment, useMemo } from "@wordpress/element";
import { PanelBody, ToggleControl } from "@wordpress/components";
import { createBlock, store as blocksStore } from "@wordpress/blocks";
import { useDispatch, useSelect } from "@wordpress/data";
import { InspectorControls } from "../components";
import { store as blockEditorStore } from "../store";
import { jsx, jsxs } from "react/jsx-runtime";
var EMPTY_OBJECT = {};
function BlockHooksControlPure({
name,
clientId,
metadata: { ignoredHookedBlocks = [] } = {}
}) {
const blockTypes = useSelect(
(select) => select(blocksStore).getBlockTypes(),
[]
);
const hookedBlocksForCurrentBlock = useMemo(
() => blockTypes?.filter(
({ name: blockName, blockHooks }) => blockHooks && name in blockHooks || ignoredHookedBlocks.includes(blockName)
),
[blockTypes, name, ignoredHookedBlocks]
);
const hookedBlockClientIds = useSelect(
(select) => {
const { getBlocks, getBlockRootClientId: getBlockRootClientId2, getGlobalBlockCount } = select(blockEditorStore);
const rootClientId = getBlockRootClientId2(clientId);
const _hookedBlockClientIds = hookedBlocksForCurrentBlock.reduce(
(clientIds, block) => {
if (getGlobalBlockCount(block.name) === 0) {
return clientIds;
}
const relativePosition = block?.blockHooks?.[name];
let candidates;
switch (relativePosition) {
case "before":
case "after":
candidates = getBlocks(rootClientId);
break;
case "first_child":
case "last_child":
candidates = getBlocks(clientId);
break;
case void 0:
candidates = [
...getBlocks(rootClientId),
...getBlocks(clientId)
];
break;
}
const hookedBlock = candidates?.find(
(candidate) => candidate.name === block.name
);
if (hookedBlock) {
return {
...clientIds,
[block.name]: hookedBlock.clientId
};
}
return clientIds;
},
{}
);
if (Object.values(_hookedBlockClientIds).length > 0) {
return _hookedBlockClientIds;
}
return EMPTY_OBJECT;
},
[hookedBlocksForCurrentBlock, name, clientId]
);
const { getBlockIndex, getBlockCount, getBlockRootClientId } = useSelect(blockEditorStore);
const { insertBlock, removeBlock } = useDispatch(blockEditorStore);
if (!hookedBlocksForCurrentBlock.length) {
return null;
}
const groupedHookedBlocks = hookedBlocksForCurrentBlock.reduce(
(groups, block) => {
const [namespace] = block.name.split("/");
if (!groups[namespace]) {
groups[namespace] = [];
}
groups[namespace].push(block);
return groups;
},
{}
);
const insertBlockIntoDesignatedLocation = (block, relativePosition) => {
const blockIndex = getBlockIndex(clientId);
const innerBlocksLength = getBlockCount(clientId);
const rootClientId = getBlockRootClientId(clientId);
switch (relativePosition) {
case "before":
case "after":
insertBlock(
block,
relativePosition === "after" ? blockIndex + 1 : blockIndex,
rootClientId,
// Insert as a child of the current block's parent
false
);
break;
case "first_child":
case "last_child":
insertBlock(
block,
// TODO: It'd be great if insertBlock() would accept negative indices for insertion.
relativePosition === "first_child" ? 0 : innerBlocksLength,
clientId,
// Insert as a child of the current block.
false
);
break;
case void 0:
insertBlock(
block,
blockIndex + 1,
rootClientId,
// Insert as a child of the current block's parent
false
);
break;
}
};
return /* @__PURE__ */ jsx(InspectorControls, { children: /* @__PURE__ */ jsxs(
PanelBody,
{
className: "block-editor-hooks__block-hooks",
title: __("Plugins"),
initialOpen: true,
children: [
/* @__PURE__ */ jsx("p", { className: "block-editor-hooks__block-hooks-helptext", children: __(
"Manage the inclusion of blocks added automatically by plugins."
) }),
Object.keys(groupedHookedBlocks).map((vendor) => {
return /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx("h3", { children: vendor }),
groupedHookedBlocks[vendor].map((block) => {
const checked = block.name in hookedBlockClientIds;
return /* @__PURE__ */ jsx(
ToggleControl,
{
__nextHasNoMarginBottom: true,
checked,
label: block.title,
onChange: () => {
if (!checked) {
const relativePosition = block.blockHooks[name];
insertBlockIntoDesignatedLocation(
createBlock(block.name),
relativePosition
);
return;
}
removeBlock(
hookedBlockClientIds[block.name],
false
);
}
},
block.title
);
})
] }, vendor);
})
]
}
) });
}
var block_hooks_default = {
edit: BlockHooksControlPure,
attributeKeys: ["metadata"],
hasSupport() {
return true;
}
};
export {
block_hooks_default as default
};
//# sourceMappingURL=block-hooks.js.map