@wordpress/block-library
Version:
Block library for the WordPress editor.
216 lines (210 loc) • 7.22 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = ReusableBlockEditRecursionWrapper;
var _clsx = _interopRequireDefault(require("clsx"));
var _data = require("@wordpress/data");
var _element = require("@wordpress/element");
var _coreData = require("@wordpress/core-data");
var _components = require("@wordpress/components");
var _i18n = require("@wordpress/i18n");
var _blockEditor = require("@wordpress/block-editor");
var _patterns = require("@wordpress/patterns");
var _blocks = require("@wordpress/blocks");
var _lockUnlock = require("../lock-unlock");
var _jsxRuntime = require("react/jsx-runtime");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const {
useLayoutClasses
} = (0, _lockUnlock.unlock)(_blockEditor.privateApis);
const {
hasOverridableBlocks
} = (0, _lockUnlock.unlock)(_patterns.privateApis);
const fullAlignments = ['full', 'wide', 'left', 'right'];
const useInferredLayout = (blocks, parentLayout) => {
const initialInferredAlignmentRef = (0, _element.useRef)();
return (0, _element.useMemo)(() => {
// Exit early if the pattern's blocks haven't loaded yet.
if (!blocks?.length) {
return {};
}
let alignment = initialInferredAlignmentRef.current;
// Only track the initial alignment so that temporarily removed
// alignments can be reapplied.
if (alignment === undefined) {
const isConstrained = parentLayout?.type === 'constrained';
const hasFullAlignment = blocks.some(block => fullAlignments.includes(block.attributes.align));
alignment = isConstrained && hasFullAlignment ? 'full' : null;
initialInferredAlignmentRef.current = alignment;
}
const layout = alignment ? parentLayout : undefined;
return {
alignment,
layout
};
}, [blocks, parentLayout]);
};
function RecursionWarning() {
const blockProps = (0, _blockEditor.useBlockProps)();
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
...blockProps,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.Warning, {
children: (0, _i18n.__)('Block cannot be rendered inside itself.')
})
});
}
const NOOP = () => {};
// Wrap the main Edit function for the pattern block with a recursion wrapper
// that allows short-circuiting rendering as early as possible, before any
// of the other effects in the block edit have run.
function ReusableBlockEditRecursionWrapper(props) {
const {
ref
} = props.attributes;
const hasAlreadyRendered = (0, _blockEditor.useHasRecursion)(ref);
if (hasAlreadyRendered) {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(RecursionWarning, {});
}
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.RecursionProvider, {
uniqueId: ref,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ReusableBlockEdit, {
...props
})
});
}
function ReusableBlockControl({
recordId,
canOverrideBlocks,
hasContent,
handleEditOriginal,
resetContent
}) {
const canUserEdit = (0, _data.useSelect)(select => !!select(_coreData.store).canUser('update', {
kind: 'postType',
name: 'wp_block',
id: recordId
}), [recordId]);
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [canUserEdit && !!handleEditOriginal && /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.BlockControls, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarGroup, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarButton, {
onClick: handleEditOriginal,
children: (0, _i18n.__)('Edit original')
})
})
}), canOverrideBlocks && /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.BlockControls, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarGroup, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarButton, {
onClick: resetContent,
disabled: !hasContent,
children: (0, _i18n.__)('Reset')
})
})
})]
});
}
function ReusableBlockEdit({
name,
attributes: {
ref,
content
},
__unstableParentLayout: parentLayout,
setAttributes
}) {
const {
record,
hasResolved
} = (0, _coreData.useEntityRecord)('postType', 'wp_block', ref);
const [blocks] = (0, _coreData.useEntityBlockEditor)('postType', 'wp_block', {
id: ref
});
const isMissing = hasResolved && !record;
const {
__unstableMarkLastChangeAsPersistent
} = (0, _data.useDispatch)(_blockEditor.store);
const {
onNavigateToEntityRecord,
hasPatternOverridesSource
} = (0, _data.useSelect)(select => {
const {
getSettings
} = select(_blockEditor.store);
// For editing link to the site editor if the theme and user permissions support it.
return {
onNavigateToEntityRecord: getSettings().onNavigateToEntityRecord,
hasPatternOverridesSource: !!(0, _blocks.getBlockBindingsSource)('core/pattern-overrides')
};
}, []);
const canOverrideBlocks = (0, _element.useMemo)(() => hasPatternOverridesSource && hasOverridableBlocks(blocks), [hasPatternOverridesSource, blocks]);
const {
alignment,
layout
} = useInferredLayout(blocks, parentLayout);
const layoutClasses = useLayoutClasses({
layout
}, name);
const blockProps = (0, _blockEditor.useBlockProps)({
className: (0, _clsx.default)('block-library-block__reusable-block-container', layout && layoutClasses, {
[`align${alignment}`]: alignment
})
});
const innerBlocksProps = (0, _blockEditor.useInnerBlocksProps)(blockProps, {
layout,
value: blocks,
onInput: NOOP,
onChange: NOOP,
renderAppender: blocks?.length ? undefined : _blockEditor.InnerBlocks.ButtonBlockAppender
});
const handleEditOriginal = () => {
onNavigateToEntityRecord({
postId: ref,
postType: 'wp_block'
});
};
const resetContent = () => {
if (content) {
// Make sure any previous changes are persisted before resetting.
__unstableMarkLastChangeAsPersistent();
setAttributes({
content: undefined
});
}
};
let children = null;
if (isMissing) {
children = /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.Warning, {
children: (0, _i18n.__)('Block has been deleted or is unavailable.')
});
}
if (!hasResolved) {
children = /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Placeholder, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Spinner, {})
});
}
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [hasResolved && !isMissing && /*#__PURE__*/(0, _jsxRuntime.jsx)(ReusableBlockControl, {
recordId: ref,
canOverrideBlocks: canOverrideBlocks,
hasContent: !!content,
handleEditOriginal: onNavigateToEntityRecord ? handleEditOriginal : undefined,
resetContent: resetContent
}), children === null ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
...innerBlocksProps
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
...blockProps,
children: children
})]
});
}
//# sourceMappingURL=edit.js.map
;