UNPKG

@wordpress/edit-post

Version:
116 lines (106 loc) 4.02 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import { createElement } from "@wordpress/element"; /** * External dependencies */ import { find } from 'lodash'; /** * WordPress dependencies */ import { createBlock, findTransform, getBlockTransforms, getBlockType, hasBlockSupport } from '@wordpress/blocks'; import { Button } from '@wordpress/components'; import { withSelect, withDispatch } from '@wordpress/data'; import { Warning, store as blockEditorStore } from '@wordpress/block-editor'; import { addFilter } from '@wordpress/hooks'; import { __ } from '@wordpress/i18n'; import { compose, createHigherOrderComponent } from '@wordpress/compose'; const enhance = compose( /** * For blocks whose block type doesn't support `multiple`, provides the * wrapped component with `originalBlockClientId` -- a reference to the * first block of the same type in the content -- if and only if that * "original" block is not the current one. Thus, an inexisting * `originalBlockClientId` prop signals that the block is valid. * * @param {WPComponent} WrappedBlockEdit A filtered BlockEdit instance. * * @return {WPComponent} Enhanced component with merged state data props. */ withSelect((select, block) => { const multiple = hasBlockSupport(block.name, 'multiple', true); // For block types with `multiple` support, there is no "original // block" to be found in the content, as the block itself is valid. if (multiple) { return {}; } // Otherwise, only pass `originalBlockClientId` if it refers to a different // block from the current one. const blocks = select(blockEditorStore).getBlocks(); const firstOfSameType = find(blocks, ({ name }) => block.name === name); const isInvalid = firstOfSameType && firstOfSameType.clientId !== block.clientId; return { originalBlockClientId: isInvalid && firstOfSameType.clientId }; }), withDispatch((dispatch, { originalBlockClientId }) => ({ selectFirst: () => dispatch(blockEditorStore).selectBlock(originalBlockClientId) }))); const withMultipleValidation = createHigherOrderComponent(BlockEdit => { return enhance(({ originalBlockClientId, selectFirst, ...props }) => { if (!originalBlockClientId) { return createElement(BlockEdit, props); } const blockType = getBlockType(props.name); const outboundType = getOutboundType(props.name); return [createElement("div", { key: "invalid-preview", style: { minHeight: '60px' } }, createElement(BlockEdit, _extends({ key: "block-edit" }, props))), createElement(Warning, { key: "multiple-use-warning", actions: [createElement(Button, { key: "find-original", isSecondary: true, onClick: selectFirst }, __('Find original')), createElement(Button, { key: "remove", isSecondary: true, onClick: () => props.onReplace([]) }, __('Remove')), outboundType && createElement(Button, { key: "transform", isSecondary: true, onClick: () => props.onReplace(createBlock(outboundType.name, props.attributes)) }, __('Transform into:'), " ", outboundType.title)] }, createElement("strong", null, blockType.title, ": "), __('This block can only be used once.'))]; }); }, 'withMultipleValidation'); /** * Given a base block name, returns the default block type to which to offer * transforms. * * @param {string} blockName Base block name. * * @return {?Object} The chosen default block type. */ function getOutboundType(blockName) { // Grab the first outbound transform const transform = findTransform(getBlockTransforms('to', blockName), ({ type, blocks }) => type === 'block' && blocks.length === 1 // What about when .length > 1? ); if (!transform) { return null; } return getBlockType(transform.blocks[0]); } addFilter('editor.BlockEdit', 'core/edit-post/validate-multiple-use/with-multiple-validation', withMultipleValidation); //# sourceMappingURL=index.js.map